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>
27 #include "afs_ptsAdmin.h"
28 #include "../adminutil/afs_AdminInternal.h"
29 #include <afs/afs_AdminErrors.h>
30 #include <afs/afs_utilAdmin.h>
31 #include <afs/ptint.h>
32 #include <afs/ptserver.h>
35 * IsValidCellHandle - validate the cell handle for making pts
40 * IN cellHandle - a previously opened cellHandle that is to be validated.
44 * No locks are obtained or released by this function
48 * Returns != 0 upon successful completion.
53 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
58 if (!CellHandleIsValid((void *)c_handle, &tst)) {
59 goto fail_IsValidCellHandle;
62 if (c_handle->pts_valid == 0) {
63 tst = ADMCLIENTCELLPTSINVALID;
64 goto fail_IsValidCellHandle;
67 if (c_handle->pts == NULL) {
68 tst = ADMCLIENTCELLPTSNULL;
69 goto fail_IsValidCellHandle;
74 fail_IsValidCellHandle:
84 * TranslatePTSNames - translate character representations of pts names
85 * into their numeric equivalent.
89 * IN cellHandle - a previously opened cellHandle that corresponds
90 * to the cell where the id's exist.
92 * IN names - the list of names to be translated.
94 * OUT ids - the list of translated names
98 * No locks are obtained or released by this function
102 * Returns != 0 upon successful completion.
107 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
108 idlist * ids, afs_status_p st)
111 afs_status_t tst = 0;
116 * Lowercase the names to translate
119 for (i = 0; i < names->namelist_len; i++) {
120 p = names->namelist_val[i];
127 tst = ubik_PR_NameToID(cellHandle->pts, 0, names, ids);
130 goto fail_TranslatePTSNames;
135 * Check to see if the lookup failed
138 for (i = 0; i < ids->idlist_len; i++) {
139 if (ids->idlist_val[i] == ANONYMOUSID) {
140 tst = ADMPTSFAILEDNAMETRANSLATE;
141 goto fail_TranslatePTSNames;
146 fail_TranslatePTSNames:
155 * TranslateTwoNames - translate two pts names to their pts ids.
159 * IN cellHandle - a previously opened cellHandle that corresponds
160 * to the cell where the group exists.
162 * IN id1 - one id to be translated
164 * IN error1 - the error status to be returned in the event that id1 is
167 * IN id2 - one id to be translated
169 * IN error2 - the error status to be returned in the event that id2 is
173 * OUT idlist - the list of pts id's
177 * No locks are obtained or released by this function
181 * Returns != 0 upon successful completion.
186 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
187 afs_status_t error1, const char *id2, afs_status_t error2,
188 idlist * ids, afs_status_p st)
191 afs_status_t tst = 0;
193 char tmp_array[2 * PTS_MAX_NAME_LEN];
196 * Copy the group and user names in order to translate them
199 names.namelist_len = 2;
200 names.namelist_val = (prname *) & tmp_array[0];
202 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
203 names.namelist_val[0][PTS_MAX_NAME_LEN - 1] = '\0';
204 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
205 names.namelist_val[1][PTS_MAX_NAME_LEN - 1] = '\0';
210 * Check that user and group aren't too long
211 * This is a cheaper check than calling strlen
214 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
216 goto fail_TranslateTwoNames;
219 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
221 goto fail_TranslateTwoNames;
225 * Translate user and group into pts ID's
228 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
229 goto fail_TranslateTwoNames;
234 fail_TranslateTwoNames:
243 * TranslateOneName - translate a pts name to its pts id.
247 * IN cellHandle - a previously opened cellHandle that corresponds
248 * to the cell where the group exists.
250 * IN userName - the user to be translated.
252 * OUT idlist - the user pts id.
256 * No locks are obtained or released by this function
260 * Returns != 0 upon successful completion.
265 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
266 afs_status_t tooLongError, afs_int32 * ptsId,
270 afs_status_t tst = 0;
272 char tmp_array[PTS_MAX_NAME_LEN];
276 * Copy the name in order to translate it
279 names[0].namelist_len = 1;
280 names[0].namelist_val = (prname *) & tmp_array[0];
282 strncpy((char *)names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
283 ((char *)names[0].namelist_val)[PTS_MAX_NAME_LEN - 1] = '\0';
288 * Check that user isn't too long
289 * This is a cheaper check than calling strlen
292 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
294 goto fail_TranslateOneName;
298 * Translate user into pts ID
301 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
302 goto fail_TranslateOneName;
304 if (ids.idlist_val != NULL) {
305 *ptsId = *ids.idlist_val;
306 free(ids.idlist_val);
312 fail_TranslateOneName:
321 * TranslatePTSIds - translate numeric representations of pts names
322 * into their character equivalent.
326 * IN cellHandle - a previously opened cellHandle that corresponds
327 * to the cell where the id's exist.
329 * IN ids - the list of ids to be translated.
331 * OUT names - the list of translated names
335 * No locks are obtained or released by this function
339 * Returns != 0 upon successful completion.
344 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
345 idlist * ids, afs_status_p st)
348 afs_status_t tst = 0;
350 tst = ubik_PR_IDToName(cellHandle->pts, 0, ids, names);
353 goto fail_TranslatePTSIds;
357 fail_TranslatePTSIds:
366 * pts_GroupMemberAdd - add one member to a pts group
370 * IN cellHandle - a previously opened cellHandle that corresponds
371 * to the cell where the group exists.
373 * IN userName - the name to be added to the group.
375 * IN groupName - the group to be modified.
379 * No locks are obtained or released by this function
383 * Returns != 0 upon successful completion.
388 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
389 const char *groupName, afs_status_p st)
392 afs_status_t tst = 0;
393 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
400 if (!IsValidCellHandle(c_handle, &tst)) {
401 goto fail_pts_GroupMemberAdd;
404 if ((userName == NULL) || (*userName == 0)) {
405 tst = ADMPTSUSERNAMENULL;
406 goto fail_pts_GroupMemberAdd;
409 if ((groupName == NULL) || (*groupName == 0)) {
410 tst = ADMPTSGROUPNAMENULL;
411 goto fail_pts_GroupMemberAdd;
414 if (!TranslateTwoNames
415 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
416 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
417 goto fail_pts_GroupMemberAdd;
425 ubik_PR_AddToGroup(c_handle->pts, 0, ids.idlist_val[0],
429 goto fail_pts_GroupMemberAdd;
433 fail_pts_GroupMemberAdd:
435 if (ids.idlist_val != 0) {
436 free(ids.idlist_val);
446 * pts_GroupOwnerChange - change the owner of a group
450 * IN cellHandle - a previously opened cellHandle that corresponds
451 * to the cell where the group exists.
453 * IN targetGroup - the group to be modified.
455 * IN userName - the new owner of the group.
459 * No locks are obtained or released by this function
463 * Returns != 0 upon successful completion.
468 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
469 const char *newOwner, afs_status_p st)
472 afs_status_t tst = 0;
473 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
480 if (!IsValidCellHandle(c_handle, &tst)) {
481 goto fail_pts_GroupOwnerChange;
484 if ((newOwner == NULL) || (*newOwner == 0)) {
485 tst = ADMPTSNEWOWNERNULL;
486 goto fail_pts_GroupOwnerChange;
489 if ((targetGroup == NULL) || (*targetGroup == 0)) {
490 tst = ADMPTSTARGETGROUPNULL;
491 goto fail_pts_GroupOwnerChange;
494 if (!TranslateTwoNames
495 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
496 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
497 goto fail_pts_GroupOwnerChange;
505 ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
506 ids.idlist_val[0], 0);
509 goto fail_pts_GroupOwnerChange;
513 fail_pts_GroupOwnerChange:
515 if (ids.idlist_val != 0) {
516 free(ids.idlist_val);
526 * pts_GroupCreate - create a new group
530 * IN cellHandle - a previously opened cellHandle that corresponds
531 * to the cell where the group exists.
533 * IN newGroup - the group to be created.
535 * IN newOwner - the owner of the group. Pass NULL if the current user
536 * is to be the new owner, or the character string of the owner otherwise.
538 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
539 * generate a value, != 0 to assign a value on your own. The group id
540 * that is used to create the group is copied into this parameter in the
541 * event you pass in 0.
545 * No locks are obtained or released by this function
549 * Returns != 0 upon successful completion.
554 pts_GroupCreate(const void *cellHandle, const char *newGroup,
555 const char *newOwner, int *newGroupId, afs_status_p st)
558 afs_status_t tst = 0;
559 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
560 afs_int32 newOwnerId = 0;
566 if (!IsValidCellHandle(c_handle, &tst)) {
567 goto fail_pts_GroupCreate;
570 if ((newGroup == NULL) || (*newGroup == 0)) {
571 tst = ADMPTSNEWGROUPNULL;
572 goto fail_pts_GroupCreate;
575 if (newGroupId == NULL) {
576 tst = ADMPTSNEWGROUPIDNULL;
577 goto fail_pts_GroupCreate;
580 if (*newGroupId > 0) {
581 tst = ADMPTSNEWGROUPIDPOSITIVE;
582 goto fail_pts_GroupCreate;
586 * If a newOwner was specified, validate that it exists
589 if (newOwner != NULL) {
590 if (!TranslateOneName
591 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
592 goto fail_pts_GroupCreate;
597 * We make a different rpc based upon the input to this function
600 if (*newGroupId != 0) {
602 ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
606 ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
607 newOwnerId, newGroupId);
611 goto fail_pts_GroupCreate;
615 fail_pts_GroupCreate:
624 * GetGroupAccess - a small convenience function for setting
629 * IN access - a pointer to a pts_groupAccess_t to be set with the
630 * correct permission.
632 * IN flag - the current permission flag used to derive the permission.
636 * No locks are obtained or released by this function
640 * Since this function cannot fail, it returns void.
645 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
648 *access = PTS_GROUP_OWNER_ACCESS;
650 *access = PTS_GROUP_OWNER_ACCESS;
651 } else if (flag == 1) {
652 *access = PTS_GROUP_ACCESS;
653 } else if (flag == 2) {
654 *access = PTS_GROUP_ANYUSER_ACCESS;
660 * pts_GroupGet - retrieve information about a particular group.
664 * IN cellHandle - a previously opened cellHandle that corresponds
665 * to the cell where the group exists.
667 * IN groupName - the group to retrieve.
669 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
670 * successful completion is filled with information about groupName.
674 * No locks are obtained or released by this function
678 * Returns != 0 upon successful completion.
683 pts_GroupGet(const void *cellHandle, const char *groupName,
684 pts_GroupEntry_p groupP, afs_status_p st)
687 afs_status_t tst = 0;
688 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
689 afs_int32 groupId = 0;
692 struct prcheckentry groupEntry;
701 if (!IsValidCellHandle(c_handle, &tst)) {
702 goto fail_pts_GroupGet;
705 if ((groupName == NULL) || (*groupName == 0)) {
706 tst = ADMPTSGROUPNAMENULL;
707 goto fail_pts_GroupGet;
710 if (groupP == NULL) {
711 tst = ADMPTSGROUPPNULL;
712 goto fail_pts_GroupGet;
716 * Translate the group name into an id.
719 if (!TranslateOneName
720 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
721 goto fail_pts_GroupGet;
725 * Retrieve information about the group
728 tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
731 goto fail_pts_GroupGet;
734 groupP->membershipCount = groupEntry.count;
735 groupP->nameUid = groupEntry.id;
736 groupP->ownerUid = groupEntry.owner;
737 groupP->creatorUid = groupEntry.creator;
738 strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
739 groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
741 * Set the access rights based upon the value of the flags member
742 * of the groupEntry struct.
744 * To the best of my ability to decypher the pts code, it looks like
745 * the rights are stored in flags as follows:
747 * I number my bits from least significant to most significant starting
751 * if bit 0 == 0 -> r access is denied
752 * if bit 0 == 1 -> r access is granted
755 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
756 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
757 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
758 * if bit 2 == 1 and bit 1 == 1 -> this is an error
760 * membership - bits 3 and 4
761 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
762 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
763 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
764 * if bit 4 == 1 and bit 3 == 1 -> this is an error
767 * if bit 5 == 0 -> O access is denied
768 * if bit 5 == 1 -> O access is granted
770 * status - bits 6 and 7
771 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
772 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
773 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
774 * if bit 7 == 1 and bit 6 == 1 -> this is an error
776 * For cases where the permission doesn't make sense for the
777 * type of entry, or where an error occurs, we ignore it.
778 * This is the behavior of the pts code.
781 flags = groupEntry.flags;
783 groupP->listDelete = PTS_GROUP_ACCESS;
785 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
791 GetGroupAccess(&groupP->listAdd, twobit);
796 GetGroupAccess(&groupP->listMembership, twobit);
801 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
803 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
809 GetGroupAccess(&groupP->listStatus, twobit);
812 * Make another rpc and translate the owner and creator ids into
817 ids.idlist_val = ptsids;
818 ptsids[0] = groupEntry.owner;
819 ptsids[1] = groupEntry.creator;
820 names.namelist_len = 0;
821 names.namelist_val = 0;
824 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
825 goto fail_pts_GroupGet;
828 strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
829 groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
830 strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
831 groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
832 free(names.namelist_val);
844 * EntryDelete - delete a pts entry (group or user).
848 * IN cellHandle - a previously opened cellHandle that corresponds
849 * to the cell where the group exists.
851 * IN entryName - the entry to be deleted.
853 * IN error1 - the error status to be returned in the event that entryName is
856 * IN error2 - the error status to be returned in the event that entryName is
861 * No locks are obtained or released by this function
865 * Returns != 0 upon successful completion.
870 EntryDelete(const void *cellHandle, const char *entryName,
871 afs_status_t error1, afs_status_t error2, afs_status_p st)
874 afs_status_t tst = 0;
875 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
876 afs_int32 entryId = 0;
882 if (!IsValidCellHandle(c_handle, &tst)) {
883 goto fail_EntryDelete;
886 if ((entryName == NULL) || (*entryName == 0)) {
888 goto fail_EntryDelete;
892 * Translate the entry name into an id.
895 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
896 goto fail_EntryDelete;
903 tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
906 goto fail_EntryDelete;
920 * pts_GroupDelete - delete a group
924 * IN cellHandle - a previously opened cellHandle that corresponds
925 * to the cell where the group exists.
927 * IN groupName - the group to be deleted.
931 * No locks are obtained or released by this function
935 * Returns != 0 upon successful completion.
940 pts_GroupDelete(const void *cellHandle, const char *groupName,
944 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
945 ADMPTSGROUPNAMETOOLONG, st);
949 * pts_GroupMaxGet - get the maximum in use group id.
953 * IN cellHandle - a previously opened cellHandle that corresponds
954 * to the cell where the group exists.
956 * OUT maxGroupId - upon successful completion contains the maximum
957 * group Id in use at the server.
961 * No locks are obtained or released by this function
965 * Returns != 0 upon successful completion.
970 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
973 afs_status_t tst = 0;
974 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
975 afs_int32 maxUserId = 0;
981 if (!IsValidCellHandle(c_handle, &tst)) {
982 goto fail_pts_GroupMaxGet;
985 if (maxGroupId == NULL) {
986 tst = ADMPTSMAXGROUPIDNULL;
987 goto fail_pts_GroupMaxGet;
990 tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
993 goto fail_pts_GroupMaxGet;
997 fail_pts_GroupMaxGet:
1006 * pts_GroupMaxSet - set the maximum in use group id.
1010 * IN cellHandle - a previously opened cellHandle that corresponds
1011 * to the cell where the group exists.
1013 * IN maxGroupId - the new maximum group id.
1017 * No locks are obtained or released by this function
1021 * Returns != 0 upon successful completion.
1026 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1029 afs_status_t tst = 0;
1030 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1033 * Validate arguments
1036 if (!IsValidCellHandle(c_handle, &tst)) {
1037 goto fail_pts_GroupMaxSet;
1040 tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
1043 goto fail_pts_GroupMaxSet;
1047 fail_pts_GroupMaxSet:
1058 * I'm not using the common iterator pattern here since the retrival
1059 * of the member list is actually accomplished in 1 rpc. There's no
1060 * sense in trying to fit this pts specific behavior into the more
1061 * generic model, so instead the Begin functions actually do all the
1062 * rpc work and the next/done functions just manipulate the retrieved
1066 typedef struct pts_group_member_list_iterator {
1069 pthread_mutex_t mutex; /* hold to manipulate this structure */
1074 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1077 * pts_GroupMemberListBegin - begin iterating over the list of members
1078 * of a particular group.
1082 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1086 * No locks are obtained or released by this function
1090 * Returns != 0 upon successful completion.
1095 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1099 afs_status_t tst = 0;
1102 tst = ADMITERATORNULL;
1103 goto fail_IsValidPtsGroupMemberListIterator;
1106 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1107 tst = ADMITERATORBADMAGICNULL;
1108 goto fail_IsValidPtsGroupMemberListIterator;
1111 if (iter->is_valid == 0) {
1112 tst = ADMITERATORINVALID;
1113 goto fail_IsValidPtsGroupMemberListIterator;
1117 fail_IsValidPtsGroupMemberListIterator:
1126 * MemberListBegin - an internal function which is used to get both
1127 * the list of members in a group and the list of groups a user belongs
1132 * IN cellHandle - a previously opened cellHandle that corresponds
1133 * to the cell where the group exists.
1135 * IN name - the name whose membership will be retrieved.
1137 * OUT iterationIdP - upon successful completion contains a iterator that
1138 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1142 * No locks are obtained or released by this function
1146 * Returns != 0 upon successful completion.
1151 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1152 afs_status_t error2, void **iterationIdP, afs_status_p st)
1155 afs_status_t tst = 0;
1156 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1157 afs_int32 groupId = 0;
1158 afs_int32 exceeded = 0;
1159 pts_group_member_list_iterator_p iter = (pts_group_member_list_iterator_p)
1160 malloc(sizeof(pts_group_member_list_iterator_t));
1161 int iter_allocated = 0;
1162 int ids_allocated = 0;
1163 int names_allocated = 0;
1164 int mutex_inited = 0;
1167 * Validate arguments
1170 if (!IsValidCellHandle(c_handle, &tst)) {
1171 goto fail_MemberListBegin;
1174 if ((name == NULL) || (*name == 0)) {
1175 tst = ADMPTSGROUPNAMENULL;
1176 goto fail_MemberListBegin;
1179 if (iterationIdP == NULL) {
1180 tst = ADMITERATORNULL;
1181 goto fail_MemberListBegin;
1186 goto fail_MemberListBegin;
1192 * Translate the name into an id.
1195 if (!TranslateOneName
1196 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1197 goto fail_MemberListBegin;
1200 if (pthread_mutex_init(&iter->mutex, 0)) {
1202 goto fail_MemberListBegin;
1207 iter->ids.prlist_len = 0;
1208 iter->ids.prlist_val = 0;
1211 ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
1215 goto fail_MemberListBegin;
1218 if (exceeded != 0) {
1219 tst = ADMPTSGROUPMEMEXCEEDED;
1220 goto fail_MemberListBegin;
1224 iter->names.namelist_len = 0;
1225 iter->names.namelist_val = 0;
1227 if (!TranslatePTSIds
1228 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1229 goto fail_MemberListBegin;
1232 names_allocated = 1;
1233 iter->begin_magic = BEGIN_MAGIC;
1234 iter->end_magic = END_MAGIC;
1238 *iterationIdP = (void *)iter;
1241 fail_MemberListBegin:
1243 if (ids_allocated) {
1244 free(iter->ids.prlist_val);
1248 if (names_allocated) {
1249 free(iter->names.namelist_val);
1252 pthread_mutex_destroy(&iter->mutex);
1254 if (iter_allocated) {
1266 * pts_GroupMemberListBegin - begin iterating over the list of members
1267 * of a particular group.
1271 * IN cellHandle - a previously opened cellHandle that corresponds
1272 * to the cell where the group exists.
1274 * IN groupName - the group whose members will be returned.
1276 * OUT iterationIdP - upon successful completion contains a iterator that
1277 * can be passed to pts_GroupMemberListNext.
1281 * No locks are obtained or released by this function
1285 * Returns != 0 upon successful completion.
1290 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1291 void **iterationIdP, afs_status_p st)
1293 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1294 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1298 * pts_GroupMemberListNext - get the next member of a group
1302 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1304 * OUT memberName - upon successful completion contains the next member of
1309 * The iterator mutex is held during the retrieval of the next member.
1313 * Returns != 0 upon successful completion.
1318 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1322 afs_status_t tst = 0;
1323 pts_group_member_list_iterator_p iter =
1324 (pts_group_member_list_iterator_p) iterationId;
1325 int mutex_locked = 0;
1328 * Validate arguments
1332 tst = ADMITERATORNULL;
1333 goto fail_pts_GroupMemberListNext;
1336 if (memberName == NULL) {
1337 tst = ADMPTSMEMBERNAMENULL;
1338 goto fail_pts_GroupMemberListNext;
1342 * Lock the mutex and check the validity of the iterator
1345 if (pthread_mutex_lock(&iter->mutex)) {
1347 goto fail_pts_GroupMemberListNext;
1352 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1353 goto fail_pts_GroupMemberListNext;
1357 * Check to see if we've copied out all the data. If we haven't,
1358 * copy another item. If we have, mark the iterator done.
1361 if (iter->index >= iter->names.namelist_len) {
1362 tst = ADMITERATORDONE;
1363 goto fail_pts_GroupMemberListNext;
1365 strcpy(memberName, iter->names.namelist_val[iter->index]);
1370 fail_pts_GroupMemberListNext:
1373 pthread_mutex_unlock(&iter->mutex);
1383 * pts_GroupMemberListDone - finish using a member list iterator
1387 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1391 * The iterator is locked and then destroyed
1395 * Returns != 0 upon successful completion.
1399 * It is the user's responsibility to make sure pts_GroupMemberListDone
1400 * is called only once for each iterator.
1404 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1407 afs_status_t tst = 0;
1408 pts_group_member_list_iterator_p iter =
1409 (pts_group_member_list_iterator_p) iterationId;
1410 int mutex_locked = 0;
1413 * Validate arguments
1417 tst = ADMITERATORNULL;
1418 goto fail_pts_GroupMemberListDone;
1422 * Lock the mutex and check the validity of the iterator
1425 if (pthread_mutex_lock(&iter->mutex)) {
1427 goto fail_pts_GroupMemberListDone;
1432 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1433 goto fail_pts_GroupMemberListDone;
1437 * Free the namelist and the iterator.
1440 pthread_mutex_destroy(&iter->mutex);
1443 free(iter->names.namelist_val);
1447 fail_pts_GroupMemberListDone:
1450 pthread_mutex_unlock(&iter->mutex);
1460 * pts_GroupMemberRemove - remove a member from a group.
1464 * IN cellHandle - a previously opened cellHandle that corresponds
1465 * to the cell where the group exists.
1467 * IN userName - the user to remove.
1469 * IN groupName - the group to modify
1473 * No locks are held by this function
1477 * Returns != 0 upon successful completion.
1482 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1483 const char *groupName, afs_status_p st)
1486 afs_status_t tst = 0;
1487 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1491 * Validate arguments
1494 if (!IsValidCellHandle(c_handle, &tst)) {
1495 goto fail_pts_GroupMemberRemove;
1498 if ((userName == NULL) || (*userName == 0)) {
1499 tst = ADMPTSUSERNAMENULL;
1500 goto fail_pts_GroupMemberRemove;
1503 if ((groupName == NULL) || (*groupName == 0)) {
1504 tst = ADMPTSGROUPNAMENULL;
1505 goto fail_pts_GroupMemberRemove;
1508 if (!TranslateTwoNames
1509 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1510 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1511 goto fail_pts_GroupMemberRemove;
1519 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1523 goto fail_pts_GroupMemberRemove;
1527 fail_pts_GroupMemberRemove:
1529 if (ids.idlist_val != 0) {
1530 free(ids.idlist_val);
1540 * pts_GroupRename - change the name of a group
1544 * IN cellHandle - a previously opened cellHandle that corresponds
1545 * to the cell where the group exists.
1547 * IN oldName - the current group name
1549 * IN newName - the new group name
1553 * No locks are held by this function
1557 * Returns != 0 upon successful completion.
1562 pts_GroupRename(const void *cellHandle, const char *oldName,
1563 const char *newName, afs_status_p st)
1566 afs_status_t tst = 0;
1567 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1568 afs_int32 groupId = 0;
1571 * Validate arguments
1574 if (!IsValidCellHandle(c_handle, &tst)) {
1575 goto fail_pts_GroupRename;
1578 if ((newName == NULL) || (*newName == 0)) {
1579 tst = ADMPTSNEWNAMENULL;
1580 goto fail_pts_GroupRename;
1583 if ((oldName == NULL) || (*oldName == 0)) {
1584 tst = ADMPTSOLDNAMENULL;
1585 goto fail_pts_GroupRename;
1589 * Translate the group name into an id.
1592 if (!TranslateOneName
1593 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1594 goto fail_pts_GroupRename;
1601 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1604 goto fail_pts_GroupRename;
1608 fail_pts_GroupRename:
1617 * SetGroupAccess - translate our Access notation to pts flags.
1621 * IN rights - the permissions.
1623 * OUT flags - a pointer to an afs_int32 structure that
1624 * contains the flags to pass to pts.
1628 * No locks are held by this function
1632 * Returns != 0 upon successful completion.
1637 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1641 afs_status_t tst = 0;
1645 if (rights->listDelete == PTS_GROUP_ACCESS) {
1647 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1648 tst = ADMPTSINVALIDGROUPDELETEPERM;
1649 goto fail_SetGroupAccess;
1652 if (rights->listAdd == PTS_GROUP_ACCESS) {
1654 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1658 if (rights->listMembership == PTS_GROUP_ACCESS) {
1660 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1664 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1666 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1667 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1668 goto fail_SetGroupAccess;
1671 if (rights->listStatus == PTS_GROUP_ACCESS) {
1673 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1678 fail_SetGroupAccess:
1687 * pts_GroupModify - change the contents of a group entry.
1691 * IN cellHandle - a previously opened cellHandle that corresponds
1692 * to the cell where the group exists.
1694 * IN groupName - the group to change
1696 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1697 * contains the new information for the group.
1701 * No locks are held by this function
1705 * Returns != 0 upon successful completion.
1710 pts_GroupModify(const void *cellHandle, const char *groupName,
1711 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1714 afs_status_t tst = 0;
1715 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1716 afs_int32 groupId = 0;
1717 afs_int32 flags = 0;
1720 * Validate arguments
1723 if (!IsValidCellHandle(c_handle, &tst)) {
1724 goto fail_pts_GroupModify;
1727 if ((groupName == NULL) || (*groupName == 0)) {
1728 tst = ADMPTSGROUPNAMENULL;
1729 goto fail_pts_GroupModify;
1733 if (newEntryP == NULL) {
1734 tst = ADMPTSNEWENTRYPNULL;
1735 goto fail_pts_GroupModify;
1739 * Translate the group name into an id.
1742 if (!TranslateOneName
1743 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1744 goto fail_pts_GroupModify;
1748 * Set the flags argument
1751 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1752 goto fail_pts_GroupModify;
1760 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1764 goto fail_pts_GroupModify;
1768 fail_pts_GroupModify:
1777 * pts_UserCreate - create a new user.
1781 * IN cellHandle - a previously opened cellHandle that corresponds
1782 * to the cell where the group exists.
1784 * IN newUser - the name of the new user.
1786 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1787 * id assigned by pts.
1791 * No locks are held by this function
1795 * Returns != 0 upon successful completion.
1800 pts_UserCreate(const void *cellHandle, const char *userName, int *newUserId,
1804 afs_status_t tst = 0;
1805 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1806 afs_int32 userId = 0;
1809 * Validate arguments
1812 if (!IsValidCellHandle(c_handle, &tst)) {
1813 goto fail_pts_UserCreate;
1816 if ((userName == NULL) || (*userName == 0)) {
1817 tst = ADMPTSUSERNAMENULL;
1818 goto fail_pts_UserCreate;
1821 if (newUserId == NULL) {
1822 tst = ADMPTSNEWUSERIDNULL;
1823 goto fail_pts_UserCreate;
1827 * We make a different rpc based upon the input to this function
1830 if (*newUserId != 0) {
1832 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1836 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1841 goto fail_pts_UserCreate;
1845 fail_pts_UserCreate:
1854 * pts_UserDelete - delete a user.
1858 * IN cellHandle - a previously opened cellHandle that corresponds
1859 * to the cell where the group exists.
1861 * IN user - the name of the user to delete.
1865 * No locks are held by this function
1869 * Returns != 0 upon successful completion.
1874 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1876 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1877 ADMPTSUSERNAMETOOLONG, st);
1882 * GetUserAccess - a small convenience function for setting
1887 * IN access - a pointer to a pts_userAccess_t to be set with the
1888 * correct permission.
1890 * IN flag - the current permission flag used to derive the permission.
1894 * No locks are obtained or released by this function
1898 * Since this function cannot fail, it returns void.
1903 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1906 *access = PTS_USER_OWNER_ACCESS;
1908 *access = PTS_USER_ANYUSER_ACCESS;
1913 * IsAdministrator - determine if a user is an administrator.
1917 * IN cellHandle - a previously opened cellHandle that corresponds
1918 * to the cell where the group exists.
1920 * IN userEntry - the user data for the user in question.
1922 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1926 * No locks are held by this function
1930 * Returns != 0 upon successful completion.
1935 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1936 int *admin, afs_status_p st)
1939 afs_status_t tst = 0;
1940 afs_int32 adminId = 0;
1941 afs_int32 isAdmin = 0;
1945 if (userId == SYSADMINID) {
1948 if (!TranslateOneName
1949 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1951 goto fail_IsAdministrator;
1954 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1957 goto fail_IsAdministrator;
1965 fail_IsAdministrator:
1974 * pts_UserGet - retrieve information about a particular user.
1978 * IN cellHandle - a previously opened cellHandle that corresponds
1979 * to the cell where the group exists.
1981 * IN userName - the name of the user to retrieve.
1983 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1988 * No locks are held by this function
1992 * Returns != 0 upon successful completion.
1997 pts_UserGet(const void *cellHandle, const char *userName,
1998 pts_UserEntry_p userP, afs_status_p st)
2001 afs_status_t tst = 0;
2002 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2003 struct prcheckentry userEntry;
2004 afs_int32 userId = 0;
2008 afs_int32 ptsids[2];
2014 * Validate arguments
2017 if (!IsValidCellHandle(c_handle, &tst)) {
2018 goto fail_pts_UserGet;
2021 if ((userName == NULL) || (*userName == 0)) {
2022 tst = ADMPTSUSERNAMENULL;
2023 goto fail_pts_UserGet;
2026 if (userP == NULL) {
2027 tst = ADMPTSUSERPNULL;
2028 goto fail_pts_UserGet;
2032 * Translate the group name into an id.
2035 if (!TranslateOneName
2036 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2037 goto fail_pts_UserGet;
2041 * Retrieve information about the group
2044 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2047 goto fail_pts_UserGet;
2050 userP->groupMembershipCount = userEntry.count;
2051 userP->groupCreationQuota = userEntry.ngroups;
2053 * The administrator id, or any member of "system:administrators"
2054 * has unlimited group creation quota. Denote this by setting
2058 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2059 goto fail_pts_UserGet;
2063 userP->groupCreationQuota = -1;
2066 userP->nameUid = userEntry.id;
2067 userP->ownerUid = userEntry.owner;
2068 userP->creatorUid = userEntry.creator;
2069 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2070 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2073 * The permission bits are described in the GroupGet function above.
2074 * The user entry only uses 3 of the 5 permissions, so we shift
2075 * past the unused entries.
2078 flags = userEntry.flags;
2082 GetUserAccess(&userP->listMembership, twobit);
2087 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2089 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2095 GetUserAccess(&userP->listStatus, twobit);
2098 * Make another rpc and translate the owner and creator ids into
2099 * character strings.
2103 ids.idlist_val = ptsids;
2104 ptsids[0] = userEntry.owner;
2105 ptsids[1] = userEntry.creator;
2106 names.namelist_len = 0;
2107 names.namelist_val = 0;
2110 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2111 goto fail_pts_UserGet;
2114 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2115 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2116 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2117 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2118 free(names.namelist_val);
2130 * pts_UserRename - rename a user.
2134 * IN cellHandle - a previously opened cellHandle that corresponds
2135 * to the cell where the group exists.
2137 * IN oldName - the name of the user to rename.
2139 * IN newName - the new user name.
2143 * No locks are held by this function
2147 * Returns != 0 upon successful completion.
2152 pts_UserRename(const void *cellHandle, const char *oldName,
2153 const char *newName, afs_status_p st)
2156 afs_status_t tst = 0;
2157 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2158 afs_int32 userId = 0;
2161 * Validate arguments
2164 if (!IsValidCellHandle(c_handle, &tst)) {
2165 goto fail_pts_UserRename;
2168 if ((oldName == NULL) || (*oldName == 0)) {
2169 tst = ADMPTSOLDNAMENULL;
2170 goto fail_pts_UserRename;
2173 if ((newName == NULL) || (*newName == 0)) {
2174 tst = ADMPTSNEWNAMENULL;
2175 goto fail_pts_UserRename;
2179 * Translate the user name into an id.
2182 if (!TranslateOneName
2183 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2184 goto fail_pts_UserRename;
2191 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2194 goto fail_pts_UserRename;
2198 fail_pts_UserRename:
2207 * SetUserAccess - translate our Access notation to pts flags.
2211 * IN userP - the user structure that contains the new permissions.
2213 * OUT flags - a pointer to an afs_int32 structure that
2214 * contains the flags to pass to pts.
2218 * No locks are held by this function
2222 * Returns != 0 upon successful completion.
2227 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2231 afs_status_t tst = 0;
2235 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2239 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2243 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2256 * pts_UserModify - update a user entry.
2260 * IN cellHandle - a previously opened cellHandle that corresponds
2261 * to the cell where the group exists.
2263 * IN userName - the name of the user to update.
2265 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2266 * new information for user.
2270 * No locks are held by this function
2274 * Returns != 0 upon successful completion.
2279 pts_UserModify(const void *cellHandle, const char *userName,
2280 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2283 afs_status_t tst = 0;
2284 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2285 afs_int32 userId = 0;
2286 afs_int32 newQuota = 0;
2288 afs_int32 flags = 0;
2291 * Validate arguments
2294 if (!IsValidCellHandle(c_handle, &tst)) {
2295 goto fail_pts_UserModify;
2298 if ((userName == NULL) || (*userName == 0)) {
2299 tst = ADMPTSUSERNAMENULL;
2300 goto fail_pts_UserModify;
2303 if (newEntryP == NULL) {
2304 tst = ADMPTSNEWENTRYPNULL;
2305 goto fail_pts_UserModify;
2309 * Translate the user name into an id.
2312 if (!TranslateOneName
2313 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2314 goto fail_pts_UserModify;
2318 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2319 mask |= PR_SF_NGROUPS;
2320 newQuota = newEntryP->groupCreationQuota;
2323 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2324 mask |= PR_SF_ALLBITS;
2325 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2326 goto fail_pts_UserModify;
2335 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2339 goto fail_pts_UserModify;
2343 fail_pts_UserModify:
2352 * pts_UserMaxGet - get the maximum in use user id.
2356 * IN cellHandle - a previously opened cellHandle that corresponds
2357 * to the cell where the group exists.
2359 * OUT maxUserId - upon successful completion contains the max in use id.
2363 * No locks are held by this function
2367 * Returns != 0 upon successful completion.
2372 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2375 afs_status_t tst = 0;
2376 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2377 afs_int32 maxGroupId = 0;
2380 * Validate arguments
2383 if (!IsValidCellHandle(c_handle, &tst)) {
2384 goto fail_pts_UserMaxGet;
2387 if (maxUserId == NULL) {
2388 tst = ADMPTSMAXUSERIDNULL;
2389 goto fail_pts_UserMaxGet;
2392 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2395 goto fail_pts_UserMaxGet;
2399 fail_pts_UserMaxGet:
2408 * pts_UserMaxSet - set the maximum user id.
2412 * IN cellHandle - a previously opened cellHandle that corresponds
2413 * to the cell where the group exists.
2415 * IN maxUserId - the new max user id.
2419 * No locks are held by this function
2423 * Returns != 0 upon successful completion.
2428 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2431 afs_status_t tst = 0;
2432 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2435 * Validate arguments
2438 if (!IsValidCellHandle(c_handle, &tst)) {
2439 goto fail_pts_UserMaxSet;
2442 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2445 goto fail_pts_UserMaxSet;
2449 fail_pts_UserMaxSet:
2458 * pts_UserMemberListBegin - begin iterating over the list of groups
2459 * a particular user belongs to.
2463 * IN cellHandle - a previously opened cellHandle that corresponds
2464 * to the cell where the group exists.
2466 * IN groupName - the group whose members will be returned.
2468 * OUT iterationIdP - upon successful completion contains a iterator that
2469 * can be passed to pts_GroupMemberListNext.
2473 * No locks are obtained or released by this function
2477 * Returns != 0 upon successful completion.
2482 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2483 void **iterationIdP, afs_status_p st)
2485 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2486 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2491 * pts_UserMemberListNext - get the next group a user belongs to
2495 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2497 * OUT userName - upon successful completion contains the next group a user
2502 * The iterator mutex is held during the retrieval of the next member.
2506 * Returns != 0 upon successful completion.
2511 pts_UserMemberListNext(const void *iterationId, char *userName,
2514 return pts_GroupMemberListNext(iterationId, userName, st);
2518 * pts_UserMemberListDone - finish using a user list iterator
2522 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2526 * The iterator is locked and then destroyed
2530 * Returns != 0 upon successful completion.
2534 * It is the user's responsibility to make sure pts_UserMemberListDone
2535 * is called only once for each iterator.
2539 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2541 return pts_GroupMemberListDone(iterationId, st);
2544 typedef struct owned_group_list {
2545 namelist owned_names; /* the list of character names owned by this id */
2546 prlist owned_ids; /* the list of pts ids owned by this id */
2547 afs_int32 index; /* the index into owned_names for the next group */
2548 afs_int32 owner; /* the pts id of the owner */
2549 afs_int32 more; /* the last parameter to PR_ListOwned */
2550 int finished_retrieving; /* set when we've processed the last owned_names */
2551 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2552 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2553 } owned_group_list_t, *owned_group_list_p;
2556 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2559 afs_status_t tst = 0;
2560 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2562 if (list->owned_names.namelist_val != NULL) {
2563 free(list->owned_names.namelist_val);
2566 if (list->owned_ids.prlist_val != NULL) {
2567 free(list->owned_ids.prlist_val);
2578 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2579 int *last_item_contains_data, afs_status_p st)
2582 afs_status_t tst = 0;
2583 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2586 * We really don't make an rpc for every entry we return here
2587 * since the pts interface allows several members to be returned
2588 * with one rpc, but we fake it to make the iterator happy.
2592 * Check to see if we are done retrieving data
2595 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2597 *last_item_contains_data = 0;
2598 goto fail_GetOwnedGroupRPC;
2602 * Check to see if we really need to make an rpc
2605 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2607 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2608 &list->owned_ids, &list->more);
2610 goto fail_GetOwnedGroupRPC;
2613 if (!TranslatePTSIds
2614 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2616 goto fail_GetOwnedGroupRPC;
2620 if (list->owned_names.namelist_val == NULL) {
2622 *last_item_contains_data = 0;
2623 goto fail_GetOwnedGroupRPC;
2628 * We can retrieve the next group from data we already received
2631 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2635 * Check to see if there is more data to be retrieved
2636 * We need to free up the previously retrieved data here
2637 * and then check to see if the last rpc indicated that there
2638 * were more items to retrieve.
2641 if (list->index >= list->owned_names.namelist_len) {
2642 list->owned_names.namelist_len = 0;
2643 free(list->owned_names.namelist_val);
2644 list->owned_names.namelist_val = 0;
2646 list->owned_ids.prlist_len = 0;
2647 free(list->owned_ids.prlist_val);
2648 list->owned_ids.prlist_val = 0;
2651 list->finished_retrieving = 1;
2656 fail_GetOwnedGroupRPC:
2665 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2669 afs_status_t tst = 0;
2670 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2672 strcpy((char *)dest, list->group[slot]);
2683 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2684 * a particular user owns.
2688 * IN cellHandle - a previously opened cellHandle that corresponds
2689 * to the cell where the group exists.
2691 * IN ownerName - the owner of the groups of interest.
2693 * OUT iterationIdP - upon successful completion contains a iterator that
2694 * can be passed to pts_OwnedGroupListNext.
2698 * No locks are held by this function
2702 * Returns != 0 upon successful completion.
2707 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2708 void **iterationIdP, afs_status_p st)
2711 afs_status_t tst = 0;
2712 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2713 afs_admin_iterator_p iter =
2714 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2715 owned_group_list_p list =
2716 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2719 * Validate arguments
2722 if (!IsValidCellHandle(c_handle, &tst)) {
2723 goto fail_pts_OwnedGroupListBegin;
2726 if ((userName == NULL) || (*userName == 0)) {
2727 tst = ADMPTSUSERNAMENULL;
2728 goto fail_pts_OwnedGroupListBegin;
2731 if (iterationIdP == NULL) {
2732 tst = ADMITERATORNULL;
2733 goto fail_pts_OwnedGroupListBegin;
2736 if ((iter == NULL) || (list == NULL)) {
2738 goto fail_pts_OwnedGroupListBegin;
2742 * Initialize the iterator specific data
2746 list->finished_retrieving = 0;
2747 list->c_handle = c_handle;
2748 list->owned_names.namelist_len = 0;
2749 list->owned_names.namelist_val = 0;
2750 list->owned_ids.prlist_len = 0;
2751 list->owned_ids.prlist_val = 0;
2754 * Translate the user name into an id.
2757 if (!TranslateOneName
2758 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2759 goto fail_pts_OwnedGroupListBegin;
2763 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2764 DeleteOwnedGroupSpecificData, &tst)) {
2765 *iterationIdP = (void *)iter;
2769 fail_pts_OwnedGroupListBegin:
2787 * pts_OwnedGroupListNext - get the next group a user owns.
2791 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2793 * OUT groupName - upon successful completion contains the next group a user
2798 * The iterator mutex is held during the retrieval of the next member.
2802 * Returns != 0 upon successful completion.
2807 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2811 afs_status_t tst = 0;
2812 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2815 * Validate arguments
2818 if (iterationId == NULL) {
2819 tst = ADMITERATORNULL;
2820 goto fail_pts_OwnedGroupListNext;
2823 if (groupName == NULL) {
2824 tst = ADMPTSGROUPNAMENULL;
2825 goto fail_pts_OwnedGroupListNext;
2828 rc = IteratorNext(iter, (void *)groupName, &tst);
2830 fail_pts_OwnedGroupListNext:
2839 * pts_OwnedGroupListDone - finish using a group list iterator
2843 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2847 * The iterator is locked and then destroyed
2851 * Returns != 0 upon successful completion.
2855 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2856 * is called only once for each iterator.
2860 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2863 afs_status_t tst = 0;
2864 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2867 * Validate arguments
2870 if (iterationId == NULL) {
2871 tst = ADMITERATORNULL;
2872 goto fail_pts_OwnedGroupListDone;
2875 rc = IteratorDone(iter, &tst);
2877 fail_pts_OwnedGroupListDone:
2885 typedef struct pts_list {
2886 prlistentries *names; /* the current list of pts names in this cell */
2887 prlistentries *currName; /* the current pts entry */
2888 afs_int32 index; /* the index into names for the next pts entry */
2889 afs_int32 nextstartindex; /* the next start index for the RPC */
2890 afs_int32 nentries; /* the number of entries in names */
2891 afs_int32 flag; /* the type of the list */
2892 int finished_retrieving; /* set when we've processed the last owned_names */
2893 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2894 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2895 } pts_list_t, *pts_list_p;
2898 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2901 afs_status_t tst = 0;
2902 pts_list_p list = (pts_list_p) rpc_specific;
2917 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2918 int *last_item_contains_data, afs_status_p st)
2921 afs_status_t tst = 0;
2922 pts_list_p list = (pts_list_p) rpc_specific;
2925 * We really don't make an rpc for every entry we return here
2926 * since the pts interface allows several members to be returned
2927 * with one rpc, but we fake it to make the iterator happy.
2931 * Check to see if we are done retrieving data
2934 if (list->finished_retrieving) {
2936 *last_item_contains_data = 0;
2937 goto fail_GetPTSRPC;
2941 * Check to see if we really need to make an rpc
2944 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2945 afs_int32 start = list->nextstartindex;
2946 prentries bulkentries;
2947 list->nextstartindex = -1;
2948 bulkentries.prentries_val = 0;
2949 bulkentries.prentries_len = 0;
2952 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2953 start, &bulkentries, &(list->nextstartindex));
2956 goto fail_GetPTSRPC;
2959 list->nentries = bulkentries.prentries_len;
2960 list->names = bulkentries.prentries_val;
2963 list->currName = list->names;
2968 * We can retrieve the next entry from data we already received
2971 strcpy(list->entries[slot], list->currName->name);
2977 * Check to see if there is more data to be retrieved
2978 * We need to free up the previously retrieved data here
2979 * and then check to see if the last rpc indicated that there
2980 * were more items to retrieve.
2983 if (list->index >= list->nentries) {
2989 if (list->nextstartindex == -1) {
2990 list->finished_retrieving = 1;
3005 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3008 afs_status_t tst = 0;
3009 pts_list_p list = (pts_list_p) rpc_specific;
3011 strcpy((char *)dest, list->entries[slot]);
3022 * pts_UserListBegin - begin iterating over the list of users
3023 * in a particular cell
3027 * IN cellHandle - a previously opened cellHandle that corresponds
3028 * to the cell where the users exist.
3030 * OUT iterationIdP - upon successful completion contains a iterator that
3031 * can be passed to pts_UserListNext.
3035 * No locks are held by this function
3039 * Returns != 0 upon successful completion.
3044 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3048 afs_status_t tst = 0;
3049 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3050 afs_admin_iterator_p iter =
3051 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3052 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3055 * Validate arguments
3058 if (!IsValidCellHandle(c_handle, &tst)) {
3059 goto fail_pts_UserListBegin;
3062 if (iterationIdP == NULL) {
3063 tst = ADMITERATORNULL;
3064 goto fail_pts_UserListBegin;
3067 if ((iter == NULL) || (list == NULL)) {
3069 goto fail_pts_UserListBegin;
3073 * Initialize the iterator specific data
3077 list->finished_retrieving = 0;
3078 list->c_handle = c_handle;
3080 list->nextstartindex = 0;
3082 list->flag = PRUSERS;
3085 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3086 DeletePTSSpecificData, &tst)) {
3087 *iterationIdP = (void *)iter;
3091 fail_pts_UserListBegin:
3109 * pts_UserListNext - get the next user in the cell.
3113 * IN iterationId - an iterator previously returned by pts_UserListBegin
3115 * OUT groupName - upon successful completion contains the next user
3119 * The iterator mutex is held during the retrieval of the next member.
3123 * Returns != 0 upon successful completion.
3128 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3131 afs_status_t tst = 0;
3132 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3135 * Validate arguments
3138 if (iterationId == NULL) {
3139 tst = ADMITERATORNULL;
3140 goto fail_pts_UserListNext;
3143 if (userName == NULL) {
3144 tst = ADMPTSUSERNAMENULL;
3145 goto fail_pts_UserListNext;
3148 rc = IteratorNext(iter, (void *)userName, &tst);
3150 fail_pts_UserListNext:
3159 * pts_UserListDone - finish using a user list iterator
3163 * IN iterationId - an iterator previously returned by pts_UserListBegin
3167 * The iterator is locked and then destroyed
3171 * Returns != 0 upon successful completion.
3175 * It is the user's responsibility to make sure pts_UserListDone
3176 * is called only once for each iterator.
3180 pts_UserListDone(const void *iterationId, afs_status_p st)
3183 afs_status_t tst = 0;
3184 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3187 * Validate arguments
3190 if (iterationId == NULL) {
3191 tst = ADMITERATORNULL;
3192 goto fail_pts_UserListDone;
3195 rc = IteratorDone(iter, &tst);
3197 fail_pts_UserListDone:
3206 * pts_GroupListBegin - begin iterating over the list of groups
3207 * in a particular cell.
3211 * IN cellHandle - a previously opened cellHandle that corresponds
3212 * to the cell where the groups exist.
3214 * OUT iterationIdP - upon successful completion contains a iterator that
3215 * can be passed to pts_GroupListNext.
3219 * No locks are held by this function
3223 * Returns != 0 upon successful completion.
3228 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3232 afs_status_t tst = 0;
3233 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3234 afs_admin_iterator_p iter =
3235 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3236 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3239 * Validate arguments
3242 if (!IsValidCellHandle(c_handle, &tst)) {
3243 goto fail_pts_GroupListBegin;
3246 if (iterationIdP == NULL) {
3247 tst = ADMITERATORNULL;
3248 goto fail_pts_GroupListBegin;
3251 if ((iter == NULL) || (list == NULL)) {
3253 goto fail_pts_GroupListBegin;
3257 * Initialize the iterator specific data
3261 list->finished_retrieving = 0;
3262 list->c_handle = c_handle;
3264 list->nextstartindex = 0;
3266 list->flag = PRGROUPS;
3269 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3270 DeletePTSSpecificData, &tst)) {
3271 *iterationIdP = (void *)iter;
3275 fail_pts_GroupListBegin:
3293 * pts_UserListNext - get the next group in a cell.
3297 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3299 * OUT groupName - upon successful completion contains the next group
3303 * The iterator mutex is held during the retrieval of the next member.
3307 * Returns != 0 upon successful completion.
3312 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3315 afs_status_t tst = 0;
3316 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3319 * Validate arguments
3322 if (iterationId == NULL) {
3323 tst = ADMITERATORNULL;
3324 goto fail_pts_GroupListNext;
3327 if (groupName == NULL) {
3328 tst = ADMPTSGROUPNAMENULL;
3329 goto fail_pts_GroupListNext;
3332 rc = IteratorNext(iter, (void *)groupName, &tst);
3334 fail_pts_GroupListNext:
3343 * pts_GroupListDone - finish using a group list iterator
3347 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3351 * The iterator is locked and then destroyed
3355 * Returns != 0 upon successful completion.
3359 * It is the user's responsibility to make sure pts_GroupListDone
3360 * is called only once for each iterator.
3364 pts_GroupListDone(const void *iterationId, afs_status_p st)
3367 afs_status_t tst = 0;
3368 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3371 * Validate arguments
3374 if (iterationId == NULL) {
3375 tst = ADMITERATORNULL;
3376 goto fail_pts_GroupListDone;
3379 rc = IteratorDone(iter, &tst);
3381 fail_pts_GroupListDone: