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