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, char *newGroup,
547 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;
1482 ids.idlist_val = NULL;
1485 * Validate arguments
1488 if (!IsValidCellHandle(c_handle, &tst)) {
1489 goto fail_pts_GroupMemberRemove;
1492 if ((userName == NULL) || (*userName == 0)) {
1493 tst = ADMPTSUSERNAMENULL;
1494 goto fail_pts_GroupMemberRemove;
1497 if ((groupName == NULL) || (*groupName == 0)) {
1498 tst = ADMPTSGROUPNAMENULL;
1499 goto fail_pts_GroupMemberRemove;
1502 if (!TranslateTwoNames
1503 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1504 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1505 goto fail_pts_GroupMemberRemove;
1513 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1517 goto fail_pts_GroupMemberRemove;
1521 fail_pts_GroupMemberRemove:
1523 if (ids.idlist_val != 0) {
1524 free(ids.idlist_val);
1534 * pts_GroupRename - change the name of a group
1538 * IN cellHandle - a previously opened cellHandle that corresponds
1539 * to the cell where the group exists.
1541 * IN oldName - the current group name
1543 * IN newName - the new group name
1547 * No locks are held by this function
1551 * Returns != 0 upon successful completion.
1556 pts_GroupRename(const void *cellHandle, const char *oldName,
1557 char *newName, afs_status_p st)
1560 afs_status_t tst = 0;
1561 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1562 afs_int32 groupId = 0;
1565 * Validate arguments
1568 if (!IsValidCellHandle(c_handle, &tst)) {
1569 goto fail_pts_GroupRename;
1572 if ((newName == NULL) || (*newName == 0)) {
1573 tst = ADMPTSNEWNAMENULL;
1574 goto fail_pts_GroupRename;
1577 if ((oldName == NULL) || (*oldName == 0)) {
1578 tst = ADMPTSOLDNAMENULL;
1579 goto fail_pts_GroupRename;
1583 * Translate the group name into an id.
1586 if (!TranslateOneName
1587 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1588 goto fail_pts_GroupRename;
1595 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1598 goto fail_pts_GroupRename;
1602 fail_pts_GroupRename:
1611 * SetGroupAccess - translate our Access notation to pts flags.
1615 * IN rights - the permissions.
1617 * OUT flags - a pointer to an afs_int32 structure that
1618 * contains the flags to pass to pts.
1622 * No locks are held by this function
1626 * Returns != 0 upon successful completion.
1631 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1635 afs_status_t tst = 0;
1639 if (rights->listDelete == PTS_GROUP_ACCESS) {
1641 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1642 tst = ADMPTSINVALIDGROUPDELETEPERM;
1643 goto fail_SetGroupAccess;
1646 if (rights->listAdd == PTS_GROUP_ACCESS) {
1648 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1652 if (rights->listMembership == PTS_GROUP_ACCESS) {
1654 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1658 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1660 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1661 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1662 goto fail_SetGroupAccess;
1665 if (rights->listStatus == PTS_GROUP_ACCESS) {
1667 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1672 fail_SetGroupAccess:
1681 * pts_GroupModify - change the contents of a group entry.
1685 * IN cellHandle - a previously opened cellHandle that corresponds
1686 * to the cell where the group exists.
1688 * IN groupName - the group to change
1690 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1691 * contains the new information for the group.
1695 * No locks are held by this function
1699 * Returns != 0 upon successful completion.
1704 pts_GroupModify(const void *cellHandle, const char *groupName,
1705 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1708 afs_status_t tst = 0;
1709 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1710 afs_int32 groupId = 0;
1711 afs_int32 flags = 0;
1714 * Validate arguments
1717 if (!IsValidCellHandle(c_handle, &tst)) {
1718 goto fail_pts_GroupModify;
1721 if ((groupName == NULL) || (*groupName == 0)) {
1722 tst = ADMPTSGROUPNAMENULL;
1723 goto fail_pts_GroupModify;
1727 if (newEntryP == NULL) {
1728 tst = ADMPTSNEWENTRYPNULL;
1729 goto fail_pts_GroupModify;
1733 * Translate the group name into an id.
1736 if (!TranslateOneName
1737 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1738 goto fail_pts_GroupModify;
1742 * Set the flags argument
1745 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1746 goto fail_pts_GroupModify;
1754 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1758 goto fail_pts_GroupModify;
1762 fail_pts_GroupModify:
1771 * pts_UserCreate - create a new user.
1775 * IN cellHandle - a previously opened cellHandle that corresponds
1776 * to the cell where the group exists.
1778 * IN newUser - the name of the new user.
1780 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1781 * id assigned by pts.
1785 * No locks are held by this function
1789 * Returns != 0 upon successful completion.
1794 pts_UserCreate(const void *cellHandle, char *userName, int *newUserId,
1798 afs_status_t tst = 0;
1799 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1802 * Validate arguments
1805 if (!IsValidCellHandle(c_handle, &tst)) {
1806 goto fail_pts_UserCreate;
1809 if ((userName == NULL) || (*userName == 0)) {
1810 tst = ADMPTSUSERNAMENULL;
1811 goto fail_pts_UserCreate;
1814 if (newUserId == NULL) {
1815 tst = ADMPTSNEWUSERIDNULL;
1816 goto fail_pts_UserCreate;
1820 * We make a different rpc based upon the input to this function
1823 if (*newUserId != 0) {
1825 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1829 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1834 goto fail_pts_UserCreate;
1838 fail_pts_UserCreate:
1847 * pts_UserDelete - delete a user.
1851 * IN cellHandle - a previously opened cellHandle that corresponds
1852 * to the cell where the group exists.
1854 * IN user - the name of the user to delete.
1858 * No locks are held by this function
1862 * Returns != 0 upon successful completion.
1867 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1869 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1870 ADMPTSUSERNAMETOOLONG, st);
1875 * GetUserAccess - a small convenience function for setting
1880 * IN access - a pointer to a pts_userAccess_t to be set with the
1881 * correct permission.
1883 * IN flag - the current permission flag used to derive the permission.
1887 * No locks are obtained or released by this function
1891 * Since this function cannot fail, it returns void.
1896 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1899 *access = PTS_USER_OWNER_ACCESS;
1901 *access = PTS_USER_ANYUSER_ACCESS;
1906 * IsAdministrator - determine if a user is an administrator.
1910 * IN cellHandle - a previously opened cellHandle that corresponds
1911 * to the cell where the group exists.
1913 * IN userEntry - the user data for the user in question.
1915 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1919 * No locks are held by this function
1923 * Returns != 0 upon successful completion.
1928 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1929 int *admin, afs_status_p st)
1932 afs_status_t tst = 0;
1933 afs_int32 adminId = 0;
1934 afs_int32 isAdmin = 0;
1938 if (userId == SYSADMINID) {
1941 if (!TranslateOneName
1942 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1944 goto fail_IsAdministrator;
1947 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1950 goto fail_IsAdministrator;
1958 fail_IsAdministrator:
1967 * pts_UserGet - retrieve information about a particular user.
1971 * IN cellHandle - a previously opened cellHandle that corresponds
1972 * to the cell where the group exists.
1974 * IN userName - the name of the user to retrieve.
1976 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1981 * No locks are held by this function
1985 * Returns != 0 upon successful completion.
1990 pts_UserGet(const void *cellHandle, const char *userName,
1991 pts_UserEntry_p userP, afs_status_p st)
1994 afs_status_t tst = 0;
1995 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1996 struct prcheckentry userEntry;
1997 afs_int32 userId = 0;
2001 afs_int32 ptsids[2];
2007 * Validate arguments
2010 if (!IsValidCellHandle(c_handle, &tst)) {
2011 goto fail_pts_UserGet;
2014 if ((userName == NULL) || (*userName == 0)) {
2015 tst = ADMPTSUSERNAMENULL;
2016 goto fail_pts_UserGet;
2019 if (userP == NULL) {
2020 tst = ADMPTSUSERPNULL;
2021 goto fail_pts_UserGet;
2025 * Translate the group name into an id.
2028 if (!TranslateOneName
2029 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2030 goto fail_pts_UserGet;
2034 * Retrieve information about the group
2037 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2040 goto fail_pts_UserGet;
2043 userP->groupMembershipCount = userEntry.count;
2044 userP->groupCreationQuota = userEntry.ngroups;
2046 * The administrator id, or any member of "system:administrators"
2047 * has unlimited group creation quota. Denote this by setting
2051 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2052 goto fail_pts_UserGet;
2056 userP->groupCreationQuota = -1;
2059 userP->nameUid = userEntry.id;
2060 userP->ownerUid = userEntry.owner;
2061 userP->creatorUid = userEntry.creator;
2062 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2063 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2066 * The permission bits are described in the GroupGet function above.
2067 * The user entry only uses 3 of the 5 permissions, so we shift
2068 * past the unused entries.
2071 flags = userEntry.flags;
2075 GetUserAccess(&userP->listMembership, twobit);
2080 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2082 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2088 GetUserAccess(&userP->listStatus, twobit);
2091 * Make another rpc and translate the owner and creator ids into
2092 * character strings.
2096 ids.idlist_val = ptsids;
2097 ptsids[0] = userEntry.owner;
2098 ptsids[1] = userEntry.creator;
2099 names.namelist_len = 0;
2100 names.namelist_val = 0;
2103 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2104 goto fail_pts_UserGet;
2107 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2108 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2109 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2110 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2111 free(names.namelist_val);
2123 * pts_UserRename - rename a user.
2127 * IN cellHandle - a previously opened cellHandle that corresponds
2128 * to the cell where the group exists.
2130 * IN oldName - the name of the user to rename.
2132 * IN newName - the new user name.
2136 * No locks are held by this function
2140 * Returns != 0 upon successful completion.
2145 pts_UserRename(const void *cellHandle, const char *oldName,
2146 char *newName, afs_status_p st)
2149 afs_status_t tst = 0;
2150 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2151 afs_int32 userId = 0;
2154 * Validate arguments
2157 if (!IsValidCellHandle(c_handle, &tst)) {
2158 goto fail_pts_UserRename;
2161 if ((oldName == NULL) || (*oldName == 0)) {
2162 tst = ADMPTSOLDNAMENULL;
2163 goto fail_pts_UserRename;
2166 if ((newName == NULL) || (*newName == 0)) {
2167 tst = ADMPTSNEWNAMENULL;
2168 goto fail_pts_UserRename;
2172 * Translate the user name into an id.
2175 if (!TranslateOneName
2176 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2177 goto fail_pts_UserRename;
2184 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2187 goto fail_pts_UserRename;
2191 fail_pts_UserRename:
2200 * SetUserAccess - translate our Access notation to pts flags.
2204 * IN userP - the user structure that contains the new permissions.
2206 * OUT flags - a pointer to an afs_int32 structure that
2207 * contains the flags to pass to pts.
2211 * No locks are held by this function
2215 * Returns != 0 upon successful completion.
2220 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2224 afs_status_t tst = 0;
2228 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2232 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2236 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2249 * pts_UserModify - update a user entry.
2253 * IN cellHandle - a previously opened cellHandle that corresponds
2254 * to the cell where the group exists.
2256 * IN userName - the name of the user to update.
2258 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2259 * new information for user.
2263 * No locks are held by this function
2267 * Returns != 0 upon successful completion.
2272 pts_UserModify(const void *cellHandle, const char *userName,
2273 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2276 afs_status_t tst = 0;
2277 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2278 afs_int32 userId = 0;
2279 afs_int32 newQuota = 0;
2281 afs_int32 flags = 0;
2284 * Validate arguments
2287 if (!IsValidCellHandle(c_handle, &tst)) {
2288 goto fail_pts_UserModify;
2291 if ((userName == NULL) || (*userName == 0)) {
2292 tst = ADMPTSUSERNAMENULL;
2293 goto fail_pts_UserModify;
2296 if (newEntryP == NULL) {
2297 tst = ADMPTSNEWENTRYPNULL;
2298 goto fail_pts_UserModify;
2302 * Translate the user name into an id.
2305 if (!TranslateOneName
2306 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2307 goto fail_pts_UserModify;
2311 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2312 mask |= PR_SF_NGROUPS;
2313 newQuota = newEntryP->groupCreationQuota;
2316 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2317 mask |= PR_SF_ALLBITS;
2318 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2319 goto fail_pts_UserModify;
2328 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2332 goto fail_pts_UserModify;
2336 fail_pts_UserModify:
2345 * pts_UserMaxGet - get the maximum in use user id.
2349 * IN cellHandle - a previously opened cellHandle that corresponds
2350 * to the cell where the group exists.
2352 * OUT maxUserId - upon successful completion contains the max in use id.
2356 * No locks are held by this function
2360 * Returns != 0 upon successful completion.
2365 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2368 afs_status_t tst = 0;
2369 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2370 afs_int32 maxGroupId = 0;
2373 * Validate arguments
2376 if (!IsValidCellHandle(c_handle, &tst)) {
2377 goto fail_pts_UserMaxGet;
2380 if (maxUserId == NULL) {
2381 tst = ADMPTSMAXUSERIDNULL;
2382 goto fail_pts_UserMaxGet;
2385 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2388 goto fail_pts_UserMaxGet;
2392 fail_pts_UserMaxGet:
2401 * pts_UserMaxSet - set the maximum user id.
2405 * IN cellHandle - a previously opened cellHandle that corresponds
2406 * to the cell where the group exists.
2408 * IN maxUserId - the new max user id.
2412 * No locks are held by this function
2416 * Returns != 0 upon successful completion.
2421 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2424 afs_status_t tst = 0;
2425 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2428 * Validate arguments
2431 if (!IsValidCellHandle(c_handle, &tst)) {
2432 goto fail_pts_UserMaxSet;
2435 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2438 goto fail_pts_UserMaxSet;
2442 fail_pts_UserMaxSet:
2451 * pts_UserMemberListBegin - begin iterating over the list of groups
2452 * a particular user belongs to.
2456 * IN cellHandle - a previously opened cellHandle that corresponds
2457 * to the cell where the group exists.
2459 * IN groupName - the group whose members will be returned.
2461 * OUT iterationIdP - upon successful completion contains a iterator that
2462 * can be passed to pts_GroupMemberListNext.
2466 * No locks are obtained or released by this function
2470 * Returns != 0 upon successful completion.
2475 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2476 void **iterationIdP, afs_status_p st)
2478 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2479 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2484 * pts_UserMemberListNext - get the next group a user belongs to
2488 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2490 * OUT userName - upon successful completion contains the next group a user
2495 * The iterator mutex is held during the retrieval of the next member.
2499 * Returns != 0 upon successful completion.
2504 pts_UserMemberListNext(const void *iterationId, char *userName,
2507 return pts_GroupMemberListNext(iterationId, userName, st);
2511 * pts_UserMemberListDone - finish using a user list iterator
2515 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2519 * The iterator is locked and then destroyed
2523 * Returns != 0 upon successful completion.
2527 * It is the user's responsibility to make sure pts_UserMemberListDone
2528 * is called only once for each iterator.
2532 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2534 return pts_GroupMemberListDone(iterationId, st);
2537 typedef struct owned_group_list {
2538 namelist owned_names; /* the list of character names owned by this id */
2539 prlist owned_ids; /* the list of pts ids owned by this id */
2540 afs_int32 index; /* the index into owned_names for the next group */
2541 afs_int32 owner; /* the pts id of the owner */
2542 afs_int32 more; /* the last parameter to PR_ListOwned */
2543 int finished_retrieving; /* set when we've processed the last owned_names */
2544 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2545 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2546 } owned_group_list_t, *owned_group_list_p;
2549 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2552 afs_status_t tst = 0;
2553 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2555 if (list->owned_names.namelist_val != NULL) {
2556 free(list->owned_names.namelist_val);
2559 if (list->owned_ids.prlist_val != NULL) {
2560 free(list->owned_ids.prlist_val);
2571 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2572 int *last_item_contains_data, afs_status_p st)
2575 afs_status_t tst = 0;
2576 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2579 * We really don't make an rpc for every entry we return here
2580 * since the pts interface allows several members to be returned
2581 * with one rpc, but we fake it to make the iterator happy.
2585 * Check to see if we are done retrieving data
2588 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2590 *last_item_contains_data = 0;
2591 goto fail_GetOwnedGroupRPC;
2595 * Check to see if we really need to make an rpc
2598 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2600 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2601 &list->owned_ids, &list->more);
2603 goto fail_GetOwnedGroupRPC;
2606 if (!TranslatePTSIds
2607 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2609 goto fail_GetOwnedGroupRPC;
2613 if (list->owned_names.namelist_val == NULL) {
2615 *last_item_contains_data = 0;
2616 goto fail_GetOwnedGroupRPC;
2621 * We can retrieve the next group from data we already received
2624 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2628 * Check to see if there is more data to be retrieved
2629 * We need to free up the previously retrieved data here
2630 * and then check to see if the last rpc indicated that there
2631 * were more items to retrieve.
2634 if (list->index >= list->owned_names.namelist_len) {
2635 list->owned_names.namelist_len = 0;
2636 free(list->owned_names.namelist_val);
2637 list->owned_names.namelist_val = 0;
2639 list->owned_ids.prlist_len = 0;
2640 free(list->owned_ids.prlist_val);
2641 list->owned_ids.prlist_val = 0;
2644 list->finished_retrieving = 1;
2649 fail_GetOwnedGroupRPC:
2658 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2662 afs_status_t tst = 0;
2663 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2665 strcpy((char *)dest, list->group[slot]);
2676 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2677 * a particular user owns.
2681 * IN cellHandle - a previously opened cellHandle that corresponds
2682 * to the cell where the group exists.
2684 * IN ownerName - the owner of the groups of interest.
2686 * OUT iterationIdP - upon successful completion contains a iterator that
2687 * can be passed to pts_OwnedGroupListNext.
2691 * No locks are held by this function
2695 * Returns != 0 upon successful completion.
2700 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2701 void **iterationIdP, afs_status_p st)
2704 afs_status_t tst = 0;
2705 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2706 afs_admin_iterator_p iter =
2707 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2708 owned_group_list_p list =
2709 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2712 * Validate arguments
2715 if (!IsValidCellHandle(c_handle, &tst)) {
2716 goto fail_pts_OwnedGroupListBegin;
2719 if ((userName == NULL) || (*userName == 0)) {
2720 tst = ADMPTSUSERNAMENULL;
2721 goto fail_pts_OwnedGroupListBegin;
2724 if (iterationIdP == NULL) {
2725 tst = ADMITERATORNULL;
2726 goto fail_pts_OwnedGroupListBegin;
2729 if ((iter == NULL) || (list == NULL)) {
2731 goto fail_pts_OwnedGroupListBegin;
2735 * Initialize the iterator specific data
2739 list->finished_retrieving = 0;
2740 list->c_handle = c_handle;
2741 list->owned_names.namelist_len = 0;
2742 list->owned_names.namelist_val = 0;
2743 list->owned_ids.prlist_len = 0;
2744 list->owned_ids.prlist_val = 0;
2747 * Translate the user name into an id.
2750 if (!TranslateOneName
2751 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2752 goto fail_pts_OwnedGroupListBegin;
2756 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2757 DeleteOwnedGroupSpecificData, &tst)) {
2758 *iterationIdP = (void *)iter;
2762 fail_pts_OwnedGroupListBegin:
2780 * pts_OwnedGroupListNext - get the next group a user owns.
2784 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2786 * OUT groupName - upon successful completion contains the next group a user
2791 * The iterator mutex is held during the retrieval of the next member.
2795 * Returns != 0 upon successful completion.
2800 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2804 afs_status_t tst = 0;
2805 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2808 * Validate arguments
2811 if (iterationId == NULL) {
2812 tst = ADMITERATORNULL;
2813 goto fail_pts_OwnedGroupListNext;
2816 if (groupName == NULL) {
2817 tst = ADMPTSGROUPNAMENULL;
2818 goto fail_pts_OwnedGroupListNext;
2821 rc = IteratorNext(iter, (void *)groupName, &tst);
2823 fail_pts_OwnedGroupListNext:
2832 * pts_OwnedGroupListDone - finish using a group list iterator
2836 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2840 * The iterator is locked and then destroyed
2844 * Returns != 0 upon successful completion.
2848 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2849 * is called only once for each iterator.
2853 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2856 afs_status_t tst = 0;
2857 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2860 * Validate arguments
2863 if (iterationId == NULL) {
2864 tst = ADMITERATORNULL;
2865 goto fail_pts_OwnedGroupListDone;
2868 rc = IteratorDone(iter, &tst);
2870 fail_pts_OwnedGroupListDone:
2878 typedef struct pts_list {
2879 prlistentries *names; /* the current list of pts names in this cell */
2880 prlistentries *currName; /* the current pts entry */
2881 afs_int32 index; /* the index into names for the next pts entry */
2882 afs_int32 nextstartindex; /* the next start index for the RPC */
2883 afs_int32 nentries; /* the number of entries in names */
2884 afs_int32 flag; /* the type of the list */
2885 int finished_retrieving; /* set when we've processed the last owned_names */
2886 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2887 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2888 } pts_list_t, *pts_list_p;
2891 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2894 afs_status_t tst = 0;
2895 pts_list_p list = (pts_list_p) rpc_specific;
2910 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2911 int *last_item_contains_data, afs_status_p st)
2914 afs_status_t tst = 0;
2915 pts_list_p list = (pts_list_p) rpc_specific;
2918 * We really don't make an rpc for every entry we return here
2919 * since the pts interface allows several members to be returned
2920 * with one rpc, but we fake it to make the iterator happy.
2924 * Check to see if we are done retrieving data
2927 if (list->finished_retrieving) {
2929 *last_item_contains_data = 0;
2930 goto fail_GetPTSRPC;
2934 * Check to see if we really need to make an rpc
2937 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2938 afs_int32 start = list->nextstartindex;
2939 prentries bulkentries;
2940 list->nextstartindex = -1;
2941 bulkentries.prentries_val = 0;
2942 bulkentries.prentries_len = 0;
2945 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2946 start, &bulkentries, &(list->nextstartindex));
2949 goto fail_GetPTSRPC;
2952 list->nentries = bulkentries.prentries_len;
2953 list->names = bulkentries.prentries_val;
2956 list->currName = list->names;
2961 * We can retrieve the next entry from data we already received
2964 strcpy(list->entries[slot], list->currName->name);
2970 * Check to see if there is more data to be retrieved
2971 * We need to free up the previously retrieved data here
2972 * and then check to see if the last rpc indicated that there
2973 * were more items to retrieve.
2976 if (list->index >= list->nentries) {
2982 if (list->nextstartindex == -1) {
2983 list->finished_retrieving = 1;
2998 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3001 afs_status_t tst = 0;
3002 pts_list_p list = (pts_list_p) rpc_specific;
3004 strcpy((char *)dest, list->entries[slot]);
3015 * pts_UserListBegin - begin iterating over the list of users
3016 * in a particular cell
3020 * IN cellHandle - a previously opened cellHandle that corresponds
3021 * to the cell where the users exist.
3023 * OUT iterationIdP - upon successful completion contains a iterator that
3024 * can be passed to pts_UserListNext.
3028 * No locks are held by this function
3032 * Returns != 0 upon successful completion.
3037 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3041 afs_status_t tst = 0;
3042 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3043 afs_admin_iterator_p iter =
3044 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3045 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3048 * Validate arguments
3051 if (!IsValidCellHandle(c_handle, &tst)) {
3052 goto fail_pts_UserListBegin;
3055 if (iterationIdP == NULL) {
3056 tst = ADMITERATORNULL;
3057 goto fail_pts_UserListBegin;
3060 if ((iter == NULL) || (list == NULL)) {
3062 goto fail_pts_UserListBegin;
3066 * Initialize the iterator specific data
3070 list->finished_retrieving = 0;
3071 list->c_handle = c_handle;
3073 list->nextstartindex = 0;
3075 list->flag = PRUSERS;
3078 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3079 DeletePTSSpecificData, &tst)) {
3080 *iterationIdP = (void *)iter;
3084 fail_pts_UserListBegin:
3102 * pts_UserListNext - get the next user in the cell.
3106 * IN iterationId - an iterator previously returned by pts_UserListBegin
3108 * OUT groupName - upon successful completion contains the next user
3112 * The iterator mutex is held during the retrieval of the next member.
3116 * Returns != 0 upon successful completion.
3121 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3124 afs_status_t tst = 0;
3125 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3128 * Validate arguments
3131 if (iterationId == NULL) {
3132 tst = ADMITERATORNULL;
3133 goto fail_pts_UserListNext;
3136 if (userName == NULL) {
3137 tst = ADMPTSUSERNAMENULL;
3138 goto fail_pts_UserListNext;
3141 rc = IteratorNext(iter, (void *)userName, &tst);
3143 fail_pts_UserListNext:
3152 * pts_UserListDone - finish using a user list iterator
3156 * IN iterationId - an iterator previously returned by pts_UserListBegin
3160 * The iterator is locked and then destroyed
3164 * Returns != 0 upon successful completion.
3168 * It is the user's responsibility to make sure pts_UserListDone
3169 * is called only once for each iterator.
3173 pts_UserListDone(const void *iterationId, afs_status_p st)
3176 afs_status_t tst = 0;
3177 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3180 * Validate arguments
3183 if (iterationId == NULL) {
3184 tst = ADMITERATORNULL;
3185 goto fail_pts_UserListDone;
3188 rc = IteratorDone(iter, &tst);
3190 fail_pts_UserListDone:
3199 * pts_GroupListBegin - begin iterating over the list of groups
3200 * in a particular cell.
3204 * IN cellHandle - a previously opened cellHandle that corresponds
3205 * to the cell where the groups exist.
3207 * OUT iterationIdP - upon successful completion contains a iterator that
3208 * can be passed to pts_GroupListNext.
3212 * No locks are held by this function
3216 * Returns != 0 upon successful completion.
3221 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3225 afs_status_t tst = 0;
3226 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3227 afs_admin_iterator_p iter =
3228 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3229 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3232 * Validate arguments
3235 if (!IsValidCellHandle(c_handle, &tst)) {
3236 goto fail_pts_GroupListBegin;
3239 if (iterationIdP == NULL) {
3240 tst = ADMITERATORNULL;
3241 goto fail_pts_GroupListBegin;
3244 if ((iter == NULL) || (list == NULL)) {
3246 goto fail_pts_GroupListBegin;
3250 * Initialize the iterator specific data
3254 list->finished_retrieving = 0;
3255 list->c_handle = c_handle;
3257 list->nextstartindex = 0;
3259 list->flag = PRGROUPS;
3262 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3263 DeletePTSSpecificData, &tst)) {
3264 *iterationIdP = (void *)iter;
3268 fail_pts_GroupListBegin:
3286 * pts_UserListNext - get the next group in a cell.
3290 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3292 * OUT groupName - upon successful completion contains the next group
3296 * The iterator mutex is held during the retrieval of the next member.
3300 * Returns != 0 upon successful completion.
3305 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3308 afs_status_t tst = 0;
3309 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3312 * Validate arguments
3315 if (iterationId == NULL) {
3316 tst = ADMITERATORNULL;
3317 goto fail_pts_GroupListNext;
3320 if (groupName == NULL) {
3321 tst = ADMPTSGROUPNAMENULL;
3322 goto fail_pts_GroupListNext;
3325 rc = IteratorNext(iter, (void *)groupName, &tst);
3327 fail_pts_GroupListNext:
3336 * pts_GroupListDone - finish using a group list iterator
3340 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3344 * The iterator is locked and then destroyed
3348 * Returns != 0 upon successful completion.
3352 * It is the user's responsibility to make sure pts_GroupListDone
3353 * is called only once for each iterator.
3357 pts_GroupListDone(const void *iterationId, afs_status_p st)
3360 afs_status_t tst = 0;
3361 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3364 * Validate arguments
3367 if (iterationId == NULL) {
3368 tst = ADMITERATORNULL;
3369 goto fail_pts_GroupListDone;
3372 rc = IteratorDone(iter, &tst);
3374 fail_pts_GroupListDone: