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>
20 #include "afs_ptsAdmin.h"
21 #include "../adminutil/afs_AdminInternal.h"
22 #include <afs/afs_AdminErrors.h>
23 #include <afs/afs_utilAdmin.h>
24 #include <afs/ptint.h>
25 #include <afs/ptserver.h>
28 * IsValidCellHandle - validate the cell handle for making pts
33 * IN cellHandle - a previously opened cellHandle that is to be validated.
37 * No locks are obtained or released by this function
41 * Returns != 0 upon successful completion.
46 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
51 if (!CellHandleIsValid((void *)c_handle, &tst)) {
52 goto fail_IsValidCellHandle;
55 if (c_handle->pts_valid == 0) {
56 tst = ADMCLIENTCELLPTSINVALID;
57 goto fail_IsValidCellHandle;
60 if (c_handle->pts == NULL) {
61 tst = ADMCLIENTCELLPTSNULL;
62 goto fail_IsValidCellHandle;
67 fail_IsValidCellHandle:
77 * TranslatePTSNames - translate character representations of pts names
78 * into their numeric equivalent.
82 * IN cellHandle - a previously opened cellHandle that corresponds
83 * to the cell where the id's exist.
85 * IN names - the list of names to be translated.
87 * OUT ids - the list of translated names
91 * No locks are obtained or released by this function
95 * Returns != 0 upon successful completion.
100 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
101 idlist * ids, afs_status_p st)
104 afs_status_t tst = 0;
109 * Lowercase the names to translate
112 for (i = 0; i < names->namelist_len; i++) {
113 p = names->namelist_val[i];
120 tst = ubik_PR_NameToID(cellHandle->pts, 0, names, ids);
123 goto fail_TranslatePTSNames;
128 * Check to see if the lookup failed
131 for (i = 0; i < ids->idlist_len; i++) {
132 if (ids->idlist_val[i] == ANONYMOUSID) {
133 tst = ADMPTSFAILEDNAMETRANSLATE;
134 goto fail_TranslatePTSNames;
139 fail_TranslatePTSNames:
148 * TranslateTwoNames - translate two pts names to their pts ids.
152 * IN cellHandle - a previously opened cellHandle that corresponds
153 * to the cell where the group exists.
155 * IN id1 - one id to be translated
157 * IN error1 - the error status to be returned in the event that id1 is
160 * IN id2 - one id to be translated
162 * IN error2 - the error status to be returned in the event that id2 is
166 * OUT idlist - the list of pts id's
170 * No locks are obtained or released by this function
174 * Returns != 0 upon successful completion.
179 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
180 afs_status_t error1, const char *id2, afs_status_t error2,
181 idlist * ids, afs_status_p st)
184 afs_status_t tst = 0;
186 char tmp_array[2 * PTS_MAX_NAME_LEN];
189 * Copy the group and user names in order to translate them
192 names.namelist_len = 2;
193 names.namelist_val = (prname *) & tmp_array[0];
195 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
196 names.namelist_val[0][PTS_MAX_NAME_LEN - 1] = '\0';
197 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
198 names.namelist_val[1][PTS_MAX_NAME_LEN - 1] = '\0';
203 * Check that user and group aren't too long
204 * This is a cheaper check than calling strlen
207 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
209 goto fail_TranslateTwoNames;
212 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
214 goto fail_TranslateTwoNames;
218 * Translate user and group into pts ID's
221 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
222 goto fail_TranslateTwoNames;
227 fail_TranslateTwoNames:
236 * TranslateOneName - translate a pts name to its pts id.
240 * IN cellHandle - a previously opened cellHandle that corresponds
241 * to the cell where the group exists.
243 * IN userName - the user to be translated.
245 * OUT idlist - the user pts id.
249 * No locks are obtained or released by this function
253 * Returns != 0 upon successful completion.
258 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
259 afs_status_t tooLongError, afs_int32 * ptsId,
263 afs_status_t tst = 0;
265 char tmp_array[PTS_MAX_NAME_LEN];
269 * Copy the name in order to translate it
272 names[0].namelist_len = 1;
273 names[0].namelist_val = (prname *) & tmp_array[0];
275 strncpy((char *)names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
276 ((char *)names[0].namelist_val)[PTS_MAX_NAME_LEN - 1] = '\0';
281 * Check that user isn't too long
282 * This is a cheaper check than calling strlen
285 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
287 goto fail_TranslateOneName;
291 * Translate user into pts ID
294 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
295 goto fail_TranslateOneName;
297 if (ids.idlist_val != NULL) {
298 *ptsId = *ids.idlist_val;
299 free(ids.idlist_val);
305 fail_TranslateOneName:
314 * TranslatePTSIds - translate numeric representations of pts names
315 * into their character equivalent.
319 * IN cellHandle - a previously opened cellHandle that corresponds
320 * to the cell where the id's exist.
322 * IN ids - the list of ids to be translated.
324 * OUT names - the list of translated names
328 * No locks are obtained or released by this function
332 * Returns != 0 upon successful completion.
337 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
338 idlist * ids, afs_status_p st)
341 afs_status_t tst = 0;
343 tst = ubik_PR_IDToName(cellHandle->pts, 0, ids, names);
346 goto fail_TranslatePTSIds;
350 fail_TranslatePTSIds:
359 * pts_GroupMemberAdd - add one member to a pts group
363 * IN cellHandle - a previously opened cellHandle that corresponds
364 * to the cell where the group exists.
366 * IN userName - the name to be added to the group.
368 * IN groupName - the group to be modified.
372 * No locks are obtained or released by this function
376 * Returns != 0 upon successful completion.
381 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
382 const char *groupName, afs_status_p st)
385 afs_status_t tst = 0;
386 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
393 if (!IsValidCellHandle(c_handle, &tst)) {
394 goto fail_pts_GroupMemberAdd;
397 if ((userName == NULL) || (*userName == 0)) {
398 tst = ADMPTSUSERNAMENULL;
399 goto fail_pts_GroupMemberAdd;
402 if ((groupName == NULL) || (*groupName == 0)) {
403 tst = ADMPTSGROUPNAMENULL;
404 goto fail_pts_GroupMemberAdd;
407 if (!TranslateTwoNames
408 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
409 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
410 goto fail_pts_GroupMemberAdd;
418 ubik_PR_AddToGroup(c_handle->pts, 0, ids.idlist_val[0],
422 goto fail_pts_GroupMemberAdd;
426 fail_pts_GroupMemberAdd:
428 if (ids.idlist_val != 0) {
429 free(ids.idlist_val);
439 * pts_GroupOwnerChange - change the owner of a group
443 * IN cellHandle - a previously opened cellHandle that corresponds
444 * to the cell where the group exists.
446 * IN targetGroup - the group to be modified.
448 * IN userName - the new owner of the group.
452 * No locks are obtained or released by this function
456 * Returns != 0 upon successful completion.
461 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
462 const char *newOwner, afs_status_p st)
465 afs_status_t tst = 0;
466 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
473 if (!IsValidCellHandle(c_handle, &tst)) {
474 goto fail_pts_GroupOwnerChange;
477 if ((newOwner == NULL) || (*newOwner == 0)) {
478 tst = ADMPTSNEWOWNERNULL;
479 goto fail_pts_GroupOwnerChange;
482 if ((targetGroup == NULL) || (*targetGroup == 0)) {
483 tst = ADMPTSTARGETGROUPNULL;
484 goto fail_pts_GroupOwnerChange;
487 if (!TranslateTwoNames
488 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
489 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
490 goto fail_pts_GroupOwnerChange;
498 ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
499 ids.idlist_val[0], 0);
502 goto fail_pts_GroupOwnerChange;
506 fail_pts_GroupOwnerChange:
508 if (ids.idlist_val != 0) {
509 free(ids.idlist_val);
519 * pts_GroupCreate - create a new group
523 * IN cellHandle - a previously opened cellHandle that corresponds
524 * to the cell where the group exists.
526 * IN newGroup - the group to be created.
528 * IN newOwner - the owner of the group. Pass NULL if the current user
529 * is to be the new owner, or the character string of the owner otherwise.
531 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
532 * generate a value, != 0 to assign a value on your own. The group id
533 * that is used to create the group is copied into this parameter in the
534 * event you pass in 0.
538 * No locks are obtained or released by this function
542 * Returns != 0 upon successful completion.
547 pts_GroupCreate(const void *cellHandle, char *newGroup,
548 char *newOwner, int *newGroupId, afs_status_p st)
551 afs_status_t tst = 0;
552 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
553 afs_int32 newOwnerId = 0;
559 if (!IsValidCellHandle(c_handle, &tst)) {
560 goto fail_pts_GroupCreate;
563 if ((newGroup == NULL) || (*newGroup == 0)) {
564 tst = ADMPTSNEWGROUPNULL;
565 goto fail_pts_GroupCreate;
568 if (newGroupId == NULL) {
569 tst = ADMPTSNEWGROUPIDNULL;
570 goto fail_pts_GroupCreate;
573 if (*newGroupId > 0) {
574 tst = ADMPTSNEWGROUPIDPOSITIVE;
575 goto fail_pts_GroupCreate;
579 * If a newOwner was specified, validate that it exists
582 if (newOwner != NULL) {
583 if (!TranslateOneName
584 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
585 goto fail_pts_GroupCreate;
590 * We make a different rpc based upon the input to this function
593 if (*newGroupId != 0) {
595 ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
599 ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
600 newOwnerId, newGroupId);
604 goto fail_pts_GroupCreate;
608 fail_pts_GroupCreate:
617 * GetGroupAccess - a small convenience function for setting
622 * IN access - a pointer to a pts_groupAccess_t to be set with the
623 * correct permission.
625 * IN flag - the current permission flag used to derive the permission.
629 * No locks are obtained or released by this function
633 * Since this function cannot fail, it returns void.
638 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
641 *access = PTS_GROUP_OWNER_ACCESS;
643 *access = PTS_GROUP_OWNER_ACCESS;
644 } else if (flag == 1) {
645 *access = PTS_GROUP_ACCESS;
646 } else if (flag == 2) {
647 *access = PTS_GROUP_ANYUSER_ACCESS;
653 * pts_GroupGet - retrieve information about a particular group.
657 * IN cellHandle - a previously opened cellHandle that corresponds
658 * to the cell where the group exists.
660 * IN groupName - the group to retrieve.
662 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
663 * successful completion is filled with information about groupName.
667 * No locks are obtained or released by this function
671 * Returns != 0 upon successful completion.
676 pts_GroupGet(const void *cellHandle, const char *groupName,
677 pts_GroupEntry_p groupP, afs_status_p st)
680 afs_status_t tst = 0;
681 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
682 afs_int32 groupId = 0;
685 struct prcheckentry groupEntry;
694 if (!IsValidCellHandle(c_handle, &tst)) {
695 goto fail_pts_GroupGet;
698 if ((groupName == NULL) || (*groupName == 0)) {
699 tst = ADMPTSGROUPNAMENULL;
700 goto fail_pts_GroupGet;
703 if (groupP == NULL) {
704 tst = ADMPTSGROUPPNULL;
705 goto fail_pts_GroupGet;
709 * Translate the group name into an id.
712 if (!TranslateOneName
713 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
714 goto fail_pts_GroupGet;
718 * Retrieve information about the group
721 tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
724 goto fail_pts_GroupGet;
727 groupP->membershipCount = groupEntry.count;
728 groupP->nameUid = groupEntry.id;
729 groupP->ownerUid = groupEntry.owner;
730 groupP->creatorUid = groupEntry.creator;
731 strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
732 groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
734 * Set the access rights based upon the value of the flags member
735 * of the groupEntry struct.
737 * To the best of my ability to decypher the pts code, it looks like
738 * the rights are stored in flags as follows:
740 * I number my bits from least significant to most significant starting
744 * if bit 0 == 0 -> r access is denied
745 * if bit 0 == 1 -> r access is granted
748 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
749 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
750 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
751 * if bit 2 == 1 and bit 1 == 1 -> this is an error
753 * membership - bits 3 and 4
754 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
755 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
756 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
757 * if bit 4 == 1 and bit 3 == 1 -> this is an error
760 * if bit 5 == 0 -> O access is denied
761 * if bit 5 == 1 -> O access is granted
763 * status - bits 6 and 7
764 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
765 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
766 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
767 * if bit 7 == 1 and bit 6 == 1 -> this is an error
769 * For cases where the permission doesn't make sense for the
770 * type of entry, or where an error occurs, we ignore it.
771 * This is the behavior of the pts code.
774 flags = groupEntry.flags;
776 groupP->listDelete = PTS_GROUP_ACCESS;
778 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
784 GetGroupAccess(&groupP->listAdd, twobit);
789 GetGroupAccess(&groupP->listMembership, twobit);
794 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
796 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
802 GetGroupAccess(&groupP->listStatus, twobit);
805 * Make another rpc and translate the owner and creator ids into
810 ids.idlist_val = ptsids;
811 ptsids[0] = groupEntry.owner;
812 ptsids[1] = groupEntry.creator;
813 names.namelist_len = 0;
814 names.namelist_val = 0;
817 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
818 goto fail_pts_GroupGet;
821 strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
822 groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
823 strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
824 groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
825 free(names.namelist_val);
837 * EntryDelete - delete a pts entry (group or user).
841 * IN cellHandle - a previously opened cellHandle that corresponds
842 * to the cell where the group exists.
844 * IN entryName - the entry to be deleted.
846 * IN error1 - the error status to be returned in the event that entryName is
849 * IN error2 - the error status to be returned in the event that entryName is
854 * No locks are obtained or released by this function
858 * Returns != 0 upon successful completion.
863 EntryDelete(const void *cellHandle, const char *entryName,
864 afs_status_t error1, afs_status_t error2, afs_status_p st)
867 afs_status_t tst = 0;
868 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
869 afs_int32 entryId = 0;
875 if (!IsValidCellHandle(c_handle, &tst)) {
876 goto fail_EntryDelete;
879 if ((entryName == NULL) || (*entryName == 0)) {
881 goto fail_EntryDelete;
885 * Translate the entry name into an id.
888 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
889 goto fail_EntryDelete;
896 tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
899 goto fail_EntryDelete;
913 * pts_GroupDelete - delete a group
917 * IN cellHandle - a previously opened cellHandle that corresponds
918 * to the cell where the group exists.
920 * IN groupName - the group to be deleted.
924 * No locks are obtained or released by this function
928 * Returns != 0 upon successful completion.
933 pts_GroupDelete(const void *cellHandle, const char *groupName,
937 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
938 ADMPTSGROUPNAMETOOLONG, st);
942 * pts_GroupMaxGet - get the maximum in use group id.
946 * IN cellHandle - a previously opened cellHandle that corresponds
947 * to the cell where the group exists.
949 * OUT maxGroupId - upon successful completion contains the maximum
950 * group Id in use at the server.
954 * No locks are obtained or released by this function
958 * Returns != 0 upon successful completion.
963 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
966 afs_status_t tst = 0;
967 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
968 afs_int32 maxUserId = 0;
974 if (!IsValidCellHandle(c_handle, &tst)) {
975 goto fail_pts_GroupMaxGet;
978 if (maxGroupId == NULL) {
979 tst = ADMPTSMAXGROUPIDNULL;
980 goto fail_pts_GroupMaxGet;
983 tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
986 goto fail_pts_GroupMaxGet;
990 fail_pts_GroupMaxGet:
999 * pts_GroupMaxSet - set the maximum in use group id.
1003 * IN cellHandle - a previously opened cellHandle that corresponds
1004 * to the cell where the group exists.
1006 * IN maxGroupId - the new maximum group id.
1010 * No locks are obtained or released by this function
1014 * Returns != 0 upon successful completion.
1019 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1022 afs_status_t tst = 0;
1023 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1026 * Validate arguments
1029 if (!IsValidCellHandle(c_handle, &tst)) {
1030 goto fail_pts_GroupMaxSet;
1033 tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
1036 goto fail_pts_GroupMaxSet;
1040 fail_pts_GroupMaxSet:
1051 * I'm not using the common iterator pattern here since the retrival
1052 * of the member list is actually accomplished in 1 rpc. There's no
1053 * sense in trying to fit this pts specific behavior into the more
1054 * generic model, so instead the Begin functions actually do all the
1055 * rpc work and the next/done functions just manipulate the retrieved
1059 typedef struct pts_group_member_list_iterator {
1062 pthread_mutex_t mutex; /* hold to manipulate this structure */
1067 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1070 * pts_GroupMemberListBegin - begin iterating over the list of members
1071 * of a particular group.
1075 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1079 * No locks are obtained or released by this function
1083 * Returns != 0 upon successful completion.
1088 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1092 afs_status_t tst = 0;
1095 tst = ADMITERATORNULL;
1096 goto fail_IsValidPtsGroupMemberListIterator;
1099 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1100 tst = ADMITERATORBADMAGICNULL;
1101 goto fail_IsValidPtsGroupMemberListIterator;
1104 if (iter->is_valid == 0) {
1105 tst = ADMITERATORINVALID;
1106 goto fail_IsValidPtsGroupMemberListIterator;
1110 fail_IsValidPtsGroupMemberListIterator:
1119 * MemberListBegin - an internal function which is used to get both
1120 * the list of members in a group and the list of groups a user belongs
1125 * IN cellHandle - a previously opened cellHandle that corresponds
1126 * to the cell where the group exists.
1128 * IN name - the name whose membership will be retrieved.
1130 * OUT iterationIdP - upon successful completion contains a iterator that
1131 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1135 * No locks are obtained or released by this function
1139 * Returns != 0 upon successful completion.
1144 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1145 afs_status_t error2, void **iterationIdP, afs_status_p st)
1148 afs_status_t tst = 0;
1149 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1150 afs_int32 groupId = 0;
1151 afs_int32 exceeded = 0;
1152 pts_group_member_list_iterator_p iter = (pts_group_member_list_iterator_p)
1153 malloc(sizeof(pts_group_member_list_iterator_t));
1154 int iter_allocated = 0;
1155 int ids_allocated = 0;
1156 int names_allocated = 0;
1157 int mutex_inited = 0;
1160 * Validate arguments
1163 if (!IsValidCellHandle(c_handle, &tst)) {
1164 goto fail_MemberListBegin;
1167 if ((name == NULL) || (*name == 0)) {
1168 tst = ADMPTSGROUPNAMENULL;
1169 goto fail_MemberListBegin;
1172 if (iterationIdP == NULL) {
1173 tst = ADMITERATORNULL;
1174 goto fail_MemberListBegin;
1179 goto fail_MemberListBegin;
1185 * Translate the name into an id.
1188 if (!TranslateOneName
1189 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1190 goto fail_MemberListBegin;
1193 if (pthread_mutex_init(&iter->mutex, 0)) {
1195 goto fail_MemberListBegin;
1200 iter->ids.prlist_len = 0;
1201 iter->ids.prlist_val = 0;
1204 ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
1208 goto fail_MemberListBegin;
1211 if (exceeded != 0) {
1212 tst = ADMPTSGROUPMEMEXCEEDED;
1213 goto fail_MemberListBegin;
1217 iter->names.namelist_len = 0;
1218 iter->names.namelist_val = 0;
1220 if (!TranslatePTSIds
1221 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1222 goto fail_MemberListBegin;
1225 names_allocated = 1;
1226 iter->begin_magic = BEGIN_MAGIC;
1227 iter->end_magic = END_MAGIC;
1231 *iterationIdP = (void *)iter;
1234 fail_MemberListBegin:
1236 if (ids_allocated) {
1237 free(iter->ids.prlist_val);
1241 if (names_allocated) {
1242 free(iter->names.namelist_val);
1245 pthread_mutex_destroy(&iter->mutex);
1247 if (iter_allocated) {
1259 * pts_GroupMemberListBegin - begin iterating over the list of members
1260 * of a particular group.
1264 * IN cellHandle - a previously opened cellHandle that corresponds
1265 * to the cell where the group exists.
1267 * IN groupName - the group whose members will be returned.
1269 * OUT iterationIdP - upon successful completion contains a iterator that
1270 * can be passed to pts_GroupMemberListNext.
1274 * No locks are obtained or released by this function
1278 * Returns != 0 upon successful completion.
1283 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1284 void **iterationIdP, afs_status_p st)
1286 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1287 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1291 * pts_GroupMemberListNext - get the next member of a group
1295 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1297 * OUT memberName - upon successful completion contains the next member of
1302 * The iterator mutex is held during the retrieval of the next member.
1306 * Returns != 0 upon successful completion.
1311 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1315 afs_status_t tst = 0;
1316 pts_group_member_list_iterator_p iter =
1317 (pts_group_member_list_iterator_p) iterationId;
1318 int mutex_locked = 0;
1321 * Validate arguments
1325 tst = ADMITERATORNULL;
1326 goto fail_pts_GroupMemberListNext;
1329 if (memberName == NULL) {
1330 tst = ADMPTSMEMBERNAMENULL;
1331 goto fail_pts_GroupMemberListNext;
1335 * Lock the mutex and check the validity of the iterator
1338 if (pthread_mutex_lock(&iter->mutex)) {
1340 goto fail_pts_GroupMemberListNext;
1345 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1346 goto fail_pts_GroupMemberListNext;
1350 * Check to see if we've copied out all the data. If we haven't,
1351 * copy another item. If we have, mark the iterator done.
1354 if (iter->index >= iter->names.namelist_len) {
1355 tst = ADMITERATORDONE;
1356 goto fail_pts_GroupMemberListNext;
1358 strcpy(memberName, iter->names.namelist_val[iter->index]);
1363 fail_pts_GroupMemberListNext:
1366 pthread_mutex_unlock(&iter->mutex);
1376 * pts_GroupMemberListDone - finish using a member list iterator
1380 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1384 * The iterator is locked and then destroyed
1388 * Returns != 0 upon successful completion.
1392 * It is the user's responsibility to make sure pts_GroupMemberListDone
1393 * is called only once for each iterator.
1397 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1400 afs_status_t tst = 0;
1401 pts_group_member_list_iterator_p iter =
1402 (pts_group_member_list_iterator_p) iterationId;
1403 int mutex_locked = 0;
1406 * Validate arguments
1410 tst = ADMITERATORNULL;
1411 goto fail_pts_GroupMemberListDone;
1415 * Lock the mutex and check the validity of the iterator
1418 if (pthread_mutex_lock(&iter->mutex)) {
1420 goto fail_pts_GroupMemberListDone;
1425 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1426 goto fail_pts_GroupMemberListDone;
1430 * Free the namelist and the iterator.
1433 pthread_mutex_destroy(&iter->mutex);
1436 free(iter->names.namelist_val);
1440 fail_pts_GroupMemberListDone:
1443 pthread_mutex_unlock(&iter->mutex);
1453 * pts_GroupMemberRemove - remove a member from a group.
1457 * IN cellHandle - a previously opened cellHandle that corresponds
1458 * to the cell where the group exists.
1460 * IN userName - the user to remove.
1462 * IN groupName - the group to modify
1466 * No locks are held by this function
1470 * Returns != 0 upon successful completion.
1475 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1476 const char *groupName, afs_status_p st)
1479 afs_status_t tst = 0;
1480 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1483 ids.idlist_val = NULL;
1486 * Validate arguments
1489 if (!IsValidCellHandle(c_handle, &tst)) {
1490 goto fail_pts_GroupMemberRemove;
1493 if ((userName == NULL) || (*userName == 0)) {
1494 tst = ADMPTSUSERNAMENULL;
1495 goto fail_pts_GroupMemberRemove;
1498 if ((groupName == NULL) || (*groupName == 0)) {
1499 tst = ADMPTSGROUPNAMENULL;
1500 goto fail_pts_GroupMemberRemove;
1503 if (!TranslateTwoNames
1504 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1505 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1506 goto fail_pts_GroupMemberRemove;
1514 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1518 goto fail_pts_GroupMemberRemove;
1522 fail_pts_GroupMemberRemove:
1524 if (ids.idlist_val != 0) {
1525 free(ids.idlist_val);
1535 * pts_GroupRename - change the name of a group
1539 * IN cellHandle - a previously opened cellHandle that corresponds
1540 * to the cell where the group exists.
1542 * IN oldName - the current group name
1544 * IN newName - the new group name
1548 * No locks are held by this function
1552 * Returns != 0 upon successful completion.
1557 pts_GroupRename(const void *cellHandle, const char *oldName,
1558 char *newName, afs_status_p st)
1561 afs_status_t tst = 0;
1562 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1563 afs_int32 groupId = 0;
1566 * Validate arguments
1569 if (!IsValidCellHandle(c_handle, &tst)) {
1570 goto fail_pts_GroupRename;
1573 if ((newName == NULL) || (*newName == 0)) {
1574 tst = ADMPTSNEWNAMENULL;
1575 goto fail_pts_GroupRename;
1578 if ((oldName == NULL) || (*oldName == 0)) {
1579 tst = ADMPTSOLDNAMENULL;
1580 goto fail_pts_GroupRename;
1584 * Translate the group name into an id.
1587 if (!TranslateOneName
1588 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1589 goto fail_pts_GroupRename;
1596 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1599 goto fail_pts_GroupRename;
1603 fail_pts_GroupRename:
1612 * SetGroupAccess - translate our Access notation to pts flags.
1616 * IN rights - the permissions.
1618 * OUT flags - a pointer to an afs_int32 structure that
1619 * contains the flags to pass to pts.
1623 * No locks are held by this function
1627 * Returns != 0 upon successful completion.
1632 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1636 afs_status_t tst = 0;
1640 if (rights->listDelete == PTS_GROUP_ACCESS) {
1642 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1643 tst = ADMPTSINVALIDGROUPDELETEPERM;
1644 goto fail_SetGroupAccess;
1647 if (rights->listAdd == PTS_GROUP_ACCESS) {
1649 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1653 if (rights->listMembership == PTS_GROUP_ACCESS) {
1655 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1659 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1661 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1662 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1663 goto fail_SetGroupAccess;
1666 if (rights->listStatus == PTS_GROUP_ACCESS) {
1668 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1673 fail_SetGroupAccess:
1682 * pts_GroupModify - change the contents of a group entry.
1686 * IN cellHandle - a previously opened cellHandle that corresponds
1687 * to the cell where the group exists.
1689 * IN groupName - the group to change
1691 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1692 * contains the new information for the group.
1696 * No locks are held by this function
1700 * Returns != 0 upon successful completion.
1705 pts_GroupModify(const void *cellHandle, const char *groupName,
1706 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1709 afs_status_t tst = 0;
1710 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1711 afs_int32 groupId = 0;
1712 afs_int32 flags = 0;
1715 * Validate arguments
1718 if (!IsValidCellHandle(c_handle, &tst)) {
1719 goto fail_pts_GroupModify;
1722 if ((groupName == NULL) || (*groupName == 0)) {
1723 tst = ADMPTSGROUPNAMENULL;
1724 goto fail_pts_GroupModify;
1728 if (newEntryP == NULL) {
1729 tst = ADMPTSNEWENTRYPNULL;
1730 goto fail_pts_GroupModify;
1734 * Translate the group name into an id.
1737 if (!TranslateOneName
1738 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1739 goto fail_pts_GroupModify;
1743 * Set the flags argument
1746 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1747 goto fail_pts_GroupModify;
1755 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1759 goto fail_pts_GroupModify;
1763 fail_pts_GroupModify:
1772 * pts_UserCreate - create a new user.
1776 * IN cellHandle - a previously opened cellHandle that corresponds
1777 * to the cell where the group exists.
1779 * IN newUser - the name of the new user.
1781 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1782 * id assigned by pts.
1786 * No locks are held by this function
1790 * Returns != 0 upon successful completion.
1795 pts_UserCreate(const void *cellHandle, char *userName, int *newUserId,
1799 afs_status_t tst = 0;
1800 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1803 * Validate arguments
1806 if (!IsValidCellHandle(c_handle, &tst)) {
1807 goto fail_pts_UserCreate;
1810 if ((userName == NULL) || (*userName == 0)) {
1811 tst = ADMPTSUSERNAMENULL;
1812 goto fail_pts_UserCreate;
1815 if (newUserId == NULL) {
1816 tst = ADMPTSNEWUSERIDNULL;
1817 goto fail_pts_UserCreate;
1821 * We make a different rpc based upon the input to this function
1824 if (*newUserId != 0) {
1826 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1830 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1835 goto fail_pts_UserCreate;
1839 fail_pts_UserCreate:
1848 * pts_UserDelete - delete a user.
1852 * IN cellHandle - a previously opened cellHandle that corresponds
1853 * to the cell where the group exists.
1855 * IN user - the name of the user to delete.
1859 * No locks are held by this function
1863 * Returns != 0 upon successful completion.
1868 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1870 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1871 ADMPTSUSERNAMETOOLONG, st);
1876 * GetUserAccess - a small convenience function for setting
1881 * IN access - a pointer to a pts_userAccess_t to be set with the
1882 * correct permission.
1884 * IN flag - the current permission flag used to derive the permission.
1888 * No locks are obtained or released by this function
1892 * Since this function cannot fail, it returns void.
1897 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1900 *access = PTS_USER_OWNER_ACCESS;
1902 *access = PTS_USER_ANYUSER_ACCESS;
1907 * IsAdministrator - determine if a user is an administrator.
1911 * IN cellHandle - a previously opened cellHandle that corresponds
1912 * to the cell where the group exists.
1914 * IN userEntry - the user data for the user in question.
1916 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1920 * No locks are held by this function
1924 * Returns != 0 upon successful completion.
1929 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1930 int *admin, afs_status_p st)
1933 afs_status_t tst = 0;
1934 afs_int32 adminId = 0;
1935 afs_int32 isAdmin = 0;
1939 if (userId == SYSADMINID) {
1942 if (!TranslateOneName
1943 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1945 goto fail_IsAdministrator;
1948 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1951 goto fail_IsAdministrator;
1959 fail_IsAdministrator:
1968 * pts_UserGet - retrieve information about a particular user.
1972 * IN cellHandle - a previously opened cellHandle that corresponds
1973 * to the cell where the group exists.
1975 * IN userName - the name of the user to retrieve.
1977 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1982 * No locks are held by this function
1986 * Returns != 0 upon successful completion.
1991 pts_UserGet(const void *cellHandle, const char *userName,
1992 pts_UserEntry_p userP, afs_status_p st)
1995 afs_status_t tst = 0;
1996 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1997 struct prcheckentry userEntry;
1998 afs_int32 userId = 0;
2002 afs_int32 ptsids[2];
2008 * Validate arguments
2011 if (!IsValidCellHandle(c_handle, &tst)) {
2012 goto fail_pts_UserGet;
2015 if ((userName == NULL) || (*userName == 0)) {
2016 tst = ADMPTSUSERNAMENULL;
2017 goto fail_pts_UserGet;
2020 if (userP == NULL) {
2021 tst = ADMPTSUSERPNULL;
2022 goto fail_pts_UserGet;
2026 * Translate the group name into an id.
2029 if (!TranslateOneName
2030 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2031 goto fail_pts_UserGet;
2035 * Retrieve information about the group
2038 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2041 goto fail_pts_UserGet;
2044 userP->groupMembershipCount = userEntry.count;
2045 userP->groupCreationQuota = userEntry.ngroups;
2047 * The administrator id, or any member of "system:administrators"
2048 * has unlimited group creation quota. Denote this by setting
2052 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2053 goto fail_pts_UserGet;
2057 userP->groupCreationQuota = -1;
2060 userP->nameUid = userEntry.id;
2061 userP->ownerUid = userEntry.owner;
2062 userP->creatorUid = userEntry.creator;
2063 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2064 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2067 * The permission bits are described in the GroupGet function above.
2068 * The user entry only uses 3 of the 5 permissions, so we shift
2069 * past the unused entries.
2072 flags = userEntry.flags;
2076 GetUserAccess(&userP->listMembership, twobit);
2081 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2083 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2089 GetUserAccess(&userP->listStatus, twobit);
2092 * Make another rpc and translate the owner and creator ids into
2093 * character strings.
2097 ids.idlist_val = ptsids;
2098 ptsids[0] = userEntry.owner;
2099 ptsids[1] = userEntry.creator;
2100 names.namelist_len = 0;
2101 names.namelist_val = 0;
2104 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2105 goto fail_pts_UserGet;
2108 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2109 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2110 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2111 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2112 free(names.namelist_val);
2124 * pts_UserRename - rename a user.
2128 * IN cellHandle - a previously opened cellHandle that corresponds
2129 * to the cell where the group exists.
2131 * IN oldName - the name of the user to rename.
2133 * IN newName - the new user name.
2137 * No locks are held by this function
2141 * Returns != 0 upon successful completion.
2146 pts_UserRename(const void *cellHandle, const char *oldName,
2147 char *newName, afs_status_p st)
2150 afs_status_t tst = 0;
2151 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2152 afs_int32 userId = 0;
2155 * Validate arguments
2158 if (!IsValidCellHandle(c_handle, &tst)) {
2159 goto fail_pts_UserRename;
2162 if ((oldName == NULL) || (*oldName == 0)) {
2163 tst = ADMPTSOLDNAMENULL;
2164 goto fail_pts_UserRename;
2167 if ((newName == NULL) || (*newName == 0)) {
2168 tst = ADMPTSNEWNAMENULL;
2169 goto fail_pts_UserRename;
2173 * Translate the user name into an id.
2176 if (!TranslateOneName
2177 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2178 goto fail_pts_UserRename;
2185 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2188 goto fail_pts_UserRename;
2192 fail_pts_UserRename:
2201 * SetUserAccess - translate our Access notation to pts flags.
2205 * IN userP - the user structure that contains the new permissions.
2207 * OUT flags - a pointer to an afs_int32 structure that
2208 * contains the flags to pass to pts.
2212 * No locks are held by this function
2216 * Returns != 0 upon successful completion.
2221 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2225 afs_status_t tst = 0;
2229 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2233 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2237 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2250 * pts_UserModify - update a user entry.
2254 * IN cellHandle - a previously opened cellHandle that corresponds
2255 * to the cell where the group exists.
2257 * IN userName - the name of the user to update.
2259 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2260 * new information for user.
2264 * No locks are held by this function
2268 * Returns != 0 upon successful completion.
2273 pts_UserModify(const void *cellHandle, const char *userName,
2274 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2277 afs_status_t tst = 0;
2278 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2279 afs_int32 userId = 0;
2280 afs_int32 newQuota = 0;
2282 afs_int32 flags = 0;
2285 * Validate arguments
2288 if (!IsValidCellHandle(c_handle, &tst)) {
2289 goto fail_pts_UserModify;
2292 if ((userName == NULL) || (*userName == 0)) {
2293 tst = ADMPTSUSERNAMENULL;
2294 goto fail_pts_UserModify;
2297 if (newEntryP == NULL) {
2298 tst = ADMPTSNEWENTRYPNULL;
2299 goto fail_pts_UserModify;
2303 * Translate the user name into an id.
2306 if (!TranslateOneName
2307 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2308 goto fail_pts_UserModify;
2312 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2313 mask |= PR_SF_NGROUPS;
2314 newQuota = newEntryP->groupCreationQuota;
2317 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2318 mask |= PR_SF_ALLBITS;
2319 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2320 goto fail_pts_UserModify;
2329 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2333 goto fail_pts_UserModify;
2337 fail_pts_UserModify:
2346 * pts_UserMaxGet - get the maximum in use user id.
2350 * IN cellHandle - a previously opened cellHandle that corresponds
2351 * to the cell where the group exists.
2353 * OUT maxUserId - upon successful completion contains the max in use id.
2357 * No locks are held by this function
2361 * Returns != 0 upon successful completion.
2366 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2369 afs_status_t tst = 0;
2370 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2371 afs_int32 maxGroupId = 0;
2374 * Validate arguments
2377 if (!IsValidCellHandle(c_handle, &tst)) {
2378 goto fail_pts_UserMaxGet;
2381 if (maxUserId == NULL) {
2382 tst = ADMPTSMAXUSERIDNULL;
2383 goto fail_pts_UserMaxGet;
2386 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2389 goto fail_pts_UserMaxGet;
2393 fail_pts_UserMaxGet:
2402 * pts_UserMaxSet - set the maximum user id.
2406 * IN cellHandle - a previously opened cellHandle that corresponds
2407 * to the cell where the group exists.
2409 * IN maxUserId - the new max user id.
2413 * No locks are held by this function
2417 * Returns != 0 upon successful completion.
2422 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2425 afs_status_t tst = 0;
2426 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2429 * Validate arguments
2432 if (!IsValidCellHandle(c_handle, &tst)) {
2433 goto fail_pts_UserMaxSet;
2436 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2439 goto fail_pts_UserMaxSet;
2443 fail_pts_UserMaxSet:
2452 * pts_UserMemberListBegin - begin iterating over the list of groups
2453 * a particular user belongs to.
2457 * IN cellHandle - a previously opened cellHandle that corresponds
2458 * to the cell where the group exists.
2460 * IN groupName - the group whose members will be returned.
2462 * OUT iterationIdP - upon successful completion contains a iterator that
2463 * can be passed to pts_GroupMemberListNext.
2467 * No locks are obtained or released by this function
2471 * Returns != 0 upon successful completion.
2476 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2477 void **iterationIdP, afs_status_p st)
2479 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2480 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2485 * pts_UserMemberListNext - get the next group a user belongs to
2489 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2491 * OUT userName - upon successful completion contains the next group a user
2496 * The iterator mutex is held during the retrieval of the next member.
2500 * Returns != 0 upon successful completion.
2505 pts_UserMemberListNext(const void *iterationId, char *userName,
2508 return pts_GroupMemberListNext(iterationId, userName, st);
2512 * pts_UserMemberListDone - finish using a user list iterator
2516 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2520 * The iterator is locked and then destroyed
2524 * Returns != 0 upon successful completion.
2528 * It is the user's responsibility to make sure pts_UserMemberListDone
2529 * is called only once for each iterator.
2533 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2535 return pts_GroupMemberListDone(iterationId, st);
2538 typedef struct owned_group_list {
2539 namelist owned_names; /* the list of character names owned by this id */
2540 prlist owned_ids; /* the list of pts ids owned by this id */
2541 afs_int32 index; /* the index into owned_names for the next group */
2542 afs_int32 owner; /* the pts id of the owner */
2543 afs_int32 more; /* the last parameter to PR_ListOwned */
2544 int finished_retrieving; /* set when we've processed the last owned_names */
2545 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2546 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2547 } owned_group_list_t, *owned_group_list_p;
2550 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2553 afs_status_t tst = 0;
2554 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2556 if (list->owned_names.namelist_val != NULL) {
2557 free(list->owned_names.namelist_val);
2560 if (list->owned_ids.prlist_val != NULL) {
2561 free(list->owned_ids.prlist_val);
2572 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2573 int *last_item_contains_data, afs_status_p st)
2576 afs_status_t tst = 0;
2577 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2580 * We really don't make an rpc for every entry we return here
2581 * since the pts interface allows several members to be returned
2582 * with one rpc, but we fake it to make the iterator happy.
2586 * Check to see if we are done retrieving data
2589 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2591 *last_item_contains_data = 0;
2592 goto fail_GetOwnedGroupRPC;
2596 * Check to see if we really need to make an rpc
2599 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2601 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2602 &list->owned_ids, &list->more);
2604 goto fail_GetOwnedGroupRPC;
2607 if (!TranslatePTSIds
2608 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2610 goto fail_GetOwnedGroupRPC;
2614 if (list->owned_names.namelist_val == NULL) {
2616 *last_item_contains_data = 0;
2617 goto fail_GetOwnedGroupRPC;
2622 * We can retrieve the next group from data we already received
2625 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2629 * Check to see if there is more data to be retrieved
2630 * We need to free up the previously retrieved data here
2631 * and then check to see if the last rpc indicated that there
2632 * were more items to retrieve.
2635 if (list->index >= list->owned_names.namelist_len) {
2636 list->owned_names.namelist_len = 0;
2637 free(list->owned_names.namelist_val);
2638 list->owned_names.namelist_val = 0;
2640 list->owned_ids.prlist_len = 0;
2641 free(list->owned_ids.prlist_val);
2642 list->owned_ids.prlist_val = 0;
2645 list->finished_retrieving = 1;
2650 fail_GetOwnedGroupRPC:
2659 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2663 afs_status_t tst = 0;
2664 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2666 strcpy((char *)dest, list->group[slot]);
2677 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2678 * a particular user owns.
2682 * IN cellHandle - a previously opened cellHandle that corresponds
2683 * to the cell where the group exists.
2685 * IN ownerName - the owner of the groups of interest.
2687 * OUT iterationIdP - upon successful completion contains a iterator that
2688 * can be passed to pts_OwnedGroupListNext.
2692 * No locks are held by this function
2696 * Returns != 0 upon successful completion.
2701 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2702 void **iterationIdP, afs_status_p st)
2705 afs_status_t tst = 0;
2706 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2707 afs_admin_iterator_p iter =
2708 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2709 owned_group_list_p list =
2710 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2713 * Validate arguments
2716 if (!IsValidCellHandle(c_handle, &tst)) {
2717 goto fail_pts_OwnedGroupListBegin;
2720 if ((userName == NULL) || (*userName == 0)) {
2721 tst = ADMPTSUSERNAMENULL;
2722 goto fail_pts_OwnedGroupListBegin;
2725 if (iterationIdP == NULL) {
2726 tst = ADMITERATORNULL;
2727 goto fail_pts_OwnedGroupListBegin;
2730 if ((iter == NULL) || (list == NULL)) {
2732 goto fail_pts_OwnedGroupListBegin;
2736 * Initialize the iterator specific data
2740 list->finished_retrieving = 0;
2741 list->c_handle = c_handle;
2742 list->owned_names.namelist_len = 0;
2743 list->owned_names.namelist_val = 0;
2744 list->owned_ids.prlist_len = 0;
2745 list->owned_ids.prlist_val = 0;
2748 * Translate the user name into an id.
2751 if (!TranslateOneName
2752 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2753 goto fail_pts_OwnedGroupListBegin;
2757 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2758 DeleteOwnedGroupSpecificData, &tst)) {
2759 *iterationIdP = (void *)iter;
2763 fail_pts_OwnedGroupListBegin:
2781 * pts_OwnedGroupListNext - get the next group a user owns.
2785 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2787 * OUT groupName - upon successful completion contains the next group a user
2792 * The iterator mutex is held during the retrieval of the next member.
2796 * Returns != 0 upon successful completion.
2801 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2805 afs_status_t tst = 0;
2806 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2809 * Validate arguments
2812 if (iterationId == NULL) {
2813 tst = ADMITERATORNULL;
2814 goto fail_pts_OwnedGroupListNext;
2817 if (groupName == NULL) {
2818 tst = ADMPTSGROUPNAMENULL;
2819 goto fail_pts_OwnedGroupListNext;
2822 rc = IteratorNext(iter, (void *)groupName, &tst);
2824 fail_pts_OwnedGroupListNext:
2833 * pts_OwnedGroupListDone - finish using a group list iterator
2837 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2841 * The iterator is locked and then destroyed
2845 * Returns != 0 upon successful completion.
2849 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2850 * is called only once for each iterator.
2854 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2857 afs_status_t tst = 0;
2858 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2861 * Validate arguments
2864 if (iterationId == NULL) {
2865 tst = ADMITERATORNULL;
2866 goto fail_pts_OwnedGroupListDone;
2869 rc = IteratorDone(iter, &tst);
2871 fail_pts_OwnedGroupListDone:
2879 typedef struct pts_list {
2880 prlistentries *names; /* the current list of pts names in this cell */
2881 prlistentries *currName; /* the current pts entry */
2882 afs_int32 index; /* the index into names for the next pts entry */
2883 afs_int32 nextstartindex; /* the next start index for the RPC */
2884 afs_int32 nentries; /* the number of entries in names */
2885 afs_int32 flag; /* the type of the list */
2886 int finished_retrieving; /* set when we've processed the last owned_names */
2887 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2888 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2889 } pts_list_t, *pts_list_p;
2892 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2895 afs_status_t tst = 0;
2896 pts_list_p list = (pts_list_p) rpc_specific;
2911 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2912 int *last_item_contains_data, afs_status_p st)
2915 afs_status_t tst = 0;
2916 pts_list_p list = (pts_list_p) rpc_specific;
2919 * We really don't make an rpc for every entry we return here
2920 * since the pts interface allows several members to be returned
2921 * with one rpc, but we fake it to make the iterator happy.
2925 * Check to see if we are done retrieving data
2928 if (list->finished_retrieving) {
2930 *last_item_contains_data = 0;
2931 goto fail_GetPTSRPC;
2935 * Check to see if we really need to make an rpc
2938 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2939 afs_int32 start = list->nextstartindex;
2940 prentries bulkentries;
2941 list->nextstartindex = -1;
2942 bulkentries.prentries_val = 0;
2943 bulkentries.prentries_len = 0;
2946 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2947 start, &bulkentries, &(list->nextstartindex));
2950 goto fail_GetPTSRPC;
2953 list->nentries = bulkentries.prentries_len;
2954 list->names = bulkentries.prentries_val;
2957 list->currName = list->names;
2962 * We can retrieve the next entry from data we already received
2965 strcpy(list->entries[slot], list->currName->name);
2971 * Check to see if there is more data to be retrieved
2972 * We need to free up the previously retrieved data here
2973 * and then check to see if the last rpc indicated that there
2974 * were more items to retrieve.
2977 if (list->index >= list->nentries) {
2983 if (list->nextstartindex == -1) {
2984 list->finished_retrieving = 1;
2999 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
3002 afs_status_t tst = 0;
3003 pts_list_p list = (pts_list_p) rpc_specific;
3005 strcpy((char *)dest, list->entries[slot]);
3016 * pts_UserListBegin - begin iterating over the list of users
3017 * in a particular cell
3021 * IN cellHandle - a previously opened cellHandle that corresponds
3022 * to the cell where the users exist.
3024 * OUT iterationIdP - upon successful completion contains a iterator that
3025 * can be passed to pts_UserListNext.
3029 * No locks are held by this function
3033 * Returns != 0 upon successful completion.
3038 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3042 afs_status_t tst = 0;
3043 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3044 afs_admin_iterator_p iter =
3045 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3046 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3049 * Validate arguments
3052 if (!IsValidCellHandle(c_handle, &tst)) {
3053 goto fail_pts_UserListBegin;
3056 if (iterationIdP == NULL) {
3057 tst = ADMITERATORNULL;
3058 goto fail_pts_UserListBegin;
3061 if ((iter == NULL) || (list == NULL)) {
3063 goto fail_pts_UserListBegin;
3067 * Initialize the iterator specific data
3071 list->finished_retrieving = 0;
3072 list->c_handle = c_handle;
3074 list->nextstartindex = 0;
3076 list->flag = PRUSERS;
3079 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3080 DeletePTSSpecificData, &tst)) {
3081 *iterationIdP = (void *)iter;
3085 fail_pts_UserListBegin:
3103 * pts_UserListNext - get the next user in the cell.
3107 * IN iterationId - an iterator previously returned by pts_UserListBegin
3109 * OUT groupName - upon successful completion contains the next user
3113 * The iterator mutex is held during the retrieval of the next member.
3117 * Returns != 0 upon successful completion.
3122 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3125 afs_status_t tst = 0;
3126 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3129 * Validate arguments
3132 if (iterationId == NULL) {
3133 tst = ADMITERATORNULL;
3134 goto fail_pts_UserListNext;
3137 if (userName == NULL) {
3138 tst = ADMPTSUSERNAMENULL;
3139 goto fail_pts_UserListNext;
3142 rc = IteratorNext(iter, (void *)userName, &tst);
3144 fail_pts_UserListNext:
3153 * pts_UserListDone - finish using a user list iterator
3157 * IN iterationId - an iterator previously returned by pts_UserListBegin
3161 * The iterator is locked and then destroyed
3165 * Returns != 0 upon successful completion.
3169 * It is the user's responsibility to make sure pts_UserListDone
3170 * is called only once for each iterator.
3174 pts_UserListDone(const void *iterationId, afs_status_p st)
3177 afs_status_t tst = 0;
3178 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3181 * Validate arguments
3184 if (iterationId == NULL) {
3185 tst = ADMITERATORNULL;
3186 goto fail_pts_UserListDone;
3189 rc = IteratorDone(iter, &tst);
3191 fail_pts_UserListDone:
3200 * pts_GroupListBegin - begin iterating over the list of groups
3201 * in a particular cell.
3205 * IN cellHandle - a previously opened cellHandle that corresponds
3206 * to the cell where the groups exist.
3208 * OUT iterationIdP - upon successful completion contains a iterator that
3209 * can be passed to pts_GroupListNext.
3213 * No locks are held by this function
3217 * Returns != 0 upon successful completion.
3222 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3226 afs_status_t tst = 0;
3227 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3228 afs_admin_iterator_p iter =
3229 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3230 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3233 * Validate arguments
3236 if (!IsValidCellHandle(c_handle, &tst)) {
3237 goto fail_pts_GroupListBegin;
3240 if (iterationIdP == NULL) {
3241 tst = ADMITERATORNULL;
3242 goto fail_pts_GroupListBegin;
3245 if ((iter == NULL) || (list == NULL)) {
3247 goto fail_pts_GroupListBegin;
3251 * Initialize the iterator specific data
3255 list->finished_retrieving = 0;
3256 list->c_handle = c_handle;
3258 list->nextstartindex = 0;
3260 list->flag = PRGROUPS;
3263 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3264 DeletePTSSpecificData, &tst)) {
3265 *iterationIdP = (void *)iter;
3269 fail_pts_GroupListBegin:
3287 * pts_UserListNext - get the next group in a cell.
3291 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3293 * OUT groupName - upon successful completion contains the next group
3297 * The iterator mutex is held during the retrieval of the next member.
3301 * Returns != 0 upon successful completion.
3306 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3309 afs_status_t tst = 0;
3310 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3313 * Validate arguments
3316 if (iterationId == NULL) {
3317 tst = ADMITERATORNULL;
3318 goto fail_pts_GroupListNext;
3321 if (groupName == NULL) {
3322 tst = ADMPTSGROUPNAMENULL;
3323 goto fail_pts_GroupListNext;
3326 rc = IteratorNext(iter, (void *)groupName, &tst);
3328 fail_pts_GroupListNext:
3337 * pts_GroupListDone - finish using a group list iterator
3341 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3345 * The iterator is locked and then destroyed
3349 * Returns != 0 upon successful completion.
3353 * It is the user's responsibility to make sure pts_GroupListDone
3354 * is called only once for each iterator.
3358 pts_GroupListDone(const void *iterationId, afs_status_p st)
3361 afs_status_t tst = 0;
3362 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3365 * Validate arguments
3368 if (iterationId == NULL) {
3369 tst = ADMITERATORNULL;
3370 goto fail_pts_GroupListDone;
3373 rc = IteratorDone(iter, &tst);
3375 fail_pts_GroupListDone: