2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
27 #include "afs_ptsAdmin.h"
28 #include "../adminutil/afs_AdminInternal.h"
29 #include <afs/afs_AdminErrors.h>
30 #include <afs/afs_utilAdmin.h>
31 #include <afs/ptint.h>
32 #include <afs/ptserver.h>
35 * IsValidCellHandle - validate the cell handle for making pts
40 * IN cellHandle - a previously opened cellHandle that is to be validated.
44 * No locks are obtained or released by this function
48 * Returns != 0 upon successful completion.
53 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
58 if (!CellHandleIsValid((void *)c_handle, &tst)) {
59 goto fail_IsValidCellHandle;
62 if (c_handle->pts_valid == 0) {
63 tst = ADMCLIENTCELLPTSINVALID;
64 goto fail_IsValidCellHandle;
67 if (c_handle->pts == NULL) {
68 tst = ADMCLIENTCELLPTSNULL;
69 goto fail_IsValidCellHandle;
74 fail_IsValidCellHandle:
84 * TranslatePTSNames - translate character representations of pts names
85 * into their numeric equivalent.
89 * IN cellHandle - a previously opened cellHandle that corresponds
90 * to the cell where the id's exist.
92 * IN names - the list of names to be translated.
94 * OUT ids - the list of translated names
98 * No locks are obtained or released by this function
102 * Returns != 0 upon successful completion.
107 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
108 idlist * ids, afs_status_p st)
111 afs_status_t tst = 0;
116 * Lowercase the names to translate
119 for (i = 0; i < names->namelist_len; i++) {
120 p = names->namelist_val[i];
127 tst = ubik_Call(PR_NameToID, cellHandle->pts, 0, names, ids);
130 goto fail_TranslatePTSNames;
135 * Check to see if the lookup failed
138 for (i = 0; i < ids->idlist_len; i++) {
139 if (ids->idlist_val[i] == ANONYMOUSID) {
140 tst = ADMPTSFAILEDNAMETRANSLATE;
141 goto fail_TranslatePTSNames;
146 fail_TranslatePTSNames:
155 * TranslateTwoNames - translate two pts names to their pts ids.
159 * IN cellHandle - a previously opened cellHandle that corresponds
160 * to the cell where the group exists.
162 * IN id1 - one id to be translated
164 * IN error1 - the error status to be returned in the event that id1 is
167 * IN id2 - one id to be translated
169 * IN error2 - the error status to be returned in the event that id2 is
173 * OUT idlist - the list of pts id's
177 * No locks are obtained or released by this function
181 * Returns != 0 upon successful completion.
186 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
187 afs_status_t error1, const char *id2, afs_status_t error2,
188 idlist * ids, afs_status_p st)
191 afs_status_t tst = 0;
193 char tmp_array[2 * PTS_MAX_NAME_LEN];
196 * Copy the group and user names in order to translate them
199 names.namelist_len = 2;
200 names.namelist_val = (prname *) & tmp_array[0];
202 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
203 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
208 * Check that user and group aren't too long
209 * This is a cheaper check than calling strlen
212 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
214 goto fail_TranslateTwoNames;
217 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
219 goto fail_TranslateTwoNames;
223 * Translate user and group into pts ID's
226 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
227 goto fail_TranslateTwoNames;
232 fail_TranslateTwoNames:
241 * TranslateOneName - translate a pts name to its pts id.
245 * IN cellHandle - a previously opened cellHandle that corresponds
246 * to the cell where the group exists.
248 * IN userName - the user to be translated.
250 * OUT idlist - the user pts id.
254 * No locks are obtained or released by this function
258 * Returns != 0 upon successful completion.
263 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
264 afs_status_t tooLongError, afs_int32 * ptsId,
268 afs_status_t tst = 0;
270 char tmp_array[PTS_MAX_NAME_LEN];
274 * Copy the name in order to translate it
277 names[0].namelist_len = 1;
278 names[0].namelist_val = (prname *) & tmp_array[0];
280 strncpy(names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
285 * Check that user isn't too long
286 * This is a cheaper check than calling strlen
289 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
291 goto fail_TranslateOneName;
295 * Translate user into pts ID
298 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
299 goto fail_TranslateOneName;
301 if (ids.idlist_val != NULL) {
302 *ptsId = *ids.idlist_val;
303 free(ids.idlist_val);
309 fail_TranslateOneName:
318 * TranslatePTSIds - translate numeric representations of pts names
319 * into their character equivalent.
323 * IN cellHandle - a previously opened cellHandle that corresponds
324 * to the cell where the id's exist.
326 * IN ids - the list of ids to be translated.
328 * OUT names - the list of translated names
332 * No locks are obtained or released by this function
336 * Returns != 0 upon successful completion.
341 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
342 idlist * ids, afs_status_p st)
345 afs_status_t tst = 0;
347 tst = ubik_Call(PR_IDToName, cellHandle->pts, 0, ids, names);
350 goto fail_TranslatePTSIds;
354 fail_TranslatePTSIds:
363 * pts_GroupMemberAdd - add one member to a pts group
367 * IN cellHandle - a previously opened cellHandle that corresponds
368 * to the cell where the group exists.
370 * IN userName - the name to be added to the group.
372 * IN groupName - the group to be modified.
376 * No locks are obtained or released by this function
380 * Returns != 0 upon successful completion.
385 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
386 const char *groupName, afs_status_p st)
389 afs_status_t tst = 0;
390 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
397 if (!IsValidCellHandle(c_handle, &tst)) {
398 goto fail_pts_GroupMemberAdd;
401 if ((userName == NULL) || (*userName == 0)) {
402 tst = ADMPTSUSERNAMENULL;
403 goto fail_pts_GroupMemberAdd;
406 if ((groupName == NULL) || (*groupName == 0)) {
407 tst = ADMPTSGROUPNAMENULL;
408 goto fail_pts_GroupMemberAdd;
411 if (!TranslateTwoNames
412 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
413 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
414 goto fail_pts_GroupMemberAdd;
422 ubik_Call(PR_AddToGroup, c_handle->pts, 0, ids.idlist_val[0],
426 goto fail_pts_GroupMemberAdd;
430 fail_pts_GroupMemberAdd:
432 if (ids.idlist_val != 0) {
433 free(ids.idlist_val);
443 * pts_GroupOwnerChange - change the owner of a group
447 * IN cellHandle - a previously opened cellHandle that corresponds
448 * to the cell where the group exists.
450 * IN targetGroup - the group to be modified.
452 * IN userName - the new owner of the group.
456 * No locks are obtained or released by this function
460 * Returns != 0 upon successful completion.
465 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
466 const char *newOwner, afs_status_p st)
469 afs_status_t tst = 0;
470 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
477 if (!IsValidCellHandle(c_handle, &tst)) {
478 goto fail_pts_GroupOwnerChange;
481 if ((newOwner == NULL) || (*newOwner == 0)) {
482 tst = ADMPTSNEWOWNERNULL;
483 goto fail_pts_GroupOwnerChange;
486 if ((targetGroup == NULL) || (*targetGroup == 0)) {
487 tst = ADMPTSTARGETGROUPNULL;
488 goto fail_pts_GroupOwnerChange;
491 if (!TranslateTwoNames
492 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
493 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
494 goto fail_pts_GroupOwnerChange;
502 ubik_Call(PR_ChangeEntry, c_handle->pts, 0, ids.idlist_val[1], "",
503 ids.idlist_val[0], 0);
506 goto fail_pts_GroupOwnerChange;
510 fail_pts_GroupOwnerChange:
512 if (ids.idlist_val != 0) {
513 free(ids.idlist_val);
523 * pts_GroupCreate - create a new group
527 * IN cellHandle - a previously opened cellHandle that corresponds
528 * to the cell where the group exists.
530 * IN newGroup - the group to be created.
532 * IN newOwner - the owner of the group. Pass NULL if the current user
533 * is to be the new owner, or the character string of the owner otherwise.
535 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
536 * generate a value, != 0 to assign a value on your own. The group id
537 * that is used to create the group is copied into this parameter in the
538 * event you pass in 0.
542 * No locks are obtained or released by this function
546 * Returns != 0 upon successful completion.
551 pts_GroupCreate(const void *cellHandle, const char *newGroup,
552 const char *newOwner, int *newGroupId, afs_status_p st)
555 afs_status_t tst = 0;
556 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
557 afs_int32 newOwnerId = 0;
563 if (!IsValidCellHandle(c_handle, &tst)) {
564 goto fail_pts_GroupCreate;
567 if ((newGroup == NULL) || (*newGroup == 0)) {
568 tst = ADMPTSNEWGROUPNULL;
569 goto fail_pts_GroupCreate;
572 if (newGroupId == NULL) {
573 tst = ADMPTSNEWGROUPIDNULL;
574 goto fail_pts_GroupCreate;
577 if (*newGroupId > 0) {
578 tst = ADMPTSNEWGROUPIDPOSITIVE;
579 goto fail_pts_GroupCreate;
583 * If a newOwner was specified, validate that it exists
586 if (newOwner != NULL) {
587 if (!TranslateOneName
588 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
589 goto fail_pts_GroupCreate;
594 * We make a different rpc based upon the input to this function
597 if (*newGroupId != 0) {
599 ubik_Call(PR_INewEntry, c_handle->pts, 0, newGroup, *newGroupId,
603 ubik_Call(PR_NewEntry, c_handle->pts, 0, newGroup, PRGRP,
604 newOwnerId, newGroupId);
608 goto fail_pts_GroupCreate;
612 fail_pts_GroupCreate:
621 * GetGroupAccess - a small convenience function for setting
626 * IN access - a pointer to a pts_groupAccess_t to be set with the
627 * correct permission.
629 * IN flag - the current permission flag used to derive the permission.
633 * No locks are obtained or released by this function
637 * Since this function cannot fail, it returns void.
642 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
645 *access = PTS_GROUP_OWNER_ACCESS;
647 *access = PTS_GROUP_OWNER_ACCESS;
648 } else if (flag == 1) {
649 *access = PTS_GROUP_ACCESS;
650 } else if (flag == 2) {
651 *access = PTS_GROUP_ANYUSER_ACCESS;
657 * pts_GroupGet - retrieve information about a particular group.
661 * IN cellHandle - a previously opened cellHandle that corresponds
662 * to the cell where the group exists.
664 * IN groupName - the group to retrieve.
666 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
667 * successful completion is filled with information about groupName.
671 * No locks are obtained or released by this function
675 * Returns != 0 upon successful completion.
680 pts_GroupGet(const void *cellHandle, const char *groupName,
681 pts_GroupEntry_p groupP, afs_status_p st)
684 afs_status_t tst = 0;
685 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
686 afs_int32 groupId = 0;
689 struct prcheckentry groupEntry;
698 if (!IsValidCellHandle(c_handle, &tst)) {
699 goto fail_pts_GroupGet;
702 if ((groupName == NULL) || (*groupName == 0)) {
703 tst = ADMPTSGROUPNAMENULL;
704 goto fail_pts_GroupGet;
707 if (groupP == NULL) {
708 tst = ADMPTSGROUPPNULL;
709 goto fail_pts_GroupGet;
713 * Translate the group name into an id.
716 if (!TranslateOneName
717 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
718 goto fail_pts_GroupGet;
722 * Retrieve information about the group
725 tst = ubik_Call(PR_ListEntry, c_handle->pts, 0, groupId, &groupEntry);
728 goto fail_pts_GroupGet;
731 groupP->membershipCount = groupEntry.count;
732 groupP->nameUid = groupEntry.id;
733 groupP->ownerUid = groupEntry.owner;
734 groupP->creatorUid = groupEntry.creator;
735 strcpy(groupP->name, groupEntry.name);
737 * Set the access rights based upon the value of the flags member
738 * of the groupEntry struct.
740 * To the best of my ability to decypher the pts code, it looks like
741 * the rights are stored in flags as follows:
743 * I number my bits from least significant to most significant starting
747 * if bit 0 == 0 -> r access is denied
748 * if bit 0 == 1 -> r access is granted
751 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
752 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
753 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
754 * if bit 2 == 1 and bit 1 == 1 -> this is an error
756 * membership - bits 3 and 4
757 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
758 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
759 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
760 * if bit 4 == 1 and bit 3 == 1 -> this is an error
763 * if bit 5 == 0 -> O access is denied
764 * if bit 5 == 1 -> O access is granted
766 * status - bits 6 and 7
767 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
768 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
769 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
770 * if bit 7 == 1 and bit 6 == 1 -> this is an error
772 * For cases where the permission doesn't make sense for the
773 * type of entry, or where an error occurs, we ignore it.
774 * This is the behavior of the pts code.
777 flags = groupEntry.flags;
779 groupP->listDelete = PTS_GROUP_ACCESS;
781 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
787 GetGroupAccess(&groupP->listAdd, twobit);
792 GetGroupAccess(&groupP->listMembership, twobit);
797 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
799 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
805 GetGroupAccess(&groupP->listStatus, twobit);
808 * Make another rpc and translate the owner and creator ids into
813 ids.idlist_val = ptsids;
814 ptsids[0] = groupEntry.owner;
815 ptsids[1] = groupEntry.creator;
816 names.namelist_len = 0;
817 names.namelist_val = 0;
820 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
821 goto fail_pts_GroupGet;
824 strcpy(groupP->owner, names.namelist_val[0]);
825 strcpy(groupP->creator, names.namelist_val[1]);
826 free(names.namelist_val);
838 * EntryDelete - delete a pts entry (group or user).
842 * IN cellHandle - a previously opened cellHandle that corresponds
843 * to the cell where the group exists.
845 * IN entryName - the entry to be deleted.
847 * IN error1 - the error status to be returned in the event that entryName is
850 * IN error2 - the error status to be returned in the event that entryName is
855 * No locks are obtained or released by this function
859 * Returns != 0 upon successful completion.
864 EntryDelete(const void *cellHandle, const char *entryName,
865 afs_status_t error1, afs_status_t error2, afs_status_p st)
868 afs_status_t tst = 0;
869 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
870 afs_int32 entryId = 0;
876 if (!IsValidCellHandle(c_handle, &tst)) {
877 goto fail_EntryDelete;
880 if ((entryName == NULL) || (*entryName == 0)) {
882 goto fail_EntryDelete;
886 * Translate the entry name into an id.
889 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
890 goto fail_EntryDelete;
897 tst = ubik_Call(PR_Delete, c_handle->pts, 0, entryId);
900 goto fail_EntryDelete;
914 * pts_GroupDelete - delete a group
918 * IN cellHandle - a previously opened cellHandle that corresponds
919 * to the cell where the group exists.
921 * IN groupName - the group to be deleted.
925 * No locks are obtained or released by this function
929 * Returns != 0 upon successful completion.
934 pts_GroupDelete(const void *cellHandle, const char *groupName,
938 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
939 ADMPTSGROUPNAMETOOLONG, st);
943 * pts_GroupMaxGet - get the maximum in use group id.
947 * IN cellHandle - a previously opened cellHandle that corresponds
948 * to the cell where the group exists.
950 * OUT maxGroupId - upon successful completion contains the maximum
951 * group Id in use at the server.
955 * No locks are obtained or released by this function
959 * Returns != 0 upon successful completion.
964 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
967 afs_status_t tst = 0;
968 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
969 afs_int32 maxUserId = 0;
975 if (!IsValidCellHandle(c_handle, &tst)) {
976 goto fail_pts_GroupMaxGet;
979 if (maxGroupId == NULL) {
980 tst = ADMPTSMAXGROUPIDNULL;
981 goto fail_pts_GroupMaxGet;
984 tst = ubik_Call(PR_ListMax, c_handle->pts, 0, &maxUserId, maxGroupId);
987 goto fail_pts_GroupMaxGet;
991 fail_pts_GroupMaxGet:
1000 * pts_GroupMaxSet - set the maximum in use group id.
1004 * IN cellHandle - a previously opened cellHandle that corresponds
1005 * to the cell where the group exists.
1007 * IN maxGroupId - the new maximum group id.
1011 * No locks are obtained or released by this function
1015 * Returns != 0 upon successful completion.
1020 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1023 afs_status_t tst = 0;
1024 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1027 * Validate arguments
1030 if (!IsValidCellHandle(c_handle, &tst)) {
1031 goto fail_pts_GroupMaxSet;
1034 tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxGroupId, PRGRP);
1037 goto fail_pts_GroupMaxSet;
1041 fail_pts_GroupMaxSet:
1052 * I'm not using the common iterator pattern here since the retrival
1053 * of the member list is actually accomplished in 1 rpc. There's no
1054 * sense in trying to fit this pts specific behavior into the more
1055 * generic model, so instead the Begin functions actually do all the
1056 * rpc work and the next/done functions just manipulate the retrieved
1060 typedef struct pts_group_member_list_iterator {
1063 pthread_mutex_t mutex; /* hold to manipulate this structure */
1068 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1071 * pts_GroupMemberListBegin - begin iterating over the list of members
1072 * of a particular group.
1076 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1080 * No locks are obtained or released by this function
1084 * Returns != 0 upon successful completion.
1089 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1093 afs_status_t tst = 0;
1096 tst = ADMITERATORNULL;
1097 goto fail_IsValidPtsGroupMemberListIterator;
1100 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1101 tst = ADMITERATORBADMAGICNULL;
1102 goto fail_IsValidPtsGroupMemberListIterator;
1105 if (iter->is_valid == 0) {
1106 tst = ADMITERATORINVALID;
1107 goto fail_IsValidPtsGroupMemberListIterator;
1111 fail_IsValidPtsGroupMemberListIterator:
1120 * MemberListBegin - an internal function which is used to get both
1121 * the list of members in a group and the list of groups a user belongs
1126 * IN cellHandle - a previously opened cellHandle that corresponds
1127 * to the cell where the group exists.
1129 * IN name - the name whose membership will be retrieved.
1131 * OUT iterationIdP - upon successful completion contains a iterator that
1132 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1136 * No locks are obtained or released by this function
1140 * Returns != 0 upon successful completion.
1145 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1146 afs_status_t error2, void **iterationIdP, afs_status_p st)
1149 afs_status_t tst = 0;
1150 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1151 afs_int32 groupId = 0;
1152 afs_int32 exceeded = 0;
1153 pts_group_member_list_iterator_p iter = (pts_group_member_list_iterator_p)
1154 malloc(sizeof(pts_group_member_list_iterator_t));
1155 int iter_allocated = 0;
1156 int ids_allocated = 0;
1157 int names_allocated = 0;
1158 int mutex_inited = 0;
1161 * Validate arguments
1164 if (!IsValidCellHandle(c_handle, &tst)) {
1165 goto fail_MemberListBegin;
1168 if ((name == NULL) || (*name == 0)) {
1169 tst = ADMPTSGROUPNAMENULL;
1170 goto fail_MemberListBegin;
1173 if (iterationIdP == NULL) {
1174 tst = ADMITERATORNULL;
1175 goto fail_MemberListBegin;
1180 goto fail_MemberListBegin;
1186 * Translate the name into an id.
1189 if (!TranslateOneName
1190 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1191 goto fail_MemberListBegin;
1194 if (pthread_mutex_init(&iter->mutex, 0)) {
1196 goto fail_MemberListBegin;
1201 iter->ids.prlist_len = 0;
1202 iter->ids.prlist_val = 0;
1205 ubik_Call(PR_ListElements, c_handle->pts, 0, groupId, &iter->ids,
1209 goto fail_MemberListBegin;
1212 if (exceeded != 0) {
1213 tst = ADMPTSGROUPMEMEXCEEDED;
1214 goto fail_MemberListBegin;
1218 iter->names.namelist_len = 0;
1219 iter->names.namelist_val = 0;
1221 if (!TranslatePTSIds
1222 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1223 goto fail_MemberListBegin;
1226 names_allocated = 1;
1227 iter->begin_magic = BEGIN_MAGIC;
1228 iter->end_magic = END_MAGIC;
1232 *iterationIdP = (void *)iter;
1235 fail_MemberListBegin:
1237 if (ids_allocated) {
1238 free(iter->ids.prlist_val);
1242 if (names_allocated) {
1243 free(iter->names.namelist_val);
1246 pthread_mutex_destroy(&iter->mutex);
1248 if (iter_allocated) {
1260 * pts_GroupMemberListBegin - begin iterating over the list of members
1261 * of a particular group.
1265 * IN cellHandle - a previously opened cellHandle that corresponds
1266 * to the cell where the group exists.
1268 * IN groupName - the group whose members will be returned.
1270 * OUT iterationIdP - upon successful completion contains a iterator that
1271 * can be passed to pts_GroupMemberListNext.
1275 * No locks are obtained or released by this function
1279 * Returns != 0 upon successful completion.
1284 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1285 void **iterationIdP, afs_status_p st)
1287 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1288 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1292 * pts_GroupMemberListNext - get the next member of a group
1296 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1298 * OUT memberName - upon successful completion contains the next member of
1303 * The iterator mutex is held during the retrieval of the next member.
1307 * Returns != 0 upon successful completion.
1312 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1316 afs_status_t tst = 0;
1317 pts_group_member_list_iterator_p iter =
1318 (pts_group_member_list_iterator_p) iterationId;
1319 int mutex_locked = 0;
1322 * Validate arguments
1326 tst = ADMITERATORNULL;
1327 goto fail_pts_GroupMemberListNext;
1330 if (memberName == NULL) {
1331 tst = ADMPTSMEMBERNAMENULL;
1332 goto fail_pts_GroupMemberListNext;
1336 * Lock the mutex and check the validity of the iterator
1339 if (pthread_mutex_lock(&iter->mutex)) {
1341 goto fail_pts_GroupMemberListNext;
1346 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1347 goto fail_pts_GroupMemberListNext;
1351 * Check to see if we've copied out all the data. If we haven't,
1352 * copy another item. If we have, mark the iterator done.
1355 if (iter->index >= iter->names.namelist_len) {
1356 tst = ADMITERATORDONE;
1357 goto fail_pts_GroupMemberListNext;
1359 strcpy(memberName, iter->names.namelist_val[iter->index]);
1364 fail_pts_GroupMemberListNext:
1367 pthread_mutex_unlock(&iter->mutex);
1377 * pts_GroupMemberListDone - finish using a member list iterator
1381 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1385 * The iterator is locked and then destroyed
1389 * Returns != 0 upon successful completion.
1393 * It is the user's responsibility to make sure pts_GroupMemberListDone
1394 * is called only once for each iterator.
1398 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1401 afs_status_t tst = 0;
1402 pts_group_member_list_iterator_p iter =
1403 (pts_group_member_list_iterator_p) iterationId;
1404 int mutex_locked = 0;
1407 * Validate arguments
1411 tst = ADMITERATORNULL;
1412 goto fail_pts_GroupMemberListDone;
1416 * Lock the mutex and check the validity of the iterator
1419 if (pthread_mutex_lock(&iter->mutex)) {
1421 goto fail_pts_GroupMemberListDone;
1426 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1427 goto fail_pts_GroupMemberListDone;
1431 * Free the namelist and the iterator.
1434 pthread_mutex_destroy(&iter->mutex);
1437 free(iter->names.namelist_val);
1441 fail_pts_GroupMemberListDone:
1444 pthread_mutex_unlock(&iter->mutex);
1454 * pts_GroupMemberRemove - remove a member from a group.
1458 * IN cellHandle - a previously opened cellHandle that corresponds
1459 * to the cell where the group exists.
1461 * IN userName - the user to remove.
1463 * IN groupName - the group to modify
1467 * No locks are held by this function
1471 * Returns != 0 upon successful completion.
1476 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1477 const char *groupName, afs_status_p st)
1480 afs_status_t tst = 0;
1481 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
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_Call(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 const 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_Call(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_Call(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, const char *userName, int *newUserId,
1798 afs_status_t tst = 0;
1799 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1800 afs_int32 userId = 0;
1803 * Validate arguments
1806 if (!IsValidCellHandle(c_handle, &tst)) {
1807 goto fail_pts_UserCreate;
1810 if ((userName == NULL) || (*userName == 0)) {
1811 tst = ADMPTSUSERNAMENULL;
1812 goto fail_pts_UserCreate;
1815 if (newUserId == NULL) {
1816 tst = ADMPTSNEWUSERIDNULL;
1817 goto fail_pts_UserCreate;
1821 * We make a different rpc based upon the input to this function
1824 if (*newUserId != 0) {
1826 ubik_Call(PR_INewEntry, c_handle->pts, 0, userName, *newUserId,
1830 ubik_Call(PR_NewEntry, c_handle->pts, 0, userName, 0, 0,
1835 goto fail_pts_UserCreate;
1839 fail_pts_UserCreate:
1848 * pts_UserDelete - delete a user.
1852 * IN cellHandle - a previously opened cellHandle that corresponds
1853 * to the cell where the group exists.
1855 * IN user - the name of the user to delete.
1859 * No locks are held by this function
1863 * Returns != 0 upon successful completion.
1868 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1870 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1871 ADMPTSUSERNAMETOOLONG, st);
1876 * GetUserAccess - a small convenience function for setting
1881 * IN access - a pointer to a pts_userAccess_t to be set with the
1882 * correct permission.
1884 * IN flag - the current permission flag used to derive the permission.
1888 * No locks are obtained or released by this function
1892 * Since this function cannot fail, it returns void.
1897 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1900 *access = PTS_USER_OWNER_ACCESS;
1902 *access = PTS_USER_ANYUSER_ACCESS;
1907 * IsAdministrator - determine if a user is an administrator.
1911 * IN cellHandle - a previously opened cellHandle that corresponds
1912 * to the cell where the group exists.
1914 * IN userEntry - the user data for the user in question.
1916 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1920 * No locks are held by this function
1924 * Returns != 0 upon successful completion.
1929 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1930 int *admin, afs_status_p st)
1933 afs_status_t tst = 0;
1934 afs_int32 adminId = 0;
1935 afs_int32 isAdmin = 0;
1939 if (userId == SYSADMINID) {
1942 if (!TranslateOneName
1943 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1945 goto fail_IsAdministrator;
1948 ubik_Call(PR_IsAMemberOf, c_handle->pts, 0, userId, adminId,
1951 goto fail_IsAdministrator;
1959 fail_IsAdministrator:
1968 * pts_UserGet - retrieve information about a particular user.
1972 * IN cellHandle - a previously opened cellHandle that corresponds
1973 * to the cell where the group exists.
1975 * IN userName - the name of the user to retrieve.
1977 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1982 * No locks are held by this function
1986 * Returns != 0 upon successful completion.
1991 pts_UserGet(const void *cellHandle, const char *userName,
1992 pts_UserEntry_p userP, afs_status_p st)
1995 afs_status_t tst = 0;
1996 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1997 struct prcheckentry userEntry;
1998 afs_int32 userId = 0;
2002 afs_int32 ptsids[2];
2008 * Validate arguments
2011 if (!IsValidCellHandle(c_handle, &tst)) {
2012 goto fail_pts_UserGet;
2015 if ((userName == NULL) || (*userName == 0)) {
2016 tst = ADMPTSUSERNAMENULL;
2017 goto fail_pts_UserGet;
2020 if (userP == NULL) {
2021 tst = ADMPTSUSERPNULL;
2022 goto fail_pts_UserGet;
2026 * Translate the group name into an id.
2029 if (!TranslateOneName
2030 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2031 goto fail_pts_UserGet;
2035 * Retrieve information about the group
2038 tst = ubik_Call(PR_ListEntry, c_handle->pts, 0, userId, &userEntry);
2041 goto fail_pts_UserGet;
2044 userP->groupMembershipCount = userEntry.count;
2045 userP->groupCreationQuota = userEntry.ngroups;
2047 * The administrator id, or any member of "system:administrators"
2048 * has unlimited group creation quota. Denote this by setting
2052 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2053 goto fail_pts_UserGet;
2057 userP->groupCreationQuota = -1;
2060 userP->nameUid = userEntry.id;
2061 userP->ownerUid = userEntry.owner;
2062 userP->creatorUid = userEntry.creator;
2063 strcpy(userP->name, userEntry.name);
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 strcpy(userP->owner, names.namelist_val[0]);
2108 strcpy(userP->creator, names.namelist_val[1]);
2109 free(names.namelist_val);
2121 * pts_UserRename - rename a user.
2125 * IN cellHandle - a previously opened cellHandle that corresponds
2126 * to the cell where the group exists.
2128 * IN oldName - the name of the user to rename.
2130 * IN newName - the new user name.
2134 * No locks are held by this function
2138 * Returns != 0 upon successful completion.
2143 pts_UserRename(const void *cellHandle, const char *oldName,
2144 const char *newName, afs_status_p st)
2147 afs_status_t tst = 0;
2148 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2149 afs_int32 userId = 0;
2152 * Validate arguments
2155 if (!IsValidCellHandle(c_handle, &tst)) {
2156 goto fail_pts_UserRename;
2159 if ((oldName == NULL) || (*oldName == 0)) {
2160 tst = ADMPTSOLDNAMENULL;
2161 goto fail_pts_UserRename;
2164 if ((newName == NULL) || (*newName == 0)) {
2165 tst = ADMPTSNEWNAMENULL;
2166 goto fail_pts_UserRename;
2170 * Translate the user name into an id.
2173 if (!TranslateOneName
2174 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2175 goto fail_pts_UserRename;
2182 tst = ubik_Call(PR_ChangeEntry, c_handle->pts, 0, userId, newName, 0, 0);
2185 goto fail_pts_UserRename;
2189 fail_pts_UserRename:
2198 * SetUserAccess - translate our Access notation to pts flags.
2202 * IN userP - the user structure that contains the new permissions.
2204 * OUT flags - a pointer to an afs_int32 structure that
2205 * contains the flags to pass to pts.
2209 * No locks are held by this function
2213 * Returns != 0 upon successful completion.
2218 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2222 afs_status_t tst = 0;
2226 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2230 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2234 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2247 * pts_UserModify - update a user entry.
2251 * IN cellHandle - a previously opened cellHandle that corresponds
2252 * to the cell where the group exists.
2254 * IN userName - the name of the user to update.
2256 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2257 * new information for user.
2261 * No locks are held by this function
2265 * Returns != 0 upon successful completion.
2270 pts_UserModify(const void *cellHandle, const char *userName,
2271 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2274 afs_status_t tst = 0;
2275 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2276 afs_int32 userId = 0;
2277 afs_int32 newQuota = 0;
2279 afs_int32 flags = 0;
2282 * Validate arguments
2285 if (!IsValidCellHandle(c_handle, &tst)) {
2286 goto fail_pts_UserModify;
2289 if ((userName == NULL) || (*userName == 0)) {
2290 tst = ADMPTSUSERNAMENULL;
2291 goto fail_pts_UserModify;
2294 if (newEntryP == NULL) {
2295 tst = ADMPTSNEWENTRYPNULL;
2296 goto fail_pts_UserModify;
2300 * Translate the user name into an id.
2303 if (!TranslateOneName
2304 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2305 goto fail_pts_UserModify;
2309 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2310 mask |= PR_SF_NGROUPS;
2311 newQuota = newEntryP->groupCreationQuota;
2314 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2315 mask |= PR_SF_ALLBITS;
2316 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2317 goto fail_pts_UserModify;
2326 ubik_Call(PR_SetFieldsEntry, c_handle->pts, 0, userId, mask, flags,
2330 goto fail_pts_UserModify;
2334 fail_pts_UserModify:
2343 * pts_UserMaxGet - get the maximum in use user id.
2347 * IN cellHandle - a previously opened cellHandle that corresponds
2348 * to the cell where the group exists.
2350 * OUT maxUserId - upon successful completion contains the max in use id.
2354 * No locks are held by this function
2358 * Returns != 0 upon successful completion.
2363 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2366 afs_status_t tst = 0;
2367 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2368 afs_int32 maxGroupId = 0;
2371 * Validate arguments
2374 if (!IsValidCellHandle(c_handle, &tst)) {
2375 goto fail_pts_UserMaxGet;
2378 if (maxUserId == NULL) {
2379 tst = ADMPTSMAXUSERIDNULL;
2380 goto fail_pts_UserMaxGet;
2383 tst = ubik_Call(PR_ListMax, c_handle->pts, 0, maxUserId, &maxGroupId);
2386 goto fail_pts_UserMaxGet;
2390 fail_pts_UserMaxGet:
2399 * pts_UserMaxSet - set the maximum user id.
2403 * IN cellHandle - a previously opened cellHandle that corresponds
2404 * to the cell where the group exists.
2406 * IN maxUserId - the new max user id.
2410 * No locks are held by this function
2414 * Returns != 0 upon successful completion.
2419 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2422 afs_status_t tst = 0;
2423 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2426 * Validate arguments
2429 if (!IsValidCellHandle(c_handle, &tst)) {
2430 goto fail_pts_UserMaxSet;
2433 tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxUserId, 0);
2436 goto fail_pts_UserMaxSet;
2440 fail_pts_UserMaxSet:
2449 * pts_UserMemberListBegin - begin iterating over the list of groups
2450 * a particular user belongs to.
2454 * IN cellHandle - a previously opened cellHandle that corresponds
2455 * to the cell where the group exists.
2457 * IN groupName - the group whose members will be returned.
2459 * OUT iterationIdP - upon successful completion contains a iterator that
2460 * can be passed to pts_GroupMemberListNext.
2464 * No locks are obtained or released by this function
2468 * Returns != 0 upon successful completion.
2473 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2474 void **iterationIdP, afs_status_p st)
2476 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2477 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2482 * pts_UserMemberListNext - get the next group a user belongs to
2486 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2488 * OUT userName - upon successful completion contains the next group a user
2493 * The iterator mutex is held during the retrieval of the next member.
2497 * Returns != 0 upon successful completion.
2502 pts_UserMemberListNext(const void *iterationId, char *userName,
2505 return pts_GroupMemberListNext(iterationId, userName, st);
2509 * pts_UserMemberListDone - finish using a user list iterator
2513 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2517 * The iterator is locked and then destroyed
2521 * Returns != 0 upon successful completion.
2525 * It is the user's responsibility to make sure pts_UserMemberListDone
2526 * is called only once for each iterator.
2530 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2532 return pts_GroupMemberListDone(iterationId, st);
2535 typedef struct owned_group_list {
2536 namelist owned_names; /* the list of character names owned by this id */
2537 prlist owned_ids; /* the list of pts ids owned by this id */
2538 afs_int32 index; /* the index into owned_names for the next group */
2539 afs_int32 owner; /* the pts id of the owner */
2540 afs_int32 more; /* the last parameter to PR_ListOwned */
2541 int finished_retrieving; /* set when we've processed the last owned_names */
2542 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2543 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2544 } owned_group_list_t, *owned_group_list_p;
2547 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2550 afs_status_t tst = 0;
2551 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2553 if (list->owned_names.namelist_val != NULL) {
2554 free(list->owned_names.namelist_val);
2557 if (list->owned_ids.prlist_val != NULL) {
2558 free(list->owned_ids.prlist_val);
2569 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2570 int *last_item_contains_data, afs_status_p st)
2573 afs_status_t tst = 0;
2574 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2577 * We really don't make an rpc for every entry we return here
2578 * since the pts interface allows several members to be returned
2579 * with one rpc, but we fake it to make the iterator happy.
2583 * Check to see if we are done retrieving data
2586 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2588 *last_item_contains_data = 0;
2589 goto fail_GetOwnedGroupRPC;
2593 * Check to see if we really need to make an rpc
2596 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2598 ubik_Call(PR_ListOwned, list->c_handle->pts, 0, list->owner,
2599 &list->owned_ids, &list->more);
2601 goto fail_GetOwnedGroupRPC;
2604 if (!TranslatePTSIds
2605 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2607 goto fail_GetOwnedGroupRPC;
2611 if (list->owned_names.namelist_val == NULL) {
2613 *last_item_contains_data = 0;
2614 goto fail_GetOwnedGroupRPC;
2619 * We can retrieve the next group from data we already received
2622 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2626 * Check to see if there is more data to be retrieved
2627 * We need to free up the previously retrieved data here
2628 * and then check to see if the last rpc indicated that there
2629 * were more items to retrieve.
2632 if (list->index >= list->owned_names.namelist_len) {
2633 list->owned_names.namelist_len = 0;
2634 free(list->owned_names.namelist_val);
2635 list->owned_names.namelist_val = 0;
2637 list->owned_ids.prlist_len = 0;
2638 free(list->owned_ids.prlist_val);
2639 list->owned_ids.prlist_val = 0;
2642 list->finished_retrieving = 1;
2647 fail_GetOwnedGroupRPC:
2656 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2660 afs_status_t tst = 0;
2661 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2663 strcpy((char *)dest, list->group[slot]);
2674 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2675 * a particular user owns.
2679 * IN cellHandle - a previously opened cellHandle that corresponds
2680 * to the cell where the group exists.
2682 * IN ownerName - the owner of the groups of interest.
2684 * OUT iterationIdP - upon successful completion contains a iterator that
2685 * can be passed to pts_OwnedGroupListNext.
2689 * No locks are held by this function
2693 * Returns != 0 upon successful completion.
2698 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2699 void **iterationIdP, afs_status_p st)
2702 afs_status_t tst = 0;
2703 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2704 afs_admin_iterator_p iter =
2705 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2706 owned_group_list_p list =
2707 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2710 * Validate arguments
2713 if (!IsValidCellHandle(c_handle, &tst)) {
2714 goto fail_pts_OwnedGroupListBegin;
2717 if ((userName == NULL) || (*userName == 0)) {
2718 tst = ADMPTSUSERNAMENULL;
2719 goto fail_pts_OwnedGroupListBegin;
2722 if (iterationIdP == NULL) {
2723 tst = ADMITERATORNULL;
2724 goto fail_pts_OwnedGroupListBegin;
2727 if ((iter == NULL) || (list == NULL)) {
2729 goto fail_pts_OwnedGroupListBegin;
2733 * Initialize the iterator specific data
2737 list->finished_retrieving = 0;
2738 list->c_handle = c_handle;
2739 list->owned_names.namelist_len = 0;
2740 list->owned_names.namelist_val = 0;
2741 list->owned_ids.prlist_len = 0;
2742 list->owned_ids.prlist_val = 0;
2745 * Translate the user name into an id.
2748 if (!TranslateOneName
2749 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2750 goto fail_pts_OwnedGroupListBegin;
2754 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2755 DeleteOwnedGroupSpecificData, &tst)) {
2756 *iterationIdP = (void *)iter;
2760 fail_pts_OwnedGroupListBegin:
2778 * pts_OwnedGroupListNext - get the next group a user owns.
2782 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2784 * OUT groupName - upon successful completion contains the next group a user
2789 * The iterator mutex is held during the retrieval of the next member.
2793 * Returns != 0 upon successful completion.
2798 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2802 afs_status_t tst = 0;
2803 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2806 * Validate arguments
2809 if (iterationId == NULL) {
2810 tst = ADMITERATORNULL;
2811 goto fail_pts_OwnedGroupListNext;
2814 if (groupName == NULL) {
2815 tst = ADMPTSGROUPNAMENULL;
2816 goto fail_pts_OwnedGroupListNext;
2819 rc = IteratorNext(iter, (void *)groupName, &tst);
2821 fail_pts_OwnedGroupListNext:
2830 * pts_OwnedGroupListDone - finish using a group list iterator
2834 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2838 * The iterator is locked and then destroyed
2842 * Returns != 0 upon successful completion.
2846 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2847 * is called only once for each iterator.
2851 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2854 afs_status_t tst = 0;
2855 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2858 * Validate arguments
2861 if (iterationId == NULL) {
2862 tst = ADMITERATORNULL;
2863 goto fail_pts_OwnedGroupListDone;
2866 rc = IteratorDone(iter, &tst);
2868 fail_pts_OwnedGroupListDone:
2876 typedef struct pts_list {
2877 prlistentries *names; /* the current list of pts names in this cell */
2878 prlistentries *currName; /* the current pts entry */
2879 afs_int32 index; /* the index into names for the next pts entry */
2880 afs_int32 nextstartindex; /* the next start index for the RPC */
2881 afs_int32 nentries; /* the number of entries in names */
2882 afs_int32 flag; /* the type of the list */
2883 int finished_retrieving; /* set when we've processed the last owned_names */
2884 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2885 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2886 } pts_list_t, *pts_list_p;
2889 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2892 afs_status_t tst = 0;
2893 pts_list_p list = (pts_list_p) rpc_specific;
2908 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2909 int *last_item_contains_data, afs_status_p st)
2912 afs_status_t tst = 0;
2913 pts_list_p list = (pts_list_p) rpc_specific;
2916 * We really don't make an rpc for every entry we return here
2917 * since the pts interface allows several members to be returned
2918 * with one rpc, but we fake it to make the iterator happy.
2922 * Check to see if we are done retrieving data
2925 if (list->finished_retrieving) {
2927 *last_item_contains_data = 0;
2928 goto fail_GetPTSRPC;
2932 * Check to see if we really need to make an rpc
2935 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2936 afs_int32 start = list->nextstartindex;
2937 prentries bulkentries;
2938 list->nextstartindex = -1;
2939 bulkentries.prentries_val = 0;
2940 bulkentries.prentries_len = 0;
2943 ubik_Call(PR_ListEntries, list->c_handle->pts, 0, list->flag,
2944 start, &bulkentries, &(list->nextstartindex));
2947 goto fail_GetPTSRPC;
2950 list->nentries = bulkentries.prentries_len;
2951 list->names = bulkentries.prentries_val;
2954 list->currName = list->names;
2959 * We can retrieve the next entry from data we already received
2962 strcpy(list->entries[slot], list->currName->name);
2968 * Check to see if there is more data to be retrieved
2969 * We need to free up the previously retrieved data here
2970 * and then check to see if the last rpc indicated that there
2971 * were more items to retrieve.
2974 if (list->index >= list->nentries) {
2980 if (list->nextstartindex == -1) {
2981 list->finished_retrieving = 1;
2996 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
2999 afs_status_t tst = 0;
3000 pts_list_p list = (pts_list_p) rpc_specific;
3002 strcpy((char *)dest, list->entries[slot]);
3013 * pts_UserListBegin - begin iterating over the list of users
3014 * in a particular cell
3018 * IN cellHandle - a previously opened cellHandle that corresponds
3019 * to the cell where the users exist.
3021 * OUT iterationIdP - upon successful completion contains a iterator that
3022 * can be passed to pts_UserListNext.
3026 * No locks are held by this function
3030 * Returns != 0 upon successful completion.
3035 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3039 afs_status_t tst = 0;
3040 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3041 afs_admin_iterator_p iter =
3042 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3043 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3046 * Validate arguments
3049 if (!IsValidCellHandle(c_handle, &tst)) {
3050 goto fail_pts_UserListBegin;
3053 if (iterationIdP == NULL) {
3054 tst = ADMITERATORNULL;
3055 goto fail_pts_UserListBegin;
3058 if ((iter == NULL) || (list == NULL)) {
3060 goto fail_pts_UserListBegin;
3064 * Initialize the iterator specific data
3068 list->finished_retrieving = 0;
3069 list->c_handle = c_handle;
3071 list->nextstartindex = 0;
3073 list->flag = PRUSERS;
3076 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3077 DeletePTSSpecificData, &tst)) {
3078 *iterationIdP = (void *)iter;
3082 fail_pts_UserListBegin:
3100 * pts_UserListNext - get the next user in the cell.
3104 * IN iterationId - an iterator previously returned by pts_UserListBegin
3106 * OUT groupName - upon successful completion contains the next user
3110 * The iterator mutex is held during the retrieval of the next member.
3114 * Returns != 0 upon successful completion.
3119 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3122 afs_status_t tst = 0;
3123 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3126 * Validate arguments
3129 if (iterationId == NULL) {
3130 tst = ADMITERATORNULL;
3131 goto fail_pts_UserListNext;
3134 if (userName == NULL) {
3135 tst = ADMPTSUSERNAMENULL;
3136 goto fail_pts_UserListNext;
3139 rc = IteratorNext(iter, (void *)userName, &tst);
3141 fail_pts_UserListNext:
3150 * pts_UserListDone - finish using a user list iterator
3154 * IN iterationId - an iterator previously returned by pts_UserListBegin
3158 * The iterator is locked and then destroyed
3162 * Returns != 0 upon successful completion.
3166 * It is the user's responsibility to make sure pts_UserListDone
3167 * is called only once for each iterator.
3171 pts_UserListDone(const void *iterationId, afs_status_p st)
3174 afs_status_t tst = 0;
3175 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3178 * Validate arguments
3181 if (iterationId == NULL) {
3182 tst = ADMITERATORNULL;
3183 goto fail_pts_UserListDone;
3186 rc = IteratorDone(iter, &tst);
3188 fail_pts_UserListDone:
3197 * pts_GroupListBegin - begin iterating over the list of groups
3198 * in a particular cell.
3202 * IN cellHandle - a previously opened cellHandle that corresponds
3203 * to the cell where the groups exist.
3205 * OUT iterationIdP - upon successful completion contains a iterator that
3206 * can be passed to pts_GroupListNext.
3210 * No locks are held by this function
3214 * Returns != 0 upon successful completion.
3219 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3223 afs_status_t tst = 0;
3224 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3225 afs_admin_iterator_p iter =
3226 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3227 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3230 * Validate arguments
3233 if (!IsValidCellHandle(c_handle, &tst)) {
3234 goto fail_pts_GroupListBegin;
3237 if (iterationIdP == NULL) {
3238 tst = ADMITERATORNULL;
3239 goto fail_pts_GroupListBegin;
3242 if ((iter == NULL) || (list == NULL)) {
3244 goto fail_pts_GroupListBegin;
3248 * Initialize the iterator specific data
3252 list->finished_retrieving = 0;
3253 list->c_handle = c_handle;
3255 list->nextstartindex = 0;
3257 list->flag = PRGROUPS;
3260 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3261 DeletePTSSpecificData, &tst)) {
3262 *iterationIdP = (void *)iter;
3266 fail_pts_GroupListBegin:
3284 * pts_UserListNext - get the next group in a cell.
3288 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3290 * OUT groupName - upon successful completion contains the next group
3294 * The iterator mutex is held during the retrieval of the next member.
3298 * Returns != 0 upon successful completion.
3303 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3306 afs_status_t tst = 0;
3307 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3310 * Validate arguments
3313 if (iterationId == NULL) {
3314 tst = ADMITERATORNULL;
3315 goto fail_pts_GroupListNext;
3318 if (groupName == NULL) {
3319 tst = ADMPTSGROUPNAMENULL;
3320 goto fail_pts_GroupListNext;
3323 rc = IteratorNext(iter, (void *)groupName, &tst);
3325 fail_pts_GroupListNext:
3334 * pts_GroupListDone - finish using a group list iterator
3338 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3342 * The iterator is locked and then destroyed
3346 * Returns != 0 upon successful completion.
3350 * It is the user's responsibility to make sure pts_GroupListDone
3351 * is called only once for each iterator.
3355 pts_GroupListDone(const void *iterationId, afs_status_p st)
3358 afs_status_t tst = 0;
3359 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3362 * Validate arguments
3365 if (iterationId == NULL) {
3366 tst = ADMITERATORNULL;
3367 goto fail_pts_GroupListDone;
3370 rc = IteratorDone(iter, &tst);
3372 fail_pts_GroupListDone: