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;
1800 * Validate arguments
1803 if (!IsValidCellHandle(c_handle, &tst)) {
1804 goto fail_pts_UserCreate;
1807 if ((userName == NULL) || (*userName == 0)) {
1808 tst = ADMPTSUSERNAMENULL;
1809 goto fail_pts_UserCreate;
1812 if (newUserId == NULL) {
1813 tst = ADMPTSNEWUSERIDNULL;
1814 goto fail_pts_UserCreate;
1818 * We make a different rpc based upon the input to this function
1821 if (*newUserId != 0) {
1823 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1827 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1832 goto fail_pts_UserCreate;
1836 fail_pts_UserCreate:
1845 * pts_UserDelete - delete a user.
1849 * IN cellHandle - a previously opened cellHandle that corresponds
1850 * to the cell where the group exists.
1852 * IN user - the name of the user to delete.
1856 * No locks are held by this function
1860 * Returns != 0 upon successful completion.
1865 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1867 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1868 ADMPTSUSERNAMETOOLONG, st);
1873 * GetUserAccess - a small convenience function for setting
1878 * IN access - a pointer to a pts_userAccess_t to be set with the
1879 * correct permission.
1881 * IN flag - the current permission flag used to derive the permission.
1885 * No locks are obtained or released by this function
1889 * Since this function cannot fail, it returns void.
1894 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1897 *access = PTS_USER_OWNER_ACCESS;
1899 *access = PTS_USER_ANYUSER_ACCESS;
1904 * IsAdministrator - determine if a user is an administrator.
1908 * IN cellHandle - a previously opened cellHandle that corresponds
1909 * to the cell where the group exists.
1911 * IN userEntry - the user data for the user in question.
1913 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1917 * No locks are held by this function
1921 * Returns != 0 upon successful completion.
1926 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1927 int *admin, afs_status_p st)
1930 afs_status_t tst = 0;
1931 afs_int32 adminId = 0;
1932 afs_int32 isAdmin = 0;
1936 if (userId == SYSADMINID) {
1939 if (!TranslateOneName
1940 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1942 goto fail_IsAdministrator;
1945 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1948 goto fail_IsAdministrator;
1956 fail_IsAdministrator:
1965 * pts_UserGet - retrieve information about a particular user.
1969 * IN cellHandle - a previously opened cellHandle that corresponds
1970 * to the cell where the group exists.
1972 * IN userName - the name of the user to retrieve.
1974 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1979 * No locks are held by this function
1983 * Returns != 0 upon successful completion.
1988 pts_UserGet(const void *cellHandle, const char *userName,
1989 pts_UserEntry_p userP, afs_status_p st)
1992 afs_status_t tst = 0;
1993 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1994 struct prcheckentry userEntry;
1995 afs_int32 userId = 0;
1999 afs_int32 ptsids[2];
2005 * Validate arguments
2008 if (!IsValidCellHandle(c_handle, &tst)) {
2009 goto fail_pts_UserGet;
2012 if ((userName == NULL) || (*userName == 0)) {
2013 tst = ADMPTSUSERNAMENULL;
2014 goto fail_pts_UserGet;
2017 if (userP == NULL) {
2018 tst = ADMPTSUSERPNULL;
2019 goto fail_pts_UserGet;
2023 * Translate the group name into an id.
2026 if (!TranslateOneName
2027 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2028 goto fail_pts_UserGet;
2032 * Retrieve information about the group
2035 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2038 goto fail_pts_UserGet;
2041 userP->groupMembershipCount = userEntry.count;
2042 userP->groupCreationQuota = userEntry.ngroups;
2044 * The administrator id, or any member of "system:administrators"
2045 * has unlimited group creation quota. Denote this by setting
2049 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2050 goto fail_pts_UserGet;
2054 userP->groupCreationQuota = -1;
2057 userP->nameUid = userEntry.id;
2058 userP->ownerUid = userEntry.owner;
2059 userP->creatorUid = userEntry.creator;
2060 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2061 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2064 * The permission bits are described in the GroupGet function above.
2065 * The user entry only uses 3 of the 5 permissions, so we shift
2066 * past the unused entries.
2069 flags = userEntry.flags;
2073 GetUserAccess(&userP->listMembership, twobit);
2078 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2080 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2086 GetUserAccess(&userP->listStatus, twobit);
2089 * Make another rpc and translate the owner and creator ids into
2090 * character strings.
2094 ids.idlist_val = ptsids;
2095 ptsids[0] = userEntry.owner;
2096 ptsids[1] = userEntry.creator;
2097 names.namelist_len = 0;
2098 names.namelist_val = 0;
2101 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2102 goto fail_pts_UserGet;
2105 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2106 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2107 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2108 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2109 free(names.namelist_val);
2121 * pts_UserRename - rename a user.
2125 * IN cellHandle - a previously opened cellHandle that corresponds
2126 * to the cell where the group exists.
2128 * IN oldName - the name of the user to rename.
2130 * IN newName - the new user name.
2134 * No locks are held by this function
2138 * Returns != 0 upon successful completion.
2143 pts_UserRename(const void *cellHandle, const char *oldName,
2144 const char *newName, afs_status_p st)
2147 afs_status_t tst = 0;
2148 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2149 afs_int32 userId = 0;
2152 * Validate arguments
2155 if (!IsValidCellHandle(c_handle, &tst)) {
2156 goto fail_pts_UserRename;
2159 if ((oldName == NULL) || (*oldName == 0)) {
2160 tst = ADMPTSOLDNAMENULL;
2161 goto fail_pts_UserRename;
2164 if ((newName == NULL) || (*newName == 0)) {
2165 tst = ADMPTSNEWNAMENULL;
2166 goto fail_pts_UserRename;
2170 * Translate the user name into an id.
2173 if (!TranslateOneName
2174 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2175 goto fail_pts_UserRename;
2182 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2185 goto fail_pts_UserRename;
2189 fail_pts_UserRename:
2198 * SetUserAccess - translate our Access notation to pts flags.
2202 * IN userP - the user structure that contains the new permissions.
2204 * OUT flags - a pointer to an afs_int32 structure that
2205 * contains the flags to pass to pts.
2209 * No locks are held by this function
2213 * Returns != 0 upon successful completion.
2218 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2222 afs_status_t tst = 0;
2226 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2230 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2234 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2247 * pts_UserModify - update a user entry.
2251 * IN cellHandle - a previously opened cellHandle that corresponds
2252 * to the cell where the group exists.
2254 * IN userName - the name of the user to update.
2256 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2257 * new information for user.
2261 * No locks are held by this function
2265 * Returns != 0 upon successful completion.
2270 pts_UserModify(const void *cellHandle, const char *userName,
2271 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2274 afs_status_t tst = 0;
2275 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2276 afs_int32 userId = 0;
2277 afs_int32 newQuota = 0;
2279 afs_int32 flags = 0;
2282 * Validate arguments
2285 if (!IsValidCellHandle(c_handle, &tst)) {
2286 goto fail_pts_UserModify;
2289 if ((userName == NULL) || (*userName == 0)) {
2290 tst = ADMPTSUSERNAMENULL;
2291 goto fail_pts_UserModify;
2294 if (newEntryP == NULL) {
2295 tst = ADMPTSNEWENTRYPNULL;
2296 goto fail_pts_UserModify;
2300 * Translate the user name into an id.
2303 if (!TranslateOneName
2304 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2305 goto fail_pts_UserModify;
2309 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2310 mask |= PR_SF_NGROUPS;
2311 newQuota = newEntryP->groupCreationQuota;
2314 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2315 mask |= PR_SF_ALLBITS;
2316 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2317 goto fail_pts_UserModify;
2326 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2330 goto fail_pts_UserModify;
2334 fail_pts_UserModify:
2343 * pts_UserMaxGet - get the maximum in use user id.
2347 * IN cellHandle - a previously opened cellHandle that corresponds
2348 * to the cell where the group exists.
2350 * OUT maxUserId - upon successful completion contains the max in use id.
2354 * No locks are held by this function
2358 * Returns != 0 upon successful completion.
2363 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2366 afs_status_t tst = 0;
2367 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2368 afs_int32 maxGroupId = 0;
2371 * Validate arguments
2374 if (!IsValidCellHandle(c_handle, &tst)) {
2375 goto fail_pts_UserMaxGet;
2378 if (maxUserId == NULL) {
2379 tst = ADMPTSMAXUSERIDNULL;
2380 goto fail_pts_UserMaxGet;
2383 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2386 goto fail_pts_UserMaxGet;
2390 fail_pts_UserMaxGet:
2399 * pts_UserMaxSet - set the maximum user id.
2403 * IN cellHandle - a previously opened cellHandle that corresponds
2404 * to the cell where the group exists.
2406 * IN maxUserId - the new max user id.
2410 * No locks are held by this function
2414 * Returns != 0 upon successful completion.
2419 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2422 afs_status_t tst = 0;
2423 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2426 * Validate arguments
2429 if (!IsValidCellHandle(c_handle, &tst)) {
2430 goto fail_pts_UserMaxSet;
2433 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2436 goto fail_pts_UserMaxSet;
2440 fail_pts_UserMaxSet:
2449 * pts_UserMemberListBegin - begin iterating over the list of groups
2450 * a particular user belongs to.
2454 * IN cellHandle - a previously opened cellHandle that corresponds
2455 * to the cell where the group exists.
2457 * IN groupName - the group whose members will be returned.
2459 * OUT iterationIdP - upon successful completion contains a iterator that
2460 * can be passed to pts_GroupMemberListNext.
2464 * No locks are obtained or released by this function
2468 * Returns != 0 upon successful completion.
2473 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2474 void **iterationIdP, afs_status_p st)
2476 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2477 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2482 * pts_UserMemberListNext - get the next group a user belongs to
2486 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2488 * OUT userName - upon successful completion contains the next group a user
2493 * The iterator mutex is held during the retrieval of the next member.
2497 * Returns != 0 upon successful completion.
2502 pts_UserMemberListNext(const void *iterationId, char *userName,
2505 return pts_GroupMemberListNext(iterationId, userName, st);
2509 * pts_UserMemberListDone - finish using a user list iterator
2513 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2517 * The iterator is locked and then destroyed
2521 * Returns != 0 upon successful completion.
2525 * It is the user's responsibility to make sure pts_UserMemberListDone
2526 * is called only once for each iterator.
2530 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2532 return pts_GroupMemberListDone(iterationId, st);
2535 typedef struct owned_group_list {
2536 namelist owned_names; /* the list of character names owned by this id */
2537 prlist owned_ids; /* the list of pts ids owned by this id */
2538 afs_int32 index; /* the index into owned_names for the next group */
2539 afs_int32 owner; /* the pts id of the owner */
2540 afs_int32 more; /* the last parameter to PR_ListOwned */
2541 int finished_retrieving; /* set when we've processed the last owned_names */
2542 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2543 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2544 } owned_group_list_t, *owned_group_list_p;
2547 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2550 afs_status_t tst = 0;
2551 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2553 if (list->owned_names.namelist_val != NULL) {
2554 free(list->owned_names.namelist_val);
2557 if (list->owned_ids.prlist_val != NULL) {
2558 free(list->owned_ids.prlist_val);
2569 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2570 int *last_item_contains_data, afs_status_p st)
2573 afs_status_t tst = 0;
2574 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2577 * We really don't make an rpc for every entry we return here
2578 * since the pts interface allows several members to be returned
2579 * with one rpc, but we fake it to make the iterator happy.
2583 * Check to see if we are done retrieving data
2586 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2588 *last_item_contains_data = 0;
2589 goto fail_GetOwnedGroupRPC;
2593 * Check to see if we really need to make an rpc
2596 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2598 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2599 &list->owned_ids, &list->more);
2601 goto fail_GetOwnedGroupRPC;
2604 if (!TranslatePTSIds
2605 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2607 goto fail_GetOwnedGroupRPC;
2611 if (list->owned_names.namelist_val == NULL) {
2613 *last_item_contains_data = 0;
2614 goto fail_GetOwnedGroupRPC;
2619 * We can retrieve the next group from data we already received
2622 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2626 * Check to see if there is more data to be retrieved
2627 * We need to free up the previously retrieved data here
2628 * and then check to see if the last rpc indicated that there
2629 * were more items to retrieve.
2632 if (list->index >= list->owned_names.namelist_len) {
2633 list->owned_names.namelist_len = 0;
2634 free(list->owned_names.namelist_val);
2635 list->owned_names.namelist_val = 0;
2637 list->owned_ids.prlist_len = 0;
2638 free(list->owned_ids.prlist_val);
2639 list->owned_ids.prlist_val = 0;
2642 list->finished_retrieving = 1;
2647 fail_GetOwnedGroupRPC:
2656 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2660 afs_status_t tst = 0;
2661 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2663 strcpy((char *)dest, list->group[slot]);
2674 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2675 * a particular user owns.
2679 * IN cellHandle - a previously opened cellHandle that corresponds
2680 * to the cell where the group exists.
2682 * IN ownerName - the owner of the groups of interest.
2684 * OUT iterationIdP - upon successful completion contains a iterator that
2685 * can be passed to pts_OwnedGroupListNext.
2689 * No locks are held by this function
2693 * Returns != 0 upon successful completion.
2698 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2699 void **iterationIdP, afs_status_p st)
2702 afs_status_t tst = 0;
2703 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2704 afs_admin_iterator_p iter =
2705 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2706 owned_group_list_p list =
2707 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2710 * Validate arguments
2713 if (!IsValidCellHandle(c_handle, &tst)) {
2714 goto fail_pts_OwnedGroupListBegin;
2717 if ((userName == NULL) || (*userName == 0)) {
2718 tst = ADMPTSUSERNAMENULL;
2719 goto fail_pts_OwnedGroupListBegin;
2722 if (iterationIdP == NULL) {
2723 tst = ADMITERATORNULL;
2724 goto fail_pts_OwnedGroupListBegin;
2727 if ((iter == NULL) || (list == NULL)) {
2729 goto fail_pts_OwnedGroupListBegin;
2733 * Initialize the iterator specific data
2737 list->finished_retrieving = 0;
2738 list->c_handle = c_handle;
2739 list->owned_names.namelist_len = 0;
2740 list->owned_names.namelist_val = 0;
2741 list->owned_ids.prlist_len = 0;
2742 list->owned_ids.prlist_val = 0;
2745 * Translate the user name into an id.
2748 if (!TranslateOneName
2749 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2750 goto fail_pts_OwnedGroupListBegin;
2754 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2755 DeleteOwnedGroupSpecificData, &tst)) {
2756 *iterationIdP = (void *)iter;
2760 fail_pts_OwnedGroupListBegin:
2778 * pts_OwnedGroupListNext - get the next group a user owns.
2782 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2784 * OUT groupName - upon successful completion contains the next group a user
2789 * The iterator mutex is held during the retrieval of the next member.
2793 * Returns != 0 upon successful completion.
2798 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2802 afs_status_t tst = 0;
2803 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2806 * Validate arguments
2809 if (iterationId == NULL) {
2810 tst = ADMITERATORNULL;
2811 goto fail_pts_OwnedGroupListNext;
2814 if (groupName == NULL) {
2815 tst = ADMPTSGROUPNAMENULL;
2816 goto fail_pts_OwnedGroupListNext;
2819 rc = IteratorNext(iter, (void *)groupName, &tst);
2821 fail_pts_OwnedGroupListNext:
2830 * pts_OwnedGroupListDone - finish using a group list iterator
2834 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2838 * The iterator is locked and then destroyed
2842 * Returns != 0 upon successful completion.
2846 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2847 * is called only once for each iterator.
2851 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2854 afs_status_t tst = 0;
2855 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2858 * Validate arguments
2861 if (iterationId == NULL) {
2862 tst = ADMITERATORNULL;
2863 goto fail_pts_OwnedGroupListDone;
2866 rc = IteratorDone(iter, &tst);
2868 fail_pts_OwnedGroupListDone:
2876 typedef struct pts_list {
2877 prlistentries *names; /* the current list of pts names in this cell */
2878 prlistentries *currName; /* the current pts entry */
2879 afs_int32 index; /* the index into names for the next pts entry */
2880 afs_int32 nextstartindex; /* the next start index for the RPC */
2881 afs_int32 nentries; /* the number of entries in names */
2882 afs_int32 flag; /* the type of the list */
2883 int finished_retrieving; /* set when we've processed the last owned_names */
2884 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2885 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2886 } pts_list_t, *pts_list_p;
2889 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2892 afs_status_t tst = 0;
2893 pts_list_p list = (pts_list_p) rpc_specific;
2908 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2909 int *last_item_contains_data, afs_status_p st)
2912 afs_status_t tst = 0;
2913 pts_list_p list = (pts_list_p) rpc_specific;
2916 * We really don't make an rpc for every entry we return here
2917 * since the pts interface allows several members to be returned
2918 * with one rpc, but we fake it to make the iterator happy.
2922 * Check to see if we are done retrieving data
2925 if (list->finished_retrieving) {
2927 *last_item_contains_data = 0;
2928 goto fail_GetPTSRPC;
2932 * Check to see if we really need to make an rpc
2935 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2936 afs_int32 start = list->nextstartindex;
2937 prentries bulkentries;
2938 list->nextstartindex = -1;
2939 bulkentries.prentries_val = 0;
2940 bulkentries.prentries_len = 0;
2943 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2944 start, &bulkentries, &(list->nextstartindex));
2947 goto fail_GetPTSRPC;
2950 list->nentries = bulkentries.prentries_len;
2951 list->names = bulkentries.prentries_val;
2954 list->currName = list->names;
2959 * We can retrieve the next entry from data we already received
2962 strcpy(list->entries[slot], list->currName->name);
2968 * Check to see if there is more data to be retrieved
2969 * We need to free up the previously retrieved data here
2970 * and then check to see if the last rpc indicated that there
2971 * were more items to retrieve.
2974 if (list->index >= list->nentries) {
2980 if (list->nextstartindex == -1) {
2981 list->finished_retrieving = 1;
2996 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
2999 afs_status_t tst = 0;
3000 pts_list_p list = (pts_list_p) rpc_specific;
3002 strcpy((char *)dest, list->entries[slot]);
3013 * pts_UserListBegin - begin iterating over the list of users
3014 * in a particular cell
3018 * IN cellHandle - a previously opened cellHandle that corresponds
3019 * to the cell where the users exist.
3021 * OUT iterationIdP - upon successful completion contains a iterator that
3022 * can be passed to pts_UserListNext.
3026 * No locks are held by this function
3030 * Returns != 0 upon successful completion.
3035 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3039 afs_status_t tst = 0;
3040 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3041 afs_admin_iterator_p iter =
3042 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3043 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3046 * Validate arguments
3049 if (!IsValidCellHandle(c_handle, &tst)) {
3050 goto fail_pts_UserListBegin;
3053 if (iterationIdP == NULL) {
3054 tst = ADMITERATORNULL;
3055 goto fail_pts_UserListBegin;
3058 if ((iter == NULL) || (list == NULL)) {
3060 goto fail_pts_UserListBegin;
3064 * Initialize the iterator specific data
3068 list->finished_retrieving = 0;
3069 list->c_handle = c_handle;
3071 list->nextstartindex = 0;
3073 list->flag = PRUSERS;
3076 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3077 DeletePTSSpecificData, &tst)) {
3078 *iterationIdP = (void *)iter;
3082 fail_pts_UserListBegin:
3100 * pts_UserListNext - get the next user in the cell.
3104 * IN iterationId - an iterator previously returned by pts_UserListBegin
3106 * OUT groupName - upon successful completion contains the next user
3110 * The iterator mutex is held during the retrieval of the next member.
3114 * Returns != 0 upon successful completion.
3119 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3122 afs_status_t tst = 0;
3123 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3126 * Validate arguments
3129 if (iterationId == NULL) {
3130 tst = ADMITERATORNULL;
3131 goto fail_pts_UserListNext;
3134 if (userName == NULL) {
3135 tst = ADMPTSUSERNAMENULL;
3136 goto fail_pts_UserListNext;
3139 rc = IteratorNext(iter, (void *)userName, &tst);
3141 fail_pts_UserListNext:
3150 * pts_UserListDone - finish using a user list iterator
3154 * IN iterationId - an iterator previously returned by pts_UserListBegin
3158 * The iterator is locked and then destroyed
3162 * Returns != 0 upon successful completion.
3166 * It is the user's responsibility to make sure pts_UserListDone
3167 * is called only once for each iterator.
3171 pts_UserListDone(const void *iterationId, afs_status_p st)
3174 afs_status_t tst = 0;
3175 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3178 * Validate arguments
3181 if (iterationId == NULL) {
3182 tst = ADMITERATORNULL;
3183 goto fail_pts_UserListDone;
3186 rc = IteratorDone(iter, &tst);
3188 fail_pts_UserListDone:
3197 * pts_GroupListBegin - begin iterating over the list of groups
3198 * in a particular cell.
3202 * IN cellHandle - a previously opened cellHandle that corresponds
3203 * to the cell where the groups exist.
3205 * OUT iterationIdP - upon successful completion contains a iterator that
3206 * can be passed to pts_GroupListNext.
3210 * No locks are held by this function
3214 * Returns != 0 upon successful completion.
3219 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3223 afs_status_t tst = 0;
3224 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3225 afs_admin_iterator_p iter =
3226 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3227 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3230 * Validate arguments
3233 if (!IsValidCellHandle(c_handle, &tst)) {
3234 goto fail_pts_GroupListBegin;
3237 if (iterationIdP == NULL) {
3238 tst = ADMITERATORNULL;
3239 goto fail_pts_GroupListBegin;
3242 if ((iter == NULL) || (list == NULL)) {
3244 goto fail_pts_GroupListBegin;
3248 * Initialize the iterator specific data
3252 list->finished_retrieving = 0;
3253 list->c_handle = c_handle;
3255 list->nextstartindex = 0;
3257 list->flag = PRGROUPS;
3260 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3261 DeletePTSSpecificData, &tst)) {
3262 *iterationIdP = (void *)iter;
3266 fail_pts_GroupListBegin:
3284 * pts_UserListNext - get the next group in a cell.
3288 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3290 * OUT groupName - upon successful completion contains the next group
3294 * The iterator mutex is held during the retrieval of the next member.
3298 * Returns != 0 upon successful completion.
3303 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3306 afs_status_t tst = 0;
3307 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3310 * Validate arguments
3313 if (iterationId == NULL) {
3314 tst = ADMITERATORNULL;
3315 goto fail_pts_GroupListNext;
3318 if (groupName == NULL) {
3319 tst = ADMPTSGROUPNAMENULL;
3320 goto fail_pts_GroupListNext;
3323 rc = IteratorNext(iter, (void *)groupName, &tst);
3325 fail_pts_GroupListNext:
3334 * pts_GroupListDone - finish using a group list iterator
3338 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3342 * The iterator is locked and then destroyed
3346 * Returns != 0 upon successful completion.
3350 * It is the user's responsibility to make sure pts_GroupListDone
3351 * is called only once for each iterator.
3355 pts_GroupListDone(const void *iterationId, afs_status_p st)
3358 afs_status_t tst = 0;
3359 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3362 * Validate arguments
3365 if (iterationId == NULL) {
3366 tst = ADMITERATORNULL;
3367 goto fail_pts_GroupListDone;
3370 rc = IteratorDone(iter, &tst);
3372 fail_pts_GroupListDone: