2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
19 #include <rx/rxstat.h>
21 #include <afs/afs_AdminErrors.h>
22 #include <afs/afs_utilAdmin.h>
23 #include <afs/ptint.h>
24 #include <afs/ptserver.h>
26 #include "afs_ptsAdmin.h"
27 #include "../adminutil/afs_AdminInternal.h"
30 * IsValidCellHandle - validate the cell handle for making pts
35 * IN cellHandle - a previously opened cellHandle that is to be validated.
39 * No locks are obtained or released by this function
43 * Returns != 0 upon successful completion.
48 IsValidCellHandle(const afs_cell_handle_p c_handle
, afs_status_p st
)
53 if (!CellHandleIsValid((void *)c_handle
, &tst
)) {
54 goto fail_IsValidCellHandle
;
57 if (c_handle
->pts_valid
== 0) {
58 tst
= ADMCLIENTCELLPTSINVALID
;
59 goto fail_IsValidCellHandle
;
62 if (c_handle
->pts
== NULL
) {
63 tst
= ADMCLIENTCELLPTSNULL
;
64 goto fail_IsValidCellHandle
;
69 fail_IsValidCellHandle
:
79 * TranslatePTSNames - translate character representations of pts names
80 * into their numeric equivalent.
84 * IN cellHandle - a previously opened cellHandle that corresponds
85 * to the cell where the id's exist.
87 * IN names - the list of names to be translated.
89 * OUT ids - the list of translated names
93 * No locks are obtained or released by this function
97 * Returns != 0 upon successful completion.
102 TranslatePTSNames(const afs_cell_handle_p cellHandle
, namelist
* names
,
103 idlist
* ids
, afs_status_p st
)
106 afs_status_t tst
= 0;
111 * Lowercase the names to translate
114 for (i
= 0; i
< names
->namelist_len
; i
++) {
115 p
= names
->namelist_val
[i
];
122 tst
= ubik_PR_NameToID(cellHandle
->pts
, 0, names
, ids
);
125 goto fail_TranslatePTSNames
;
130 * Check to see if the lookup failed
133 for (i
= 0; i
< ids
->idlist_len
; i
++) {
134 if (ids
->idlist_val
[i
] == ANONYMOUSID
) {
135 tst
= ADMPTSFAILEDNAMETRANSLATE
;
136 goto fail_TranslatePTSNames
;
141 fail_TranslatePTSNames
:
150 * TranslateTwoNames - translate two pts names to their pts ids.
154 * IN cellHandle - a previously opened cellHandle that corresponds
155 * to the cell where the group exists.
157 * IN id1 - one id to be translated
159 * IN error1 - the error status to be returned in the event that id1 is
162 * IN id2 - one id to be translated
164 * IN error2 - the error status to be returned in the event that id2 is
168 * OUT idlist - the list of pts id's
172 * No locks are obtained or released by this function
176 * Returns != 0 upon successful completion.
181 TranslateTwoNames(const afs_cell_handle_p c_handle
, const char *id1
,
182 afs_status_t error1
, const char *id2
, afs_status_t error2
,
183 idlist
* ids
, afs_status_p st
)
186 afs_status_t tst
= 0;
188 char tmp_array
[2 * PTS_MAX_NAME_LEN
];
191 * Copy the group and user names in order to translate them
194 names
.namelist_len
= 2;
195 names
.namelist_val
= (prname
*) & tmp_array
[0];
197 strncpy(names
.namelist_val
[0], id1
, PTS_MAX_NAME_LEN
);
198 names
.namelist_val
[0][PTS_MAX_NAME_LEN
- 1] = '\0';
199 strncpy(names
.namelist_val
[1], id2
, PTS_MAX_NAME_LEN
);
200 names
.namelist_val
[1][PTS_MAX_NAME_LEN
- 1] = '\0';
205 * Check that user and group aren't too long
206 * This is a cheaper check than calling strlen
209 if (names
.namelist_val
[0][PTS_MAX_NAME_LEN
- 1] != 0) {
211 goto fail_TranslateTwoNames
;
214 if (names
.namelist_val
[0][PTS_MAX_NAME_LEN
- 1] != 0) {
216 goto fail_TranslateTwoNames
;
220 * Translate user and group into pts ID's
223 if (TranslatePTSNames(c_handle
, &names
, ids
, &tst
) == 0) {
224 goto fail_TranslateTwoNames
;
229 fail_TranslateTwoNames
:
238 * TranslateOneName - translate a pts name to its pts id.
242 * IN cellHandle - a previously opened cellHandle that corresponds
243 * to the cell where the group exists.
245 * IN userName - the user to be translated.
247 * OUT idlist - the user pts id.
251 * No locks are obtained or released by this function
255 * Returns != 0 upon successful completion.
260 TranslateOneName(const afs_cell_handle_p c_handle
, const char *ptsName
,
261 afs_status_t tooLongError
, afs_int32
* ptsId
,
265 afs_status_t tst
= 0;
267 char tmp_array
[PTS_MAX_NAME_LEN
];
271 * Copy the name in order to translate it
274 names
[0].namelist_len
= 1;
275 names
[0].namelist_val
= (prname
*) & tmp_array
[0];
277 strncpy((char *)names
[0].namelist_val
, ptsName
, PTS_MAX_NAME_LEN
);
278 ((char *)names
[0].namelist_val
)[PTS_MAX_NAME_LEN
- 1] = '\0';
283 * Check that user isn't too long
284 * This is a cheaper check than calling strlen
287 if (names
[0].namelist_val
[0][PTS_MAX_NAME_LEN
- 1] != 0) {
289 goto fail_TranslateOneName
;
293 * Translate user into pts ID
296 if (TranslatePTSNames(c_handle
, names
, &ids
, &tst
) == 0) {
297 goto fail_TranslateOneName
;
299 if (ids
.idlist_val
!= NULL
) {
300 *ptsId
= *ids
.idlist_val
;
301 free(ids
.idlist_val
);
307 fail_TranslateOneName
:
316 * TranslatePTSIds - translate numeric representations of pts names
317 * into their character equivalent.
321 * IN cellHandle - a previously opened cellHandle that corresponds
322 * to the cell where the id's exist.
324 * IN ids - the list of ids to be translated.
326 * OUT names - the list of translated names
330 * No locks are obtained or released by this function
334 * Returns != 0 upon successful completion.
339 TranslatePTSIds(const afs_cell_handle_p cellHandle
, namelist
* names
,
340 idlist
* ids
, afs_status_p st
)
343 afs_status_t tst
= 0;
345 tst
= string_PR_IDToName(cellHandle
->pts
, 0, ids
, names
);
348 goto fail_TranslatePTSIds
;
352 fail_TranslatePTSIds
:
361 * pts_GroupMemberAdd - add one member to a pts group
365 * IN cellHandle - a previously opened cellHandle that corresponds
366 * to the cell where the group exists.
368 * IN userName - the name to be added to the group.
370 * IN groupName - the group to be modified.
374 * No locks are obtained or released by this function
378 * Returns != 0 upon successful completion.
383 pts_GroupMemberAdd(const void *cellHandle
, const char *userName
,
384 const char *groupName
, afs_status_p st
)
387 afs_status_t tst
= 0;
388 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
395 if (!IsValidCellHandle(c_handle
, &tst
)) {
396 goto fail_pts_GroupMemberAdd
;
399 if ((userName
== NULL
) || (*userName
== 0)) {
400 tst
= ADMPTSUSERNAMENULL
;
401 goto fail_pts_GroupMemberAdd
;
404 if ((groupName
== NULL
) || (*groupName
== 0)) {
405 tst
= ADMPTSGROUPNAMENULL
;
406 goto fail_pts_GroupMemberAdd
;
409 if (!TranslateTwoNames
410 (c_handle
, userName
, ADMPTSUSERNAMETOOLONG
, groupName
,
411 ADMPTSGROUPNAMETOOLONG
, &ids
, &tst
)) {
412 goto fail_pts_GroupMemberAdd
;
420 ubik_PR_AddToGroup(c_handle
->pts
, 0, ids
.idlist_val
[0],
424 goto fail_pts_GroupMemberAdd
;
428 fail_pts_GroupMemberAdd
:
430 if (ids
.idlist_val
!= 0) {
431 free(ids
.idlist_val
);
441 * pts_GroupOwnerChange - change the owner of a group
445 * IN cellHandle - a previously opened cellHandle that corresponds
446 * to the cell where the group exists.
448 * IN targetGroup - the group to be modified.
450 * IN userName - the new owner of the group.
454 * No locks are obtained or released by this function
458 * Returns != 0 upon successful completion.
463 pts_GroupOwnerChange(const void *cellHandle
, const char *targetGroup
,
464 const char *newOwner
, afs_status_p st
)
467 afs_status_t tst
= 0;
468 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
471 memset(&ids
, 0, sizeof(ids
));
477 if (!IsValidCellHandle(c_handle
, &tst
)) {
478 goto fail_pts_GroupOwnerChange
;
481 if ((newOwner
== NULL
) || (*newOwner
== 0)) {
482 tst
= ADMPTSNEWOWNERNULL
;
483 goto fail_pts_GroupOwnerChange
;
486 if ((targetGroup
== NULL
) || (*targetGroup
== 0)) {
487 tst
= ADMPTSTARGETGROUPNULL
;
488 goto fail_pts_GroupOwnerChange
;
491 if (!TranslateTwoNames
492 (c_handle
, newOwner
, ADMPTSNEWOWNERTOOLONG
, targetGroup
,
493 ADMPTSTARGETGROUPTOOLONG
, &ids
, &tst
)) {
494 goto fail_pts_GroupOwnerChange
;
502 ubik_PR_ChangeEntry(c_handle
->pts
, 0, ids
.idlist_val
[1], "",
503 ids
.idlist_val
[0], 0);
506 goto fail_pts_GroupOwnerChange
;
510 fail_pts_GroupOwnerChange
:
512 if (ids
.idlist_val
!= 0) {
513 free(ids
.idlist_val
);
523 * pts_GroupCreate - create a new group
527 * IN cellHandle - a previously opened cellHandle that corresponds
528 * to the cell where the group exists.
530 * IN newGroup - the group to be created.
532 * IN newOwner - the owner of the group. Pass NULL if the current user
533 * is to be the new owner, or the character string of the owner otherwise.
535 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
536 * generate a value, != 0 to assign a value on your own. The group id
537 * that is used to create the group is copied into this parameter in the
538 * event you pass in 0.
542 * No locks are obtained or released by this function
546 * Returns != 0 upon successful completion.
551 pts_GroupCreate(const void *cellHandle
, char *newGroup
,
552 char *newOwner
, int *newGroupId
, afs_status_p st
)
555 afs_status_t tst
= 0;
556 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
557 afs_int32 newOwnerId
= 0;
563 if (!IsValidCellHandle(c_handle
, &tst
)) {
564 goto fail_pts_GroupCreate
;
567 if ((newGroup
== NULL
) || (*newGroup
== 0)) {
568 tst
= ADMPTSNEWGROUPNULL
;
569 goto fail_pts_GroupCreate
;
572 if (newGroupId
== NULL
) {
573 tst
= ADMPTSNEWGROUPIDNULL
;
574 goto fail_pts_GroupCreate
;
577 if (*newGroupId
> 0) {
578 tst
= ADMPTSNEWGROUPIDPOSITIVE
;
579 goto fail_pts_GroupCreate
;
583 * If a newOwner was specified, validate that it exists
586 if (newOwner
!= NULL
) {
587 if (!TranslateOneName
588 (c_handle
, newOwner
, ADMPTSNEWOWNERTOOLONG
, &newOwnerId
, &tst
)) {
589 goto fail_pts_GroupCreate
;
594 * We make a different rpc based upon the input to this function
597 if (*newGroupId
!= 0) {
599 ubik_PR_INewEntry(c_handle
->pts
, 0, newGroup
, *newGroupId
,
603 ubik_PR_NewEntry(c_handle
->pts
, 0, newGroup
, PRGRP
,
604 newOwnerId
, newGroupId
);
608 goto fail_pts_GroupCreate
;
612 fail_pts_GroupCreate
:
621 * GetGroupAccess - a small convenience function for setting
626 * IN access - a pointer to a pts_groupAccess_t to be set with the
627 * correct permission.
629 * IN flag - the current permission flag used to derive the permission.
633 * No locks are obtained or released by this function
637 * Since this function cannot fail, it returns void.
642 GetGroupAccess(pts_groupAccess_p access
, afs_int32 flag
)
645 *access
= PTS_GROUP_OWNER_ACCESS
;
647 *access
= PTS_GROUP_OWNER_ACCESS
;
648 } else if (flag
== 1) {
649 *access
= PTS_GROUP_ACCESS
;
650 } else if (flag
== 2) {
651 *access
= PTS_GROUP_ANYUSER_ACCESS
;
657 * pts_GroupGet - retrieve information about a particular group.
661 * IN cellHandle - a previously opened cellHandle that corresponds
662 * to the cell where the group exists.
664 * IN groupName - the group to retrieve.
666 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
667 * successful completion is filled with information about groupName.
671 * No locks are obtained or released by this function
675 * Returns != 0 upon successful completion.
680 pts_GroupGet(const void *cellHandle
, const char *groupName
,
681 pts_GroupEntry_p groupP
, afs_status_p st
)
684 afs_status_t tst
= 0;
685 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
686 afs_int32 groupId
= 0;
689 struct prcheckentry groupEntry
;
698 if (!IsValidCellHandle(c_handle
, &tst
)) {
699 goto fail_pts_GroupGet
;
702 if ((groupName
== NULL
) || (*groupName
== 0)) {
703 tst
= ADMPTSGROUPNAMENULL
;
704 goto fail_pts_GroupGet
;
707 if (groupP
== NULL
) {
708 tst
= ADMPTSGROUPPNULL
;
709 goto fail_pts_GroupGet
;
713 * Translate the group name into an id.
716 if (!TranslateOneName
717 (c_handle
, groupName
, ADMPTSGROUPNAMETOOLONG
, &groupId
, &tst
)) {
718 goto fail_pts_GroupGet
;
722 * Retrieve information about the group
725 tst
= ubik_PR_ListEntry(c_handle
->pts
, 0, groupId
, &groupEntry
);
728 goto fail_pts_GroupGet
;
731 groupP
->membershipCount
= groupEntry
.count
;
732 groupP
->nameUid
= groupEntry
.id
;
733 groupP
->ownerUid
= groupEntry
.owner
;
734 groupP
->creatorUid
= groupEntry
.creator
;
735 strncpy(groupP
->name
, groupEntry
.name
, PTS_MAX_NAME_LEN
);
736 groupP
->name
[PTS_MAX_NAME_LEN
- 1] = '\0';
738 * Set the access rights based upon the value of the flags member
739 * of the groupEntry struct.
741 * To the best of my ability to decypher the pts code, it looks like
742 * the rights are stored in flags as follows:
744 * I number my bits from least significant to most significant starting
748 * if bit 0 == 0 -> r access is denied
749 * if bit 0 == 1 -> r access is granted
752 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
753 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
754 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
755 * if bit 2 == 1 and bit 1 == 1 -> this is an error
757 * membership - bits 3 and 4
758 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
759 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
760 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
761 * if bit 4 == 1 and bit 3 == 1 -> this is an error
764 * if bit 5 == 0 -> O access is denied
765 * if bit 5 == 1 -> O access is granted
767 * status - bits 6 and 7
768 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
769 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
770 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
771 * if bit 7 == 1 and bit 6 == 1 -> this is an error
773 * For cases where the permission doesn't make sense for the
774 * type of entry, or where an error occurs, we ignore it.
775 * This is the behavior of the pts code.
778 flags
= groupEntry
.flags
;
780 groupP
->listDelete
= PTS_GROUP_ACCESS
;
782 groupP
->listDelete
= PTS_GROUP_OWNER_ACCESS
;
788 GetGroupAccess(&groupP
->listAdd
, twobit
);
793 GetGroupAccess(&groupP
->listMembership
, twobit
);
798 groupP
->listGroupsOwned
= PTS_GROUP_ANYUSER_ACCESS
;
800 groupP
->listGroupsOwned
= PTS_GROUP_OWNER_ACCESS
;
806 GetGroupAccess(&groupP
->listStatus
, twobit
);
809 * Make another rpc and translate the owner and creator ids into
814 ids
.idlist_val
= ptsids
;
815 ptsids
[0] = groupEntry
.owner
;
816 ptsids
[1] = groupEntry
.creator
;
817 names
.namelist_len
= 0;
818 names
.namelist_val
= 0;
821 if (!TranslatePTSIds(c_handle
, &names
, &ids
, &tst
)) {
822 goto fail_pts_GroupGet
;
825 strncpy(groupP
->owner
, names
.namelist_val
[0], PTS_MAX_NAME_LEN
);
826 groupP
->owner
[PTS_MAX_NAME_LEN
- 1] = '\0';
827 strncpy(groupP
->creator
, names
.namelist_val
[1], PTS_MAX_NAME_LEN
);
828 groupP
->creator
[PTS_MAX_NAME_LEN
- 1] = '\0';
829 free(names
.namelist_val
);
841 * EntryDelete - delete a pts entry (group or user).
845 * IN cellHandle - a previously opened cellHandle that corresponds
846 * to the cell where the group exists.
848 * IN entryName - the entry to be deleted.
850 * IN error1 - the error status to be returned in the event that entryName is
853 * IN error2 - the error status to be returned in the event that entryName is
858 * No locks are obtained or released by this function
862 * Returns != 0 upon successful completion.
867 EntryDelete(const void *cellHandle
, const char *entryName
,
868 afs_status_t error1
, afs_status_t error2
, afs_status_p st
)
871 afs_status_t tst
= 0;
872 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
873 afs_int32 entryId
= 0;
879 if (!IsValidCellHandle(c_handle
, &tst
)) {
880 goto fail_EntryDelete
;
883 if ((entryName
== NULL
) || (*entryName
== 0)) {
885 goto fail_EntryDelete
;
889 * Translate the entry name into an id.
892 if (!TranslateOneName(c_handle
, entryName
, error2
, &entryId
, &tst
)) {
893 goto fail_EntryDelete
;
900 tst
= ubik_PR_Delete(c_handle
->pts
, 0, entryId
);
903 goto fail_EntryDelete
;
917 * pts_GroupDelete - delete a group
921 * IN cellHandle - a previously opened cellHandle that corresponds
922 * to the cell where the group exists.
924 * IN groupName - the group to be deleted.
928 * No locks are obtained or released by this function
932 * Returns != 0 upon successful completion.
937 pts_GroupDelete(const void *cellHandle
, const char *groupName
,
941 return EntryDelete(cellHandle
, groupName
, ADMPTSGROUPNAMENULL
,
942 ADMPTSGROUPNAMETOOLONG
, st
);
946 * pts_GroupMaxGet - get the maximum in use group id.
950 * IN cellHandle - a previously opened cellHandle that corresponds
951 * to the cell where the group exists.
953 * OUT maxGroupId - upon successful completion contains the maximum
954 * group Id in use at the server.
958 * No locks are obtained or released by this function
962 * Returns != 0 upon successful completion.
967 pts_GroupMaxGet(const void *cellHandle
, int *maxGroupId
, afs_status_p st
)
970 afs_status_t tst
= 0;
971 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
972 afs_int32 maxUserId
= 0;
978 if (!IsValidCellHandle(c_handle
, &tst
)) {
979 goto fail_pts_GroupMaxGet
;
982 if (maxGroupId
== NULL
) {
983 tst
= ADMPTSMAXGROUPIDNULL
;
984 goto fail_pts_GroupMaxGet
;
987 tst
= ubik_PR_ListMax(c_handle
->pts
, 0, &maxUserId
, maxGroupId
);
990 goto fail_pts_GroupMaxGet
;
994 fail_pts_GroupMaxGet
:
1003 * pts_GroupMaxSet - set the maximum in use group id.
1007 * IN cellHandle - a previously opened cellHandle that corresponds
1008 * to the cell where the group exists.
1010 * IN maxGroupId - the new maximum group id.
1014 * No locks are obtained or released by this function
1018 * Returns != 0 upon successful completion.
1023 pts_GroupMaxSet(const void *cellHandle
, int maxGroupId
, afs_status_p st
)
1026 afs_status_t tst
= 0;
1027 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1030 * Validate arguments
1033 if (!IsValidCellHandle(c_handle
, &tst
)) {
1034 goto fail_pts_GroupMaxSet
;
1037 tst
= ubik_PR_SetMax(c_handle
->pts
, 0, maxGroupId
, PRGRP
);
1040 goto fail_pts_GroupMaxSet
;
1044 fail_pts_GroupMaxSet
:
1055 * I'm not using the common iterator pattern here since the retrival
1056 * of the member list is actually accomplished in 1 rpc. There's no
1057 * sense in trying to fit this pts specific behavior into the more
1058 * generic model, so instead the Begin functions actually do all the
1059 * rpc work and the next/done functions just manipulate the retrieved
1063 typedef struct pts_group_member_list_iterator
{
1066 pthread_mutex_t mutex
; /* hold to manipulate this structure */
1071 } pts_group_member_list_iterator_t
, *pts_group_member_list_iterator_p
;
1074 * pts_GroupMemberListBegin - begin iterating over the list of members
1075 * of a particular group.
1079 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1083 * No locks are obtained or released by this function
1087 * Returns != 0 upon successful completion.
1092 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter
,
1096 afs_status_t tst
= 0;
1099 tst
= ADMITERATORNULL
;
1100 goto fail_IsValidPtsGroupMemberListIterator
;
1103 if ((iter
->begin_magic
!= BEGIN_MAGIC
) || (iter
->end_magic
!= END_MAGIC
)) {
1104 tst
= ADMITERATORBADMAGICNULL
;
1105 goto fail_IsValidPtsGroupMemberListIterator
;
1108 if (iter
->is_valid
== 0) {
1109 tst
= ADMITERATORINVALID
;
1110 goto fail_IsValidPtsGroupMemberListIterator
;
1114 fail_IsValidPtsGroupMemberListIterator
:
1123 * MemberListBegin - an internal function which is used to get both
1124 * the list of members in a group and the list of groups a user belongs
1129 * IN cellHandle - a previously opened cellHandle that corresponds
1130 * to the cell where the group exists.
1132 * IN name - the name whose membership will be retrieved.
1134 * OUT iterationIdP - upon successful completion contains a iterator that
1135 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1139 * No locks are obtained or released by this function
1143 * Returns != 0 upon successful completion.
1148 MemberListBegin(const void *cellHandle
, const char *name
, afs_status_t error1
,
1149 afs_status_t error2
, void **iterationIdP
, afs_status_p st
)
1152 afs_status_t tst
= 0;
1153 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1154 afs_int32 groupId
= 0;
1155 afs_int32 exceeded
= 0;
1156 pts_group_member_list_iterator_p iter
=
1157 malloc(sizeof(pts_group_member_list_iterator_t
));
1158 int iter_allocated
= 0;
1159 int ids_allocated
= 0;
1160 int names_allocated
= 0;
1161 int mutex_inited
= 0;
1164 * Validate arguments
1167 if (!IsValidCellHandle(c_handle
, &tst
)) {
1168 goto fail_MemberListBegin
;
1171 if ((name
== NULL
) || (*name
== 0)) {
1172 tst
= ADMPTSGROUPNAMENULL
;
1173 goto fail_MemberListBegin
;
1176 if (iterationIdP
== NULL
) {
1177 tst
= ADMITERATORNULL
;
1178 goto fail_MemberListBegin
;
1183 goto fail_MemberListBegin
;
1189 * Translate the name into an id.
1192 if (!TranslateOneName
1193 (c_handle
, name
, ADMPTSGROUPNAMETOOLONG
, &groupId
, &tst
)) {
1194 goto fail_MemberListBegin
;
1197 if (pthread_mutex_init(&iter
->mutex
, 0)) {
1199 goto fail_MemberListBegin
;
1204 iter
->ids
.prlist_len
= 0;
1205 iter
->ids
.prlist_val
= 0;
1208 ubik_PR_ListElements(c_handle
->pts
, 0, groupId
, &iter
->ids
,
1212 goto fail_MemberListBegin
;
1215 if (exceeded
!= 0) {
1216 tst
= ADMPTSGROUPMEMEXCEEDED
;
1217 goto fail_MemberListBegin
;
1221 iter
->names
.namelist_len
= 0;
1222 iter
->names
.namelist_val
= 0;
1224 if (!TranslatePTSIds
1225 (c_handle
, &iter
->names
, (idlist
*) & iter
->ids
, &tst
)) {
1226 goto fail_MemberListBegin
;
1229 names_allocated
= 1;
1230 iter
->begin_magic
= BEGIN_MAGIC
;
1231 iter
->end_magic
= END_MAGIC
;
1235 *iterationIdP
= (void *)iter
;
1238 fail_MemberListBegin
:
1240 if (ids_allocated
) {
1241 free(iter
->ids
.prlist_val
);
1245 if (names_allocated
) {
1246 free(iter
->names
.namelist_val
);
1249 pthread_mutex_destroy(&iter
->mutex
);
1251 if (iter_allocated
) {
1263 * pts_GroupMemberListBegin - begin iterating over the list of members
1264 * of a particular group.
1268 * IN cellHandle - a previously opened cellHandle that corresponds
1269 * to the cell where the group exists.
1271 * IN groupName - the group whose members will be returned.
1273 * OUT iterationIdP - upon successful completion contains a iterator that
1274 * can be passed to pts_GroupMemberListNext.
1278 * No locks are obtained or released by this function
1282 * Returns != 0 upon successful completion.
1287 pts_GroupMemberListBegin(const void *cellHandle
, const char *groupName
,
1288 void **iterationIdP
, afs_status_p st
)
1290 return MemberListBegin(cellHandle
, groupName
, ADMPTSGROUPNAMENULL
,
1291 ADMPTSGROUPNAMETOOLONG
, iterationIdP
, st
);
1295 * pts_GroupMemberListNext - get the next member of a group
1299 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1301 * OUT memberName - upon successful completion contains the next member of
1306 * The iterator mutex is held during the retrieval of the next member.
1310 * Returns != 0 upon successful completion.
1315 pts_GroupMemberListNext(const void *iterationId
, char *memberName
,
1319 afs_status_t tst
= 0;
1320 pts_group_member_list_iterator_p iter
=
1321 (pts_group_member_list_iterator_p
) iterationId
;
1322 int mutex_locked
= 0;
1325 * Validate arguments
1329 tst
= ADMITERATORNULL
;
1330 goto fail_pts_GroupMemberListNext
;
1333 if (memberName
== NULL
) {
1334 tst
= ADMPTSMEMBERNAMENULL
;
1335 goto fail_pts_GroupMemberListNext
;
1339 * Lock the mutex and check the validity of the iterator
1342 if (pthread_mutex_lock(&iter
->mutex
)) {
1344 goto fail_pts_GroupMemberListNext
;
1349 if (!IsValidPtsGroupMemberListIterator(iter
, &tst
)) {
1350 goto fail_pts_GroupMemberListNext
;
1354 * Check to see if we've copied out all the data. If we haven't,
1355 * copy another item. If we have, mark the iterator done.
1358 if (iter
->index
>= iter
->names
.namelist_len
) {
1359 tst
= ADMITERATORDONE
;
1360 goto fail_pts_GroupMemberListNext
;
1362 strcpy(memberName
, iter
->names
.namelist_val
[iter
->index
]);
1367 fail_pts_GroupMemberListNext
:
1370 pthread_mutex_unlock(&iter
->mutex
);
1380 * pts_GroupMemberListDone - finish using a member list iterator
1384 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1388 * The iterator is locked and then destroyed
1392 * Returns != 0 upon successful completion.
1396 * It is the user's responsibility to make sure pts_GroupMemberListDone
1397 * is called only once for each iterator.
1401 pts_GroupMemberListDone(const void *iterationId
, afs_status_p st
)
1404 afs_status_t tst
= 0;
1405 pts_group_member_list_iterator_p iter
=
1406 (pts_group_member_list_iterator_p
) iterationId
;
1407 int mutex_locked
= 0;
1410 * Validate arguments
1414 tst
= ADMITERATORNULL
;
1415 goto fail_pts_GroupMemberListDone
;
1419 * Lock the mutex and check the validity of the iterator
1422 if (pthread_mutex_lock(&iter
->mutex
)) {
1424 goto fail_pts_GroupMemberListDone
;
1429 if (!IsValidPtsGroupMemberListIterator(iter
, &tst
)) {
1430 goto fail_pts_GroupMemberListDone
;
1434 * Free the namelist and the iterator.
1437 pthread_mutex_destroy(&iter
->mutex
);
1440 free(iter
->names
.namelist_val
);
1444 fail_pts_GroupMemberListDone
:
1447 pthread_mutex_unlock(&iter
->mutex
);
1457 * pts_GroupMemberRemove - remove a member from a group.
1461 * IN cellHandle - a previously opened cellHandle that corresponds
1462 * to the cell where the group exists.
1464 * IN userName - the user to remove.
1466 * IN groupName - the group to modify
1470 * No locks are held by this function
1474 * Returns != 0 upon successful completion.
1479 pts_GroupMemberRemove(const void *cellHandle
, const char *userName
,
1480 const char *groupName
, afs_status_p st
)
1483 afs_status_t tst
= 0;
1484 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1487 ids
.idlist_val
= NULL
;
1490 * Validate arguments
1493 if (!IsValidCellHandle(c_handle
, &tst
)) {
1494 goto fail_pts_GroupMemberRemove
;
1497 if ((userName
== NULL
) || (*userName
== 0)) {
1498 tst
= ADMPTSUSERNAMENULL
;
1499 goto fail_pts_GroupMemberRemove
;
1502 if ((groupName
== NULL
) || (*groupName
== 0)) {
1503 tst
= ADMPTSGROUPNAMENULL
;
1504 goto fail_pts_GroupMemberRemove
;
1507 if (!TranslateTwoNames
1508 (c_handle
, userName
, ADMPTSUSERNAMETOOLONG
, groupName
,
1509 ADMPTSGROUPNAMETOOLONG
, &ids
, &tst
)) {
1510 goto fail_pts_GroupMemberRemove
;
1518 ubik_PR_RemoveFromGroup(c_handle
->pts
, 0, ids
.idlist_val
[0],
1522 goto fail_pts_GroupMemberRemove
;
1526 fail_pts_GroupMemberRemove
:
1528 if (ids
.idlist_val
!= 0) {
1529 free(ids
.idlist_val
);
1539 * pts_GroupRename - change the name of a group
1543 * IN cellHandle - a previously opened cellHandle that corresponds
1544 * to the cell where the group exists.
1546 * IN oldName - the current group name
1548 * IN newName - the new group name
1552 * No locks are held by this function
1556 * Returns != 0 upon successful completion.
1561 pts_GroupRename(const void *cellHandle
, const char *oldName
,
1562 char *newName
, afs_status_p st
)
1565 afs_status_t tst
= 0;
1566 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1567 afs_int32 groupId
= 0;
1570 * Validate arguments
1573 if (!IsValidCellHandle(c_handle
, &tst
)) {
1574 goto fail_pts_GroupRename
;
1577 if ((newName
== NULL
) || (*newName
== 0)) {
1578 tst
= ADMPTSNEWNAMENULL
;
1579 goto fail_pts_GroupRename
;
1582 if ((oldName
== NULL
) || (*oldName
== 0)) {
1583 tst
= ADMPTSOLDNAMENULL
;
1584 goto fail_pts_GroupRename
;
1588 * Translate the group name into an id.
1591 if (!TranslateOneName
1592 (c_handle
, oldName
, ADMPTSOLDNAMETOOLONG
, &groupId
, &tst
)) {
1593 goto fail_pts_GroupRename
;
1600 tst
= ubik_PR_ChangeEntry(c_handle
->pts
, 0, groupId
, newName
, 0, 0);
1603 goto fail_pts_GroupRename
;
1607 fail_pts_GroupRename
:
1616 * SetGroupAccess - translate our Access notation to pts flags.
1620 * IN rights - the permissions.
1622 * OUT flags - a pointer to an afs_int32 structure that
1623 * contains the flags to pass to pts.
1627 * No locks are held by this function
1631 * Returns != 0 upon successful completion.
1636 SetGroupAccess(const pts_GroupUpdateEntry_p rights
, afs_int32
* flags
,
1640 afs_status_t tst
= 0;
1644 if (rights
->listDelete
== PTS_GROUP_ACCESS
) {
1646 } else if (rights
->listDelete
== PTS_GROUP_ANYUSER_ACCESS
) {
1647 tst
= ADMPTSINVALIDGROUPDELETEPERM
;
1648 goto fail_SetGroupAccess
;
1651 if (rights
->listAdd
== PTS_GROUP_ACCESS
) {
1653 } else if (rights
->listAdd
== PTS_GROUP_ANYUSER_ACCESS
) {
1657 if (rights
->listMembership
== PTS_GROUP_ACCESS
) {
1659 } else if (rights
->listMembership
== PTS_GROUP_ANYUSER_ACCESS
) {
1663 if (rights
->listGroupsOwned
== PTS_GROUP_ANYUSER_ACCESS
) {
1665 } else if (rights
->listGroupsOwned
== PTS_GROUP_ACCESS
) {
1666 tst
= ADMPTSINVALIDGROUPSOWNEDPERM
;
1667 goto fail_SetGroupAccess
;
1670 if (rights
->listStatus
== PTS_GROUP_ACCESS
) {
1672 } else if (rights
->listStatus
== PTS_GROUP_ANYUSER_ACCESS
) {
1677 fail_SetGroupAccess
:
1686 * pts_GroupModify - change the contents of a group entry.
1690 * IN cellHandle - a previously opened cellHandle that corresponds
1691 * to the cell where the group exists.
1693 * IN groupName - the group to change
1695 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1696 * contains the new information for the group.
1700 * No locks are held by this function
1704 * Returns != 0 upon successful completion.
1709 pts_GroupModify(const void *cellHandle
, const char *groupName
,
1710 const pts_GroupUpdateEntry_p newEntryP
, afs_status_p st
)
1713 afs_status_t tst
= 0;
1714 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1715 afs_int32 groupId
= 0;
1716 afs_int32 flags
= 0;
1719 * Validate arguments
1722 if (!IsValidCellHandle(c_handle
, &tst
)) {
1723 goto fail_pts_GroupModify
;
1726 if ((groupName
== NULL
) || (*groupName
== 0)) {
1727 tst
= ADMPTSGROUPNAMENULL
;
1728 goto fail_pts_GroupModify
;
1732 if (newEntryP
== NULL
) {
1733 tst
= ADMPTSNEWENTRYPNULL
;
1734 goto fail_pts_GroupModify
;
1738 * Translate the group name into an id.
1741 if (!TranslateOneName
1742 (c_handle
, groupName
, ADMPTSGROUPNAMETOOLONG
, &groupId
, &tst
)) {
1743 goto fail_pts_GroupModify
;
1747 * Set the flags argument
1750 if (!SetGroupAccess(newEntryP
, &flags
, &tst
)) {
1751 goto fail_pts_GroupModify
;
1759 ubik_PR_SetFieldsEntry(c_handle
->pts
, 0, groupId
, PR_SF_ALLBITS
,
1763 goto fail_pts_GroupModify
;
1767 fail_pts_GroupModify
:
1776 * pts_UserCreate - create a new user.
1780 * IN cellHandle - a previously opened cellHandle that corresponds
1781 * to the cell where the group exists.
1783 * IN newUser - the name of the new user.
1785 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1786 * id assigned by pts.
1790 * No locks are held by this function
1794 * Returns != 0 upon successful completion.
1799 pts_UserCreate(const void *cellHandle
, char *userName
, int *newUserId
,
1803 afs_status_t tst
= 0;
1804 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
1807 * Validate arguments
1810 if (!IsValidCellHandle(c_handle
, &tst
)) {
1811 goto fail_pts_UserCreate
;
1814 if ((userName
== NULL
) || (*userName
== 0)) {
1815 tst
= ADMPTSUSERNAMENULL
;
1816 goto fail_pts_UserCreate
;
1819 if (newUserId
== NULL
) {
1820 tst
= ADMPTSNEWUSERIDNULL
;
1821 goto fail_pts_UserCreate
;
1825 * We make a different rpc based upon the input to this function
1828 if (*newUserId
!= 0) {
1830 ubik_PR_INewEntry(c_handle
->pts
, 0, userName
, *newUserId
,
1834 ubik_PR_NewEntry(c_handle
->pts
, 0, userName
, 0, 0,
1839 goto fail_pts_UserCreate
;
1843 fail_pts_UserCreate
:
1852 * pts_UserDelete - delete a user.
1856 * IN cellHandle - a previously opened cellHandle that corresponds
1857 * to the cell where the group exists.
1859 * IN user - the name of the user to delete.
1863 * No locks are held by this function
1867 * Returns != 0 upon successful completion.
1872 pts_UserDelete(const void *cellHandle
, const char *userName
, afs_status_p st
)
1874 return EntryDelete(cellHandle
, userName
, ADMPTSUSERNAMENULL
,
1875 ADMPTSUSERNAMETOOLONG
, st
);
1880 * GetUserAccess - a small convenience function for setting
1885 * IN access - a pointer to a pts_userAccess_t to be set with the
1886 * correct permission.
1888 * IN flag - the current permission flag used to derive the permission.
1892 * No locks are obtained or released by this function
1896 * Since this function cannot fail, it returns void.
1901 GetUserAccess(pts_userAccess_p access
, afs_int32 flag
)
1904 *access
= PTS_USER_OWNER_ACCESS
;
1906 *access
= PTS_USER_ANYUSER_ACCESS
;
1911 * IsAdministrator - determine if a user is an administrator.
1915 * IN cellHandle - a previously opened cellHandle that corresponds
1916 * to the cell where the group exists.
1918 * IN userEntry - the user data for the user in question.
1920 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1924 * No locks are held by this function
1928 * Returns != 0 upon successful completion.
1933 IsAdministrator(const afs_cell_handle_p c_handle
, afs_int32 userId
,
1934 int *admin
, afs_status_p st
)
1937 afs_status_t tst
= 0;
1938 afs_int32 adminId
= 0;
1939 afs_int32 isAdmin
= 0;
1943 if (userId
== SYSADMINID
) {
1946 if (!TranslateOneName
1947 (c_handle
, "system:administrators", ADMPTSGROUPNAMETOOLONG
,
1949 goto fail_IsAdministrator
;
1952 ubik_PR_IsAMemberOf(c_handle
->pts
, 0, userId
, adminId
,
1955 goto fail_IsAdministrator
;
1963 fail_IsAdministrator
:
1972 * pts_UserGet - retrieve information about a particular user.
1976 * IN cellHandle - a previously opened cellHandle that corresponds
1977 * to the cell where the group exists.
1979 * IN userName - the name of the user to retrieve.
1981 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1986 * No locks are held by this function
1990 * Returns != 0 upon successful completion.
1995 pts_UserGet(const void *cellHandle
, const char *userName
,
1996 pts_UserEntry_p userP
, afs_status_p st
)
1999 afs_status_t tst
= 0;
2000 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
2001 struct prcheckentry userEntry
;
2002 afs_int32 userId
= 0;
2006 afs_int32 ptsids
[2];
2012 * Validate arguments
2015 if (!IsValidCellHandle(c_handle
, &tst
)) {
2016 goto fail_pts_UserGet
;
2019 if ((userName
== NULL
) || (*userName
== 0)) {
2020 tst
= ADMPTSUSERNAMENULL
;
2021 goto fail_pts_UserGet
;
2024 if (userP
== NULL
) {
2025 tst
= ADMPTSUSERPNULL
;
2026 goto fail_pts_UserGet
;
2030 * Translate the group name into an id.
2033 if (!TranslateOneName
2034 (c_handle
, userName
, ADMPTSUSERNAMETOOLONG
, &userId
, &tst
)) {
2035 goto fail_pts_UserGet
;
2039 * Retrieve information about the group
2042 tst
= ubik_PR_ListEntry(c_handle
->pts
, 0, userId
, &userEntry
);
2045 goto fail_pts_UserGet
;
2048 userP
->groupMembershipCount
= userEntry
.count
;
2049 userP
->groupCreationQuota
= userEntry
.ngroups
;
2051 * The administrator id, or any member of "system:administrators"
2052 * has unlimited group creation quota. Denote this by setting
2056 if (!IsAdministrator(c_handle
, userEntry
.id
, &admin
, &tst
)) {
2057 goto fail_pts_UserGet
;
2061 userP
->groupCreationQuota
= -1;
2064 userP
->nameUid
= userEntry
.id
;
2065 userP
->ownerUid
= userEntry
.owner
;
2066 userP
->creatorUid
= userEntry
.creator
;
2067 strncpy(userP
->name
, userEntry
.name
, PTS_MAX_NAME_LEN
);
2068 userP
->name
[PTS_MAX_NAME_LEN
- 1] = '\0';
2071 * The permission bits are described in the GroupGet function above.
2072 * The user entry only uses 3 of the 5 permissions, so we shift
2073 * past the unused entries.
2076 flags
= userEntry
.flags
;
2080 GetUserAccess(&userP
->listMembership
, twobit
);
2085 userP
->listGroupsOwned
= PTS_USER_ANYUSER_ACCESS
;
2087 userP
->listGroupsOwned
= PTS_USER_OWNER_ACCESS
;
2093 GetUserAccess(&userP
->listStatus
, twobit
);
2096 * Make another rpc and translate the owner and creator ids into
2097 * character strings.
2101 ids
.idlist_val
= ptsids
;
2102 ptsids
[0] = userEntry
.owner
;
2103 ptsids
[1] = userEntry
.creator
;
2104 names
.namelist_len
= 0;
2105 names
.namelist_val
= 0;
2108 if (!TranslatePTSIds(c_handle
, &names
, &ids
, &tst
)) {
2109 goto fail_pts_UserGet
;
2112 strncpy(userP
->owner
, names
.namelist_val
[0], PTS_MAX_NAME_LEN
);
2113 userP
->owner
[PTS_MAX_NAME_LEN
- 1] ='\0';
2114 strncpy(userP
->creator
, names
.namelist_val
[1], PTS_MAX_NAME_LEN
);
2115 userP
->creator
[PTS_MAX_NAME_LEN
- 1] = '\0';
2116 free(names
.namelist_val
);
2128 * pts_UserRename - rename a user.
2132 * IN cellHandle - a previously opened cellHandle that corresponds
2133 * to the cell where the group exists.
2135 * IN oldName - the name of the user to rename.
2137 * IN newName - the new user name.
2141 * No locks are held by this function
2145 * Returns != 0 upon successful completion.
2150 pts_UserRename(const void *cellHandle
, const char *oldName
,
2151 char *newName
, afs_status_p st
)
2154 afs_status_t tst
= 0;
2155 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
2156 afs_int32 userId
= 0;
2159 * Validate arguments
2162 if (!IsValidCellHandle(c_handle
, &tst
)) {
2163 goto fail_pts_UserRename
;
2166 if ((oldName
== NULL
) || (*oldName
== 0)) {
2167 tst
= ADMPTSOLDNAMENULL
;
2168 goto fail_pts_UserRename
;
2171 if ((newName
== NULL
) || (*newName
== 0)) {
2172 tst
= ADMPTSNEWNAMENULL
;
2173 goto fail_pts_UserRename
;
2177 * Translate the user name into an id.
2180 if (!TranslateOneName
2181 (c_handle
, oldName
, ADMPTSOLDNAMETOOLONG
, &userId
, &tst
)) {
2182 goto fail_pts_UserRename
;
2189 tst
= ubik_PR_ChangeEntry(c_handle
->pts
, 0, userId
, newName
, 0, 0);
2192 goto fail_pts_UserRename
;
2196 fail_pts_UserRename
:
2205 * SetUserAccess - translate our Access notation to pts flags.
2209 * IN userP - the user structure that contains the new permissions.
2211 * OUT flags - a pointer to an afs_int32 structure that
2212 * contains the flags to pass to pts.
2216 * No locks are held by this function
2220 * Returns != 0 upon successful completion.
2225 SetUserAccess(const pts_UserUpdateEntry_p userP
, afs_int32
* flags
,
2229 afs_status_t tst
= 0;
2233 if (userP
->listMembership
== PTS_USER_ANYUSER_ACCESS
) {
2237 if (userP
->listGroupsOwned
== PTS_USER_ANYUSER_ACCESS
) {
2241 if (userP
->listStatus
== PTS_USER_ANYUSER_ACCESS
) {
2254 * pts_UserModify - update a user entry.
2258 * IN cellHandle - a previously opened cellHandle that corresponds
2259 * to the cell where the group exists.
2261 * IN userName - the name of the user to update.
2263 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2264 * new information for user.
2268 * No locks are held by this function
2272 * Returns != 0 upon successful completion.
2277 pts_UserModify(const void *cellHandle
, const char *userName
,
2278 const pts_UserUpdateEntry_p newEntryP
, afs_status_p st
)
2281 afs_status_t tst
= 0;
2282 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
2283 afs_int32 userId
= 0;
2284 afs_int32 newQuota
= 0;
2286 afs_int32 flags
= 0;
2289 * Validate arguments
2292 if (!IsValidCellHandle(c_handle
, &tst
)) {
2293 goto fail_pts_UserModify
;
2296 if ((userName
== NULL
) || (*userName
== 0)) {
2297 tst
= ADMPTSUSERNAMENULL
;
2298 goto fail_pts_UserModify
;
2301 if (newEntryP
== NULL
) {
2302 tst
= ADMPTSNEWENTRYPNULL
;
2303 goto fail_pts_UserModify
;
2307 * Translate the user name into an id.
2310 if (!TranslateOneName
2311 (c_handle
, userName
, ADMPTSUSERNAMETOOLONG
, &userId
, &tst
)) {
2312 goto fail_pts_UserModify
;
2316 if (newEntryP
->flag
& PTS_USER_UPDATE_GROUP_CREATE_QUOTA
) {
2317 mask
|= PR_SF_NGROUPS
;
2318 newQuota
= newEntryP
->groupCreationQuota
;
2321 if (newEntryP
->flag
& PTS_USER_UPDATE_PERMISSIONS
) {
2322 mask
|= PR_SF_ALLBITS
;
2323 if (!SetUserAccess(newEntryP
, &flags
, &tst
)) {
2324 goto fail_pts_UserModify
;
2333 ubik_PR_SetFieldsEntry(c_handle
->pts
, 0, userId
, mask
, flags
,
2337 goto fail_pts_UserModify
;
2341 fail_pts_UserModify
:
2350 * pts_UserMaxGet - get the maximum in use user id.
2354 * IN cellHandle - a previously opened cellHandle that corresponds
2355 * to the cell where the group exists.
2357 * OUT maxUserId - upon successful completion contains the max in use id.
2361 * No locks are held by this function
2365 * Returns != 0 upon successful completion.
2370 pts_UserMaxGet(const void *cellHandle
, int *maxUserId
, afs_status_p st
)
2373 afs_status_t tst
= 0;
2374 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
2375 afs_int32 maxGroupId
= 0;
2378 * Validate arguments
2381 if (!IsValidCellHandle(c_handle
, &tst
)) {
2382 goto fail_pts_UserMaxGet
;
2385 if (maxUserId
== NULL
) {
2386 tst
= ADMPTSMAXUSERIDNULL
;
2387 goto fail_pts_UserMaxGet
;
2390 tst
= ubik_PR_ListMax(c_handle
->pts
, 0, maxUserId
, &maxGroupId
);
2393 goto fail_pts_UserMaxGet
;
2397 fail_pts_UserMaxGet
:
2406 * pts_UserMaxSet - set the maximum user id.
2410 * IN cellHandle - a previously opened cellHandle that corresponds
2411 * to the cell where the group exists.
2413 * IN maxUserId - the new max user id.
2417 * No locks are held by this function
2421 * Returns != 0 upon successful completion.
2426 pts_UserMaxSet(const void *cellHandle
, int maxUserId
, afs_status_p st
)
2429 afs_status_t tst
= 0;
2430 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
2433 * Validate arguments
2436 if (!IsValidCellHandle(c_handle
, &tst
)) {
2437 goto fail_pts_UserMaxSet
;
2440 tst
= ubik_PR_SetMax(c_handle
->pts
, 0, maxUserId
, 0);
2443 goto fail_pts_UserMaxSet
;
2447 fail_pts_UserMaxSet
:
2456 * pts_UserMemberListBegin - begin iterating over the list of groups
2457 * a particular user belongs to.
2461 * IN cellHandle - a previously opened cellHandle that corresponds
2462 * to the cell where the group exists.
2464 * IN groupName - the group whose members will be returned.
2466 * OUT iterationIdP - upon successful completion contains a iterator that
2467 * can be passed to pts_GroupMemberListNext.
2471 * No locks are obtained or released by this function
2475 * Returns != 0 upon successful completion.
2480 pts_UserMemberListBegin(const void *cellHandle
, const char *userName
,
2481 void **iterationIdP
, afs_status_p st
)
2483 return MemberListBegin(cellHandle
, userName
, ADMPTSUSERNAMENULL
,
2484 ADMPTSUSERNAMETOOLONG
, iterationIdP
, st
);
2489 * pts_UserMemberListNext - get the next group a user belongs to
2493 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2495 * OUT userName - upon successful completion contains the next group a user
2500 * The iterator mutex is held during the retrieval of the next member.
2504 * Returns != 0 upon successful completion.
2509 pts_UserMemberListNext(const void *iterationId
, char *userName
,
2512 return pts_GroupMemberListNext(iterationId
, userName
, st
);
2516 * pts_UserMemberListDone - finish using a user list iterator
2520 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2524 * The iterator is locked and then destroyed
2528 * Returns != 0 upon successful completion.
2532 * It is the user's responsibility to make sure pts_UserMemberListDone
2533 * is called only once for each iterator.
2537 pts_UserMemberListDone(const void *iterationId
, afs_status_p st
)
2539 return pts_GroupMemberListDone(iterationId
, st
);
2542 typedef struct owned_group_list
{
2543 namelist owned_names
; /* the list of character names owned by this id */
2544 prlist owned_ids
; /* the list of pts ids owned by this id */
2545 afs_int32 index
; /* the index into owned_names for the next group */
2546 afs_int32 owner
; /* the pts id of the owner */
2547 afs_int32 more
; /* the last parameter to PR_ListOwned */
2548 int finished_retrieving
; /* set when we've processed the last owned_names */
2549 afs_cell_handle_p c_handle
; /* ubik client to pts server's from c_handle */
2550 char group
[CACHED_ITEMS
][PTS_MAX_NAME_LEN
]; /* cache of names */
2551 } owned_group_list_t
, *owned_group_list_p
;
2554 DeleteOwnedGroupSpecificData(void *rpc_specific
, afs_status_p st
)
2557 afs_status_t tst
= 0;
2558 owned_group_list_p list
= (owned_group_list_p
) rpc_specific
;
2560 if (list
->owned_names
.namelist_val
!= NULL
) {
2561 free(list
->owned_names
.namelist_val
);
2564 if (list
->owned_ids
.prlist_val
!= NULL
) {
2565 free(list
->owned_ids
.prlist_val
);
2576 GetOwnedGroupRPC(void *rpc_specific
, int slot
, int *last_item
,
2577 int *last_item_contains_data
, afs_status_p st
)
2580 afs_status_t tst
= 0;
2581 owned_group_list_p list
= (owned_group_list_p
) rpc_specific
;
2584 * We really don't make an rpc for every entry we return here
2585 * since the pts interface allows several members to be returned
2586 * with one rpc, but we fake it to make the iterator happy.
2590 * Check to see if we are done retrieving data
2593 if ((list
->finished_retrieving
) && (list
->owned_names
.namelist_len
== 0)) {
2595 *last_item_contains_data
= 0;
2596 goto fail_GetOwnedGroupRPC
;
2600 * Check to see if we really need to make an rpc
2603 if ((!list
->finished_retrieving
) && (list
->owned_names
.namelist_len
== 0)) {
2605 ubik_PR_ListOwned(list
->c_handle
->pts
, 0, list
->owner
,
2606 &list
->owned_ids
, &list
->more
);
2608 goto fail_GetOwnedGroupRPC
;
2611 if (!TranslatePTSIds
2612 (list
->c_handle
, &list
->owned_names
, (idlist
*) & list
->owned_ids
,
2614 goto fail_GetOwnedGroupRPC
;
2618 if (list
->owned_names
.namelist_val
== NULL
) {
2620 *last_item_contains_data
= 0;
2621 goto fail_GetOwnedGroupRPC
;
2626 * We can retrieve the next group from data we already received
2629 strcpy(list
->group
[slot
], list
->owned_names
.namelist_val
[list
->index
]);
2633 * Check to see if there is more data to be retrieved
2634 * We need to free up the previously retrieved data here
2635 * and then check to see if the last rpc indicated that there
2636 * were more items to retrieve.
2639 if (list
->index
>= list
->owned_names
.namelist_len
) {
2640 list
->owned_names
.namelist_len
= 0;
2641 free(list
->owned_names
.namelist_val
);
2642 list
->owned_names
.namelist_val
= 0;
2644 list
->owned_ids
.prlist_len
= 0;
2645 free(list
->owned_ids
.prlist_val
);
2646 list
->owned_ids
.prlist_val
= 0;
2649 list
->finished_retrieving
= 1;
2654 fail_GetOwnedGroupRPC
:
2663 GetOwnedGroupFromCache(void *rpc_specific
, int slot
, void *dest
,
2667 afs_status_t tst
= 0;
2668 owned_group_list_p list
= (owned_group_list_p
) rpc_specific
;
2670 strcpy((char *)dest
, list
->group
[slot
]);
2681 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2682 * a particular user owns.
2686 * IN cellHandle - a previously opened cellHandle that corresponds
2687 * to the cell where the group exists.
2689 * IN ownerName - the owner of the groups of interest.
2691 * OUT iterationIdP - upon successful completion contains a iterator that
2692 * can be passed to pts_OwnedGroupListNext.
2696 * No locks are held by this function
2700 * Returns != 0 upon successful completion.
2705 pts_OwnedGroupListBegin(const void *cellHandle
, const char *userName
,
2706 void **iterationIdP
, afs_status_p st
)
2709 afs_status_t tst
= 0;
2710 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
2711 afs_admin_iterator_p iter
= malloc(sizeof(afs_admin_iterator_t
));
2712 owned_group_list_p list
= malloc(sizeof(owned_group_list_t
));
2715 * Validate arguments
2718 if (!IsValidCellHandle(c_handle
, &tst
)) {
2719 goto fail_pts_OwnedGroupListBegin
;
2722 if ((userName
== NULL
) || (*userName
== 0)) {
2723 tst
= ADMPTSUSERNAMENULL
;
2724 goto fail_pts_OwnedGroupListBegin
;
2727 if (iterationIdP
== NULL
) {
2728 tst
= ADMITERATORNULL
;
2729 goto fail_pts_OwnedGroupListBegin
;
2732 if ((iter
== NULL
) || (list
== NULL
)) {
2734 goto fail_pts_OwnedGroupListBegin
;
2738 * Initialize the iterator specific data
2742 list
->finished_retrieving
= 0;
2743 list
->c_handle
= c_handle
;
2744 list
->owned_names
.namelist_len
= 0;
2745 list
->owned_names
.namelist_val
= 0;
2746 list
->owned_ids
.prlist_len
= 0;
2747 list
->owned_ids
.prlist_val
= 0;
2750 * Translate the user name into an id.
2753 if (!TranslateOneName
2754 (c_handle
, userName
, ADMPTSUSERNAMETOOLONG
, &list
->owner
, &tst
)) {
2755 goto fail_pts_OwnedGroupListBegin
;
2759 (iter
, (void *)list
, GetOwnedGroupRPC
, GetOwnedGroupFromCache
, NULL
,
2760 DeleteOwnedGroupSpecificData
, &tst
)) {
2761 *iterationIdP
= (void *)iter
;
2765 fail_pts_OwnedGroupListBegin
:
2783 * pts_OwnedGroupListNext - get the next group a user owns.
2787 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2789 * OUT groupName - upon successful completion contains the next group a user
2794 * The iterator mutex is held during the retrieval of the next member.
2798 * Returns != 0 upon successful completion.
2803 pts_OwnedGroupListNext(const void *iterationId
, char *groupName
,
2807 afs_status_t tst
= 0;
2808 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
2811 * Validate arguments
2814 if (iterationId
== NULL
) {
2815 tst
= ADMITERATORNULL
;
2816 goto fail_pts_OwnedGroupListNext
;
2819 if (groupName
== NULL
) {
2820 tst
= ADMPTSGROUPNAMENULL
;
2821 goto fail_pts_OwnedGroupListNext
;
2824 rc
= IteratorNext(iter
, (void *)groupName
, &tst
);
2826 fail_pts_OwnedGroupListNext
:
2835 * pts_OwnedGroupListDone - finish using a group list iterator
2839 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2843 * The iterator is locked and then destroyed
2847 * Returns != 0 upon successful completion.
2851 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2852 * is called only once for each iterator.
2856 pts_OwnedGroupListDone(const void *iterationId
, afs_status_p st
)
2859 afs_status_t tst
= 0;
2860 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
2863 * Validate arguments
2866 if (iterationId
== NULL
) {
2867 tst
= ADMITERATORNULL
;
2868 goto fail_pts_OwnedGroupListDone
;
2871 rc
= IteratorDone(iter
, &tst
);
2873 fail_pts_OwnedGroupListDone
:
2881 typedef struct pts_list
{
2882 prlistentries
*names
; /* the current list of pts names in this cell */
2883 prlistentries
*currName
; /* the current pts entry */
2884 afs_int32 index
; /* the index into names for the next pts entry */
2885 afs_int32 nextstartindex
; /* the next start index for the RPC */
2886 afs_int32 nentries
; /* the number of entries in names */
2887 afs_int32 flag
; /* the type of the list */
2888 int finished_retrieving
; /* set when we've processed the last owned_names */
2889 afs_cell_handle_p c_handle
; /* ubik client to pts server's from c_handle */
2890 char entries
[CACHED_ITEMS
][PTS_MAX_NAME_LEN
]; /* cache of pts names */
2891 } pts_list_t
, *pts_list_p
;
2894 DeletePTSSpecificData(void *rpc_specific
, afs_status_p st
)
2897 afs_status_t tst
= 0;
2898 pts_list_p list
= (pts_list_p
) rpc_specific
;
2913 GetPTSRPC(void *rpc_specific
, int slot
, int *last_item
,
2914 int *last_item_contains_data
, afs_status_p st
)
2917 afs_status_t tst
= 0;
2918 pts_list_p list
= (pts_list_p
) rpc_specific
;
2921 * We really don't make an rpc for every entry we return here
2922 * since the pts interface allows several members to be returned
2923 * with one rpc, but we fake it to make the iterator happy.
2927 * Check to see if we are done retrieving data
2930 if (list
->finished_retrieving
) {
2932 *last_item_contains_data
= 0;
2933 goto fail_GetPTSRPC
;
2937 * Check to see if we really need to make an rpc
2940 if ((!list
->finished_retrieving
) && (list
->index
>= list
->nentries
)) {
2941 afs_int32 start
= list
->nextstartindex
;
2942 prentries bulkentries
;
2943 list
->nextstartindex
= -1;
2944 bulkentries
.prentries_val
= 0;
2945 bulkentries
.prentries_len
= 0;
2948 ubik_PR_ListEntries(list
->c_handle
->pts
, 0, list
->flag
,
2949 start
, &bulkentries
, &(list
->nextstartindex
));
2952 goto fail_GetPTSRPC
;
2955 list
->nentries
= bulkentries
.prentries_len
;
2956 list
->names
= bulkentries
.prentries_val
;
2959 list
->currName
= list
->names
;
2964 * We can retrieve the next entry from data we already received
2967 strcpy(list
->entries
[slot
], list
->currName
->name
);
2973 * Check to see if there is more data to be retrieved
2974 * We need to free up the previously retrieved data here
2975 * and then check to see if the last rpc indicated that there
2976 * were more items to retrieve.
2979 if (list
->index
>= list
->nentries
) {
2985 if (list
->nextstartindex
== -1) {
2986 list
->finished_retrieving
= 1;
3001 GetPTSFromCache(void *rpc_specific
, int slot
, void *dest
, afs_status_p st
)
3004 afs_status_t tst
= 0;
3005 pts_list_p list
= (pts_list_p
) rpc_specific
;
3007 strcpy((char *)dest
, list
->entries
[slot
]);
3018 * pts_UserListBegin - begin iterating over the list of users
3019 * in a particular cell
3023 * IN cellHandle - a previously opened cellHandle that corresponds
3024 * to the cell where the users exist.
3026 * OUT iterationIdP - upon successful completion contains a iterator that
3027 * can be passed to pts_UserListNext.
3031 * No locks are held by this function
3035 * Returns != 0 upon successful completion.
3040 pts_UserListBegin(const void *cellHandle
, void **iterationIdP
,
3044 afs_status_t tst
= 0;
3045 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
3046 afs_admin_iterator_p iter
= malloc(sizeof(afs_admin_iterator_t
));
3047 pts_list_p list
= malloc(sizeof(pts_list_t
));
3050 * Validate arguments
3053 if (!IsValidCellHandle(c_handle
, &tst
)) {
3054 goto fail_pts_UserListBegin
;
3057 if (iterationIdP
== NULL
) {
3058 tst
= ADMITERATORNULL
;
3059 goto fail_pts_UserListBegin
;
3062 if ((iter
== NULL
) || (list
== NULL
)) {
3064 goto fail_pts_UserListBegin
;
3068 * Initialize the iterator specific data
3072 list
->finished_retrieving
= 0;
3073 list
->c_handle
= c_handle
;
3075 list
->nextstartindex
= 0;
3077 list
->flag
= PRUSERS
;
3080 (iter
, (void *)list
, GetPTSRPC
, GetPTSFromCache
, NULL
,
3081 DeletePTSSpecificData
, &tst
)) {
3082 *iterationIdP
= (void *)iter
;
3086 fail_pts_UserListBegin
:
3104 * pts_UserListNext - get the next user in the cell.
3108 * IN iterationId - an iterator previously returned by pts_UserListBegin
3110 * OUT groupName - upon successful completion contains the next user
3114 * The iterator mutex is held during the retrieval of the next member.
3118 * Returns != 0 upon successful completion.
3123 pts_UserListNext(const void *iterationId
, char *userName
, afs_status_p st
)
3126 afs_status_t tst
= 0;
3127 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
3130 * Validate arguments
3133 if (iterationId
== NULL
) {
3134 tst
= ADMITERATORNULL
;
3135 goto fail_pts_UserListNext
;
3138 if (userName
== NULL
) {
3139 tst
= ADMPTSUSERNAMENULL
;
3140 goto fail_pts_UserListNext
;
3143 rc
= IteratorNext(iter
, (void *)userName
, &tst
);
3145 fail_pts_UserListNext
:
3154 * pts_UserListDone - finish using a user list iterator
3158 * IN iterationId - an iterator previously returned by pts_UserListBegin
3162 * The iterator is locked and then destroyed
3166 * Returns != 0 upon successful completion.
3170 * It is the user's responsibility to make sure pts_UserListDone
3171 * is called only once for each iterator.
3175 pts_UserListDone(const void *iterationId
, afs_status_p st
)
3178 afs_status_t tst
= 0;
3179 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
3182 * Validate arguments
3185 if (iterationId
== NULL
) {
3186 tst
= ADMITERATORNULL
;
3187 goto fail_pts_UserListDone
;
3190 rc
= IteratorDone(iter
, &tst
);
3192 fail_pts_UserListDone
:
3201 * pts_GroupListBegin - begin iterating over the list of groups
3202 * in a particular cell.
3206 * IN cellHandle - a previously opened cellHandle that corresponds
3207 * to the cell where the groups exist.
3209 * OUT iterationIdP - upon successful completion contains a iterator that
3210 * can be passed to pts_GroupListNext.
3214 * No locks are held by this function
3218 * Returns != 0 upon successful completion.
3223 pts_GroupListBegin(const void *cellHandle
, void **iterationIdP
,
3227 afs_status_t tst
= 0;
3228 afs_cell_handle_p c_handle
= (afs_cell_handle_p
) cellHandle
;
3229 afs_admin_iterator_p iter
= malloc(sizeof(afs_admin_iterator_t
));
3230 pts_list_p list
= malloc(sizeof(pts_list_t
));
3233 * Validate arguments
3236 if (!IsValidCellHandle(c_handle
, &tst
)) {
3237 goto fail_pts_GroupListBegin
;
3240 if (iterationIdP
== NULL
) {
3241 tst
= ADMITERATORNULL
;
3242 goto fail_pts_GroupListBegin
;
3245 if ((iter
== NULL
) || (list
== NULL
)) {
3247 goto fail_pts_GroupListBegin
;
3251 * Initialize the iterator specific data
3255 list
->finished_retrieving
= 0;
3256 list
->c_handle
= c_handle
;
3258 list
->nextstartindex
= 0;
3260 list
->flag
= PRGROUPS
;
3263 (iter
, (void *)list
, GetPTSRPC
, GetPTSFromCache
, NULL
,
3264 DeletePTSSpecificData
, &tst
)) {
3265 *iterationIdP
= (void *)iter
;
3269 fail_pts_GroupListBegin
:
3287 * pts_UserListNext - get the next group in a cell.
3291 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3293 * OUT groupName - upon successful completion contains the next group
3297 * The iterator mutex is held during the retrieval of the next member.
3301 * Returns != 0 upon successful completion.
3306 pts_GroupListNext(const void *iterationId
, char *groupName
, afs_status_p st
)
3309 afs_status_t tst
= 0;
3310 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
3313 * Validate arguments
3316 if (iterationId
== NULL
) {
3317 tst
= ADMITERATORNULL
;
3318 goto fail_pts_GroupListNext
;
3321 if (groupName
== NULL
) {
3322 tst
= ADMPTSGROUPNAMENULL
;
3323 goto fail_pts_GroupListNext
;
3326 rc
= IteratorNext(iter
, (void *)groupName
, &tst
);
3328 fail_pts_GroupListNext
:
3337 * pts_GroupListDone - finish using a group list iterator
3341 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3345 * The iterator is locked and then destroyed
3349 * Returns != 0 upon successful completion.
3353 * It is the user's responsibility to make sure pts_GroupListDone
3354 * is called only once for each iterator.
3358 pts_GroupListDone(const void *iterationId
, afs_status_p st
)
3361 afs_status_t tst
= 0;
3362 afs_admin_iterator_p iter
= (afs_admin_iterator_p
) iterationId
;
3365 * Validate arguments
3368 if (iterationId
== NULL
) {
3369 tst
= ADMITERATORNULL
;
3370 goto fail_pts_GroupListDone
;
3373 rc
= IteratorDone(iter
, &tst
);
3375 fail_pts_GroupListDone
: