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>
18 #include <rx/rxstat.h>
19 #include "afs_ptsAdmin.h"
20 #include "../adminutil/afs_AdminInternal.h"
21 #include <afs/afs_AdminErrors.h>
22 #include <afs/afs_utilAdmin.h>
23 #include <afs/ptint.h>
24 #include <afs/ptserver.h>
27 * IsValidCellHandle - validate the cell handle for making pts
32 * IN cellHandle - a previously opened cellHandle that is to be validated.
36 * No locks are obtained or released by this function
40 * Returns != 0 upon successful completion.
45 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
50 if (!CellHandleIsValid((void *)c_handle, &tst)) {
51 goto fail_IsValidCellHandle;
54 if (c_handle->pts_valid == 0) {
55 tst = ADMCLIENTCELLPTSINVALID;
56 goto fail_IsValidCellHandle;
59 if (c_handle->pts == NULL) {
60 tst = ADMCLIENTCELLPTSNULL;
61 goto fail_IsValidCellHandle;
66 fail_IsValidCellHandle:
76 * TranslatePTSNames - translate character representations of pts names
77 * into their numeric equivalent.
81 * IN cellHandle - a previously opened cellHandle that corresponds
82 * to the cell where the id's exist.
84 * IN names - the list of names to be translated.
86 * OUT ids - the list of translated names
90 * No locks are obtained or released by this function
94 * Returns != 0 upon successful completion.
99 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
100 idlist * ids, afs_status_p st)
103 afs_status_t tst = 0;
108 * Lowercase the names to translate
111 for (i = 0; i < names->namelist_len; i++) {
112 p = names->namelist_val[i];
119 tst = ubik_PR_NameToID(cellHandle->pts, 0, names, ids);
122 goto fail_TranslatePTSNames;
127 * Check to see if the lookup failed
130 for (i = 0; i < ids->idlist_len; i++) {
131 if (ids->idlist_val[i] == ANONYMOUSID) {
132 tst = ADMPTSFAILEDNAMETRANSLATE;
133 goto fail_TranslatePTSNames;
138 fail_TranslatePTSNames:
147 * TranslateTwoNames - translate two pts names to their pts ids.
151 * IN cellHandle - a previously opened cellHandle that corresponds
152 * to the cell where the group exists.
154 * IN id1 - one id to be translated
156 * IN error1 - the error status to be returned in the event that id1 is
159 * IN id2 - one id to be translated
161 * IN error2 - the error status to be returned in the event that id2 is
165 * OUT idlist - the list of pts id's
169 * No locks are obtained or released by this function
173 * Returns != 0 upon successful completion.
178 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
179 afs_status_t error1, const char *id2, afs_status_t error2,
180 idlist * ids, afs_status_p st)
183 afs_status_t tst = 0;
185 char tmp_array[2 * PTS_MAX_NAME_LEN];
188 * Copy the group and user names in order to translate them
191 names.namelist_len = 2;
192 names.namelist_val = (prname *) & tmp_array[0];
194 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
195 names.namelist_val[0][PTS_MAX_NAME_LEN - 1] = '\0';
196 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
197 names.namelist_val[1][PTS_MAX_NAME_LEN - 1] = '\0';
202 * Check that user and group aren't too long
203 * This is a cheaper check than calling strlen
206 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
208 goto fail_TranslateTwoNames;
211 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
213 goto fail_TranslateTwoNames;
217 * Translate user and group into pts ID's
220 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
221 goto fail_TranslateTwoNames;
226 fail_TranslateTwoNames:
235 * TranslateOneName - translate a pts name to its pts id.
239 * IN cellHandle - a previously opened cellHandle that corresponds
240 * to the cell where the group exists.
242 * IN userName - the user to be translated.
244 * OUT idlist - the user pts id.
248 * No locks are obtained or released by this function
252 * Returns != 0 upon successful completion.
257 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
258 afs_status_t tooLongError, afs_int32 * ptsId,
262 afs_status_t tst = 0;
264 char tmp_array[PTS_MAX_NAME_LEN];
268 * Copy the name in order to translate it
271 names[0].namelist_len = 1;
272 names[0].namelist_val = (prname *) & tmp_array[0];
274 strncpy((char *)names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
275 ((char *)names[0].namelist_val)[PTS_MAX_NAME_LEN - 1] = '\0';
280 * Check that user isn't too long
281 * This is a cheaper check than calling strlen
284 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
286 goto fail_TranslateOneName;
290 * Translate user into pts ID
293 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
294 goto fail_TranslateOneName;
296 if (ids.idlist_val != NULL) {
297 *ptsId = *ids.idlist_val;
298 free(ids.idlist_val);
304 fail_TranslateOneName:
313 * TranslatePTSIds - translate numeric representations of pts names
314 * into their character equivalent.
318 * IN cellHandle - a previously opened cellHandle that corresponds
319 * to the cell where the id's exist.
321 * IN ids - the list of ids to be translated.
323 * OUT names - the list of translated names
327 * No locks are obtained or released by this function
331 * Returns != 0 upon successful completion.
336 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
337 idlist * ids, afs_status_p st)
340 afs_status_t tst = 0;
342 tst = ubik_PR_IDToName(cellHandle->pts, 0, ids, names);
345 goto fail_TranslatePTSIds;
349 fail_TranslatePTSIds:
358 * pts_GroupMemberAdd - add one member to a pts group
362 * IN cellHandle - a previously opened cellHandle that corresponds
363 * to the cell where the group exists.
365 * IN userName - the name to be added to the group.
367 * IN groupName - the group to be modified.
371 * No locks are obtained or released by this function
375 * Returns != 0 upon successful completion.
380 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
381 const char *groupName, afs_status_p st)
384 afs_status_t tst = 0;
385 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
392 if (!IsValidCellHandle(c_handle, &tst)) {
393 goto fail_pts_GroupMemberAdd;
396 if ((userName == NULL) || (*userName == 0)) {
397 tst = ADMPTSUSERNAMENULL;
398 goto fail_pts_GroupMemberAdd;
401 if ((groupName == NULL) || (*groupName == 0)) {
402 tst = ADMPTSGROUPNAMENULL;
403 goto fail_pts_GroupMemberAdd;
406 if (!TranslateTwoNames
407 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
408 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
409 goto fail_pts_GroupMemberAdd;
417 ubik_PR_AddToGroup(c_handle->pts, 0, ids.idlist_val[0],
421 goto fail_pts_GroupMemberAdd;
425 fail_pts_GroupMemberAdd:
427 if (ids.idlist_val != 0) {
428 free(ids.idlist_val);
438 * pts_GroupOwnerChange - change the owner of a group
442 * IN cellHandle - a previously opened cellHandle that corresponds
443 * to the cell where the group exists.
445 * IN targetGroup - the group to be modified.
447 * IN userName - the new owner of the group.
451 * No locks are obtained or released by this function
455 * Returns != 0 upon successful completion.
460 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
461 const char *newOwner, afs_status_p st)
464 afs_status_t tst = 0;
465 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
472 if (!IsValidCellHandle(c_handle, &tst)) {
473 goto fail_pts_GroupOwnerChange;
476 if ((newOwner == NULL) || (*newOwner == 0)) {
477 tst = ADMPTSNEWOWNERNULL;
478 goto fail_pts_GroupOwnerChange;
481 if ((targetGroup == NULL) || (*targetGroup == 0)) {
482 tst = ADMPTSTARGETGROUPNULL;
483 goto fail_pts_GroupOwnerChange;
486 if (!TranslateTwoNames
487 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
488 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
489 goto fail_pts_GroupOwnerChange;
497 ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
498 ids.idlist_val[0], 0);
501 goto fail_pts_GroupOwnerChange;
505 fail_pts_GroupOwnerChange:
507 if (ids.idlist_val != 0) {
508 free(ids.idlist_val);
518 * pts_GroupCreate - create a new group
522 * IN cellHandle - a previously opened cellHandle that corresponds
523 * to the cell where the group exists.
525 * IN newGroup - the group to be created.
527 * IN newOwner - the owner of the group. Pass NULL if the current user
528 * is to be the new owner, or the character string of the owner otherwise.
530 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
531 * generate a value, != 0 to assign a value on your own. The group id
532 * that is used to create the group is copied into this parameter in the
533 * event you pass in 0.
537 * No locks are obtained or released by this function
541 * Returns != 0 upon successful completion.
546 pts_GroupCreate(const void *cellHandle, const char *newGroup,
547 const char *newOwner, int *newGroupId, afs_status_p st)
550 afs_status_t tst = 0;
551 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
552 afs_int32 newOwnerId = 0;
558 if (!IsValidCellHandle(c_handle, &tst)) {
559 goto fail_pts_GroupCreate;
562 if ((newGroup == NULL) || (*newGroup == 0)) {
563 tst = ADMPTSNEWGROUPNULL;
564 goto fail_pts_GroupCreate;
567 if (newGroupId == NULL) {
568 tst = ADMPTSNEWGROUPIDNULL;
569 goto fail_pts_GroupCreate;
572 if (*newGroupId > 0) {
573 tst = ADMPTSNEWGROUPIDPOSITIVE;
574 goto fail_pts_GroupCreate;
578 * If a newOwner was specified, validate that it exists
581 if (newOwner != NULL) {
582 if (!TranslateOneName
583 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
584 goto fail_pts_GroupCreate;
589 * We make a different rpc based upon the input to this function
592 if (*newGroupId != 0) {
594 ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
598 ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
599 newOwnerId, newGroupId);
603 goto fail_pts_GroupCreate;
607 fail_pts_GroupCreate:
616 * GetGroupAccess - a small convenience function for setting
621 * IN access - a pointer to a pts_groupAccess_t to be set with the
622 * correct permission.
624 * IN flag - the current permission flag used to derive the permission.
628 * No locks are obtained or released by this function
632 * Since this function cannot fail, it returns void.
637 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
640 *access = PTS_GROUP_OWNER_ACCESS;
642 *access = PTS_GROUP_OWNER_ACCESS;
643 } else if (flag == 1) {
644 *access = PTS_GROUP_ACCESS;
645 } else if (flag == 2) {
646 *access = PTS_GROUP_ANYUSER_ACCESS;
652 * pts_GroupGet - retrieve information about a particular group.
656 * IN cellHandle - a previously opened cellHandle that corresponds
657 * to the cell where the group exists.
659 * IN groupName - the group to retrieve.
661 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
662 * successful completion is filled with information about groupName.
666 * No locks are obtained or released by this function
670 * Returns != 0 upon successful completion.
675 pts_GroupGet(const void *cellHandle, const char *groupName,
676 pts_GroupEntry_p groupP, afs_status_p st)
679 afs_status_t tst = 0;
680 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
681 afs_int32 groupId = 0;
684 struct prcheckentry groupEntry;
693 if (!IsValidCellHandle(c_handle, &tst)) {
694 goto fail_pts_GroupGet;
697 if ((groupName == NULL) || (*groupName == 0)) {
698 tst = ADMPTSGROUPNAMENULL;
699 goto fail_pts_GroupGet;
702 if (groupP == NULL) {
703 tst = ADMPTSGROUPPNULL;
704 goto fail_pts_GroupGet;
708 * Translate the group name into an id.
711 if (!TranslateOneName
712 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
713 goto fail_pts_GroupGet;
717 * Retrieve information about the group
720 tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
723 goto fail_pts_GroupGet;
726 groupP->membershipCount = groupEntry.count;
727 groupP->nameUid = groupEntry.id;
728 groupP->ownerUid = groupEntry.owner;
729 groupP->creatorUid = groupEntry.creator;
730 strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
731 groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
733 * Set the access rights based upon the value of the flags member
734 * of the groupEntry struct.
736 * To the best of my ability to decypher the pts code, it looks like
737 * the rights are stored in flags as follows:
739 * I number my bits from least significant to most significant starting
743 * if bit 0 == 0 -> r access is denied
744 * if bit 0 == 1 -> r access is granted
747 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
748 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
749 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
750 * if bit 2 == 1 and bit 1 == 1 -> this is an error
752 * membership - bits 3 and 4
753 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
754 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
755 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
756 * if bit 4 == 1 and bit 3 == 1 -> this is an error
759 * if bit 5 == 0 -> O access is denied
760 * if bit 5 == 1 -> O access is granted
762 * status - bits 6 and 7
763 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
764 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
765 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
766 * if bit 7 == 1 and bit 6 == 1 -> this is an error
768 * For cases where the permission doesn't make sense for the
769 * type of entry, or where an error occurs, we ignore it.
770 * This is the behavior of the pts code.
773 flags = groupEntry.flags;
775 groupP->listDelete = PTS_GROUP_ACCESS;
777 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
783 GetGroupAccess(&groupP->listAdd, twobit);
788 GetGroupAccess(&groupP->listMembership, twobit);
793 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
795 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
801 GetGroupAccess(&groupP->listStatus, twobit);
804 * Make another rpc and translate the owner and creator ids into
809 ids.idlist_val = ptsids;
810 ptsids[0] = groupEntry.owner;
811 ptsids[1] = groupEntry.creator;
812 names.namelist_len = 0;
813 names.namelist_val = 0;
816 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
817 goto fail_pts_GroupGet;
820 strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
821 groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
822 strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
823 groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
824 free(names.namelist_val);
836 * EntryDelete - delete a pts entry (group or user).
840 * IN cellHandle - a previously opened cellHandle that corresponds
841 * to the cell where the group exists.
843 * IN entryName - the entry to be deleted.
845 * IN error1 - the error status to be returned in the event that entryName is
848 * IN error2 - the error status to be returned in the event that entryName is
853 * No locks are obtained or released by this function
857 * Returns != 0 upon successful completion.
862 EntryDelete(const void *cellHandle, const char *entryName,
863 afs_status_t error1, afs_status_t error2, afs_status_p st)
866 afs_status_t tst = 0;
867 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
868 afs_int32 entryId = 0;
874 if (!IsValidCellHandle(c_handle, &tst)) {
875 goto fail_EntryDelete;
878 if ((entryName == NULL) || (*entryName == 0)) {
880 goto fail_EntryDelete;
884 * Translate the entry name into an id.
887 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
888 goto fail_EntryDelete;
895 tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
898 goto fail_EntryDelete;
912 * pts_GroupDelete - delete a group
916 * IN cellHandle - a previously opened cellHandle that corresponds
917 * to the cell where the group exists.
919 * IN groupName - the group to be deleted.
923 * No locks are obtained or released by this function
927 * Returns != 0 upon successful completion.
932 pts_GroupDelete(const void *cellHandle, const char *groupName,
936 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
937 ADMPTSGROUPNAMETOOLONG, st);
941 * pts_GroupMaxGet - get the maximum in use group id.
945 * IN cellHandle - a previously opened cellHandle that corresponds
946 * to the cell where the group exists.
948 * OUT maxGroupId - upon successful completion contains the maximum
949 * group Id in use at the server.
953 * No locks are obtained or released by this function
957 * Returns != 0 upon successful completion.
962 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
965 afs_status_t tst = 0;
966 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
967 afs_int32 maxUserId = 0;
973 if (!IsValidCellHandle(c_handle, &tst)) {
974 goto fail_pts_GroupMaxGet;
977 if (maxGroupId == NULL) {
978 tst = ADMPTSMAXGROUPIDNULL;
979 goto fail_pts_GroupMaxGet;
982 tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
985 goto fail_pts_GroupMaxGet;
989 fail_pts_GroupMaxGet:
998 * pts_GroupMaxSet - set the maximum in use group id.
1002 * IN cellHandle - a previously opened cellHandle that corresponds
1003 * to the cell where the group exists.
1005 * IN maxGroupId - the new maximum group id.
1009 * No locks are obtained or released by this function
1013 * Returns != 0 upon successful completion.
1018 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1021 afs_status_t tst = 0;
1022 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1025 * Validate arguments
1028 if (!IsValidCellHandle(c_handle, &tst)) {
1029 goto fail_pts_GroupMaxSet;
1032 tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
1035 goto fail_pts_GroupMaxSet;
1039 fail_pts_GroupMaxSet:
1050 * I'm not using the common iterator pattern here since the retrival
1051 * of the member list is actually accomplished in 1 rpc. There's no
1052 * sense in trying to fit this pts specific behavior into the more
1053 * generic model, so instead the Begin functions actually do all the
1054 * rpc work and the next/done functions just manipulate the retrieved
1058 typedef struct pts_group_member_list_iterator {
1061 pthread_mutex_t mutex; /* hold to manipulate this structure */
1066 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1069 * pts_GroupMemberListBegin - begin iterating over the list of members
1070 * of a particular group.
1074 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1078 * No locks are obtained or released by this function
1082 * Returns != 0 upon successful completion.
1087 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1091 afs_status_t tst = 0;
1094 tst = ADMITERATORNULL;
1095 goto fail_IsValidPtsGroupMemberListIterator;
1098 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1099 tst = ADMITERATORBADMAGICNULL;
1100 goto fail_IsValidPtsGroupMemberListIterator;
1103 if (iter->is_valid == 0) {
1104 tst = ADMITERATORINVALID;
1105 goto fail_IsValidPtsGroupMemberListIterator;
1109 fail_IsValidPtsGroupMemberListIterator:
1118 * MemberListBegin - an internal function which is used to get both
1119 * the list of members in a group and the list of groups a user belongs
1124 * IN cellHandle - a previously opened cellHandle that corresponds
1125 * to the cell where the group exists.
1127 * IN name - the name whose membership will be retrieved.
1129 * OUT iterationIdP - upon successful completion contains a iterator that
1130 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1134 * No locks are obtained or released by this function
1138 * Returns != 0 upon successful completion.
1143 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1144 afs_status_t error2, void **iterationIdP, afs_status_p st)
1147 afs_status_t tst = 0;
1148 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1149 afs_int32 groupId = 0;
1150 afs_int32 exceeded = 0;
1151 pts_group_member_list_iterator_p iter = (pts_group_member_list_iterator_p)
1152 malloc(sizeof(pts_group_member_list_iterator_t));
1153 int iter_allocated = 0;
1154 int ids_allocated = 0;
1155 int names_allocated = 0;
1156 int mutex_inited = 0;
1159 * Validate arguments
1162 if (!IsValidCellHandle(c_handle, &tst)) {
1163 goto fail_MemberListBegin;
1166 if ((name == NULL) || (*name == 0)) {
1167 tst = ADMPTSGROUPNAMENULL;
1168 goto fail_MemberListBegin;
1171 if (iterationIdP == NULL) {
1172 tst = ADMITERATORNULL;
1173 goto fail_MemberListBegin;
1178 goto fail_MemberListBegin;
1184 * Translate the name into an id.
1187 if (!TranslateOneName
1188 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1189 goto fail_MemberListBegin;
1192 if (pthread_mutex_init(&iter->mutex, 0)) {
1194 goto fail_MemberListBegin;
1199 iter->ids.prlist_len = 0;
1200 iter->ids.prlist_val = 0;
1203 ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
1207 goto fail_MemberListBegin;
1210 if (exceeded != 0) {
1211 tst = ADMPTSGROUPMEMEXCEEDED;
1212 goto fail_MemberListBegin;
1216 iter->names.namelist_len = 0;
1217 iter->names.namelist_val = 0;
1219 if (!TranslatePTSIds
1220 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1221 goto fail_MemberListBegin;
1224 names_allocated = 1;
1225 iter->begin_magic = BEGIN_MAGIC;
1226 iter->end_magic = END_MAGIC;
1230 *iterationIdP = (void *)iter;
1233 fail_MemberListBegin:
1235 if (ids_allocated) {
1236 free(iter->ids.prlist_val);
1240 if (names_allocated) {
1241 free(iter->names.namelist_val);
1244 pthread_mutex_destroy(&iter->mutex);
1246 if (iter_allocated) {
1258 * pts_GroupMemberListBegin - begin iterating over the list of members
1259 * of a particular group.
1263 * IN cellHandle - a previously opened cellHandle that corresponds
1264 * to the cell where the group exists.
1266 * IN groupName - the group whose members will be returned.
1268 * OUT iterationIdP - upon successful completion contains a iterator that
1269 * can be passed to pts_GroupMemberListNext.
1273 * No locks are obtained or released by this function
1277 * Returns != 0 upon successful completion.
1282 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1283 void **iterationIdP, afs_status_p st)
1285 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1286 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1290 * pts_GroupMemberListNext - get the next member of a group
1294 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1296 * OUT memberName - upon successful completion contains the next member of
1301 * The iterator mutex is held during the retrieval of the next member.
1305 * Returns != 0 upon successful completion.
1310 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1314 afs_status_t tst = 0;
1315 pts_group_member_list_iterator_p iter =
1316 (pts_group_member_list_iterator_p) iterationId;
1317 int mutex_locked = 0;
1320 * Validate arguments
1324 tst = ADMITERATORNULL;
1325 goto fail_pts_GroupMemberListNext;
1328 if (memberName == NULL) {
1329 tst = ADMPTSMEMBERNAMENULL;
1330 goto fail_pts_GroupMemberListNext;
1334 * Lock the mutex and check the validity of the iterator
1337 if (pthread_mutex_lock(&iter->mutex)) {
1339 goto fail_pts_GroupMemberListNext;
1344 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1345 goto fail_pts_GroupMemberListNext;
1349 * Check to see if we've copied out all the data. If we haven't,
1350 * copy another item. If we have, mark the iterator done.
1353 if (iter->index >= iter->names.namelist_len) {
1354 tst = ADMITERATORDONE;
1355 goto fail_pts_GroupMemberListNext;
1357 strcpy(memberName, iter->names.namelist_val[iter->index]);
1362 fail_pts_GroupMemberListNext:
1365 pthread_mutex_unlock(&iter->mutex);
1375 * pts_GroupMemberListDone - finish using a member list iterator
1379 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1383 * The iterator is locked and then destroyed
1387 * Returns != 0 upon successful completion.
1391 * It is the user's responsibility to make sure pts_GroupMemberListDone
1392 * is called only once for each iterator.
1396 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1399 afs_status_t tst = 0;
1400 pts_group_member_list_iterator_p iter =
1401 (pts_group_member_list_iterator_p) iterationId;
1402 int mutex_locked = 0;
1405 * Validate arguments
1409 tst = ADMITERATORNULL;
1410 goto fail_pts_GroupMemberListDone;
1414 * Lock the mutex and check the validity of the iterator
1417 if (pthread_mutex_lock(&iter->mutex)) {
1419 goto fail_pts_GroupMemberListDone;
1424 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1425 goto fail_pts_GroupMemberListDone;
1429 * Free the namelist and the iterator.
1432 pthread_mutex_destroy(&iter->mutex);
1435 free(iter->names.namelist_val);
1439 fail_pts_GroupMemberListDone:
1442 pthread_mutex_unlock(&iter->mutex);
1452 * pts_GroupMemberRemove - remove a member from a group.
1456 * IN cellHandle - a previously opened cellHandle that corresponds
1457 * to the cell where the group exists.
1459 * IN userName - the user to remove.
1461 * IN groupName - the group to modify
1465 * No locks are held by this function
1469 * Returns != 0 upon successful completion.
1474 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1475 const char *groupName, afs_status_p st)
1478 afs_status_t tst = 0;
1479 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1483 * Validate arguments
1486 if (!IsValidCellHandle(c_handle, &tst)) {
1487 goto fail_pts_GroupMemberRemove;
1490 if ((userName == NULL) || (*userName == 0)) {
1491 tst = ADMPTSUSERNAMENULL;
1492 goto fail_pts_GroupMemberRemove;
1495 if ((groupName == NULL) || (*groupName == 0)) {
1496 tst = ADMPTSGROUPNAMENULL;
1497 goto fail_pts_GroupMemberRemove;
1500 if (!TranslateTwoNames
1501 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1502 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1503 goto fail_pts_GroupMemberRemove;
1511 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1515 goto fail_pts_GroupMemberRemove;
1519 fail_pts_GroupMemberRemove:
1521 if (ids.idlist_val != 0) {
1522 free(ids.idlist_val);
1532 * pts_GroupRename - change the name of a group
1536 * IN cellHandle - a previously opened cellHandle that corresponds
1537 * to the cell where the group exists.
1539 * IN oldName - the current group name
1541 * IN newName - the new group name
1545 * No locks are held by this function
1549 * Returns != 0 upon successful completion.
1554 pts_GroupRename(const void *cellHandle, const char *oldName,
1555 const char *newName, afs_status_p st)
1558 afs_status_t tst = 0;
1559 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1560 afs_int32 groupId = 0;
1563 * Validate arguments
1566 if (!IsValidCellHandle(c_handle, &tst)) {
1567 goto fail_pts_GroupRename;
1570 if ((newName == NULL) || (*newName == 0)) {
1571 tst = ADMPTSNEWNAMENULL;
1572 goto fail_pts_GroupRename;
1575 if ((oldName == NULL) || (*oldName == 0)) {
1576 tst = ADMPTSOLDNAMENULL;
1577 goto fail_pts_GroupRename;
1581 * Translate the group name into an id.
1584 if (!TranslateOneName
1585 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1586 goto fail_pts_GroupRename;
1593 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1596 goto fail_pts_GroupRename;
1600 fail_pts_GroupRename:
1609 * SetGroupAccess - translate our Access notation to pts flags.
1613 * IN rights - the permissions.
1615 * OUT flags - a pointer to an afs_int32 structure that
1616 * contains the flags to pass to pts.
1620 * No locks are held by this function
1624 * Returns != 0 upon successful completion.
1629 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1633 afs_status_t tst = 0;
1637 if (rights->listDelete == PTS_GROUP_ACCESS) {
1639 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1640 tst = ADMPTSINVALIDGROUPDELETEPERM;
1641 goto fail_SetGroupAccess;
1644 if (rights->listAdd == PTS_GROUP_ACCESS) {
1646 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1650 if (rights->listMembership == PTS_GROUP_ACCESS) {
1652 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1656 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1658 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1659 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1660 goto fail_SetGroupAccess;
1663 if (rights->listStatus == PTS_GROUP_ACCESS) {
1665 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1670 fail_SetGroupAccess:
1679 * pts_GroupModify - change the contents of a group entry.
1683 * IN cellHandle - a previously opened cellHandle that corresponds
1684 * to the cell where the group exists.
1686 * IN groupName - the group to change
1688 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1689 * contains the new information for the group.
1693 * No locks are held by this function
1697 * Returns != 0 upon successful completion.
1702 pts_GroupModify(const void *cellHandle, const char *groupName,
1703 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1706 afs_status_t tst = 0;
1707 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1708 afs_int32 groupId = 0;
1709 afs_int32 flags = 0;
1712 * Validate arguments
1715 if (!IsValidCellHandle(c_handle, &tst)) {
1716 goto fail_pts_GroupModify;
1719 if ((groupName == NULL) || (*groupName == 0)) {
1720 tst = ADMPTSGROUPNAMENULL;
1721 goto fail_pts_GroupModify;
1725 if (newEntryP == NULL) {
1726 tst = ADMPTSNEWENTRYPNULL;
1727 goto fail_pts_GroupModify;
1731 * Translate the group name into an id.
1734 if (!TranslateOneName
1735 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1736 goto fail_pts_GroupModify;
1740 * Set the flags argument
1743 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1744 goto fail_pts_GroupModify;
1752 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1756 goto fail_pts_GroupModify;
1760 fail_pts_GroupModify:
1769 * pts_UserCreate - create a new user.
1773 * IN cellHandle - a previously opened cellHandle that corresponds
1774 * to the cell where the group exists.
1776 * IN newUser - the name of the new user.
1778 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1779 * id assigned by pts.
1783 * No locks are held by this function
1787 * Returns != 0 upon successful completion.
1792 pts_UserCreate(const void *cellHandle, const char *userName, int *newUserId,
1796 afs_status_t tst = 0;
1797 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1798 afs_int32 userId = 0;
1801 * Validate arguments
1804 if (!IsValidCellHandle(c_handle, &tst)) {
1805 goto fail_pts_UserCreate;
1808 if ((userName == NULL) || (*userName == 0)) {
1809 tst = ADMPTSUSERNAMENULL;
1810 goto fail_pts_UserCreate;
1813 if (newUserId == NULL) {
1814 tst = ADMPTSNEWUSERIDNULL;
1815 goto fail_pts_UserCreate;
1819 * We make a different rpc based upon the input to this function
1822 if (*newUserId != 0) {
1824 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1828 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1833 goto fail_pts_UserCreate;
1837 fail_pts_UserCreate:
1846 * pts_UserDelete - delete a user.
1850 * IN cellHandle - a previously opened cellHandle that corresponds
1851 * to the cell where the group exists.
1853 * IN user - the name of the user to delete.
1857 * No locks are held by this function
1861 * Returns != 0 upon successful completion.
1866 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1868 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1869 ADMPTSUSERNAMETOOLONG, st);
1874 * GetUserAccess - a small convenience function for setting
1879 * IN access - a pointer to a pts_userAccess_t to be set with the
1880 * correct permission.
1882 * IN flag - the current permission flag used to derive the permission.
1886 * No locks are obtained or released by this function
1890 * Since this function cannot fail, it returns void.
1895 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1898 *access = PTS_USER_OWNER_ACCESS;
1900 *access = PTS_USER_ANYUSER_ACCESS;
1905 * IsAdministrator - determine if a user is an administrator.
1909 * IN cellHandle - a previously opened cellHandle that corresponds
1910 * to the cell where the group exists.
1912 * IN userEntry - the user data for the user in question.
1914 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1918 * No locks are held by this function
1922 * Returns != 0 upon successful completion.
1927 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1928 int *admin, afs_status_p st)
1931 afs_status_t tst = 0;
1932 afs_int32 adminId = 0;
1933 afs_int32 isAdmin = 0;
1937 if (userId == SYSADMINID) {
1940 if (!TranslateOneName
1941 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1943 goto fail_IsAdministrator;
1946 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1949 goto fail_IsAdministrator;
1957 fail_IsAdministrator:
1966 * pts_UserGet - retrieve information about a particular user.
1970 * IN cellHandle - a previously opened cellHandle that corresponds
1971 * to the cell where the group exists.
1973 * IN userName - the name of the user to retrieve.
1975 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1980 * No locks are held by this function
1984 * Returns != 0 upon successful completion.
1989 pts_UserGet(const void *cellHandle, const char *userName,
1990 pts_UserEntry_p userP, afs_status_p st)
1993 afs_status_t tst = 0;
1994 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1995 struct prcheckentry userEntry;
1996 afs_int32 userId = 0;
2000 afs_int32 ptsids[2];
2006 * Validate arguments
2009 if (!IsValidCellHandle(c_handle, &tst)) {
2010 goto fail_pts_UserGet;
2013 if ((userName == NULL) || (*userName == 0)) {
2014 tst = ADMPTSUSERNAMENULL;
2015 goto fail_pts_UserGet;
2018 if (userP == NULL) {
2019 tst = ADMPTSUSERPNULL;
2020 goto fail_pts_UserGet;
2024 * Translate the group name into an id.
2027 if (!TranslateOneName
2028 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2029 goto fail_pts_UserGet;
2033 * Retrieve information about the group
2036 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2039 goto fail_pts_UserGet;
2042 userP->groupMembershipCount = userEntry.count;
2043 userP->groupCreationQuota = userEntry.ngroups;
2045 * The administrator id, or any member of "system:administrators"
2046 * has unlimited group creation quota. Denote this by setting
2050 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2051 goto fail_pts_UserGet;
2055 userP->groupCreationQuota = -1;
2058 userP->nameUid = userEntry.id;
2059 userP->ownerUid = userEntry.owner;
2060 userP->creatorUid = userEntry.creator;
2061 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2062 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2065 * The permission bits are described in the GroupGet function above.
2066 * The user entry only uses 3 of the 5 permissions, so we shift
2067 * past the unused entries.
2070 flags = userEntry.flags;
2074 GetUserAccess(&userP->listMembership, twobit);
2079 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2081 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2087 GetUserAccess(&userP->listStatus, twobit);
2090 * Make another rpc and translate the owner and creator ids into
2091 * character strings.
2095 ids.idlist_val = ptsids;
2096 ptsids[0] = userEntry.owner;
2097 ptsids[1] = userEntry.creator;
2098 names.namelist_len = 0;
2099 names.namelist_val = 0;
2102 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2103 goto fail_pts_UserGet;
2106 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2107 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2108 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2109 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2110 free(names.namelist_val);
2122 * pts_UserRename - rename a user.
2126 * IN cellHandle - a previously opened cellHandle that corresponds
2127 * to the cell where the group exists.
2129 * IN oldName - the name of the user to rename.
2131 * IN newName - the new user name.
2135 * No locks are held by this function
2139 * Returns != 0 upon successful completion.
2144 pts_UserRename(const void *cellHandle, const char *oldName,
2145 const char *newName, afs_status_p st)
2148 afs_status_t tst = 0;
2149 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2150 afs_int32 userId = 0;
2153 * Validate arguments
2156 if (!IsValidCellHandle(c_handle, &tst)) {
2157 goto fail_pts_UserRename;
2160 if ((oldName == NULL) || (*oldName == 0)) {
2161 tst = ADMPTSOLDNAMENULL;
2162 goto fail_pts_UserRename;
2165 if ((newName == NULL) || (*newName == 0)) {
2166 tst = ADMPTSNEWNAMENULL;
2167 goto fail_pts_UserRename;
2171 * Translate the user name into an id.
2174 if (!TranslateOneName
2175 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2176 goto fail_pts_UserRename;
2183 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2186 goto fail_pts_UserRename;
2190 fail_pts_UserRename:
2199 * SetUserAccess - translate our Access notation to pts flags.
2203 * IN userP - the user structure that contains the new permissions.
2205 * OUT flags - a pointer to an afs_int32 structure that
2206 * contains the flags to pass to pts.
2210 * No locks are held by this function
2214 * Returns != 0 upon successful completion.
2219 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2223 afs_status_t tst = 0;
2227 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2231 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2235 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2248 * pts_UserModify - update a user entry.
2252 * IN cellHandle - a previously opened cellHandle that corresponds
2253 * to the cell where the group exists.
2255 * IN userName - the name of the user to update.
2257 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2258 * new information for user.
2262 * No locks are held by this function
2266 * Returns != 0 upon successful completion.
2271 pts_UserModify(const void *cellHandle, const char *userName,
2272 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2275 afs_status_t tst = 0;
2276 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2277 afs_int32 userId = 0;
2278 afs_int32 newQuota = 0;
2280 afs_int32 flags = 0;
2283 * Validate arguments
2286 if (!IsValidCellHandle(c_handle, &tst)) {
2287 goto fail_pts_UserModify;
2290 if ((userName == NULL) || (*userName == 0)) {
2291 tst = ADMPTSUSERNAMENULL;
2292 goto fail_pts_UserModify;
2295 if (newEntryP == NULL) {
2296 tst = ADMPTSNEWENTRYPNULL;
2297 goto fail_pts_UserModify;
2301 * Translate the user name into an id.
2304 if (!TranslateOneName
2305 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2306 goto fail_pts_UserModify;
2310 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2311 mask |= PR_SF_NGROUPS;
2312 newQuota = newEntryP->groupCreationQuota;
2315 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2316 mask |= PR_SF_ALLBITS;
2317 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2318 goto fail_pts_UserModify;
2327 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2331 goto fail_pts_UserModify;
2335 fail_pts_UserModify:
2344 * pts_UserMaxGet - get the maximum in use user id.
2348 * IN cellHandle - a previously opened cellHandle that corresponds
2349 * to the cell where the group exists.
2351 * OUT maxUserId - upon successful completion contains the max in use id.
2355 * No locks are held by this function
2359 * Returns != 0 upon successful completion.
2364 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2367 afs_status_t tst = 0;
2368 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2369 afs_int32 maxGroupId = 0;
2372 * Validate arguments
2375 if (!IsValidCellHandle(c_handle, &tst)) {
2376 goto fail_pts_UserMaxGet;
2379 if (maxUserId == NULL) {
2380 tst = ADMPTSMAXUSERIDNULL;
2381 goto fail_pts_UserMaxGet;
2384 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2387 goto fail_pts_UserMaxGet;
2391 fail_pts_UserMaxGet:
2400 * pts_UserMaxSet - set the maximum user id.
2404 * IN cellHandle - a previously opened cellHandle that corresponds
2405 * to the cell where the group exists.
2407 * IN maxUserId - the new max user id.
2411 * No locks are held by this function
2415 * Returns != 0 upon successful completion.
2420 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2423 afs_status_t tst = 0;
2424 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2427 * Validate arguments
2430 if (!IsValidCellHandle(c_handle, &tst)) {
2431 goto fail_pts_UserMaxSet;
2434 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2437 goto fail_pts_UserMaxSet;
2441 fail_pts_UserMaxSet:
2450 * pts_UserMemberListBegin - begin iterating over the list of groups
2451 * a particular user belongs to.
2455 * IN cellHandle - a previously opened cellHandle that corresponds
2456 * to the cell where the group exists.
2458 * IN groupName - the group whose members will be returned.
2460 * OUT iterationIdP - upon successful completion contains a iterator that
2461 * can be passed to pts_GroupMemberListNext.
2465 * No locks are obtained or released by this function
2469 * Returns != 0 upon successful completion.
2474 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2475 void **iterationIdP, afs_status_p st)
2477 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2478 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2483 * pts_UserMemberListNext - get the next group a user belongs to
2487 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2489 * OUT userName - upon successful completion contains the next group a user
2494 * The iterator mutex is held during the retrieval of the next member.
2498 * Returns != 0 upon successful completion.
2503 pts_UserMemberListNext(const void *iterationId, char *userName,
2506 return pts_GroupMemberListNext(iterationId, userName, st);
2510 * pts_UserMemberListDone - finish using a user list iterator
2514 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2518 * The iterator is locked and then destroyed
2522 * Returns != 0 upon successful completion.
2526 * It is the user's responsibility to make sure pts_UserMemberListDone
2527 * is called only once for each iterator.
2531 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2533 return pts_GroupMemberListDone(iterationId, st);
2536 typedef struct owned_group_list {
2537 namelist owned_names; /* the list of character names owned by this id */
2538 prlist owned_ids; /* the list of pts ids owned by this id */
2539 afs_int32 index; /* the index into owned_names for the next group */
2540 afs_int32 owner; /* the pts id of the owner */
2541 afs_int32 more; /* the last parameter to PR_ListOwned */
2542 int finished_retrieving; /* set when we've processed the last owned_names */
2543 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2544 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2545 } owned_group_list_t, *owned_group_list_p;
2548 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2551 afs_status_t tst = 0;
2552 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2554 if (list->owned_names.namelist_val != NULL) {
2555 free(list->owned_names.namelist_val);
2558 if (list->owned_ids.prlist_val != NULL) {
2559 free(list->owned_ids.prlist_val);
2570 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2571 int *last_item_contains_data, afs_status_p st)
2574 afs_status_t tst = 0;
2575 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2578 * We really don't make an rpc for every entry we return here
2579 * since the pts interface allows several members to be returned
2580 * with one rpc, but we fake it to make the iterator happy.
2584 * Check to see if we are done retrieving data
2587 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2589 *last_item_contains_data = 0;
2590 goto fail_GetOwnedGroupRPC;
2594 * Check to see if we really need to make an rpc
2597 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2599 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2600 &list->owned_ids, &list->more);
2602 goto fail_GetOwnedGroupRPC;
2605 if (!TranslatePTSIds
2606 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2608 goto fail_GetOwnedGroupRPC;
2612 if (list->owned_names.namelist_val == NULL) {
2614 *last_item_contains_data = 0;
2615 goto fail_GetOwnedGroupRPC;
2620 * We can retrieve the next group from data we already received
2623 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2627 * Check to see if there is more data to be retrieved
2628 * We need to free up the previously retrieved data here
2629 * and then check to see if the last rpc indicated that there
2630 * were more items to retrieve.
2633 if (list->index >= list->owned_names.namelist_len) {
2634 list->owned_names.namelist_len = 0;
2635 free(list->owned_names.namelist_val);
2636 list->owned_names.namelist_val = 0;
2638 list->owned_ids.prlist_len = 0;
2639 free(list->owned_ids.prlist_val);
2640 list->owned_ids.prlist_val = 0;
2643 list->finished_retrieving = 1;
2648 fail_GetOwnedGroupRPC:
2657 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2661 afs_status_t tst = 0;
2662 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2664 strcpy((char *)dest, list->group[slot]);
2675 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2676 * a particular user owns.
2680 * IN cellHandle - a previously opened cellHandle that corresponds
2681 * to the cell where the group exists.
2683 * IN ownerName - the owner of the groups of interest.
2685 * OUT iterationIdP - upon successful completion contains a iterator that
2686 * can be passed to pts_OwnedGroupListNext.
2690 * No locks are held by this function
2694 * Returns != 0 upon successful completion.
2699 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2700 void **iterationIdP, afs_status_p st)
2703 afs_status_t tst = 0;
2704 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2705 afs_admin_iterator_p iter =
2706 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2707 owned_group_list_p list =
2708 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2711 * Validate arguments
2714 if (!IsValidCellHandle(c_handle, &tst)) {
2715 goto fail_pts_OwnedGroupListBegin;
2718 if ((userName == NULL) || (*userName == 0)) {
2719 tst = ADMPTSUSERNAMENULL;
2720 goto fail_pts_OwnedGroupListBegin;
2723 if (iterationIdP == NULL) {
2724 tst = ADMITERATORNULL;
2725 goto fail_pts_OwnedGroupListBegin;
2728 if ((iter == NULL) || (list == NULL)) {
2730 goto fail_pts_OwnedGroupListBegin;
2734 * Initialize the iterator specific data
2738 list->finished_retrieving = 0;
2739 list->c_handle = c_handle;
2740 list->owned_names.namelist_len = 0;
2741 list->owned_names.namelist_val = 0;
2742 list->owned_ids.prlist_len = 0;
2743 list->owned_ids.prlist_val = 0;
2746 * Translate the user name into an id.
2749 if (!TranslateOneName
2750 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2751 goto fail_pts_OwnedGroupListBegin;
2755 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2756 DeleteOwnedGroupSpecificData, &tst)) {
2757 *iterationIdP = (void *)iter;
2761 fail_pts_OwnedGroupListBegin:
2779 * pts_OwnedGroupListNext - get the next group a user owns.
2783 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2785 * OUT groupName - upon successful completion contains the next group a user
2790 * The iterator mutex is held during the retrieval of the next member.
2794 * Returns != 0 upon successful completion.
2799 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2803 afs_status_t tst = 0;
2804 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2807 * Validate arguments
2810 if (iterationId == NULL) {
2811 tst = ADMITERATORNULL;
2812 goto fail_pts_OwnedGroupListNext;
2815 if (groupName == NULL) {
2816 tst = ADMPTSGROUPNAMENULL;
2817 goto fail_pts_OwnedGroupListNext;
2820 rc = IteratorNext(iter, (void *)groupName, &tst);
2822 fail_pts_OwnedGroupListNext:
2831 * pts_OwnedGroupListDone - finish using a group list iterator
2835 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2839 * The iterator is locked and then destroyed
2843 * Returns != 0 upon successful completion.
2847 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2848 * is called only once for each iterator.
2852 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2855 afs_status_t tst = 0;
2856 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2859 * Validate arguments
2862 if (iterationId == NULL) {
2863 tst = ADMITERATORNULL;
2864 goto fail_pts_OwnedGroupListDone;
2867 rc = IteratorDone(iter, &tst);
2869 fail_pts_OwnedGroupListDone:
2877 typedef struct pts_list {
2878 prlistentries *names; /* the current list of pts names in this cell */
2879 prlistentries *currName; /* the current pts entry */
2880 afs_int32 index; /* the index into names for the next pts entry */
2881 afs_int32 nextstartindex; /* the next start index for the RPC */
2882 afs_int32 nentries; /* the number of entries in names */
2883 afs_int32 flag; /* the type of the list */
2884 int finished_retrieving; /* set when we've processed the last owned_names */
2885 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2886 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2887 } pts_list_t, *pts_list_p;
2890 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2893 afs_status_t tst = 0;
2894 pts_list_p list = (pts_list_p) rpc_specific;
2909 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2910 int *last_item_contains_data, afs_status_p st)
2913 afs_status_t tst = 0;
2914 pts_list_p list = (pts_list_p) rpc_specific;
2917 * We really don't make an rpc for every entry we return here
2918 * since the pts interface allows several members to be returned
2919 * with one rpc, but we fake it to make the iterator happy.
2923 * Check to see if we are done retrieving data
2926 if (list->finished_retrieving) {
2928 *last_item_contains_data = 0;
2929 goto fail_GetPTSRPC;
2933 * Check to see if we really need to make an rpc
2936 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2937 afs_int32 start = list->nextstartindex;
2938 prentries bulkentries;
2939 list->nextstartindex = -1;
2940 bulkentries.prentries_val = 0;
2941 bulkentries.prentries_len = 0;
2944 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2945 start, &bulkentries, &(list->nextstartindex));
2948 goto fail_GetPTSRPC;
2951 list->nentries = bulkentries.prentries_len;
2952 list->names = bulkentries.prentries_val;
2955 list->currName = list->names;
2960 * We can retrieve the next entry from data we already received
2963 strcpy(list->entries[slot], list->currName->name);
2969 * Check to see if there is more data to be retrieved
2970 * We need to free up the previously retrieved data here
2971 * and then check to see if the last rpc indicated that there
2972 * were more items to retrieve.
2975 if (list->index >= list->nentries) {
2981 if (list->nextstartindex == -1) {
2982 list->finished_retrieving = 1;
2997 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3000 afs_status_t tst = 0;
3001 pts_list_p list = (pts_list_p) rpc_specific;
3003 strcpy((char *)dest, list->entries[slot]);
3014 * pts_UserListBegin - begin iterating over the list of users
3015 * in a particular cell
3019 * IN cellHandle - a previously opened cellHandle that corresponds
3020 * to the cell where the users exist.
3022 * OUT iterationIdP - upon successful completion contains a iterator that
3023 * can be passed to pts_UserListNext.
3027 * No locks are held by this function
3031 * Returns != 0 upon successful completion.
3036 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3040 afs_status_t tst = 0;
3041 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3042 afs_admin_iterator_p iter =
3043 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3044 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3047 * Validate arguments
3050 if (!IsValidCellHandle(c_handle, &tst)) {
3051 goto fail_pts_UserListBegin;
3054 if (iterationIdP == NULL) {
3055 tst = ADMITERATORNULL;
3056 goto fail_pts_UserListBegin;
3059 if ((iter == NULL) || (list == NULL)) {
3061 goto fail_pts_UserListBegin;
3065 * Initialize the iterator specific data
3069 list->finished_retrieving = 0;
3070 list->c_handle = c_handle;
3072 list->nextstartindex = 0;
3074 list->flag = PRUSERS;
3077 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3078 DeletePTSSpecificData, &tst)) {
3079 *iterationIdP = (void *)iter;
3083 fail_pts_UserListBegin:
3101 * pts_UserListNext - get the next user in the cell.
3105 * IN iterationId - an iterator previously returned by pts_UserListBegin
3107 * OUT groupName - upon successful completion contains the next user
3111 * The iterator mutex is held during the retrieval of the next member.
3115 * Returns != 0 upon successful completion.
3120 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3123 afs_status_t tst = 0;
3124 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3127 * Validate arguments
3130 if (iterationId == NULL) {
3131 tst = ADMITERATORNULL;
3132 goto fail_pts_UserListNext;
3135 if (userName == NULL) {
3136 tst = ADMPTSUSERNAMENULL;
3137 goto fail_pts_UserListNext;
3140 rc = IteratorNext(iter, (void *)userName, &tst);
3142 fail_pts_UserListNext:
3151 * pts_UserListDone - finish using a user list iterator
3155 * IN iterationId - an iterator previously returned by pts_UserListBegin
3159 * The iterator is locked and then destroyed
3163 * Returns != 0 upon successful completion.
3167 * It is the user's responsibility to make sure pts_UserListDone
3168 * is called only once for each iterator.
3172 pts_UserListDone(const void *iterationId, afs_status_p st)
3175 afs_status_t tst = 0;
3176 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3179 * Validate arguments
3182 if (iterationId == NULL) {
3183 tst = ADMITERATORNULL;
3184 goto fail_pts_UserListDone;
3187 rc = IteratorDone(iter, &tst);
3189 fail_pts_UserListDone:
3198 * pts_GroupListBegin - begin iterating over the list of groups
3199 * in a particular cell.
3203 * IN cellHandle - a previously opened cellHandle that corresponds
3204 * to the cell where the groups exist.
3206 * OUT iterationIdP - upon successful completion contains a iterator that
3207 * can be passed to pts_GroupListNext.
3211 * No locks are held by this function
3215 * Returns != 0 upon successful completion.
3220 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3224 afs_status_t tst = 0;
3225 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3226 afs_admin_iterator_p iter =
3227 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3228 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3231 * Validate arguments
3234 if (!IsValidCellHandle(c_handle, &tst)) {
3235 goto fail_pts_GroupListBegin;
3238 if (iterationIdP == NULL) {
3239 tst = ADMITERATORNULL;
3240 goto fail_pts_GroupListBegin;
3243 if ((iter == NULL) || (list == NULL)) {
3245 goto fail_pts_GroupListBegin;
3249 * Initialize the iterator specific data
3253 list->finished_retrieving = 0;
3254 list->c_handle = c_handle;
3256 list->nextstartindex = 0;
3258 list->flag = PRGROUPS;
3261 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3262 DeletePTSSpecificData, &tst)) {
3263 *iterationIdP = (void *)iter;
3267 fail_pts_GroupListBegin:
3285 * pts_UserListNext - get the next group in a cell.
3289 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3291 * OUT groupName - upon successful completion contains the next group
3295 * The iterator mutex is held during the retrieval of the next member.
3299 * Returns != 0 upon successful completion.
3304 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3307 afs_status_t tst = 0;
3308 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3311 * Validate arguments
3314 if (iterationId == NULL) {
3315 tst = ADMITERATORNULL;
3316 goto fail_pts_GroupListNext;
3319 if (groupName == NULL) {
3320 tst = ADMPTSGROUPNAMENULL;
3321 goto fail_pts_GroupListNext;
3324 rc = IteratorNext(iter, (void *)groupName, &tst);
3326 fail_pts_GroupListNext:
3335 * pts_GroupListDone - finish using a group list iterator
3339 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3343 * The iterator is locked and then destroyed
3347 * Returns != 0 upon successful completion.
3351 * It is the user's responsibility to make sure pts_GroupListDone
3352 * is called only once for each iterator.
3356 pts_GroupListDone(const void *iterationId, afs_status_p st)
3359 afs_status_t tst = 0;
3360 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3363 * Validate arguments
3366 if (iterationId == NULL) {
3367 tst = ADMITERATORNULL;
3368 goto fail_pts_GroupListDone;
3371 rc = IteratorDone(iter, &tst);
3373 fail_pts_GroupListDone: