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) {
2268 * pts_UserModify - update a user entry.
2272 * IN cellHandle - a previously opened cellHandle that corresponds
2273 * to the cell where the group exists.
2275 * IN userName - the name of the user to update.
2277 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2278 * new information for user.
2282 * No locks are held by this function
2286 * Returns != 0 upon successful completion.
2291 pts_UserModify(const void *cellHandle, const char *userName,
2292 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2295 afs_status_t tst = 0;
2296 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2297 afs_int32 userId = 0;
2298 afs_int32 newQuota = 0;
2300 afs_int32 flags = 0;
2303 * Validate arguments
2306 if (!IsValidCellHandle(c_handle, &tst)) {
2307 goto fail_pts_UserModify;
2310 if ((userName == NULL) || (*userName == 0)) {
2311 tst = ADMPTSUSERNAMENULL;
2312 goto fail_pts_UserModify;
2315 if (newEntryP == NULL) {
2316 tst = ADMPTSNEWENTRYPNULL;
2317 goto fail_pts_UserModify;
2321 * Translate the user name into an id.
2324 if (!TranslateOneName
2325 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2326 goto fail_pts_UserModify;
2330 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2331 mask |= PR_SF_NGROUPS;
2332 newQuota = newEntryP->groupCreationQuota;
2335 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2336 mask |= PR_SF_ALLBITS;
2337 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2338 goto fail_pts_UserModify;
2347 ubik_Call(PR_SetFieldsEntry, c_handle->pts, 0, userId, mask, flags,
2351 goto fail_pts_UserModify;
2355 fail_pts_UserModify:
2364 * pts_UserMaxGet - get the maximum in use user id.
2368 * IN cellHandle - a previously opened cellHandle that corresponds
2369 * to the cell where the group exists.
2371 * OUT maxUserId - upon successful completion contains the max in use id.
2375 * No locks are held by this function
2379 * Returns != 0 upon successful completion.
2384 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2387 afs_status_t tst = 0;
2388 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2389 afs_int32 maxGroupId = 0;
2392 * Validate arguments
2395 if (!IsValidCellHandle(c_handle, &tst)) {
2396 goto fail_pts_UserMaxGet;
2399 if (maxUserId == NULL) {
2400 tst = ADMPTSMAXUSERIDNULL;
2401 goto fail_pts_UserMaxGet;
2404 tst = ubik_Call(PR_ListMax, c_handle->pts, 0, maxUserId, &maxGroupId);
2407 goto fail_pts_UserMaxGet;
2411 fail_pts_UserMaxGet:
2420 * pts_UserMaxSet - set the maximum user id.
2424 * IN cellHandle - a previously opened cellHandle that corresponds
2425 * to the cell where the group exists.
2427 * IN maxUserId - the new max user id.
2431 * No locks are held by this function
2435 * Returns != 0 upon successful completion.
2440 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2443 afs_status_t tst = 0;
2444 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2447 * Validate arguments
2450 if (!IsValidCellHandle(c_handle, &tst)) {
2451 goto fail_pts_UserMaxSet;
2454 tst = ubik_Call(PR_SetMax, c_handle->pts, 0, maxUserId, 0);
2457 goto fail_pts_UserMaxSet;
2461 fail_pts_UserMaxSet:
2470 * pts_UserMemberListBegin - begin iterating over the list of groups
2471 * a particular user belongs to.
2475 * IN cellHandle - a previously opened cellHandle that corresponds
2476 * to the cell where the group exists.
2478 * IN groupName - the group whose members will be returned.
2480 * OUT iterationIdP - upon successful completion contains a iterator that
2481 * can be passed to pts_GroupMemberListNext.
2485 * No locks are obtained or released by this function
2489 * Returns != 0 upon successful completion.
2494 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2495 void **iterationIdP, afs_status_p st)
2497 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2498 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2503 * pts_UserMemberListNext - get the next group a user belongs to
2507 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2509 * OUT userName - upon successful completion contains the next group a user
2514 * The iterator mutex is held during the retrieval of the next member.
2518 * Returns != 0 upon successful completion.
2523 pts_UserMemberListNext(const void *iterationId, char *userName,
2526 return pts_GroupMemberListNext(iterationId, userName, st);
2530 * pts_UserMemberListDone - finish using a user list iterator
2534 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2538 * The iterator is locked and then destroyed
2542 * Returns != 0 upon successful completion.
2546 * It is the user's responsibility to make sure pts_UserMemberListDone
2547 * is called only once for each iterator.
2551 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2553 return pts_GroupMemberListDone(iterationId, st);
2556 typedef struct owned_group_list {
2557 namelist owned_names; /* the list of character names owned by this id */
2558 prlist owned_ids; /* the list of pts ids owned by this id */
2559 afs_int32 index; /* the index into owned_names for the next group */
2560 afs_int32 owner; /* the pts id of the owner */
2561 afs_int32 more; /* the last parameter to PR_ListOwned */
2562 int finished_retrieving; /* set when we've processed the last owned_names */
2563 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2564 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2565 } owned_group_list_t, *owned_group_list_p;
2568 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2571 afs_status_t tst = 0;
2572 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2574 if (list->owned_names.namelist_val != NULL) {
2575 free(list->owned_names.namelist_val);
2578 if (list->owned_ids.prlist_val != NULL) {
2579 free(list->owned_ids.prlist_val);
2590 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2591 int *last_item_contains_data, afs_status_p st)
2594 afs_status_t tst = 0;
2595 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2598 * We really don't make an rpc for every entry we return here
2599 * since the pts interface allows several members to be returned
2600 * with one rpc, but we fake it to make the iterator happy.
2604 * Check to see if we are done retrieving data
2607 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2609 *last_item_contains_data = 0;
2610 goto fail_GetOwnedGroupRPC;
2614 * Check to see if we really need to make an rpc
2617 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2619 ubik_Call(PR_ListOwned, list->c_handle->pts, 0, list->owner,
2620 &list->owned_ids, &list->more);
2622 goto fail_GetOwnedGroupRPC;
2625 if (!TranslatePTSIds
2626 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2628 goto fail_GetOwnedGroupRPC;
2632 if (list->owned_names.namelist_val == NULL) {
2634 *last_item_contains_data = 0;
2635 goto fail_GetOwnedGroupRPC;
2640 * We can retrieve the next group from data we already received
2643 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2647 * Check to see if there is more data to be retrieved
2648 * We need to free up the previously retrieved data here
2649 * and then check to see if the last rpc indicated that there
2650 * were more items to retrieve.
2653 if (list->index >= list->owned_names.namelist_len) {
2654 list->owned_names.namelist_len = 0;
2655 free(list->owned_names.namelist_val);
2656 list->owned_names.namelist_val = 0;
2658 list->owned_ids.prlist_len = 0;
2659 free(list->owned_ids.prlist_val);
2660 list->owned_ids.prlist_val = 0;
2663 list->finished_retrieving = 1;
2668 fail_GetOwnedGroupRPC:
2677 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2681 afs_status_t tst = 0;
2682 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2684 strcpy((char *)dest, list->group[slot]);
2695 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2696 * a particular user owns.
2700 * IN cellHandle - a previously opened cellHandle that corresponds
2701 * to the cell where the group exists.
2703 * IN ownerName - the owner of the groups of interest.
2705 * OUT iterationIdP - upon successful completion contains a iterator that
2706 * can be passed to pts_OwnedGroupListNext.
2710 * No locks are held by this function
2714 * Returns != 0 upon successful completion.
2719 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2720 void **iterationIdP, afs_status_p st)
2723 afs_status_t tst = 0;
2724 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2725 afs_admin_iterator_p iter =
2726 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2727 owned_group_list_p list =
2728 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2731 * Validate arguments
2734 if (!IsValidCellHandle(c_handle, &tst)) {
2735 goto fail_pts_OwnedGroupListBegin;
2738 if ((userName == NULL) || (*userName == 0)) {
2739 tst = ADMPTSUSERNAMENULL;
2740 goto fail_pts_OwnedGroupListBegin;
2743 if (iterationIdP == NULL) {
2744 tst = ADMITERATORNULL;
2745 goto fail_pts_OwnedGroupListBegin;
2748 if ((iter == NULL) || (list == NULL)) {
2750 goto fail_pts_OwnedGroupListBegin;
2754 * Initialize the iterator specific data
2758 list->finished_retrieving = 0;
2759 list->c_handle = c_handle;
2760 list->owned_names.namelist_len = 0;
2761 list->owned_names.namelist_val = 0;
2762 list->owned_ids.prlist_len = 0;
2763 list->owned_ids.prlist_val = 0;
2766 * Translate the user name into an id.
2769 if (!TranslateOneName
2770 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2771 goto fail_pts_OwnedGroupListBegin;
2775 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2776 DeleteOwnedGroupSpecificData, &tst)) {
2777 *iterationIdP = (void *)iter;
2781 fail_pts_OwnedGroupListBegin:
2799 * pts_OwnedGroupListNext - get the next group a user owns.
2803 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2805 * OUT groupName - upon successful completion contains the next group a user
2810 * The iterator mutex is held during the retrieval of the next member.
2814 * Returns != 0 upon successful completion.
2819 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2823 afs_status_t tst = 0;
2824 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2827 * Validate arguments
2830 if (iterationId == NULL) {
2831 tst = ADMITERATORNULL;
2832 goto fail_pts_OwnedGroupListNext;
2835 if (groupName == NULL) {
2836 tst = ADMPTSGROUPNAMENULL;
2837 goto fail_pts_OwnedGroupListNext;
2840 rc = IteratorNext(iter, (void *)groupName, &tst);
2842 fail_pts_OwnedGroupListNext:
2851 * pts_OwnedGroupListDone - finish using a group list iterator
2855 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2859 * The iterator is locked and then destroyed
2863 * Returns != 0 upon successful completion.
2867 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2868 * is called only once for each iterator.
2872 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2875 afs_status_t tst = 0;
2876 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2879 * Validate arguments
2882 if (iterationId == NULL) {
2883 tst = ADMITERATORNULL;
2884 goto fail_pts_OwnedGroupListDone;
2887 rc = IteratorDone(iter, &tst);
2889 fail_pts_OwnedGroupListDone:
2897 typedef struct pts_list {
2898 prlistentries *names; /* the current list of pts names in this cell */
2899 prlistentries *currName; /* the current pts entry */
2900 afs_int32 index; /* the index into names for the next pts entry */
2901 afs_int32 nextstartindex; /* the next start index for the RPC */
2902 afs_int32 nentries; /* the number of entries in names */
2903 afs_int32 flag; /* the type of the list */
2904 int finished_retrieving; /* set when we've processed the last owned_names */
2905 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2906 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2907 } pts_list_t, *pts_list_p;
2910 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2913 afs_status_t tst = 0;
2914 pts_list_p list = (pts_list_p) rpc_specific;
2929 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2930 int *last_item_contains_data, afs_status_p st)
2933 afs_status_t tst = 0;
2934 pts_list_p list = (pts_list_p) rpc_specific;
2937 * We really don't make an rpc for every entry we return here
2938 * since the pts interface allows several members to be returned
2939 * with one rpc, but we fake it to make the iterator happy.
2943 * Check to see if we are done retrieving data
2946 if (list->finished_retrieving) {
2948 *last_item_contains_data = 0;
2949 goto fail_GetPTSRPC;
2953 * Check to see if we really need to make an rpc
2956 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2957 afs_int32 start = list->nextstartindex;
2958 prentries bulkentries;
2959 list->nextstartindex = -1;
2960 bulkentries.prentries_val = 0;
2961 bulkentries.prentries_len = 0;
2964 ubik_Call(PR_ListEntries, list->c_handle->pts, 0, list->flag,
2965 start, &bulkentries, &(list->nextstartindex));
2968 goto fail_GetPTSRPC;
2971 list->nentries = bulkentries.prentries_len;
2972 list->names = bulkentries.prentries_val;
2975 list->currName = list->names;
2980 * We can retrieve the next entry from data we already received
2983 strcpy(list->entries[slot], list->currName->name);
2989 * Check to see if there is more data to be retrieved
2990 * We need to free up the previously retrieved data here
2991 * and then check to see if the last rpc indicated that there
2992 * were more items to retrieve.
2995 if (list->index >= list->nentries) {
3001 if (list->nextstartindex == -1) {
3002 list->finished_retrieving = 1;
3017 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3020 afs_status_t tst = 0;
3021 pts_list_p list = (pts_list_p) rpc_specific;
3023 strcpy((char *)dest, list->entries[slot]);
3034 * pts_UserListBegin - begin iterating over the list of users
3035 * in a particular cell
3039 * IN cellHandle - a previously opened cellHandle that corresponds
3040 * to the cell where the users exist.
3042 * OUT iterationIdP - upon successful completion contains a iterator that
3043 * can be passed to pts_UserListNext.
3047 * No locks are held by this function
3051 * Returns != 0 upon successful completion.
3056 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3060 afs_status_t tst = 0;
3061 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3062 afs_admin_iterator_p iter =
3063 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3064 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3067 * Validate arguments
3070 if (!IsValidCellHandle(c_handle, &tst)) {
3071 goto fail_pts_UserListBegin;
3074 if (iterationIdP == NULL) {
3075 tst = ADMITERATORNULL;
3076 goto fail_pts_UserListBegin;
3079 if ((iter == NULL) || (list == NULL)) {
3081 goto fail_pts_UserListBegin;
3085 * Initialize the iterator specific data
3089 list->finished_retrieving = 0;
3090 list->c_handle = c_handle;
3092 list->nextstartindex = 0;
3094 list->flag = PRUSERS;
3097 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3098 DeletePTSSpecificData, &tst)) {
3099 *iterationIdP = (void *)iter;
3103 fail_pts_UserListBegin:
3121 * pts_UserListNext - get the next user in the cell.
3125 * IN iterationId - an iterator previously returned by pts_UserListBegin
3127 * OUT groupName - upon successful completion contains the next user
3131 * The iterator mutex is held during the retrieval of the next member.
3135 * Returns != 0 upon successful completion.
3140 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3143 afs_status_t tst = 0;
3144 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3147 * Validate arguments
3150 if (iterationId == NULL) {
3151 tst = ADMITERATORNULL;
3152 goto fail_pts_UserListNext;
3155 if (userName == NULL) {
3156 tst = ADMPTSUSERNAMENULL;
3157 goto fail_pts_UserListNext;
3160 rc = IteratorNext(iter, (void *)userName, &tst);
3162 fail_pts_UserListNext:
3171 * pts_UserListDone - finish using a user list iterator
3175 * IN iterationId - an iterator previously returned by pts_UserListBegin
3179 * The iterator is locked and then destroyed
3183 * Returns != 0 upon successful completion.
3187 * It is the user's responsibility to make sure pts_UserListDone
3188 * is called only once for each iterator.
3192 pts_UserListDone(const void *iterationId, afs_status_p st)
3195 afs_status_t tst = 0;
3196 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3199 * Validate arguments
3202 if (iterationId == NULL) {
3203 tst = ADMITERATORNULL;
3204 goto fail_pts_UserListDone;
3207 rc = IteratorDone(iter, &tst);
3209 fail_pts_UserListDone:
3218 * pts_GroupListBegin - begin iterating over the list of groups
3219 * in a particular cell.
3223 * IN cellHandle - a previously opened cellHandle that corresponds
3224 * to the cell where the groups exist.
3226 * OUT iterationIdP - upon successful completion contains a iterator that
3227 * can be passed to pts_GroupListNext.
3231 * No locks are held by this function
3235 * Returns != 0 upon successful completion.
3240 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3244 afs_status_t tst = 0;
3245 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3246 afs_admin_iterator_p iter =
3247 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3248 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3251 * Validate arguments
3254 if (!IsValidCellHandle(c_handle, &tst)) {
3255 goto fail_pts_GroupListBegin;
3258 if (iterationIdP == NULL) {
3259 tst = ADMITERATORNULL;
3260 goto fail_pts_GroupListBegin;
3263 if ((iter == NULL) || (list == NULL)) {
3265 goto fail_pts_GroupListBegin;
3269 * Initialize the iterator specific data
3273 list->finished_retrieving = 0;
3274 list->c_handle = c_handle;
3276 list->nextstartindex = 0;
3278 list->flag = PRGROUPS;
3281 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3282 DeletePTSSpecificData, &tst)) {
3283 *iterationIdP = (void *)iter;
3287 fail_pts_GroupListBegin:
3305 * pts_UserListNext - get the next group in a cell.
3309 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3311 * OUT groupName - upon successful completion contains the next group
3315 * The iterator mutex is held during the retrieval of the next member.
3319 * Returns != 0 upon successful completion.
3324 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3327 afs_status_t tst = 0;
3328 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3331 * Validate arguments
3334 if (iterationId == NULL) {
3335 tst = ADMITERATORNULL;
3336 goto fail_pts_GroupListNext;
3339 if (groupName == NULL) {
3340 tst = ADMPTSGROUPNAMENULL;
3341 goto fail_pts_GroupListNext;
3344 rc = IteratorNext(iter, (void *)groupName, &tst);
3346 fail_pts_GroupListNext:
3355 * pts_GroupListDone - finish using a group list iterator
3359 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3363 * The iterator is locked and then destroyed
3367 * Returns != 0 upon successful completion.
3371 * It is the user's responsibility to make sure pts_GroupListDone
3372 * is called only once for each iterator.
3376 pts_GroupListDone(const void *iterationId, afs_status_p st)
3379 afs_status_t tst = 0;
3380 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3383 * Validate arguments
3386 if (iterationId == NULL) {
3387 tst = ADMITERATORNULL;
3388 goto fail_pts_GroupListDone;
3391 rc = IteratorDone(iter, &tst);
3393 fail_pts_GroupListDone: