2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
19 #include <rx/rxstat.h>
21 #include <afs/afs_AdminErrors.h>
22 #include <afs/afs_utilAdmin.h>
23 #include <afs/ptint.h>
24 #include <afs/ptserver.h>
26 #include "afs_ptsAdmin.h"
27 #include "../adminutil/afs_AdminInternal.h"
30 * IsValidCellHandle - validate the cell handle for making pts
35 * IN cellHandle - a previously opened cellHandle that is to be validated.
39 * No locks are obtained or released by this function
43 * Returns != 0 upon successful completion.
48 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
53 if (!CellHandleIsValid((void *)c_handle, &tst)) {
54 goto fail_IsValidCellHandle;
57 if (c_handle->pts_valid == 0) {
58 tst = ADMCLIENTCELLPTSINVALID;
59 goto fail_IsValidCellHandle;
62 if (c_handle->pts == NULL) {
63 tst = ADMCLIENTCELLPTSNULL;
64 goto fail_IsValidCellHandle;
69 fail_IsValidCellHandle:
79 * TranslatePTSNames - translate character representations of pts names
80 * into their numeric equivalent.
84 * IN cellHandle - a previously opened cellHandle that corresponds
85 * to the cell where the id's exist.
87 * IN names - the list of names to be translated.
89 * OUT ids - the list of translated names
93 * No locks are obtained or released by this function
97 * Returns != 0 upon successful completion.
102 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
103 idlist * ids, afs_status_p st)
106 afs_status_t tst = 0;
111 * Lowercase the names to translate
114 for (i = 0; i < names->namelist_len; i++) {
115 p = names->namelist_val[i];
122 tst = ubik_PR_NameToID(cellHandle->pts, 0, names, ids);
125 goto fail_TranslatePTSNames;
130 * Check to see if the lookup failed
133 for (i = 0; i < ids->idlist_len; i++) {
134 if (ids->idlist_val[i] == ANONYMOUSID) {
135 tst = ADMPTSFAILEDNAMETRANSLATE;
136 goto fail_TranslatePTSNames;
141 fail_TranslatePTSNames:
150 * TranslateTwoNames - translate two pts names to their pts ids.
154 * IN cellHandle - a previously opened cellHandle that corresponds
155 * to the cell where the group exists.
157 * IN id1 - one id to be translated
159 * IN error1 - the error status to be returned in the event that id1 is
162 * IN id2 - one id to be translated
164 * IN error2 - the error status to be returned in the event that id2 is
168 * OUT idlist - the list of pts id's
172 * No locks are obtained or released by this function
176 * Returns != 0 upon successful completion.
181 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
182 afs_status_t error1, const char *id2, afs_status_t error2,
183 idlist * ids, afs_status_p st)
186 afs_status_t tst = 0;
188 char tmp_array[2 * PTS_MAX_NAME_LEN];
191 * Copy the group and user names in order to translate them
194 names.namelist_len = 2;
195 names.namelist_val = (prname *) & tmp_array[0];
197 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
198 names.namelist_val[0][PTS_MAX_NAME_LEN - 1] = '\0';
199 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
200 names.namelist_val[1][PTS_MAX_NAME_LEN - 1] = '\0';
205 * Check that user and group aren't too long
206 * This is a cheaper check than calling strlen
209 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
211 goto fail_TranslateTwoNames;
214 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
216 goto fail_TranslateTwoNames;
220 * Translate user and group into pts ID's
223 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
224 goto fail_TranslateTwoNames;
229 fail_TranslateTwoNames:
238 * TranslateOneName - translate a pts name to its pts id.
242 * IN cellHandle - a previously opened cellHandle that corresponds
243 * to the cell where the group exists.
245 * IN userName - the user to be translated.
247 * OUT idlist - the user pts id.
251 * No locks are obtained or released by this function
255 * Returns != 0 upon successful completion.
260 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
261 afs_status_t tooLongError, afs_int32 * ptsId,
265 afs_status_t tst = 0;
267 char tmp_array[PTS_MAX_NAME_LEN];
271 * Copy the name in order to translate it
274 names[0].namelist_len = 1;
275 names[0].namelist_val = (prname *) & tmp_array[0];
277 strncpy((char *)names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
278 ((char *)names[0].namelist_val)[PTS_MAX_NAME_LEN - 1] = '\0';
283 * Check that user isn't too long
284 * This is a cheaper check than calling strlen
287 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
289 goto fail_TranslateOneName;
293 * Translate user into pts ID
296 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
297 goto fail_TranslateOneName;
299 if (ids.idlist_val != NULL) {
300 *ptsId = *ids.idlist_val;
301 free(ids.idlist_val);
307 fail_TranslateOneName:
316 * TranslatePTSIds - translate numeric representations of pts names
317 * into their character equivalent.
321 * IN cellHandle - a previously opened cellHandle that corresponds
322 * to the cell where the id's exist.
324 * IN ids - the list of ids to be translated.
326 * OUT names - the list of translated names
330 * No locks are obtained or released by this function
334 * Returns != 0 upon successful completion.
339 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
340 idlist * ids, afs_status_p st)
343 afs_status_t tst = 0;
345 tst = ubik_PR_IDToName(cellHandle->pts, 0, ids, names);
348 goto fail_TranslatePTSIds;
352 fail_TranslatePTSIds:
361 * pts_GroupMemberAdd - add one member to a pts group
365 * IN cellHandle - a previously opened cellHandle that corresponds
366 * to the cell where the group exists.
368 * IN userName - the name to be added to the group.
370 * IN groupName - the group to be modified.
374 * No locks are obtained or released by this function
378 * Returns != 0 upon successful completion.
383 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
384 const char *groupName, afs_status_p st)
387 afs_status_t tst = 0;
388 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
395 if (!IsValidCellHandle(c_handle, &tst)) {
396 goto fail_pts_GroupMemberAdd;
399 if ((userName == NULL) || (*userName == 0)) {
400 tst = ADMPTSUSERNAMENULL;
401 goto fail_pts_GroupMemberAdd;
404 if ((groupName == NULL) || (*groupName == 0)) {
405 tst = ADMPTSGROUPNAMENULL;
406 goto fail_pts_GroupMemberAdd;
409 if (!TranslateTwoNames
410 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
411 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
412 goto fail_pts_GroupMemberAdd;
420 ubik_PR_AddToGroup(c_handle->pts, 0, ids.idlist_val[0],
424 goto fail_pts_GroupMemberAdd;
428 fail_pts_GroupMemberAdd:
430 if (ids.idlist_val != 0) {
431 free(ids.idlist_val);
441 * pts_GroupOwnerChange - change the owner of a group
445 * IN cellHandle - a previously opened cellHandle that corresponds
446 * to the cell where the group exists.
448 * IN targetGroup - the group to be modified.
450 * IN userName - the new owner of the group.
454 * No locks are obtained or released by this function
458 * Returns != 0 upon successful completion.
463 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
464 const char *newOwner, afs_status_p st)
467 afs_status_t tst = 0;
468 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
475 if (!IsValidCellHandle(c_handle, &tst)) {
476 goto fail_pts_GroupOwnerChange;
479 if ((newOwner == NULL) || (*newOwner == 0)) {
480 tst = ADMPTSNEWOWNERNULL;
481 goto fail_pts_GroupOwnerChange;
484 if ((targetGroup == NULL) || (*targetGroup == 0)) {
485 tst = ADMPTSTARGETGROUPNULL;
486 goto fail_pts_GroupOwnerChange;
489 if (!TranslateTwoNames
490 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
491 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
492 goto fail_pts_GroupOwnerChange;
500 ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
501 ids.idlist_val[0], 0);
504 goto fail_pts_GroupOwnerChange;
508 fail_pts_GroupOwnerChange:
510 if (ids.idlist_val != 0) {
511 free(ids.idlist_val);
521 * pts_GroupCreate - create a new group
525 * IN cellHandle - a previously opened cellHandle that corresponds
526 * to the cell where the group exists.
528 * IN newGroup - the group to be created.
530 * IN newOwner - the owner of the group. Pass NULL if the current user
531 * is to be the new owner, or the character string of the owner otherwise.
533 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
534 * generate a value, != 0 to assign a value on your own. The group id
535 * that is used to create the group is copied into this parameter in the
536 * event you pass in 0.
540 * No locks are obtained or released by this function
544 * Returns != 0 upon successful completion.
549 pts_GroupCreate(const void *cellHandle, char *newGroup,
550 char *newOwner, int *newGroupId, afs_status_p st)
553 afs_status_t tst = 0;
554 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
555 afs_int32 newOwnerId = 0;
561 if (!IsValidCellHandle(c_handle, &tst)) {
562 goto fail_pts_GroupCreate;
565 if ((newGroup == NULL) || (*newGroup == 0)) {
566 tst = ADMPTSNEWGROUPNULL;
567 goto fail_pts_GroupCreate;
570 if (newGroupId == NULL) {
571 tst = ADMPTSNEWGROUPIDNULL;
572 goto fail_pts_GroupCreate;
575 if (*newGroupId > 0) {
576 tst = ADMPTSNEWGROUPIDPOSITIVE;
577 goto fail_pts_GroupCreate;
581 * If a newOwner was specified, validate that it exists
584 if (newOwner != NULL) {
585 if (!TranslateOneName
586 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
587 goto fail_pts_GroupCreate;
592 * We make a different rpc based upon the input to this function
595 if (*newGroupId != 0) {
597 ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
601 ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
602 newOwnerId, newGroupId);
606 goto fail_pts_GroupCreate;
610 fail_pts_GroupCreate:
619 * GetGroupAccess - a small convenience function for setting
624 * IN access - a pointer to a pts_groupAccess_t to be set with the
625 * correct permission.
627 * IN flag - the current permission flag used to derive the permission.
631 * No locks are obtained or released by this function
635 * Since this function cannot fail, it returns void.
640 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
643 *access = PTS_GROUP_OWNER_ACCESS;
645 *access = PTS_GROUP_OWNER_ACCESS;
646 } else if (flag == 1) {
647 *access = PTS_GROUP_ACCESS;
648 } else if (flag == 2) {
649 *access = PTS_GROUP_ANYUSER_ACCESS;
655 * pts_GroupGet - retrieve information about a particular group.
659 * IN cellHandle - a previously opened cellHandle that corresponds
660 * to the cell where the group exists.
662 * IN groupName - the group to retrieve.
664 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
665 * successful completion is filled with information about groupName.
669 * No locks are obtained or released by this function
673 * Returns != 0 upon successful completion.
678 pts_GroupGet(const void *cellHandle, const char *groupName,
679 pts_GroupEntry_p groupP, afs_status_p st)
682 afs_status_t tst = 0;
683 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
684 afs_int32 groupId = 0;
687 struct prcheckentry groupEntry;
696 if (!IsValidCellHandle(c_handle, &tst)) {
697 goto fail_pts_GroupGet;
700 if ((groupName == NULL) || (*groupName == 0)) {
701 tst = ADMPTSGROUPNAMENULL;
702 goto fail_pts_GroupGet;
705 if (groupP == NULL) {
706 tst = ADMPTSGROUPPNULL;
707 goto fail_pts_GroupGet;
711 * Translate the group name into an id.
714 if (!TranslateOneName
715 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
716 goto fail_pts_GroupGet;
720 * Retrieve information about the group
723 tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
726 goto fail_pts_GroupGet;
729 groupP->membershipCount = groupEntry.count;
730 groupP->nameUid = groupEntry.id;
731 groupP->ownerUid = groupEntry.owner;
732 groupP->creatorUid = groupEntry.creator;
733 strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
734 groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
736 * Set the access rights based upon the value of the flags member
737 * of the groupEntry struct.
739 * To the best of my ability to decypher the pts code, it looks like
740 * the rights are stored in flags as follows:
742 * I number my bits from least significant to most significant starting
746 * if bit 0 == 0 -> r access is denied
747 * if bit 0 == 1 -> r access is granted
750 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
751 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
752 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
753 * if bit 2 == 1 and bit 1 == 1 -> this is an error
755 * membership - bits 3 and 4
756 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
757 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
758 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
759 * if bit 4 == 1 and bit 3 == 1 -> this is an error
762 * if bit 5 == 0 -> O access is denied
763 * if bit 5 == 1 -> O access is granted
765 * status - bits 6 and 7
766 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
767 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
768 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
769 * if bit 7 == 1 and bit 6 == 1 -> this is an error
771 * For cases where the permission doesn't make sense for the
772 * type of entry, or where an error occurs, we ignore it.
773 * This is the behavior of the pts code.
776 flags = groupEntry.flags;
778 groupP->listDelete = PTS_GROUP_ACCESS;
780 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
786 GetGroupAccess(&groupP->listAdd, twobit);
791 GetGroupAccess(&groupP->listMembership, twobit);
796 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
798 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
804 GetGroupAccess(&groupP->listStatus, twobit);
807 * Make another rpc and translate the owner and creator ids into
812 ids.idlist_val = ptsids;
813 ptsids[0] = groupEntry.owner;
814 ptsids[1] = groupEntry.creator;
815 names.namelist_len = 0;
816 names.namelist_val = 0;
819 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
820 goto fail_pts_GroupGet;
823 strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
824 groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
825 strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
826 groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
827 free(names.namelist_val);
839 * EntryDelete - delete a pts entry (group or user).
843 * IN cellHandle - a previously opened cellHandle that corresponds
844 * to the cell where the group exists.
846 * IN entryName - the entry to be deleted.
848 * IN error1 - the error status to be returned in the event that entryName is
851 * IN error2 - the error status to be returned in the event that entryName is
856 * No locks are obtained or released by this function
860 * Returns != 0 upon successful completion.
865 EntryDelete(const void *cellHandle, const char *entryName,
866 afs_status_t error1, afs_status_t error2, afs_status_p st)
869 afs_status_t tst = 0;
870 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
871 afs_int32 entryId = 0;
877 if (!IsValidCellHandle(c_handle, &tst)) {
878 goto fail_EntryDelete;
881 if ((entryName == NULL) || (*entryName == 0)) {
883 goto fail_EntryDelete;
887 * Translate the entry name into an id.
890 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
891 goto fail_EntryDelete;
898 tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
901 goto fail_EntryDelete;
915 * pts_GroupDelete - delete a group
919 * IN cellHandle - a previously opened cellHandle that corresponds
920 * to the cell where the group exists.
922 * IN groupName - the group to be deleted.
926 * No locks are obtained or released by this function
930 * Returns != 0 upon successful completion.
935 pts_GroupDelete(const void *cellHandle, const char *groupName,
939 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
940 ADMPTSGROUPNAMETOOLONG, st);
944 * pts_GroupMaxGet - get the maximum in use group id.
948 * IN cellHandle - a previously opened cellHandle that corresponds
949 * to the cell where the group exists.
951 * OUT maxGroupId - upon successful completion contains the maximum
952 * group Id in use at the server.
956 * No locks are obtained or released by this function
960 * Returns != 0 upon successful completion.
965 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
968 afs_status_t tst = 0;
969 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
970 afs_int32 maxUserId = 0;
976 if (!IsValidCellHandle(c_handle, &tst)) {
977 goto fail_pts_GroupMaxGet;
980 if (maxGroupId == NULL) {
981 tst = ADMPTSMAXGROUPIDNULL;
982 goto fail_pts_GroupMaxGet;
985 tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
988 goto fail_pts_GroupMaxGet;
992 fail_pts_GroupMaxGet:
1001 * pts_GroupMaxSet - set the maximum in use group id.
1005 * IN cellHandle - a previously opened cellHandle that corresponds
1006 * to the cell where the group exists.
1008 * IN maxGroupId - the new maximum group id.
1012 * No locks are obtained or released by this function
1016 * Returns != 0 upon successful completion.
1021 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1024 afs_status_t tst = 0;
1025 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1028 * Validate arguments
1031 if (!IsValidCellHandle(c_handle, &tst)) {
1032 goto fail_pts_GroupMaxSet;
1035 tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
1038 goto fail_pts_GroupMaxSet;
1042 fail_pts_GroupMaxSet:
1053 * I'm not using the common iterator pattern here since the retrival
1054 * of the member list is actually accomplished in 1 rpc. There's no
1055 * sense in trying to fit this pts specific behavior into the more
1056 * generic model, so instead the Begin functions actually do all the
1057 * rpc work and the next/done functions just manipulate the retrieved
1061 typedef struct pts_group_member_list_iterator {
1064 pthread_mutex_t mutex; /* hold to manipulate this structure */
1069 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1072 * pts_GroupMemberListBegin - begin iterating over the list of members
1073 * of a particular group.
1077 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1081 * No locks are obtained or released by this function
1085 * Returns != 0 upon successful completion.
1090 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1094 afs_status_t tst = 0;
1097 tst = ADMITERATORNULL;
1098 goto fail_IsValidPtsGroupMemberListIterator;
1101 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1102 tst = ADMITERATORBADMAGICNULL;
1103 goto fail_IsValidPtsGroupMemberListIterator;
1106 if (iter->is_valid == 0) {
1107 tst = ADMITERATORINVALID;
1108 goto fail_IsValidPtsGroupMemberListIterator;
1112 fail_IsValidPtsGroupMemberListIterator:
1121 * MemberListBegin - an internal function which is used to get both
1122 * the list of members in a group and the list of groups a user belongs
1127 * IN cellHandle - a previously opened cellHandle that corresponds
1128 * to the cell where the group exists.
1130 * IN name - the name whose membership will be retrieved.
1132 * OUT iterationIdP - upon successful completion contains a iterator that
1133 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1137 * No locks are obtained or released by this function
1141 * Returns != 0 upon successful completion.
1146 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1147 afs_status_t error2, void **iterationIdP, afs_status_p st)
1150 afs_status_t tst = 0;
1151 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1152 afs_int32 groupId = 0;
1153 afs_int32 exceeded = 0;
1154 pts_group_member_list_iterator_p iter =
1155 malloc(sizeof(pts_group_member_list_iterator_t));
1156 int iter_allocated = 0;
1157 int ids_allocated = 0;
1158 int names_allocated = 0;
1159 int mutex_inited = 0;
1162 * Validate arguments
1165 if (!IsValidCellHandle(c_handle, &tst)) {
1166 goto fail_MemberListBegin;
1169 if ((name == NULL) || (*name == 0)) {
1170 tst = ADMPTSGROUPNAMENULL;
1171 goto fail_MemberListBegin;
1174 if (iterationIdP == NULL) {
1175 tst = ADMITERATORNULL;
1176 goto fail_MemberListBegin;
1181 goto fail_MemberListBegin;
1187 * Translate the name into an id.
1190 if (!TranslateOneName
1191 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1192 goto fail_MemberListBegin;
1195 if (pthread_mutex_init(&iter->mutex, 0)) {
1197 goto fail_MemberListBegin;
1202 iter->ids.prlist_len = 0;
1203 iter->ids.prlist_val = 0;
1206 ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
1210 goto fail_MemberListBegin;
1213 if (exceeded != 0) {
1214 tst = ADMPTSGROUPMEMEXCEEDED;
1215 goto fail_MemberListBegin;
1219 iter->names.namelist_len = 0;
1220 iter->names.namelist_val = 0;
1222 if (!TranslatePTSIds
1223 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1224 goto fail_MemberListBegin;
1227 names_allocated = 1;
1228 iter->begin_magic = BEGIN_MAGIC;
1229 iter->end_magic = END_MAGIC;
1233 *iterationIdP = (void *)iter;
1236 fail_MemberListBegin:
1238 if (ids_allocated) {
1239 free(iter->ids.prlist_val);
1243 if (names_allocated) {
1244 free(iter->names.namelist_val);
1247 pthread_mutex_destroy(&iter->mutex);
1249 if (iter_allocated) {
1261 * pts_GroupMemberListBegin - begin iterating over the list of members
1262 * of a particular group.
1266 * IN cellHandle - a previously opened cellHandle that corresponds
1267 * to the cell where the group exists.
1269 * IN groupName - the group whose members will be returned.
1271 * OUT iterationIdP - upon successful completion contains a iterator that
1272 * can be passed to pts_GroupMemberListNext.
1276 * No locks are obtained or released by this function
1280 * Returns != 0 upon successful completion.
1285 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1286 void **iterationIdP, afs_status_p st)
1288 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1289 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1293 * pts_GroupMemberListNext - get the next member of a group
1297 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1299 * OUT memberName - upon successful completion contains the next member of
1304 * The iterator mutex is held during the retrieval of the next member.
1308 * Returns != 0 upon successful completion.
1313 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1317 afs_status_t tst = 0;
1318 pts_group_member_list_iterator_p iter =
1319 (pts_group_member_list_iterator_p) iterationId;
1320 int mutex_locked = 0;
1323 * Validate arguments
1327 tst = ADMITERATORNULL;
1328 goto fail_pts_GroupMemberListNext;
1331 if (memberName == NULL) {
1332 tst = ADMPTSMEMBERNAMENULL;
1333 goto fail_pts_GroupMemberListNext;
1337 * Lock the mutex and check the validity of the iterator
1340 if (pthread_mutex_lock(&iter->mutex)) {
1342 goto fail_pts_GroupMemberListNext;
1347 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1348 goto fail_pts_GroupMemberListNext;
1352 * Check to see if we've copied out all the data. If we haven't,
1353 * copy another item. If we have, mark the iterator done.
1356 if (iter->index >= iter->names.namelist_len) {
1357 tst = ADMITERATORDONE;
1358 goto fail_pts_GroupMemberListNext;
1360 strcpy(memberName, iter->names.namelist_val[iter->index]);
1365 fail_pts_GroupMemberListNext:
1368 pthread_mutex_unlock(&iter->mutex);
1378 * pts_GroupMemberListDone - finish using a member list iterator
1382 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1386 * The iterator is locked and then destroyed
1390 * Returns != 0 upon successful completion.
1394 * It is the user's responsibility to make sure pts_GroupMemberListDone
1395 * is called only once for each iterator.
1399 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1402 afs_status_t tst = 0;
1403 pts_group_member_list_iterator_p iter =
1404 (pts_group_member_list_iterator_p) iterationId;
1405 int mutex_locked = 0;
1408 * Validate arguments
1412 tst = ADMITERATORNULL;
1413 goto fail_pts_GroupMemberListDone;
1417 * Lock the mutex and check the validity of the iterator
1420 if (pthread_mutex_lock(&iter->mutex)) {
1422 goto fail_pts_GroupMemberListDone;
1427 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1428 goto fail_pts_GroupMemberListDone;
1432 * Free the namelist and the iterator.
1435 pthread_mutex_destroy(&iter->mutex);
1438 free(iter->names.namelist_val);
1442 fail_pts_GroupMemberListDone:
1445 pthread_mutex_unlock(&iter->mutex);
1455 * pts_GroupMemberRemove - remove a member from a group.
1459 * IN cellHandle - a previously opened cellHandle that corresponds
1460 * to the cell where the group exists.
1462 * IN userName - the user to remove.
1464 * IN groupName - the group to modify
1468 * No locks are held by this function
1472 * Returns != 0 upon successful completion.
1477 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1478 const char *groupName, afs_status_p st)
1481 afs_status_t tst = 0;
1482 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1485 ids.idlist_val = NULL;
1488 * Validate arguments
1491 if (!IsValidCellHandle(c_handle, &tst)) {
1492 goto fail_pts_GroupMemberRemove;
1495 if ((userName == NULL) || (*userName == 0)) {
1496 tst = ADMPTSUSERNAMENULL;
1497 goto fail_pts_GroupMemberRemove;
1500 if ((groupName == NULL) || (*groupName == 0)) {
1501 tst = ADMPTSGROUPNAMENULL;
1502 goto fail_pts_GroupMemberRemove;
1505 if (!TranslateTwoNames
1506 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1507 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1508 goto fail_pts_GroupMemberRemove;
1516 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1520 goto fail_pts_GroupMemberRemove;
1524 fail_pts_GroupMemberRemove:
1526 if (ids.idlist_val != 0) {
1527 free(ids.idlist_val);
1537 * pts_GroupRename - change the name of a group
1541 * IN cellHandle - a previously opened cellHandle that corresponds
1542 * to the cell where the group exists.
1544 * IN oldName - the current group name
1546 * IN newName - the new group name
1550 * No locks are held by this function
1554 * Returns != 0 upon successful completion.
1559 pts_GroupRename(const void *cellHandle, const char *oldName,
1560 char *newName, afs_status_p st)
1563 afs_status_t tst = 0;
1564 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1565 afs_int32 groupId = 0;
1568 * Validate arguments
1571 if (!IsValidCellHandle(c_handle, &tst)) {
1572 goto fail_pts_GroupRename;
1575 if ((newName == NULL) || (*newName == 0)) {
1576 tst = ADMPTSNEWNAMENULL;
1577 goto fail_pts_GroupRename;
1580 if ((oldName == NULL) || (*oldName == 0)) {
1581 tst = ADMPTSOLDNAMENULL;
1582 goto fail_pts_GroupRename;
1586 * Translate the group name into an id.
1589 if (!TranslateOneName
1590 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1591 goto fail_pts_GroupRename;
1598 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1601 goto fail_pts_GroupRename;
1605 fail_pts_GroupRename:
1614 * SetGroupAccess - translate our Access notation to pts flags.
1618 * IN rights - the permissions.
1620 * OUT flags - a pointer to an afs_int32 structure that
1621 * contains the flags to pass to pts.
1625 * No locks are held by this function
1629 * Returns != 0 upon successful completion.
1634 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1638 afs_status_t tst = 0;
1642 if (rights->listDelete == PTS_GROUP_ACCESS) {
1644 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1645 tst = ADMPTSINVALIDGROUPDELETEPERM;
1646 goto fail_SetGroupAccess;
1649 if (rights->listAdd == PTS_GROUP_ACCESS) {
1651 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1655 if (rights->listMembership == PTS_GROUP_ACCESS) {
1657 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1661 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1663 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1664 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1665 goto fail_SetGroupAccess;
1668 if (rights->listStatus == PTS_GROUP_ACCESS) {
1670 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1675 fail_SetGroupAccess:
1684 * pts_GroupModify - change the contents of a group entry.
1688 * IN cellHandle - a previously opened cellHandle that corresponds
1689 * to the cell where the group exists.
1691 * IN groupName - the group to change
1693 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1694 * contains the new information for the group.
1698 * No locks are held by this function
1702 * Returns != 0 upon successful completion.
1707 pts_GroupModify(const void *cellHandle, const char *groupName,
1708 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1711 afs_status_t tst = 0;
1712 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1713 afs_int32 groupId = 0;
1714 afs_int32 flags = 0;
1717 * Validate arguments
1720 if (!IsValidCellHandle(c_handle, &tst)) {
1721 goto fail_pts_GroupModify;
1724 if ((groupName == NULL) || (*groupName == 0)) {
1725 tst = ADMPTSGROUPNAMENULL;
1726 goto fail_pts_GroupModify;
1730 if (newEntryP == NULL) {
1731 tst = ADMPTSNEWENTRYPNULL;
1732 goto fail_pts_GroupModify;
1736 * Translate the group name into an id.
1739 if (!TranslateOneName
1740 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1741 goto fail_pts_GroupModify;
1745 * Set the flags argument
1748 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1749 goto fail_pts_GroupModify;
1757 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1761 goto fail_pts_GroupModify;
1765 fail_pts_GroupModify:
1774 * pts_UserCreate - create a new user.
1778 * IN cellHandle - a previously opened cellHandle that corresponds
1779 * to the cell where the group exists.
1781 * IN newUser - the name of the new user.
1783 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1784 * id assigned by pts.
1788 * No locks are held by this function
1792 * Returns != 0 upon successful completion.
1797 pts_UserCreate(const void *cellHandle, char *userName, int *newUserId,
1801 afs_status_t tst = 0;
1802 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1805 * Validate arguments
1808 if (!IsValidCellHandle(c_handle, &tst)) {
1809 goto fail_pts_UserCreate;
1812 if ((userName == NULL) || (*userName == 0)) {
1813 tst = ADMPTSUSERNAMENULL;
1814 goto fail_pts_UserCreate;
1817 if (newUserId == NULL) {
1818 tst = ADMPTSNEWUSERIDNULL;
1819 goto fail_pts_UserCreate;
1823 * We make a different rpc based upon the input to this function
1826 if (*newUserId != 0) {
1828 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1832 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1837 goto fail_pts_UserCreate;
1841 fail_pts_UserCreate:
1850 * pts_UserDelete - delete a user.
1854 * IN cellHandle - a previously opened cellHandle that corresponds
1855 * to the cell where the group exists.
1857 * IN user - the name of the user to delete.
1861 * No locks are held by this function
1865 * Returns != 0 upon successful completion.
1870 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1872 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1873 ADMPTSUSERNAMETOOLONG, st);
1878 * GetUserAccess - a small convenience function for setting
1883 * IN access - a pointer to a pts_userAccess_t to be set with the
1884 * correct permission.
1886 * IN flag - the current permission flag used to derive the permission.
1890 * No locks are obtained or released by this function
1894 * Since this function cannot fail, it returns void.
1899 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1902 *access = PTS_USER_OWNER_ACCESS;
1904 *access = PTS_USER_ANYUSER_ACCESS;
1909 * IsAdministrator - determine if a user is an administrator.
1913 * IN cellHandle - a previously opened cellHandle that corresponds
1914 * to the cell where the group exists.
1916 * IN userEntry - the user data for the user in question.
1918 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1922 * No locks are held by this function
1926 * Returns != 0 upon successful completion.
1931 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1932 int *admin, afs_status_p st)
1935 afs_status_t tst = 0;
1936 afs_int32 adminId = 0;
1937 afs_int32 isAdmin = 0;
1941 if (userId == SYSADMINID) {
1944 if (!TranslateOneName
1945 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1947 goto fail_IsAdministrator;
1950 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1953 goto fail_IsAdministrator;
1961 fail_IsAdministrator:
1970 * pts_UserGet - retrieve information about a particular user.
1974 * IN cellHandle - a previously opened cellHandle that corresponds
1975 * to the cell where the group exists.
1977 * IN userName - the name of the user to retrieve.
1979 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1984 * No locks are held by this function
1988 * Returns != 0 upon successful completion.
1993 pts_UserGet(const void *cellHandle, const char *userName,
1994 pts_UserEntry_p userP, afs_status_p st)
1997 afs_status_t tst = 0;
1998 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1999 struct prcheckentry userEntry;
2000 afs_int32 userId = 0;
2004 afs_int32 ptsids[2];
2010 * Validate arguments
2013 if (!IsValidCellHandle(c_handle, &tst)) {
2014 goto fail_pts_UserGet;
2017 if ((userName == NULL) || (*userName == 0)) {
2018 tst = ADMPTSUSERNAMENULL;
2019 goto fail_pts_UserGet;
2022 if (userP == NULL) {
2023 tst = ADMPTSUSERPNULL;
2024 goto fail_pts_UserGet;
2028 * Translate the group name into an id.
2031 if (!TranslateOneName
2032 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2033 goto fail_pts_UserGet;
2037 * Retrieve information about the group
2040 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2043 goto fail_pts_UserGet;
2046 userP->groupMembershipCount = userEntry.count;
2047 userP->groupCreationQuota = userEntry.ngroups;
2049 * The administrator id, or any member of "system:administrators"
2050 * has unlimited group creation quota. Denote this by setting
2054 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2055 goto fail_pts_UserGet;
2059 userP->groupCreationQuota = -1;
2062 userP->nameUid = userEntry.id;
2063 userP->ownerUid = userEntry.owner;
2064 userP->creatorUid = userEntry.creator;
2065 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2066 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2069 * The permission bits are described in the GroupGet function above.
2070 * The user entry only uses 3 of the 5 permissions, so we shift
2071 * past the unused entries.
2074 flags = userEntry.flags;
2078 GetUserAccess(&userP->listMembership, twobit);
2083 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2085 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2091 GetUserAccess(&userP->listStatus, twobit);
2094 * Make another rpc and translate the owner and creator ids into
2095 * character strings.
2099 ids.idlist_val = ptsids;
2100 ptsids[0] = userEntry.owner;
2101 ptsids[1] = userEntry.creator;
2102 names.namelist_len = 0;
2103 names.namelist_val = 0;
2106 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2107 goto fail_pts_UserGet;
2110 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2111 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2112 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2113 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2114 free(names.namelist_val);
2126 * pts_UserRename - rename a user.
2130 * IN cellHandle - a previously opened cellHandle that corresponds
2131 * to the cell where the group exists.
2133 * IN oldName - the name of the user to rename.
2135 * IN newName - the new user name.
2139 * No locks are held by this function
2143 * Returns != 0 upon successful completion.
2148 pts_UserRename(const void *cellHandle, const char *oldName,
2149 char *newName, afs_status_p st)
2152 afs_status_t tst = 0;
2153 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2154 afs_int32 userId = 0;
2157 * Validate arguments
2160 if (!IsValidCellHandle(c_handle, &tst)) {
2161 goto fail_pts_UserRename;
2164 if ((oldName == NULL) || (*oldName == 0)) {
2165 tst = ADMPTSOLDNAMENULL;
2166 goto fail_pts_UserRename;
2169 if ((newName == NULL) || (*newName == 0)) {
2170 tst = ADMPTSNEWNAMENULL;
2171 goto fail_pts_UserRename;
2175 * Translate the user name into an id.
2178 if (!TranslateOneName
2179 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2180 goto fail_pts_UserRename;
2187 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2190 goto fail_pts_UserRename;
2194 fail_pts_UserRename:
2203 * SetUserAccess - translate our Access notation to pts flags.
2207 * IN userP - the user structure that contains the new permissions.
2209 * OUT flags - a pointer to an afs_int32 structure that
2210 * contains the flags to pass to pts.
2214 * No locks are held by this function
2218 * Returns != 0 upon successful completion.
2223 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2227 afs_status_t tst = 0;
2231 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2235 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2239 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2252 * pts_UserModify - update a user entry.
2256 * IN cellHandle - a previously opened cellHandle that corresponds
2257 * to the cell where the group exists.
2259 * IN userName - the name of the user to update.
2261 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2262 * new information for user.
2266 * No locks are held by this function
2270 * Returns != 0 upon successful completion.
2275 pts_UserModify(const void *cellHandle, const char *userName,
2276 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2279 afs_status_t tst = 0;
2280 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2281 afs_int32 userId = 0;
2282 afs_int32 newQuota = 0;
2284 afs_int32 flags = 0;
2287 * Validate arguments
2290 if (!IsValidCellHandle(c_handle, &tst)) {
2291 goto fail_pts_UserModify;
2294 if ((userName == NULL) || (*userName == 0)) {
2295 tst = ADMPTSUSERNAMENULL;
2296 goto fail_pts_UserModify;
2299 if (newEntryP == NULL) {
2300 tst = ADMPTSNEWENTRYPNULL;
2301 goto fail_pts_UserModify;
2305 * Translate the user name into an id.
2308 if (!TranslateOneName
2309 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2310 goto fail_pts_UserModify;
2314 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2315 mask |= PR_SF_NGROUPS;
2316 newQuota = newEntryP->groupCreationQuota;
2319 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2320 mask |= PR_SF_ALLBITS;
2321 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2322 goto fail_pts_UserModify;
2331 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2335 goto fail_pts_UserModify;
2339 fail_pts_UserModify:
2348 * pts_UserMaxGet - get the maximum in use user id.
2352 * IN cellHandle - a previously opened cellHandle that corresponds
2353 * to the cell where the group exists.
2355 * OUT maxUserId - upon successful completion contains the max in use id.
2359 * No locks are held by this function
2363 * Returns != 0 upon successful completion.
2368 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2371 afs_status_t tst = 0;
2372 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2373 afs_int32 maxGroupId = 0;
2376 * Validate arguments
2379 if (!IsValidCellHandle(c_handle, &tst)) {
2380 goto fail_pts_UserMaxGet;
2383 if (maxUserId == NULL) {
2384 tst = ADMPTSMAXUSERIDNULL;
2385 goto fail_pts_UserMaxGet;
2388 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2391 goto fail_pts_UserMaxGet;
2395 fail_pts_UserMaxGet:
2404 * pts_UserMaxSet - set the maximum user id.
2408 * IN cellHandle - a previously opened cellHandle that corresponds
2409 * to the cell where the group exists.
2411 * IN maxUserId - the new max user id.
2415 * No locks are held by this function
2419 * Returns != 0 upon successful completion.
2424 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2427 afs_status_t tst = 0;
2428 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2431 * Validate arguments
2434 if (!IsValidCellHandle(c_handle, &tst)) {
2435 goto fail_pts_UserMaxSet;
2438 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2441 goto fail_pts_UserMaxSet;
2445 fail_pts_UserMaxSet:
2454 * pts_UserMemberListBegin - begin iterating over the list of groups
2455 * a particular user belongs to.
2459 * IN cellHandle - a previously opened cellHandle that corresponds
2460 * to the cell where the group exists.
2462 * IN groupName - the group whose members will be returned.
2464 * OUT iterationIdP - upon successful completion contains a iterator that
2465 * can be passed to pts_GroupMemberListNext.
2469 * No locks are obtained or released by this function
2473 * Returns != 0 upon successful completion.
2478 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2479 void **iterationIdP, afs_status_p st)
2481 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2482 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2487 * pts_UserMemberListNext - get the next group a user belongs to
2491 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2493 * OUT userName - upon successful completion contains the next group a user
2498 * The iterator mutex is held during the retrieval of the next member.
2502 * Returns != 0 upon successful completion.
2507 pts_UserMemberListNext(const void *iterationId, char *userName,
2510 return pts_GroupMemberListNext(iterationId, userName, st);
2514 * pts_UserMemberListDone - finish using a user list iterator
2518 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2522 * The iterator is locked and then destroyed
2526 * Returns != 0 upon successful completion.
2530 * It is the user's responsibility to make sure pts_UserMemberListDone
2531 * is called only once for each iterator.
2535 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2537 return pts_GroupMemberListDone(iterationId, st);
2540 typedef struct owned_group_list {
2541 namelist owned_names; /* the list of character names owned by this id */
2542 prlist owned_ids; /* the list of pts ids owned by this id */
2543 afs_int32 index; /* the index into owned_names for the next group */
2544 afs_int32 owner; /* the pts id of the owner */
2545 afs_int32 more; /* the last parameter to PR_ListOwned */
2546 int finished_retrieving; /* set when we've processed the last owned_names */
2547 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2548 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2549 } owned_group_list_t, *owned_group_list_p;
2552 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2555 afs_status_t tst = 0;
2556 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2558 if (list->owned_names.namelist_val != NULL) {
2559 free(list->owned_names.namelist_val);
2562 if (list->owned_ids.prlist_val != NULL) {
2563 free(list->owned_ids.prlist_val);
2574 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2575 int *last_item_contains_data, afs_status_p st)
2578 afs_status_t tst = 0;
2579 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2582 * We really don't make an rpc for every entry we return here
2583 * since the pts interface allows several members to be returned
2584 * with one rpc, but we fake it to make the iterator happy.
2588 * Check to see if we are done retrieving data
2591 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2593 *last_item_contains_data = 0;
2594 goto fail_GetOwnedGroupRPC;
2598 * Check to see if we really need to make an rpc
2601 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2603 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2604 &list->owned_ids, &list->more);
2606 goto fail_GetOwnedGroupRPC;
2609 if (!TranslatePTSIds
2610 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2612 goto fail_GetOwnedGroupRPC;
2616 if (list->owned_names.namelist_val == NULL) {
2618 *last_item_contains_data = 0;
2619 goto fail_GetOwnedGroupRPC;
2624 * We can retrieve the next group from data we already received
2627 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2631 * Check to see if there is more data to be retrieved
2632 * We need to free up the previously retrieved data here
2633 * and then check to see if the last rpc indicated that there
2634 * were more items to retrieve.
2637 if (list->index >= list->owned_names.namelist_len) {
2638 list->owned_names.namelist_len = 0;
2639 free(list->owned_names.namelist_val);
2640 list->owned_names.namelist_val = 0;
2642 list->owned_ids.prlist_len = 0;
2643 free(list->owned_ids.prlist_val);
2644 list->owned_ids.prlist_val = 0;
2647 list->finished_retrieving = 1;
2652 fail_GetOwnedGroupRPC:
2661 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2665 afs_status_t tst = 0;
2666 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2668 strcpy((char *)dest, list->group[slot]);
2679 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2680 * a particular user owns.
2684 * IN cellHandle - a previously opened cellHandle that corresponds
2685 * to the cell where the group exists.
2687 * IN ownerName - the owner of the groups of interest.
2689 * OUT iterationIdP - upon successful completion contains a iterator that
2690 * can be passed to pts_OwnedGroupListNext.
2694 * No locks are held by this function
2698 * Returns != 0 upon successful completion.
2703 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2704 void **iterationIdP, afs_status_p st)
2707 afs_status_t tst = 0;
2708 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2709 afs_admin_iterator_p iter = malloc(sizeof(afs_admin_iterator_t));
2710 owned_group_list_p list = malloc(sizeof(owned_group_list_t));
2713 * Validate arguments
2716 if (!IsValidCellHandle(c_handle, &tst)) {
2717 goto fail_pts_OwnedGroupListBegin;
2720 if ((userName == NULL) || (*userName == 0)) {
2721 tst = ADMPTSUSERNAMENULL;
2722 goto fail_pts_OwnedGroupListBegin;
2725 if (iterationIdP == NULL) {
2726 tst = ADMITERATORNULL;
2727 goto fail_pts_OwnedGroupListBegin;
2730 if ((iter == NULL) || (list == NULL)) {
2732 goto fail_pts_OwnedGroupListBegin;
2736 * Initialize the iterator specific data
2740 list->finished_retrieving = 0;
2741 list->c_handle = c_handle;
2742 list->owned_names.namelist_len = 0;
2743 list->owned_names.namelist_val = 0;
2744 list->owned_ids.prlist_len = 0;
2745 list->owned_ids.prlist_val = 0;
2748 * Translate the user name into an id.
2751 if (!TranslateOneName
2752 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2753 goto fail_pts_OwnedGroupListBegin;
2757 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2758 DeleteOwnedGroupSpecificData, &tst)) {
2759 *iterationIdP = (void *)iter;
2763 fail_pts_OwnedGroupListBegin:
2781 * pts_OwnedGroupListNext - get the next group a user owns.
2785 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2787 * OUT groupName - upon successful completion contains the next group a user
2792 * The iterator mutex is held during the retrieval of the next member.
2796 * Returns != 0 upon successful completion.
2801 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2805 afs_status_t tst = 0;
2806 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2809 * Validate arguments
2812 if (iterationId == NULL) {
2813 tst = ADMITERATORNULL;
2814 goto fail_pts_OwnedGroupListNext;
2817 if (groupName == NULL) {
2818 tst = ADMPTSGROUPNAMENULL;
2819 goto fail_pts_OwnedGroupListNext;
2822 rc = IteratorNext(iter, (void *)groupName, &tst);
2824 fail_pts_OwnedGroupListNext:
2833 * pts_OwnedGroupListDone - finish using a group list iterator
2837 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2841 * The iterator is locked and then destroyed
2845 * Returns != 0 upon successful completion.
2849 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2850 * is called only once for each iterator.
2854 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2857 afs_status_t tst = 0;
2858 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2861 * Validate arguments
2864 if (iterationId == NULL) {
2865 tst = ADMITERATORNULL;
2866 goto fail_pts_OwnedGroupListDone;
2869 rc = IteratorDone(iter, &tst);
2871 fail_pts_OwnedGroupListDone:
2879 typedef struct pts_list {
2880 prlistentries *names; /* the current list of pts names in this cell */
2881 prlistentries *currName; /* the current pts entry */
2882 afs_int32 index; /* the index into names for the next pts entry */
2883 afs_int32 nextstartindex; /* the next start index for the RPC */
2884 afs_int32 nentries; /* the number of entries in names */
2885 afs_int32 flag; /* the type of the list */
2886 int finished_retrieving; /* set when we've processed the last owned_names */
2887 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2888 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2889 } pts_list_t, *pts_list_p;
2892 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2895 afs_status_t tst = 0;
2896 pts_list_p list = (pts_list_p) rpc_specific;
2911 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2912 int *last_item_contains_data, afs_status_p st)
2915 afs_status_t tst = 0;
2916 pts_list_p list = (pts_list_p) rpc_specific;
2919 * We really don't make an rpc for every entry we return here
2920 * since the pts interface allows several members to be returned
2921 * with one rpc, but we fake it to make the iterator happy.
2925 * Check to see if we are done retrieving data
2928 if (list->finished_retrieving) {
2930 *last_item_contains_data = 0;
2931 goto fail_GetPTSRPC;
2935 * Check to see if we really need to make an rpc
2938 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2939 afs_int32 start = list->nextstartindex;
2940 prentries bulkentries;
2941 list->nextstartindex = -1;
2942 bulkentries.prentries_val = 0;
2943 bulkentries.prentries_len = 0;
2946 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2947 start, &bulkentries, &(list->nextstartindex));
2950 goto fail_GetPTSRPC;
2953 list->nentries = bulkentries.prentries_len;
2954 list->names = bulkentries.prentries_val;
2957 list->currName = list->names;
2962 * We can retrieve the next entry from data we already received
2965 strcpy(list->entries[slot], list->currName->name);
2971 * Check to see if there is more data to be retrieved
2972 * We need to free up the previously retrieved data here
2973 * and then check to see if the last rpc indicated that there
2974 * were more items to retrieve.
2977 if (list->index >= list->nentries) {
2983 if (list->nextstartindex == -1) {
2984 list->finished_retrieving = 1;
2999 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3002 afs_status_t tst = 0;
3003 pts_list_p list = (pts_list_p) rpc_specific;
3005 strcpy((char *)dest, list->entries[slot]);
3016 * pts_UserListBegin - begin iterating over the list of users
3017 * in a particular cell
3021 * IN cellHandle - a previously opened cellHandle that corresponds
3022 * to the cell where the users exist.
3024 * OUT iterationIdP - upon successful completion contains a iterator that
3025 * can be passed to pts_UserListNext.
3029 * No locks are held by this function
3033 * Returns != 0 upon successful completion.
3038 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3042 afs_status_t tst = 0;
3043 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3044 afs_admin_iterator_p iter = malloc(sizeof(afs_admin_iterator_t));
3045 pts_list_p list = 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 = malloc(sizeof(afs_admin_iterator_t));
3228 pts_list_p list = malloc(sizeof(pts_list_t));
3231 * Validate arguments
3234 if (!IsValidCellHandle(c_handle, &tst)) {
3235 goto fail_pts_GroupListBegin;
3238 if (iterationIdP == NULL) {
3239 tst = ADMITERATORNULL;
3240 goto fail_pts_GroupListBegin;
3243 if ((iter == NULL) || (list == NULL)) {
3245 goto fail_pts_GroupListBegin;
3249 * Initialize the iterator specific data
3253 list->finished_retrieving = 0;
3254 list->c_handle = c_handle;
3256 list->nextstartindex = 0;
3258 list->flag = PRGROUPS;
3261 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3262 DeletePTSSpecificData, &tst)) {
3263 *iterationIdP = (void *)iter;
3267 fail_pts_GroupListBegin:
3285 * pts_UserListNext - get the next group in a cell.
3289 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3291 * OUT groupName - upon successful completion contains the next group
3295 * The iterator mutex is held during the retrieval of the next member.
3299 * Returns != 0 upon successful completion.
3304 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3307 afs_status_t tst = 0;
3308 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3311 * Validate arguments
3314 if (iterationId == NULL) {
3315 tst = ADMITERATORNULL;
3316 goto fail_pts_GroupListNext;
3319 if (groupName == NULL) {
3320 tst = ADMPTSGROUPNAMENULL;
3321 goto fail_pts_GroupListNext;
3324 rc = IteratorNext(iter, (void *)groupName, &tst);
3326 fail_pts_GroupListNext:
3335 * pts_GroupListDone - finish using a group list iterator
3339 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3343 * The iterator is locked and then destroyed
3347 * Returns != 0 upon successful completion.
3351 * It is the user's responsibility to make sure pts_GroupListDone
3352 * is called only once for each iterator.
3356 pts_GroupListDone(const void *iterationId, afs_status_p st)
3359 afs_status_t tst = 0;
3360 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3363 * Validate arguments
3366 if (iterationId == NULL) {
3367 tst = ADMITERATORNULL;
3368 goto fail_pts_GroupListDone;
3371 rc = IteratorDone(iter, &tst);
3373 fail_pts_GroupListDone: