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 * The list of external functions that aren't prototyped anywhere
38 extern int PR_NameToID();
39 extern int PR_AddToGroup();
40 extern int PR_ChangeEntry();
41 extern int PR_RemoveFromGroup();
42 extern int PR_INewEntry();
43 extern int PR_NewEntry();
44 extern int PR_Delete();
45 extern int PR_IDToName();
46 extern int PR_ListEntry();
47 extern int PR_SetMax();
48 extern int PR_ListElements();
49 extern int PR_SetFieldsEntry();
50 extern int PR_IsAMemberOf();
51 extern int PR_ListMax();
52 extern int PR_ListOwned();
53 extern int PR_ListEntries();
56 * IsValidCellHandle - validate the cell handle for making pts
61 * IN cellHandle - a previously opened cellHandle that is to be validated.
65 * No locks are obtained or released by this function
69 * Returns != 0 upon successful completion.
74 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
79 if (!CellHandleIsValid((void *)c_handle, &tst)) {
80 goto fail_IsValidCellHandle;
83 if (c_handle->pts_valid == 0) {
84 tst = ADMCLIENTCELLPTSINVALID;
85 goto fail_IsValidCellHandle;
88 if (c_handle->pts == NULL) {
89 tst = ADMCLIENTCELLPTSNULL;
90 goto fail_IsValidCellHandle;
95 fail_IsValidCellHandle:
105 * TranslatePTSNames - translate character representations of pts names
106 * into their numeric equivalent.
110 * IN cellHandle - a previously opened cellHandle that corresponds
111 * to the cell where the id's exist.
113 * IN names - the list of names to be translated.
115 * OUT ids - the list of translated names
119 * No locks are obtained or released by this function
123 * Returns != 0 upon successful completion.
128 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
129 idlist * ids, afs_status_p st)
132 afs_status_t tst = 0;
137 * Lowercase the names to translate
140 for (i = 0; i < names->namelist_len; i++) {
141 p = names->namelist_val[i];
148 tst = ubik_Call(PR_NameToID, cellHandle->pts, 0, names, ids);
151 goto fail_TranslatePTSNames;
156 * Check to see if the lookup failed
159 for (i = 0; i < ids->idlist_len; i++) {
160 if (ids->idlist_val[i] == ANONYMOUSID) {
161 tst = ADMPTSFAILEDNAMETRANSLATE;
162 goto fail_TranslatePTSNames;
167 fail_TranslatePTSNames:
176 * TranslateTwoNames - translate two pts names to their pts ids.
180 * IN cellHandle - a previously opened cellHandle that corresponds
181 * to the cell where the group exists.
183 * IN id1 - one id to be translated
185 * IN error1 - the error status to be returned in the event that id1 is
188 * IN id2 - one id to be translated
190 * IN error2 - the error status to be returned in the event that id2 is
194 * OUT idlist - the list of pts id's
198 * No locks are obtained or released by this function
202 * Returns != 0 upon successful completion.
207 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
208 afs_status_t error1, const char *id2, afs_status_t error2,
209 idlist * ids, afs_status_p st)
212 afs_status_t tst = 0;
214 char tmp_array[2 * PTS_MAX_NAME_LEN];
217 * Copy the group and user names in order to translate them
220 names.namelist_len = 2;
221 names.namelist_val = (prname *) & tmp_array[0];
223 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
224 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
229 * Check that user and group aren't too long
230 * This is a cheaper check than calling strlen
233 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
235 goto fail_TranslateTwoNames;
238 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
240 goto fail_TranslateTwoNames;
244 * Translate user and group into pts ID's
247 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
248 goto fail_TranslateTwoNames;
253 fail_TranslateTwoNames:
262 * TranslateOneName - translate a pts name to its pts id.
266 * IN cellHandle - a previously opened cellHandle that corresponds
267 * to the cell where the group exists.
269 * IN userName - the user to be translated.
271 * OUT idlist - the user pts id.
275 * No locks are obtained or released by this function
279 * Returns != 0 upon successful completion.
284 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
285 afs_status_t tooLongError, afs_int32 * ptsId,
289 afs_status_t tst = 0;
291 char tmp_array[PTS_MAX_NAME_LEN];
295 * Copy the name in order to translate it
298 names[0].namelist_len = 1;
299 names[0].namelist_val = (prname *) & tmp_array[0];
301 strncpy(names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
306 * Check that user isn't too long
307 * This is a cheaper check than calling strlen
310 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
312 goto fail_TranslateOneName;
316 * Translate user into pts ID
319 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
320 goto fail_TranslateOneName;
322 if (ids.idlist_val != NULL) {
323 *ptsId = *ids.idlist_val;
324 free(ids.idlist_val);
330 fail_TranslateOneName:
339 * TranslatePTSIds - translate numeric representations of pts names
340 * into their character equivalent.
344 * IN cellHandle - a previously opened cellHandle that corresponds
345 * to the cell where the id's exist.
347 * IN ids - the list of ids to be translated.
349 * OUT names - the list of translated names
353 * No locks are obtained or released by this function
357 * Returns != 0 upon successful completion.
362 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
363 idlist * ids, afs_status_p st)
366 afs_status_t tst = 0;
368 tst = ubik_Call(PR_IDToName, cellHandle->pts, 0, ids, names);
371 goto fail_TranslatePTSIds;
375 fail_TranslatePTSIds:
384 * pts_GroupMemberAdd - add one member to a pts group
388 * IN cellHandle - a previously opened cellHandle that corresponds
389 * to the cell where the group exists.
391 * IN userName - the name to be added to the group.
393 * IN groupName - the group to be modified.
397 * No locks are obtained or released by this function
401 * Returns != 0 upon successful completion.
406 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
407 const char *groupName, afs_status_p st)
410 afs_status_t tst = 0;
411 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
418 if (!IsValidCellHandle(c_handle, &tst)) {
419 goto fail_pts_GroupMemberAdd;
422 if ((userName == NULL) || (*userName == 0)) {
423 tst = ADMPTSUSERNAMENULL;
424 goto fail_pts_GroupMemberAdd;
427 if ((groupName == NULL) || (*groupName == 0)) {
428 tst = ADMPTSGROUPNAMENULL;
429 goto fail_pts_GroupMemberAdd;
432 if (!TranslateTwoNames
433 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
434 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
435 goto fail_pts_GroupMemberAdd;
443 ubik_Call(PR_AddToGroup, c_handle->pts, 0, ids.idlist_val[0],
447 goto fail_pts_GroupMemberAdd;
451 fail_pts_GroupMemberAdd:
453 if (ids.idlist_val != 0) {
454 free(ids.idlist_val);
464 * pts_GroupOwnerChange - change the owner of a group
468 * IN cellHandle - a previously opened cellHandle that corresponds
469 * to the cell where the group exists.
471 * IN targetGroup - the group to be modified.
473 * IN userName - the new owner of the group.
477 * No locks are obtained or released by this function
481 * Returns != 0 upon successful completion.
486 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
487 const char *newOwner, afs_status_p st)
490 afs_status_t tst = 0;
491 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
498 if (!IsValidCellHandle(c_handle, &tst)) {
499 goto fail_pts_GroupOwnerChange;
502 if ((newOwner == NULL) || (*newOwner == 0)) {
503 tst = ADMPTSNEWOWNERNULL;
504 goto fail_pts_GroupOwnerChange;
507 if ((targetGroup == NULL) || (*targetGroup == 0)) {
508 tst = ADMPTSTARGETGROUPNULL;
509 goto fail_pts_GroupOwnerChange;
512 if (!TranslateTwoNames
513 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
514 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
515 goto fail_pts_GroupOwnerChange;
523 ubik_Call(PR_ChangeEntry, c_handle->pts, 0, ids.idlist_val[1], "",
524 ids.idlist_val[0], 0);
527 goto fail_pts_GroupOwnerChange;
531 fail_pts_GroupOwnerChange:
533 if (ids.idlist_val != 0) {
534 free(ids.idlist_val);
544 * pts_GroupCreate - create a new group
548 * IN cellHandle - a previously opened cellHandle that corresponds
549 * to the cell where the group exists.
551 * IN newGroup - the group to be created.
553 * IN newOwner - the owner of the group. Pass NULL if the current user
554 * is to be the new owner, or the character string of the owner otherwise.
556 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
557 * generate a value, != 0 to assign a value on your own. The group id
558 * that is used to create the group is copied into this parameter in the
559 * event you pass in 0.
563 * No locks are obtained or released by this function
567 * Returns != 0 upon successful completion.
572 pts_GroupCreate(const void *cellHandle, const char *newGroup,
573 const char *newOwner, int *newGroupId, afs_status_p st)
576 afs_status_t tst = 0;
577 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
578 afs_int32 newOwnerId = 0;
584 if (!IsValidCellHandle(c_handle, &tst)) {
585 goto fail_pts_GroupCreate;
588 if ((newGroup == NULL) || (*newGroup == 0)) {
589 tst = ADMPTSNEWGROUPNULL;
590 goto fail_pts_GroupCreate;
593 if (newGroupId == NULL) {
594 tst = ADMPTSNEWGROUPIDNULL;
595 goto fail_pts_GroupCreate;
598 if (*newGroupId > 0) {
599 tst = ADMPTSNEWGROUPIDPOSITIVE;
600 goto fail_pts_GroupCreate;
604 * If a newOwner was specified, validate that it exists
607 if (newOwner != NULL) {
608 if (!TranslateOneName
609 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
610 goto fail_pts_GroupCreate;
615 * We make a different rpc based upon the input to this function
618 if (*newGroupId != 0) {
620 ubik_Call(PR_INewEntry, c_handle->pts, 0, newGroup, *newGroupId,
624 ubik_Call(PR_NewEntry, c_handle->pts, 0, newGroup, PRGRP,
625 newOwnerId, newGroupId);
629 goto fail_pts_GroupCreate;
633 fail_pts_GroupCreate:
642 * GetGroupAccess - a small convenience function for setting
647 * IN access - a pointer to a pts_groupAccess_t to be set with the
648 * correct permission.
650 * IN flag - the current permission flag used to derive the permission.
654 * No locks are obtained or released by this function
658 * Since this function cannot fail, it returns void.
663 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
666 *access = PTS_GROUP_OWNER_ACCESS;
668 *access = PTS_GROUP_OWNER_ACCESS;
669 } else if (flag == 1) {
670 *access = PTS_GROUP_ACCESS;
671 } else if (flag == 2) {
672 *access = PTS_GROUP_ANYUSER_ACCESS;
678 * pts_GroupGet - retrieve information about a particular group.
682 * IN cellHandle - a previously opened cellHandle that corresponds
683 * to the cell where the group exists.
685 * IN groupName - the group to retrieve.
687 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
688 * successful completion is filled with information about groupName.
692 * No locks are obtained or released by this function
696 * Returns != 0 upon successful completion.
701 pts_GroupGet(const void *cellHandle, const char *groupName,
702 pts_GroupEntry_p groupP, afs_status_p st)
705 afs_status_t tst = 0;
706 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
707 afs_int32 groupId = 0;
710 struct prcheckentry groupEntry;
719 if (!IsValidCellHandle(c_handle, &tst)) {
720 goto fail_pts_GroupGet;
723 if ((groupName == NULL) || (*groupName == 0)) {
724 tst = ADMPTSGROUPNAMENULL;
725 goto fail_pts_GroupGet;
728 if (groupP == NULL) {
729 tst = ADMPTSGROUPPNULL;
730 goto fail_pts_GroupGet;
734 * Translate the group name into an id.
737 if (!TranslateOneName
738 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
739 goto fail_pts_GroupGet;
743 * Retrieve information about the group
746 tst = ubik_Call(PR_ListEntry, c_handle->pts, 0, groupId, &groupEntry);
749 goto fail_pts_GroupGet;
752 groupP->membershipCount = groupEntry.count;
753 groupP->nameUid = groupEntry.id;
754 groupP->ownerUid = groupEntry.owner;
755 groupP->creatorUid = groupEntry.creator;
756 strcpy(groupP->name, groupEntry.name);
758 * Set the access rights based upon the value of the flags member
759 * of the groupEntry struct.
761 * To the best of my ability to decypher the pts code, it looks like
762 * the rights are stored in flags as follows:
764 * I number my bits from least significant to most significant starting
768 * if bit 0 == 0 -> r access is denied
769 * if bit 0 == 1 -> r access is granted
772 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
773 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
774 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
775 * if bit 2 == 1 and bit 1 == 1 -> this is an error
777 * membership - bits 3 and 4
778 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
779 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
780 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
781 * if bit 4 == 1 and bit 3 == 1 -> this is an error
784 * if bit 5 == 0 -> O access is denied
785 * if bit 5 == 1 -> O access is granted
787 * status - bits 6 and 7
788 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
789 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
790 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
791 * if bit 7 == 1 and bit 6 == 1 -> this is an error
793 * For cases where the permission doesn't make sense for the
794 * type of entry, or where an error occurs, we ignore it.
795 * This is the behavior of the pts code.
798 flags = groupEntry.flags;
800 groupP->listDelete = PTS_GROUP_ACCESS;
802 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
808 GetGroupAccess(&groupP->listAdd, twobit);
813 GetGroupAccess(&groupP->listMembership, twobit);
818 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
820 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
826 GetGroupAccess(&groupP->listStatus, twobit);
829 * Make another rpc and translate the owner and creator ids into
834 ids.idlist_val = ptsids;
835 ptsids[0] = groupEntry.owner;
836 ptsids[1] = groupEntry.creator;
837 names.namelist_len = 0;
838 names.namelist_val = 0;
841 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
842 goto fail_pts_GroupGet;
845 strcpy(groupP->owner, names.namelist_val[0]);
846 strcpy(groupP->creator, names.namelist_val[1]);
847 free(names.namelist_val);
859 * EntryDelete - delete a pts entry (group or user).
863 * IN cellHandle - a previously opened cellHandle that corresponds
864 * to the cell where the group exists.
866 * IN entryName - the entry to be deleted.
868 * IN error1 - the error status to be returned in the event that entryName is
871 * IN error2 - the error status to be returned in the event that entryName is
876 * No locks are obtained or released by this function
880 * Returns != 0 upon successful completion.
885 EntryDelete(const void *cellHandle, const char *entryName,
886 afs_status_t error1, afs_status_t error2, afs_status_p st)
889 afs_status_t tst = 0;
890 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
891 afs_int32 entryId = 0;
897 if (!IsValidCellHandle(c_handle, &tst)) {
898 goto fail_EntryDelete;
901 if ((entryName == NULL) || (*entryName == 0)) {
903 goto fail_EntryDelete;
907 * Translate the entry name into an id.
910 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
911 goto fail_EntryDelete;
918 tst = ubik_Call(PR_Delete, c_handle->pts, 0, entryId);
921 goto fail_EntryDelete;
935 * pts_GroupDelete - delete a group
939 * IN cellHandle - a previously opened cellHandle that corresponds
940 * to the cell where the group exists.
942 * IN groupName - the group to be deleted.
946 * No locks are obtained or released by this function
950 * Returns != 0 upon successful completion.
955 pts_GroupDelete(const void *cellHandle, const char *groupName,
959 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
960 ADMPTSGROUPNAMETOOLONG, st);
964 * pts_GroupMaxGet - get the maximum in use group id.
968 * IN cellHandle - a previously opened cellHandle that corresponds
969 * to the cell where the group exists.
971 * OUT maxGroupId - upon successful completion contains the maximum
972 * group Id in use at the server.
976 * No locks are obtained or released by this function
980 * Returns != 0 upon successful completion.
985 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
988 afs_status_t tst = 0;
989 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
990 afs_int32 maxUserId = 0;
996 if (!IsValidCellHandle(c_handle, &tst)) {
997 goto fail_pts_GroupMaxGet;
1000 if (maxGroupId == NULL) {
1001 tst = ADMPTSMAXGROUPIDNULL;
1002 goto fail_pts_GroupMaxGet;
1005 tst = ubik_Call(PR_ListMax, c_handle->pts, 0, &maxUserId, maxGroupId);
1008 goto fail_pts_GroupMaxGet;
1012 fail_pts_GroupMaxGet:
1021 * pts_GroupMaxSet - set the maximum in use group id.
1025 * IN cellHandle - a previously opened cellHandle that corresponds
1026 * to the cell where the group exists.
1028 * IN maxGroupId - the new maximum group id.
1032 * No locks are obtained or released by this function
1036 * Returns != 0 upon successful completion.
1041 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1044 afs_status_t tst = 0;
1045 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1048 * Validate arguments
1051 if (!IsValidCellHandle(c_handle, &tst)) {
1052 goto fail_pts_GroupMaxSet;
1055 tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxGroupId, PRGRP);
1058 goto fail_pts_GroupMaxSet;
1062 fail_pts_GroupMaxSet:
1073 * I'm not using the common iterator pattern here since the retrival
1074 * of the member list is actually accomplished in 1 rpc. There's no
1075 * sense in trying to fit this pts specific behavior into the more
1076 * generic model, so instead the Begin functions actually do all the
1077 * rpc work and the next/done functions just manipulate the retrieved
1081 typedef struct pts_group_member_list_iterator {
1084 pthread_mutex_t mutex; /* hold to manipulate this structure */
1089 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1092 * pts_GroupMemberListBegin - begin iterating over the list of members
1093 * of a particular group.
1097 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1101 * No locks are obtained or released by this function
1105 * Returns != 0 upon successful completion.
1110 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1114 afs_status_t tst = 0;
1117 tst = ADMITERATORNULL;
1118 goto fail_IsValidPtsGroupMemberListIterator;
1121 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1122 tst = ADMITERATORBADMAGICNULL;
1123 goto fail_IsValidPtsGroupMemberListIterator;
1126 if (iter->is_valid == 0) {
1127 tst = ADMITERATORINVALID;
1128 goto fail_IsValidPtsGroupMemberListIterator;
1132 fail_IsValidPtsGroupMemberListIterator:
1141 * MemberListBegin - an internal function which is used to get both
1142 * the list of members in a group and the list of groups a user belongs
1147 * IN cellHandle - a previously opened cellHandle that corresponds
1148 * to the cell where the group exists.
1150 * IN name - the name whose membership will be retrieved.
1152 * OUT iterationIdP - upon successful completion contains a iterator that
1153 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1157 * No locks are obtained or released by this function
1161 * Returns != 0 upon successful completion.
1166 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1167 afs_status_t error2, void **iterationIdP, afs_status_p st)
1170 afs_status_t tst = 0;
1171 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1172 afs_int32 groupId = 0;
1173 afs_int32 exceeded = 0;
1174 pts_group_member_list_iterator_p iter = (pts_group_member_list_iterator_p)
1175 malloc(sizeof(pts_group_member_list_iterator_t));
1176 int iter_allocated = 0;
1177 int ids_allocated = 0;
1178 int names_allocated = 0;
1179 int mutex_inited = 0;
1182 * Validate arguments
1185 if (!IsValidCellHandle(c_handle, &tst)) {
1186 goto fail_MemberListBegin;
1189 if ((name == NULL) || (*name == 0)) {
1190 tst = ADMPTSGROUPNAMENULL;
1191 goto fail_MemberListBegin;
1194 if (iterationIdP == NULL) {
1195 tst = ADMITERATORNULL;
1196 goto fail_MemberListBegin;
1201 goto fail_MemberListBegin;
1207 * Translate the name into an id.
1210 if (!TranslateOneName
1211 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1212 goto fail_MemberListBegin;
1215 if (pthread_mutex_init(&iter->mutex, 0)) {
1217 goto fail_MemberListBegin;
1222 iter->ids.prlist_len = 0;
1223 iter->ids.prlist_val = 0;
1226 ubik_Call(PR_ListElements, c_handle->pts, 0, groupId, &iter->ids,
1230 goto fail_MemberListBegin;
1233 if (exceeded != 0) {
1234 tst = ADMPTSGROUPMEMEXCEEDED;
1235 goto fail_MemberListBegin;
1239 iter->names.namelist_len = 0;
1240 iter->names.namelist_val = 0;
1242 if (!TranslatePTSIds
1243 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1244 goto fail_MemberListBegin;
1247 names_allocated = 1;
1248 iter->begin_magic = BEGIN_MAGIC;
1249 iter->end_magic = END_MAGIC;
1253 *iterationIdP = (void *)iter;
1256 fail_MemberListBegin:
1258 if (ids_allocated) {
1259 free(iter->ids.prlist_val);
1263 if (names_allocated) {
1264 free(iter->names.namelist_val);
1267 pthread_mutex_destroy(&iter->mutex);
1269 if (iter_allocated) {
1281 * pts_GroupMemberListBegin - begin iterating over the list of members
1282 * of a particular group.
1286 * IN cellHandle - a previously opened cellHandle that corresponds
1287 * to the cell where the group exists.
1289 * IN groupName - the group whose members will be returned.
1291 * OUT iterationIdP - upon successful completion contains a iterator that
1292 * can be passed to pts_GroupMemberListNext.
1296 * No locks are obtained or released by this function
1300 * Returns != 0 upon successful completion.
1305 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1306 void **iterationIdP, afs_status_p st)
1308 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1309 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1313 * pts_GroupMemberListNext - get the next member of a group
1317 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1319 * OUT memberName - upon successful completion contains the next member of
1324 * The iterator mutex is held during the retrieval of the next member.
1328 * Returns != 0 upon successful completion.
1333 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1337 afs_status_t tst = 0;
1338 pts_group_member_list_iterator_p iter =
1339 (pts_group_member_list_iterator_p) iterationId;
1340 int mutex_locked = 0;
1343 * Validate arguments
1347 tst = ADMITERATORNULL;
1348 goto fail_pts_GroupMemberListNext;
1351 if (memberName == NULL) {
1352 tst = ADMPTSMEMBERNAMENULL;
1353 goto fail_pts_GroupMemberListNext;
1357 * Lock the mutex and check the validity of the iterator
1360 if (pthread_mutex_lock(&iter->mutex)) {
1362 goto fail_pts_GroupMemberListNext;
1367 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1368 goto fail_pts_GroupMemberListNext;
1372 * Check to see if we've copied out all the data. If we haven't,
1373 * copy another item. If we have, mark the iterator done.
1376 if (iter->index >= iter->names.namelist_len) {
1377 tst = ADMITERATORDONE;
1378 goto fail_pts_GroupMemberListNext;
1380 strcpy(memberName, iter->names.namelist_val[iter->index]);
1385 fail_pts_GroupMemberListNext:
1388 pthread_mutex_unlock(&iter->mutex);
1398 * pts_GroupMemberListDone - finish using a member list iterator
1402 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1406 * The iterator is locked and then destroyed
1410 * Returns != 0 upon successful completion.
1414 * It is the user's responsibility to make sure pts_GroupMemberListDone
1415 * is called only once for each iterator.
1419 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1422 afs_status_t tst = 0;
1423 pts_group_member_list_iterator_p iter =
1424 (pts_group_member_list_iterator_p) iterationId;
1425 int mutex_locked = 0;
1428 * Validate arguments
1432 tst = ADMITERATORNULL;
1433 goto fail_pts_GroupMemberListDone;
1437 * Lock the mutex and check the validity of the iterator
1440 if (pthread_mutex_lock(&iter->mutex)) {
1442 goto fail_pts_GroupMemberListDone;
1447 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1448 goto fail_pts_GroupMemberListDone;
1452 * Free the namelist and the iterator.
1455 pthread_mutex_destroy(&iter->mutex);
1458 free(iter->names.namelist_val);
1462 fail_pts_GroupMemberListDone:
1465 pthread_mutex_unlock(&iter->mutex);
1475 * pts_GroupMemberRemove - remove a member from a group.
1479 * IN cellHandle - a previously opened cellHandle that corresponds
1480 * to the cell where the group exists.
1482 * IN userName - the user to remove.
1484 * IN groupName - the group to modify
1488 * No locks are held by this function
1492 * Returns != 0 upon successful completion.
1497 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1498 const char *groupName, afs_status_p st)
1501 afs_status_t tst = 0;
1502 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1506 * Validate arguments
1509 if (!IsValidCellHandle(c_handle, &tst)) {
1510 goto fail_pts_GroupMemberRemove;
1513 if ((userName == NULL) || (*userName == 0)) {
1514 tst = ADMPTSUSERNAMENULL;
1515 goto fail_pts_GroupMemberRemove;
1518 if ((groupName == NULL) || (*groupName == 0)) {
1519 tst = ADMPTSGROUPNAMENULL;
1520 goto fail_pts_GroupMemberRemove;
1523 if (!TranslateTwoNames
1524 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1525 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1526 goto fail_pts_GroupMemberRemove;
1534 ubik_Call(PR_RemoveFromGroup, c_handle->pts, 0, ids.idlist_val[0],
1538 goto fail_pts_GroupMemberRemove;
1542 fail_pts_GroupMemberRemove:
1544 if (ids.idlist_val != 0) {
1545 free(ids.idlist_val);
1555 * pts_GroupRename - change the name of a group
1559 * IN cellHandle - a previously opened cellHandle that corresponds
1560 * to the cell where the group exists.
1562 * IN oldName - the current group name
1564 * IN newName - the new group name
1568 * No locks are held by this function
1572 * Returns != 0 upon successful completion.
1577 pts_GroupRename(const void *cellHandle, const char *oldName,
1578 const char *newName, afs_status_p st)
1581 afs_status_t tst = 0;
1582 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1583 afs_int32 groupId = 0;
1586 * Validate arguments
1589 if (!IsValidCellHandle(c_handle, &tst)) {
1590 goto fail_pts_GroupRename;
1593 if ((newName == NULL) || (*newName == 0)) {
1594 tst = ADMPTSNEWNAMENULL;
1595 goto fail_pts_GroupRename;
1598 if ((oldName == NULL) || (*oldName == 0)) {
1599 tst = ADMPTSOLDNAMENULL;
1600 goto fail_pts_GroupRename;
1604 * Translate the group name into an id.
1607 if (!TranslateOneName
1608 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1609 goto fail_pts_GroupRename;
1616 tst = ubik_Call(PR_ChangeEntry, c_handle->pts, 0, groupId, newName, 0, 0);
1619 goto fail_pts_GroupRename;
1623 fail_pts_GroupRename:
1632 * SetGroupAccess - translate our Access notation to pts flags.
1636 * IN rights - the permissions.
1638 * OUT flags - a pointer to an afs_int32 structure that
1639 * contains the flags to pass to pts.
1643 * No locks are held by this function
1647 * Returns != 0 upon successful completion.
1652 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1656 afs_status_t tst = 0;
1660 if (rights->listDelete == PTS_GROUP_ACCESS) {
1662 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1663 tst = ADMPTSINVALIDGROUPDELETEPERM;
1664 goto fail_SetGroupAccess;
1667 if (rights->listAdd == PTS_GROUP_ACCESS) {
1669 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1673 if (rights->listMembership == PTS_GROUP_ACCESS) {
1675 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1679 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1681 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1682 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1683 goto fail_SetGroupAccess;
1686 if (rights->listStatus == PTS_GROUP_ACCESS) {
1688 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1693 fail_SetGroupAccess:
1702 * pts_GroupModify - change the contents of a group entry.
1706 * IN cellHandle - a previously opened cellHandle that corresponds
1707 * to the cell where the group exists.
1709 * IN groupName - the group to change
1711 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1712 * contains the new information for the group.
1716 * No locks are held by this function
1720 * Returns != 0 upon successful completion.
1725 pts_GroupModify(const void *cellHandle, const char *groupName,
1726 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1729 afs_status_t tst = 0;
1730 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1731 afs_int32 groupId = 0;
1732 afs_int32 flags = 0;
1735 * Validate arguments
1738 if (!IsValidCellHandle(c_handle, &tst)) {
1739 goto fail_pts_GroupModify;
1742 if ((groupName == NULL) || (*groupName == 0)) {
1743 tst = ADMPTSGROUPNAMENULL;
1744 goto fail_pts_GroupModify;
1748 if (newEntryP == NULL) {
1749 tst = ADMPTSNEWENTRYPNULL;
1750 goto fail_pts_GroupModify;
1754 * Translate the group name into an id.
1757 if (!TranslateOneName
1758 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1759 goto fail_pts_GroupModify;
1763 * Set the flags argument
1766 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1767 goto fail_pts_GroupModify;
1775 ubik_Call(PR_SetFieldsEntry, c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1779 goto fail_pts_GroupModify;
1783 fail_pts_GroupModify:
1792 * pts_UserCreate - create a new user.
1796 * IN cellHandle - a previously opened cellHandle that corresponds
1797 * to the cell where the group exists.
1799 * IN newUser - the name of the new user.
1801 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1802 * id assigned by pts.
1806 * No locks are held by this function
1810 * Returns != 0 upon successful completion.
1815 pts_UserCreate(const void *cellHandle, const char *userName, int *newUserId,
1819 afs_status_t tst = 0;
1820 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1821 afs_int32 userId = 0;
1824 * Validate arguments
1827 if (!IsValidCellHandle(c_handle, &tst)) {
1828 goto fail_pts_UserCreate;
1831 if ((userName == NULL) || (*userName == 0)) {
1832 tst = ADMPTSUSERNAMENULL;
1833 goto fail_pts_UserCreate;
1836 if (newUserId == NULL) {
1837 tst = ADMPTSNEWUSERIDNULL;
1838 goto fail_pts_UserCreate;
1842 * We make a different rpc based upon the input to this function
1845 if (*newUserId != 0) {
1847 ubik_Call(PR_INewEntry, c_handle->pts, 0, userName, *newUserId,
1851 ubik_Call(PR_NewEntry, c_handle->pts, 0, userName, 0, 0,
1856 goto fail_pts_UserCreate;
1860 fail_pts_UserCreate:
1869 * pts_UserDelete - delete a user.
1873 * IN cellHandle - a previously opened cellHandle that corresponds
1874 * to the cell where the group exists.
1876 * IN user - the name of the user to delete.
1880 * No locks are held by this function
1884 * Returns != 0 upon successful completion.
1889 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1891 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1892 ADMPTSUSERNAMETOOLONG, st);
1897 * GetUserAccess - a small convenience function for setting
1902 * IN access - a pointer to a pts_userAccess_t to be set with the
1903 * correct permission.
1905 * IN flag - the current permission flag used to derive the permission.
1909 * No locks are obtained or released by this function
1913 * Since this function cannot fail, it returns void.
1918 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1921 *access = PTS_USER_OWNER_ACCESS;
1923 *access = PTS_USER_ANYUSER_ACCESS;
1928 * IsAdministrator - determine if a user is an administrator.
1932 * IN cellHandle - a previously opened cellHandle that corresponds
1933 * to the cell where the group exists.
1935 * IN userEntry - the user data for the user in question.
1937 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1941 * No locks are held by this function
1945 * Returns != 0 upon successful completion.
1950 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1951 int *admin, afs_status_p st)
1954 afs_status_t tst = 0;
1955 afs_int32 adminId = 0;
1956 afs_int32 isAdmin = 0;
1960 if (userId == SYSADMINID) {
1963 if (!TranslateOneName
1964 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1966 goto fail_IsAdministrator;
1969 ubik_Call(PR_IsAMemberOf, c_handle->pts, 0, userId, adminId,
1972 goto fail_IsAdministrator;
1980 fail_IsAdministrator:
1989 * pts_UserGet - retrieve information about a particular user.
1993 * IN cellHandle - a previously opened cellHandle that corresponds
1994 * to the cell where the group exists.
1996 * IN userName - the name of the user to retrieve.
1998 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
2003 * No locks are held by this function
2007 * Returns != 0 upon successful completion.
2012 pts_UserGet(const void *cellHandle, const char *userName,
2013 pts_UserEntry_p userP, afs_status_p st)
2016 afs_status_t tst = 0;
2017 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2018 struct prcheckentry userEntry;
2019 afs_int32 userId = 0;
2023 afs_int32 ptsids[2];
2029 * Validate arguments
2032 if (!IsValidCellHandle(c_handle, &tst)) {
2033 goto fail_pts_UserGet;
2036 if ((userName == NULL) || (*userName == 0)) {
2037 tst = ADMPTSUSERNAMENULL;
2038 goto fail_pts_UserGet;
2041 if (userP == NULL) {
2042 tst = ADMPTSUSERPNULL;
2043 goto fail_pts_UserGet;
2047 * Translate the group name into an id.
2050 if (!TranslateOneName
2051 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2052 goto fail_pts_UserGet;
2056 * Retrieve information about the group
2059 tst = ubik_Call(PR_ListEntry, c_handle->pts, 0, userId, &userEntry);
2062 goto fail_pts_UserGet;
2065 userP->groupMembershipCount = userEntry.count;
2066 userP->groupCreationQuota = userEntry.ngroups;
2068 * The administrator id, or any member of "system:administrators"
2069 * has unlimited group creation quota. Denote this by setting
2073 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2074 goto fail_pts_UserGet;
2078 userP->groupCreationQuota = -1;
2081 userP->nameUid = userEntry.id;
2082 userP->ownerUid = userEntry.owner;
2083 userP->creatorUid = userEntry.creator;
2084 strcpy(userP->name, userEntry.name);
2087 * The permission bits are described in the GroupGet function above.
2088 * The user entry only uses 3 of the 5 permissions, so we shift
2089 * past the unused entries.
2092 flags = userEntry.flags;
2096 GetUserAccess(&userP->listMembership, twobit);
2101 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2103 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2109 GetUserAccess(&userP->listStatus, twobit);
2112 * Make another rpc and translate the owner and creator ids into
2113 * character strings.
2117 ids.idlist_val = ptsids;
2118 ptsids[0] = userEntry.owner;
2119 ptsids[1] = userEntry.creator;
2120 names.namelist_len = 0;
2121 names.namelist_val = 0;
2124 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2125 goto fail_pts_UserGet;
2128 strcpy(userP->owner, names.namelist_val[0]);
2129 strcpy(userP->creator, names.namelist_val[1]);
2130 free(names.namelist_val);
2142 * pts_UserRename - rename a user.
2146 * IN cellHandle - a previously opened cellHandle that corresponds
2147 * to the cell where the group exists.
2149 * IN oldName - the name of the user to rename.
2151 * IN newName - the new user name.
2155 * No locks are held by this function
2159 * Returns != 0 upon successful completion.
2164 pts_UserRename(const void *cellHandle, const char *oldName,
2165 const char *newName, afs_status_p st)
2168 afs_status_t tst = 0;
2169 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2170 afs_int32 userId = 0;
2173 * Validate arguments
2176 if (!IsValidCellHandle(c_handle, &tst)) {
2177 goto fail_pts_UserRename;
2180 if ((oldName == NULL) || (*oldName == 0)) {
2181 tst = ADMPTSOLDNAMENULL;
2182 goto fail_pts_UserRename;
2185 if ((newName == NULL) || (*newName == 0)) {
2186 tst = ADMPTSNEWNAMENULL;
2187 goto fail_pts_UserRename;
2191 * Translate the user name into an id.
2194 if (!TranslateOneName
2195 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2196 goto fail_pts_UserRename;
2203 tst = ubik_Call(PR_ChangeEntry, c_handle->pts, 0, userId, newName, 0, 0);
2206 goto fail_pts_UserRename;
2210 fail_pts_UserRename:
2219 * SetUserAccess - translate our Access notation to pts flags.
2223 * IN userP - the user structure that contains the new permissions.
2225 * OUT flags - a pointer to an afs_int32 structure that
2226 * contains the flags to pass to pts.
2230 * No locks are held by this function
2234 * Returns != 0 upon successful completion.
2239 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2243 afs_status_t tst = 0;
2247 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2251 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2255 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2270 * pts_UserModify - update a user entry.
2274 * IN cellHandle - a previously opened cellHandle that corresponds
2275 * to the cell where the group exists.
2277 * IN userName - the name of the user to update.
2279 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2280 * new information for user.
2284 * No locks are held by this function
2288 * Returns != 0 upon successful completion.
2293 pts_UserModify(const void *cellHandle, const char *userName,
2294 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2297 afs_status_t tst = 0;
2298 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2299 afs_int32 userId = 0;
2300 afs_int32 newQuota = 0;
2302 afs_int32 flags = 0;
2305 * Validate arguments
2308 if (!IsValidCellHandle(c_handle, &tst)) {
2309 goto fail_pts_UserModify;
2312 if ((userName == NULL) || (*userName == 0)) {
2313 tst = ADMPTSUSERNAMENULL;
2314 goto fail_pts_UserModify;
2317 if (newEntryP == NULL) {
2318 tst = ADMPTSNEWENTRYPNULL;
2319 goto fail_pts_UserModify;
2323 * Translate the user name into an id.
2326 if (!TranslateOneName
2327 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2328 goto fail_pts_UserModify;
2332 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2333 mask |= PR_SF_NGROUPS;
2334 newQuota = newEntryP->groupCreationQuota;
2337 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2338 mask |= PR_SF_ALLBITS;
2339 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2340 goto fail_pts_UserModify;
2349 ubik_Call(PR_SetFieldsEntry, c_handle->pts, 0, userId, mask, flags,
2353 goto fail_pts_UserModify;
2357 fail_pts_UserModify:
2366 * pts_UserMaxGet - get the maximum in use user id.
2370 * IN cellHandle - a previously opened cellHandle that corresponds
2371 * to the cell where the group exists.
2373 * OUT maxUserId - upon successful completion contains the max in use id.
2377 * No locks are held by this function
2381 * Returns != 0 upon successful completion.
2386 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2389 afs_status_t tst = 0;
2390 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2391 afs_int32 maxGroupId = 0;
2394 * Validate arguments
2397 if (!IsValidCellHandle(c_handle, &tst)) {
2398 goto fail_pts_UserMaxGet;
2401 if (maxUserId == NULL) {
2402 tst = ADMPTSMAXUSERIDNULL;
2403 goto fail_pts_UserMaxGet;
2406 tst = ubik_Call(PR_ListMax, c_handle->pts, 0, maxUserId, &maxGroupId);
2409 goto fail_pts_UserMaxGet;
2413 fail_pts_UserMaxGet:
2422 * pts_UserMaxSet - set the maximum user id.
2426 * IN cellHandle - a previously opened cellHandle that corresponds
2427 * to the cell where the group exists.
2429 * IN maxUserId - the new max user id.
2433 * No locks are held by this function
2437 * Returns != 0 upon successful completion.
2442 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2445 afs_status_t tst = 0;
2446 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2449 * Validate arguments
2452 if (!IsValidCellHandle(c_handle, &tst)) {
2453 goto fail_pts_UserMaxSet;
2456 tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxUserId, 0);
2459 goto fail_pts_UserMaxSet;
2463 fail_pts_UserMaxSet:
2472 * pts_UserMemberListBegin - begin iterating over the list of groups
2473 * a particular user belongs to.
2477 * IN cellHandle - a previously opened cellHandle that corresponds
2478 * to the cell where the group exists.
2480 * IN groupName - the group whose members will be returned.
2482 * OUT iterationIdP - upon successful completion contains a iterator that
2483 * can be passed to pts_GroupMemberListNext.
2487 * No locks are obtained or released by this function
2491 * Returns != 0 upon successful completion.
2496 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2497 void **iterationIdP, afs_status_p st)
2499 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2500 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2505 * pts_UserMemberListNext - get the next group a user belongs to
2509 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2511 * OUT userName - upon successful completion contains the next group a user
2516 * The iterator mutex is held during the retrieval of the next member.
2520 * Returns != 0 upon successful completion.
2525 pts_UserMemberListNext(const void *iterationId, char *userName,
2528 return pts_GroupMemberListNext(iterationId, userName, st);
2532 * pts_UserMemberListDone - finish using a user list iterator
2536 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2540 * The iterator is locked and then destroyed
2544 * Returns != 0 upon successful completion.
2548 * It is the user's responsibility to make sure pts_UserMemberListDone
2549 * is called only once for each iterator.
2553 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2555 return pts_GroupMemberListDone(iterationId, st);
2558 typedef struct owned_group_list {
2559 namelist owned_names; /* the list of character names owned by this id */
2560 prlist owned_ids; /* the list of pts ids owned by this id */
2561 afs_int32 index; /* the index into owned_names for the next group */
2562 afs_int32 owner; /* the pts id of the owner */
2563 afs_int32 more; /* the last parameter to PR_ListOwned */
2564 int finished_retrieving; /* set when we've processed the last owned_names */
2565 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2566 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2567 } owned_group_list_t, *owned_group_list_p;
2570 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2573 afs_status_t tst = 0;
2574 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2576 if (list->owned_names.namelist_val != NULL) {
2577 free(list->owned_names.namelist_val);
2580 if (list->owned_ids.prlist_val != NULL) {
2581 free(list->owned_ids.prlist_val);
2592 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2593 int *last_item_contains_data, afs_status_p st)
2596 afs_status_t tst = 0;
2597 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2600 * We really don't make an rpc for every entry we return here
2601 * since the pts interface allows several members to be returned
2602 * with one rpc, but we fake it to make the iterator happy.
2606 * Check to see if we are done retrieving data
2609 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2611 *last_item_contains_data = 0;
2612 goto fail_GetOwnedGroupRPC;
2616 * Check to see if we really need to make an rpc
2619 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2621 ubik_Call(PR_ListOwned, list->c_handle->pts, 0, list->owner,
2622 &list->owned_ids, &list->more);
2624 goto fail_GetOwnedGroupRPC;
2627 if (!TranslatePTSIds
2628 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2630 goto fail_GetOwnedGroupRPC;
2634 if (list->owned_names.namelist_val == NULL) {
2636 *last_item_contains_data = 0;
2637 goto fail_GetOwnedGroupRPC;
2642 * We can retrieve the next group from data we already received
2645 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2649 * Check to see if there is more data to be retrieved
2650 * We need to free up the previously retrieved data here
2651 * and then check to see if the last rpc indicated that there
2652 * were more items to retrieve.
2655 if (list->index >= list->owned_names.namelist_len) {
2656 list->owned_names.namelist_len = 0;
2657 free(list->owned_names.namelist_val);
2658 list->owned_names.namelist_val = 0;
2660 list->owned_ids.prlist_len = 0;
2661 free(list->owned_ids.prlist_val);
2662 list->owned_ids.prlist_val = 0;
2665 list->finished_retrieving = 1;
2670 fail_GetOwnedGroupRPC:
2679 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2683 afs_status_t tst = 0;
2684 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2686 strcpy((char *)dest, list->group[slot]);
2697 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2698 * a particular user owns.
2702 * IN cellHandle - a previously opened cellHandle that corresponds
2703 * to the cell where the group exists.
2705 * IN ownerName - the owner of the groups of interest.
2707 * OUT iterationIdP - upon successful completion contains a iterator that
2708 * can be passed to pts_OwnedGroupListNext.
2712 * No locks are held by this function
2716 * Returns != 0 upon successful completion.
2721 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2722 void **iterationIdP, afs_status_p st)
2725 afs_status_t tst = 0;
2726 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2727 afs_admin_iterator_p iter =
2728 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2729 owned_group_list_p list =
2730 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2733 * Validate arguments
2736 if (!IsValidCellHandle(c_handle, &tst)) {
2737 goto fail_pts_OwnedGroupListBegin;
2740 if ((userName == NULL) || (*userName == 0)) {
2741 tst = ADMPTSUSERNAMENULL;
2742 goto fail_pts_OwnedGroupListBegin;
2745 if (iterationIdP == NULL) {
2746 tst = ADMITERATORNULL;
2747 goto fail_pts_OwnedGroupListBegin;
2750 if ((iter == NULL) || (list == NULL)) {
2752 goto fail_pts_OwnedGroupListBegin;
2756 * Initialize the iterator specific data
2760 list->finished_retrieving = 0;
2761 list->c_handle = c_handle;
2762 list->owned_names.namelist_len = 0;
2763 list->owned_names.namelist_val = 0;
2764 list->owned_ids.prlist_len = 0;
2765 list->owned_ids.prlist_val = 0;
2768 * Translate the user name into an id.
2771 if (!TranslateOneName
2772 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2773 goto fail_pts_OwnedGroupListBegin;
2777 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2778 DeleteOwnedGroupSpecificData, &tst)) {
2779 *iterationIdP = (void *)iter;
2783 fail_pts_OwnedGroupListBegin:
2801 * pts_OwnedGroupListNext - get the next group a user owns.
2805 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2807 * OUT groupName - upon successful completion contains the next group a user
2812 * The iterator mutex is held during the retrieval of the next member.
2816 * Returns != 0 upon successful completion.
2821 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2825 afs_status_t tst = 0;
2826 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2829 * Validate arguments
2832 if (iterationId == NULL) {
2833 tst = ADMITERATORNULL;
2834 goto fail_pts_OwnedGroupListNext;
2837 if (groupName == NULL) {
2838 tst = ADMPTSGROUPNAMENULL;
2839 goto fail_pts_OwnedGroupListNext;
2842 rc = IteratorNext(iter, (void *)groupName, &tst);
2844 fail_pts_OwnedGroupListNext:
2853 * pts_OwnedGroupListDone - finish using a group list iterator
2857 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2861 * The iterator is locked and then destroyed
2865 * Returns != 0 upon successful completion.
2869 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2870 * is called only once for each iterator.
2874 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2877 afs_status_t tst = 0;
2878 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2881 * Validate arguments
2884 if (iterationId == NULL) {
2885 tst = ADMITERATORNULL;
2886 goto fail_pts_OwnedGroupListDone;
2889 rc = IteratorDone(iter, &tst);
2891 fail_pts_OwnedGroupListDone:
2899 typedef struct pts_list {
2900 prlistentries *names; /* the current list of pts names in this cell */
2901 prlistentries *currName; /* the current pts entry */
2902 afs_int32 index; /* the index into names for the next pts entry */
2903 afs_int32 nextstartindex; /* the next start index for the RPC */
2904 afs_int32 nentries; /* the number of entries in names */
2905 afs_int32 flag; /* the type of the list */
2906 int finished_retrieving; /* set when we've processed the last owned_names */
2907 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2908 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2909 } pts_list_t, *pts_list_p;
2912 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2915 afs_status_t tst = 0;
2916 pts_list_p list = (pts_list_p) rpc_specific;
2931 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2932 int *last_item_contains_data, afs_status_p st)
2935 afs_status_t tst = 0;
2936 pts_list_p list = (pts_list_p) rpc_specific;
2939 * We really don't make an rpc for every entry we return here
2940 * since the pts interface allows several members to be returned
2941 * with one rpc, but we fake it to make the iterator happy.
2945 * Check to see if we are done retrieving data
2948 if (list->finished_retrieving) {
2950 *last_item_contains_data = 0;
2951 goto fail_GetPTSRPC;
2955 * Check to see if we really need to make an rpc
2958 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2959 afs_int32 start = list->nextstartindex;
2960 prentries bulkentries;
2961 list->nextstartindex = -1;
2962 bulkentries.prentries_val = 0;
2963 bulkentries.prentries_len = 0;
2966 ubik_Call(PR_ListEntries, list->c_handle->pts, 0, list->flag,
2967 start, &bulkentries, &(list->nextstartindex));
2970 goto fail_GetPTSRPC;
2973 list->nentries = bulkentries.prentries_len;
2974 list->names = bulkentries.prentries_val;
2977 list->currName = list->names;
2982 * We can retrieve the next entry from data we already received
2985 strcpy(list->entries[slot], list->currName->name);
2991 * Check to see if there is more data to be retrieved
2992 * We need to free up the previously retrieved data here
2993 * and then check to see if the last rpc indicated that there
2994 * were more items to retrieve.
2997 if (list->index >= list->nentries) {
3003 if (list->nextstartindex == -1) {
3004 list->finished_retrieving = 1;
3019 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3022 afs_status_t tst = 0;
3023 pts_list_p list = (pts_list_p) rpc_specific;
3025 strcpy((char *)dest, list->entries[slot]);
3036 * pts_UserListBegin - begin iterating over the list of users
3037 * in a particular cell
3041 * IN cellHandle - a previously opened cellHandle that corresponds
3042 * to the cell where the users exist.
3044 * OUT iterationIdP - upon successful completion contains a iterator that
3045 * can be passed to pts_UserListNext.
3049 * No locks are held by this function
3053 * Returns != 0 upon successful completion.
3058 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3062 afs_status_t tst = 0;
3063 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3064 afs_admin_iterator_p iter =
3065 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3066 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3069 * Validate arguments
3072 if (!IsValidCellHandle(c_handle, &tst)) {
3073 goto fail_pts_UserListBegin;
3076 if (iterationIdP == NULL) {
3077 tst = ADMITERATORNULL;
3078 goto fail_pts_UserListBegin;
3081 if ((iter == NULL) || (list == NULL)) {
3083 goto fail_pts_UserListBegin;
3087 * Initialize the iterator specific data
3091 list->finished_retrieving = 0;
3092 list->c_handle = c_handle;
3094 list->nextstartindex = 0;
3096 list->flag = PRUSERS;
3099 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3100 DeletePTSSpecificData, &tst)) {
3101 *iterationIdP = (void *)iter;
3105 fail_pts_UserListBegin:
3123 * pts_UserListNext - get the next user in the cell.
3127 * IN iterationId - an iterator previously returned by pts_UserListBegin
3129 * OUT groupName - upon successful completion contains the next user
3133 * The iterator mutex is held during the retrieval of the next member.
3137 * Returns != 0 upon successful completion.
3142 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3145 afs_status_t tst = 0;
3146 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3149 * Validate arguments
3152 if (iterationId == NULL) {
3153 tst = ADMITERATORNULL;
3154 goto fail_pts_UserListNext;
3157 if (userName == NULL) {
3158 tst = ADMPTSUSERNAMENULL;
3159 goto fail_pts_UserListNext;
3162 rc = IteratorNext(iter, (void *)userName, &tst);
3164 fail_pts_UserListNext:
3173 * pts_UserListDone - finish using a user list iterator
3177 * IN iterationId - an iterator previously returned by pts_UserListBegin
3181 * The iterator is locked and then destroyed
3185 * Returns != 0 upon successful completion.
3189 * It is the user's responsibility to make sure pts_UserListDone
3190 * is called only once for each iterator.
3194 pts_UserListDone(const void *iterationId, afs_status_p st)
3197 afs_status_t tst = 0;
3198 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3201 * Validate arguments
3204 if (iterationId == NULL) {
3205 tst = ADMITERATORNULL;
3206 goto fail_pts_UserListDone;
3209 rc = IteratorDone(iter, &tst);
3211 fail_pts_UserListDone:
3220 * pts_GroupListBegin - begin iterating over the list of groups
3221 * in a particular cell.
3225 * IN cellHandle - a previously opened cellHandle that corresponds
3226 * to the cell where the groups exist.
3228 * OUT iterationIdP - upon successful completion contains a iterator that
3229 * can be passed to pts_GroupListNext.
3233 * No locks are held by this function
3237 * Returns != 0 upon successful completion.
3242 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3246 afs_status_t tst = 0;
3247 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3248 afs_admin_iterator_p iter =
3249 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3250 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3253 * Validate arguments
3256 if (!IsValidCellHandle(c_handle, &tst)) {
3257 goto fail_pts_GroupListBegin;
3260 if (iterationIdP == NULL) {
3261 tst = ADMITERATORNULL;
3262 goto fail_pts_GroupListBegin;
3265 if ((iter == NULL) || (list == NULL)) {
3267 goto fail_pts_GroupListBegin;
3271 * Initialize the iterator specific data
3275 list->finished_retrieving = 0;
3276 list->c_handle = c_handle;
3278 list->nextstartindex = 0;
3280 list->flag = PRGROUPS;
3283 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3284 DeletePTSSpecificData, &tst)) {
3285 *iterationIdP = (void *)iter;
3289 fail_pts_GroupListBegin:
3307 * pts_UserListNext - get the next group in a cell.
3311 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3313 * OUT groupName - upon successful completion contains the next group
3317 * The iterator mutex is held during the retrieval of the next member.
3321 * Returns != 0 upon successful completion.
3326 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3329 afs_status_t tst = 0;
3330 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3333 * Validate arguments
3336 if (iterationId == NULL) {
3337 tst = ADMITERATORNULL;
3338 goto fail_pts_GroupListNext;
3341 if (groupName == NULL) {
3342 tst = ADMPTSGROUPNAMENULL;
3343 goto fail_pts_GroupListNext;
3346 rc = IteratorNext(iter, (void *)groupName, &tst);
3348 fail_pts_GroupListNext:
3357 * pts_GroupListDone - finish using a group list iterator
3361 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3365 * The iterator is locked and then destroyed
3369 * Returns != 0 upon successful completion.
3373 * It is the user's responsibility to make sure pts_GroupListDone
3374 * is called only once for each iterator.
3378 pts_GroupListDone(const void *iterationId, afs_status_p st)
3381 afs_status_t tst = 0;
3382 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3385 * Validate arguments
3388 if (iterationId == NULL) {
3389 tst = ADMITERATORNULL;
3390 goto fail_pts_GroupListDone;
3393 rc = IteratorDone(iter, &tst);
3395 fail_pts_GroupListDone: