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;
471 memset(&ids, 0, sizeof(ids));
477 if (!IsValidCellHandle(c_handle, &tst)) {
478 goto fail_pts_GroupOwnerChange;
481 if ((newOwner == NULL) || (*newOwner == 0)) {
482 tst = ADMPTSNEWOWNERNULL;
483 goto fail_pts_GroupOwnerChange;
486 if ((targetGroup == NULL) || (*targetGroup == 0)) {
487 tst = ADMPTSTARGETGROUPNULL;
488 goto fail_pts_GroupOwnerChange;
491 if (!TranslateTwoNames
492 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
493 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
494 goto fail_pts_GroupOwnerChange;
502 ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
503 ids.idlist_val[0], 0);
506 goto fail_pts_GroupOwnerChange;
510 fail_pts_GroupOwnerChange:
512 if (ids.idlist_val != 0) {
513 free(ids.idlist_val);
523 * pts_GroupCreate - create a new group
527 * IN cellHandle - a previously opened cellHandle that corresponds
528 * to the cell where the group exists.
530 * IN newGroup - the group to be created.
532 * IN newOwner - the owner of the group. Pass NULL if the current user
533 * is to be the new owner, or the character string of the owner otherwise.
535 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
536 * generate a value, != 0 to assign a value on your own. The group id
537 * that is used to create the group is copied into this parameter in the
538 * event you pass in 0.
542 * No locks are obtained or released by this function
546 * Returns != 0 upon successful completion.
551 pts_GroupCreate(const void *cellHandle, char *newGroup,
552 char *newOwner, int *newGroupId, afs_status_p st)
555 afs_status_t tst = 0;
556 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
557 afs_int32 newOwnerId = 0;
563 if (!IsValidCellHandle(c_handle, &tst)) {
564 goto fail_pts_GroupCreate;
567 if ((newGroup == NULL) || (*newGroup == 0)) {
568 tst = ADMPTSNEWGROUPNULL;
569 goto fail_pts_GroupCreate;
572 if (newGroupId == NULL) {
573 tst = ADMPTSNEWGROUPIDNULL;
574 goto fail_pts_GroupCreate;
577 if (*newGroupId > 0) {
578 tst = ADMPTSNEWGROUPIDPOSITIVE;
579 goto fail_pts_GroupCreate;
583 * If a newOwner was specified, validate that it exists
586 if (newOwner != NULL) {
587 if (!TranslateOneName
588 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
589 goto fail_pts_GroupCreate;
594 * We make a different rpc based upon the input to this function
597 if (*newGroupId != 0) {
599 ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
603 ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
604 newOwnerId, newGroupId);
608 goto fail_pts_GroupCreate;
612 fail_pts_GroupCreate:
621 * GetGroupAccess - a small convenience function for setting
626 * IN access - a pointer to a pts_groupAccess_t to be set with the
627 * correct permission.
629 * IN flag - the current permission flag used to derive the permission.
633 * No locks are obtained or released by this function
637 * Since this function cannot fail, it returns void.
642 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
645 *access = PTS_GROUP_OWNER_ACCESS;
647 *access = PTS_GROUP_OWNER_ACCESS;
648 } else if (flag == 1) {
649 *access = PTS_GROUP_ACCESS;
650 } else if (flag == 2) {
651 *access = PTS_GROUP_ANYUSER_ACCESS;
657 * pts_GroupGet - retrieve information about a particular group.
661 * IN cellHandle - a previously opened cellHandle that corresponds
662 * to the cell where the group exists.
664 * IN groupName - the group to retrieve.
666 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
667 * successful completion is filled with information about groupName.
671 * No locks are obtained or released by this function
675 * Returns != 0 upon successful completion.
680 pts_GroupGet(const void *cellHandle, const char *groupName,
681 pts_GroupEntry_p groupP, afs_status_p st)
684 afs_status_t tst = 0;
685 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
686 afs_int32 groupId = 0;
689 struct prcheckentry groupEntry;
698 if (!IsValidCellHandle(c_handle, &tst)) {
699 goto fail_pts_GroupGet;
702 if ((groupName == NULL) || (*groupName == 0)) {
703 tst = ADMPTSGROUPNAMENULL;
704 goto fail_pts_GroupGet;
707 if (groupP == NULL) {
708 tst = ADMPTSGROUPPNULL;
709 goto fail_pts_GroupGet;
713 * Translate the group name into an id.
716 if (!TranslateOneName
717 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
718 goto fail_pts_GroupGet;
722 * Retrieve information about the group
725 tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
728 goto fail_pts_GroupGet;
731 groupP->membershipCount = groupEntry.count;
732 groupP->nameUid = groupEntry.id;
733 groupP->ownerUid = groupEntry.owner;
734 groupP->creatorUid = groupEntry.creator;
735 strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
736 groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
738 * Set the access rights based upon the value of the flags member
739 * of the groupEntry struct.
741 * To the best of my ability to decypher the pts code, it looks like
742 * the rights are stored in flags as follows:
744 * I number my bits from least significant to most significant starting
748 * if bit 0 == 0 -> r access is denied
749 * if bit 0 == 1 -> r access is granted
752 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
753 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
754 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
755 * if bit 2 == 1 and bit 1 == 1 -> this is an error
757 * membership - bits 3 and 4
758 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
759 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
760 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
761 * if bit 4 == 1 and bit 3 == 1 -> this is an error
764 * if bit 5 == 0 -> O access is denied
765 * if bit 5 == 1 -> O access is granted
767 * status - bits 6 and 7
768 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
769 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
770 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
771 * if bit 7 == 1 and bit 6 == 1 -> this is an error
773 * For cases where the permission doesn't make sense for the
774 * type of entry, or where an error occurs, we ignore it.
775 * This is the behavior of the pts code.
778 flags = groupEntry.flags;
780 groupP->listDelete = PTS_GROUP_ACCESS;
782 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
788 GetGroupAccess(&groupP->listAdd, twobit);
793 GetGroupAccess(&groupP->listMembership, twobit);
798 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
800 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
806 GetGroupAccess(&groupP->listStatus, twobit);
809 * Make another rpc and translate the owner and creator ids into
814 ids.idlist_val = ptsids;
815 ptsids[0] = groupEntry.owner;
816 ptsids[1] = groupEntry.creator;
817 names.namelist_len = 0;
818 names.namelist_val = 0;
821 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
822 goto fail_pts_GroupGet;
825 strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
826 groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
827 strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
828 groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
829 free(names.namelist_val);
841 * EntryDelete - delete a pts entry (group or user).
845 * IN cellHandle - a previously opened cellHandle that corresponds
846 * to the cell where the group exists.
848 * IN entryName - the entry to be deleted.
850 * IN error1 - the error status to be returned in the event that entryName is
853 * IN error2 - the error status to be returned in the event that entryName is
858 * No locks are obtained or released by this function
862 * Returns != 0 upon successful completion.
867 EntryDelete(const void *cellHandle, const char *entryName,
868 afs_status_t error1, afs_status_t error2, afs_status_p st)
871 afs_status_t tst = 0;
872 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
873 afs_int32 entryId = 0;
879 if (!IsValidCellHandle(c_handle, &tst)) {
880 goto fail_EntryDelete;
883 if ((entryName == NULL) || (*entryName == 0)) {
885 goto fail_EntryDelete;
889 * Translate the entry name into an id.
892 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
893 goto fail_EntryDelete;
900 tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
903 goto fail_EntryDelete;
917 * pts_GroupDelete - delete a group
921 * IN cellHandle - a previously opened cellHandle that corresponds
922 * to the cell where the group exists.
924 * IN groupName - the group to be deleted.
928 * No locks are obtained or released by this function
932 * Returns != 0 upon successful completion.
937 pts_GroupDelete(const void *cellHandle, const char *groupName,
941 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
942 ADMPTSGROUPNAMETOOLONG, st);
946 * pts_GroupMaxGet - get the maximum in use group id.
950 * IN cellHandle - a previously opened cellHandle that corresponds
951 * to the cell where the group exists.
953 * OUT maxGroupId - upon successful completion contains the maximum
954 * group Id in use at the server.
958 * No locks are obtained or released by this function
962 * Returns != 0 upon successful completion.
967 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
970 afs_status_t tst = 0;
971 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
972 afs_int32 maxUserId = 0;
978 if (!IsValidCellHandle(c_handle, &tst)) {
979 goto fail_pts_GroupMaxGet;
982 if (maxGroupId == NULL) {
983 tst = ADMPTSMAXGROUPIDNULL;
984 goto fail_pts_GroupMaxGet;
987 tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
990 goto fail_pts_GroupMaxGet;
994 fail_pts_GroupMaxGet:
1003 * pts_GroupMaxSet - set the maximum in use group id.
1007 * IN cellHandle - a previously opened cellHandle that corresponds
1008 * to the cell where the group exists.
1010 * IN maxGroupId - the new maximum group id.
1014 * No locks are obtained or released by this function
1018 * Returns != 0 upon successful completion.
1023 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1026 afs_status_t tst = 0;
1027 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1030 * Validate arguments
1033 if (!IsValidCellHandle(c_handle, &tst)) {
1034 goto fail_pts_GroupMaxSet;
1037 tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
1040 goto fail_pts_GroupMaxSet;
1044 fail_pts_GroupMaxSet:
1055 * I'm not using the common iterator pattern here since the retrival
1056 * of the member list is actually accomplished in 1 rpc. There's no
1057 * sense in trying to fit this pts specific behavior into the more
1058 * generic model, so instead the Begin functions actually do all the
1059 * rpc work and the next/done functions just manipulate the retrieved
1063 typedef struct pts_group_member_list_iterator {
1066 pthread_mutex_t mutex; /* hold to manipulate this structure */
1071 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1074 * pts_GroupMemberListBegin - begin iterating over the list of members
1075 * of a particular group.
1079 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1083 * No locks are obtained or released by this function
1087 * Returns != 0 upon successful completion.
1092 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1096 afs_status_t tst = 0;
1099 tst = ADMITERATORNULL;
1100 goto fail_IsValidPtsGroupMemberListIterator;
1103 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1104 tst = ADMITERATORBADMAGICNULL;
1105 goto fail_IsValidPtsGroupMemberListIterator;
1108 if (iter->is_valid == 0) {
1109 tst = ADMITERATORINVALID;
1110 goto fail_IsValidPtsGroupMemberListIterator;
1114 fail_IsValidPtsGroupMemberListIterator:
1123 * MemberListBegin - an internal function which is used to get both
1124 * the list of members in a group and the list of groups a user belongs
1129 * IN cellHandle - a previously opened cellHandle that corresponds
1130 * to the cell where the group exists.
1132 * IN name - the name whose membership will be retrieved.
1134 * OUT iterationIdP - upon successful completion contains a iterator that
1135 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1139 * No locks are obtained or released by this function
1143 * Returns != 0 upon successful completion.
1148 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1149 afs_status_t error2, void **iterationIdP, afs_status_p st)
1152 afs_status_t tst = 0;
1153 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1154 afs_int32 groupId = 0;
1155 afs_int32 exceeded = 0;
1156 pts_group_member_list_iterator_p iter =
1157 malloc(sizeof(pts_group_member_list_iterator_t));
1158 int iter_allocated = 0;
1159 int ids_allocated = 0;
1160 int names_allocated = 0;
1161 int mutex_inited = 0;
1164 * Validate arguments
1167 if (!IsValidCellHandle(c_handle, &tst)) {
1168 goto fail_MemberListBegin;
1171 if ((name == NULL) || (*name == 0)) {
1172 tst = ADMPTSGROUPNAMENULL;
1173 goto fail_MemberListBegin;
1176 if (iterationIdP == NULL) {
1177 tst = ADMITERATORNULL;
1178 goto fail_MemberListBegin;
1183 goto fail_MemberListBegin;
1189 * Translate the name into an id.
1192 if (!TranslateOneName
1193 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1194 goto fail_MemberListBegin;
1197 if (pthread_mutex_init(&iter->mutex, 0)) {
1199 goto fail_MemberListBegin;
1204 iter->ids.prlist_len = 0;
1205 iter->ids.prlist_val = 0;
1208 ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
1212 goto fail_MemberListBegin;
1215 if (exceeded != 0) {
1216 tst = ADMPTSGROUPMEMEXCEEDED;
1217 goto fail_MemberListBegin;
1221 iter->names.namelist_len = 0;
1222 iter->names.namelist_val = 0;
1224 if (!TranslatePTSIds
1225 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1226 goto fail_MemberListBegin;
1229 names_allocated = 1;
1230 iter->begin_magic = BEGIN_MAGIC;
1231 iter->end_magic = END_MAGIC;
1235 *iterationIdP = (void *)iter;
1238 fail_MemberListBegin:
1240 if (ids_allocated) {
1241 free(iter->ids.prlist_val);
1245 if (names_allocated) {
1246 free(iter->names.namelist_val);
1249 pthread_mutex_destroy(&iter->mutex);
1251 if (iter_allocated) {
1263 * pts_GroupMemberListBegin - begin iterating over the list of members
1264 * of a particular group.
1268 * IN cellHandle - a previously opened cellHandle that corresponds
1269 * to the cell where the group exists.
1271 * IN groupName - the group whose members will be returned.
1273 * OUT iterationIdP - upon successful completion contains a iterator that
1274 * can be passed to pts_GroupMemberListNext.
1278 * No locks are obtained or released by this function
1282 * Returns != 0 upon successful completion.
1287 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1288 void **iterationIdP, afs_status_p st)
1290 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1291 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1295 * pts_GroupMemberListNext - get the next member of a group
1299 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1301 * OUT memberName - upon successful completion contains the next member of
1306 * The iterator mutex is held during the retrieval of the next member.
1310 * Returns != 0 upon successful completion.
1315 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1319 afs_status_t tst = 0;
1320 pts_group_member_list_iterator_p iter =
1321 (pts_group_member_list_iterator_p) iterationId;
1322 int mutex_locked = 0;
1325 * Validate arguments
1329 tst = ADMITERATORNULL;
1330 goto fail_pts_GroupMemberListNext;
1333 if (memberName == NULL) {
1334 tst = ADMPTSMEMBERNAMENULL;
1335 goto fail_pts_GroupMemberListNext;
1339 * Lock the mutex and check the validity of the iterator
1342 if (pthread_mutex_lock(&iter->mutex)) {
1344 goto fail_pts_GroupMemberListNext;
1349 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1350 goto fail_pts_GroupMemberListNext;
1354 * Check to see if we've copied out all the data. If we haven't,
1355 * copy another item. If we have, mark the iterator done.
1358 if (iter->index >= iter->names.namelist_len) {
1359 tst = ADMITERATORDONE;
1360 goto fail_pts_GroupMemberListNext;
1362 strcpy(memberName, iter->names.namelist_val[iter->index]);
1367 fail_pts_GroupMemberListNext:
1370 pthread_mutex_unlock(&iter->mutex);
1380 * pts_GroupMemberListDone - finish using a member list iterator
1384 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1388 * The iterator is locked and then destroyed
1392 * Returns != 0 upon successful completion.
1396 * It is the user's responsibility to make sure pts_GroupMemberListDone
1397 * is called only once for each iterator.
1401 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1404 afs_status_t tst = 0;
1405 pts_group_member_list_iterator_p iter =
1406 (pts_group_member_list_iterator_p) iterationId;
1407 int mutex_locked = 0;
1410 * Validate arguments
1414 tst = ADMITERATORNULL;
1415 goto fail_pts_GroupMemberListDone;
1419 * Lock the mutex and check the validity of the iterator
1422 if (pthread_mutex_lock(&iter->mutex)) {
1424 goto fail_pts_GroupMemberListDone;
1429 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1430 goto fail_pts_GroupMemberListDone;
1434 * Free the namelist and the iterator.
1437 pthread_mutex_destroy(&iter->mutex);
1440 free(iter->names.namelist_val);
1444 fail_pts_GroupMemberListDone:
1447 pthread_mutex_unlock(&iter->mutex);
1457 * pts_GroupMemberRemove - remove a member from a group.
1461 * IN cellHandle - a previously opened cellHandle that corresponds
1462 * to the cell where the group exists.
1464 * IN userName - the user to remove.
1466 * IN groupName - the group to modify
1470 * No locks are held by this function
1474 * Returns != 0 upon successful completion.
1479 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1480 const char *groupName, afs_status_p st)
1483 afs_status_t tst = 0;
1484 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1487 ids.idlist_val = NULL;
1490 * Validate arguments
1493 if (!IsValidCellHandle(c_handle, &tst)) {
1494 goto fail_pts_GroupMemberRemove;
1497 if ((userName == NULL) || (*userName == 0)) {
1498 tst = ADMPTSUSERNAMENULL;
1499 goto fail_pts_GroupMemberRemove;
1502 if ((groupName == NULL) || (*groupName == 0)) {
1503 tst = ADMPTSGROUPNAMENULL;
1504 goto fail_pts_GroupMemberRemove;
1507 if (!TranslateTwoNames
1508 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1509 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1510 goto fail_pts_GroupMemberRemove;
1518 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1522 goto fail_pts_GroupMemberRemove;
1526 fail_pts_GroupMemberRemove:
1528 if (ids.idlist_val != 0) {
1529 free(ids.idlist_val);
1539 * pts_GroupRename - change the name of a group
1543 * IN cellHandle - a previously opened cellHandle that corresponds
1544 * to the cell where the group exists.
1546 * IN oldName - the current group name
1548 * IN newName - the new group name
1552 * No locks are held by this function
1556 * Returns != 0 upon successful completion.
1561 pts_GroupRename(const void *cellHandle, const char *oldName,
1562 char *newName, afs_status_p st)
1565 afs_status_t tst = 0;
1566 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1567 afs_int32 groupId = 0;
1570 * Validate arguments
1573 if (!IsValidCellHandle(c_handle, &tst)) {
1574 goto fail_pts_GroupRename;
1577 if ((newName == NULL) || (*newName == 0)) {
1578 tst = ADMPTSNEWNAMENULL;
1579 goto fail_pts_GroupRename;
1582 if ((oldName == NULL) || (*oldName == 0)) {
1583 tst = ADMPTSOLDNAMENULL;
1584 goto fail_pts_GroupRename;
1588 * Translate the group name into an id.
1591 if (!TranslateOneName
1592 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1593 goto fail_pts_GroupRename;
1600 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1603 goto fail_pts_GroupRename;
1607 fail_pts_GroupRename:
1616 * SetGroupAccess - translate our Access notation to pts flags.
1620 * IN rights - the permissions.
1622 * OUT flags - a pointer to an afs_int32 structure that
1623 * contains the flags to pass to pts.
1627 * No locks are held by this function
1631 * Returns != 0 upon successful completion.
1636 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1640 afs_status_t tst = 0;
1644 if (rights->listDelete == PTS_GROUP_ACCESS) {
1646 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1647 tst = ADMPTSINVALIDGROUPDELETEPERM;
1648 goto fail_SetGroupAccess;
1651 if (rights->listAdd == PTS_GROUP_ACCESS) {
1653 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1657 if (rights->listMembership == PTS_GROUP_ACCESS) {
1659 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1663 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1665 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1666 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1667 goto fail_SetGroupAccess;
1670 if (rights->listStatus == PTS_GROUP_ACCESS) {
1672 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1677 fail_SetGroupAccess:
1686 * pts_GroupModify - change the contents of a group entry.
1690 * IN cellHandle - a previously opened cellHandle that corresponds
1691 * to the cell where the group exists.
1693 * IN groupName - the group to change
1695 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1696 * contains the new information for the group.
1700 * No locks are held by this function
1704 * Returns != 0 upon successful completion.
1709 pts_GroupModify(const void *cellHandle, const char *groupName,
1710 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1713 afs_status_t tst = 0;
1714 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1715 afs_int32 groupId = 0;
1716 afs_int32 flags = 0;
1719 * Validate arguments
1722 if (!IsValidCellHandle(c_handle, &tst)) {
1723 goto fail_pts_GroupModify;
1726 if ((groupName == NULL) || (*groupName == 0)) {
1727 tst = ADMPTSGROUPNAMENULL;
1728 goto fail_pts_GroupModify;
1732 if (newEntryP == NULL) {
1733 tst = ADMPTSNEWENTRYPNULL;
1734 goto fail_pts_GroupModify;
1738 * Translate the group name into an id.
1741 if (!TranslateOneName
1742 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1743 goto fail_pts_GroupModify;
1747 * Set the flags argument
1750 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1751 goto fail_pts_GroupModify;
1759 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1763 goto fail_pts_GroupModify;
1767 fail_pts_GroupModify:
1776 * pts_UserCreate - create a new user.
1780 * IN cellHandle - a previously opened cellHandle that corresponds
1781 * to the cell where the group exists.
1783 * IN newUser - the name of the new user.
1785 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1786 * id assigned by pts.
1790 * No locks are held by this function
1794 * Returns != 0 upon successful completion.
1799 pts_UserCreate(const void *cellHandle, char *userName, int *newUserId,
1803 afs_status_t tst = 0;
1804 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1807 * Validate arguments
1810 if (!IsValidCellHandle(c_handle, &tst)) {
1811 goto fail_pts_UserCreate;
1814 if ((userName == NULL) || (*userName == 0)) {
1815 tst = ADMPTSUSERNAMENULL;
1816 goto fail_pts_UserCreate;
1819 if (newUserId == NULL) {
1820 tst = ADMPTSNEWUSERIDNULL;
1821 goto fail_pts_UserCreate;
1825 * We make a different rpc based upon the input to this function
1828 if (*newUserId != 0) {
1830 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1834 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1839 goto fail_pts_UserCreate;
1843 fail_pts_UserCreate:
1852 * pts_UserDelete - delete a user.
1856 * IN cellHandle - a previously opened cellHandle that corresponds
1857 * to the cell where the group exists.
1859 * IN user - the name of the user to delete.
1863 * No locks are held by this function
1867 * Returns != 0 upon successful completion.
1872 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1874 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1875 ADMPTSUSERNAMETOOLONG, st);
1880 * GetUserAccess - a small convenience function for setting
1885 * IN access - a pointer to a pts_userAccess_t to be set with the
1886 * correct permission.
1888 * IN flag - the current permission flag used to derive the permission.
1892 * No locks are obtained or released by this function
1896 * Since this function cannot fail, it returns void.
1901 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1904 *access = PTS_USER_OWNER_ACCESS;
1906 *access = PTS_USER_ANYUSER_ACCESS;
1911 * IsAdministrator - determine if a user is an administrator.
1915 * IN cellHandle - a previously opened cellHandle that corresponds
1916 * to the cell where the group exists.
1918 * IN userEntry - the user data for the user in question.
1920 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1924 * No locks are held by this function
1928 * Returns != 0 upon successful completion.
1933 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1934 int *admin, afs_status_p st)
1937 afs_status_t tst = 0;
1938 afs_int32 adminId = 0;
1939 afs_int32 isAdmin = 0;
1943 if (userId == SYSADMINID) {
1946 if (!TranslateOneName
1947 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1949 goto fail_IsAdministrator;
1952 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1955 goto fail_IsAdministrator;
1963 fail_IsAdministrator:
1972 * pts_UserGet - retrieve information about a particular user.
1976 * IN cellHandle - a previously opened cellHandle that corresponds
1977 * to the cell where the group exists.
1979 * IN userName - the name of the user to retrieve.
1981 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1986 * No locks are held by this function
1990 * Returns != 0 upon successful completion.
1995 pts_UserGet(const void *cellHandle, const char *userName,
1996 pts_UserEntry_p userP, afs_status_p st)
1999 afs_status_t tst = 0;
2000 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2001 struct prcheckentry userEntry;
2002 afs_int32 userId = 0;
2006 afs_int32 ptsids[2];
2012 * Validate arguments
2015 if (!IsValidCellHandle(c_handle, &tst)) {
2016 goto fail_pts_UserGet;
2019 if ((userName == NULL) || (*userName == 0)) {
2020 tst = ADMPTSUSERNAMENULL;
2021 goto fail_pts_UserGet;
2024 if (userP == NULL) {
2025 tst = ADMPTSUSERPNULL;
2026 goto fail_pts_UserGet;
2030 * Translate the group name into an id.
2033 if (!TranslateOneName
2034 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2035 goto fail_pts_UserGet;
2039 * Retrieve information about the group
2042 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2045 goto fail_pts_UserGet;
2048 userP->groupMembershipCount = userEntry.count;
2049 userP->groupCreationQuota = userEntry.ngroups;
2051 * The administrator id, or any member of "system:administrators"
2052 * has unlimited group creation quota. Denote this by setting
2056 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2057 goto fail_pts_UserGet;
2061 userP->groupCreationQuota = -1;
2064 userP->nameUid = userEntry.id;
2065 userP->ownerUid = userEntry.owner;
2066 userP->creatorUid = userEntry.creator;
2067 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2068 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2071 * The permission bits are described in the GroupGet function above.
2072 * The user entry only uses 3 of the 5 permissions, so we shift
2073 * past the unused entries.
2076 flags = userEntry.flags;
2080 GetUserAccess(&userP->listMembership, twobit);
2085 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2087 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2093 GetUserAccess(&userP->listStatus, twobit);
2096 * Make another rpc and translate the owner and creator ids into
2097 * character strings.
2101 ids.idlist_val = ptsids;
2102 ptsids[0] = userEntry.owner;
2103 ptsids[1] = userEntry.creator;
2104 names.namelist_len = 0;
2105 names.namelist_val = 0;
2108 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2109 goto fail_pts_UserGet;
2112 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2113 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2114 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2115 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2116 free(names.namelist_val);
2128 * pts_UserRename - rename a user.
2132 * IN cellHandle - a previously opened cellHandle that corresponds
2133 * to the cell where the group exists.
2135 * IN oldName - the name of the user to rename.
2137 * IN newName - the new user name.
2141 * No locks are held by this function
2145 * Returns != 0 upon successful completion.
2150 pts_UserRename(const void *cellHandle, const char *oldName,
2151 char *newName, afs_status_p st)
2154 afs_status_t tst = 0;
2155 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2156 afs_int32 userId = 0;
2159 * Validate arguments
2162 if (!IsValidCellHandle(c_handle, &tst)) {
2163 goto fail_pts_UserRename;
2166 if ((oldName == NULL) || (*oldName == 0)) {
2167 tst = ADMPTSOLDNAMENULL;
2168 goto fail_pts_UserRename;
2171 if ((newName == NULL) || (*newName == 0)) {
2172 tst = ADMPTSNEWNAMENULL;
2173 goto fail_pts_UserRename;
2177 * Translate the user name into an id.
2180 if (!TranslateOneName
2181 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2182 goto fail_pts_UserRename;
2189 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2192 goto fail_pts_UserRename;
2196 fail_pts_UserRename:
2205 * SetUserAccess - translate our Access notation to pts flags.
2209 * IN userP - the user structure that contains the new permissions.
2211 * OUT flags - a pointer to an afs_int32 structure that
2212 * contains the flags to pass to pts.
2216 * No locks are held by this function
2220 * Returns != 0 upon successful completion.
2225 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2229 afs_status_t tst = 0;
2233 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2237 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2241 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2254 * pts_UserModify - update a user entry.
2258 * IN cellHandle - a previously opened cellHandle that corresponds
2259 * to the cell where the group exists.
2261 * IN userName - the name of the user to update.
2263 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2264 * new information for user.
2268 * No locks are held by this function
2272 * Returns != 0 upon successful completion.
2277 pts_UserModify(const void *cellHandle, const char *userName,
2278 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2281 afs_status_t tst = 0;
2282 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2283 afs_int32 userId = 0;
2284 afs_int32 newQuota = 0;
2286 afs_int32 flags = 0;
2289 * Validate arguments
2292 if (!IsValidCellHandle(c_handle, &tst)) {
2293 goto fail_pts_UserModify;
2296 if ((userName == NULL) || (*userName == 0)) {
2297 tst = ADMPTSUSERNAMENULL;
2298 goto fail_pts_UserModify;
2301 if (newEntryP == NULL) {
2302 tst = ADMPTSNEWENTRYPNULL;
2303 goto fail_pts_UserModify;
2307 * Translate the user name into an id.
2310 if (!TranslateOneName
2311 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2312 goto fail_pts_UserModify;
2316 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2317 mask |= PR_SF_NGROUPS;
2318 newQuota = newEntryP->groupCreationQuota;
2321 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2322 mask |= PR_SF_ALLBITS;
2323 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2324 goto fail_pts_UserModify;
2333 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2337 goto fail_pts_UserModify;
2341 fail_pts_UserModify:
2350 * pts_UserMaxGet - get the maximum in use user id.
2354 * IN cellHandle - a previously opened cellHandle that corresponds
2355 * to the cell where the group exists.
2357 * OUT maxUserId - upon successful completion contains the max in use id.
2361 * No locks are held by this function
2365 * Returns != 0 upon successful completion.
2370 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2373 afs_status_t tst = 0;
2374 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2375 afs_int32 maxGroupId = 0;
2378 * Validate arguments
2381 if (!IsValidCellHandle(c_handle, &tst)) {
2382 goto fail_pts_UserMaxGet;
2385 if (maxUserId == NULL) {
2386 tst = ADMPTSMAXUSERIDNULL;
2387 goto fail_pts_UserMaxGet;
2390 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2393 goto fail_pts_UserMaxGet;
2397 fail_pts_UserMaxGet:
2406 * pts_UserMaxSet - set the maximum user id.
2410 * IN cellHandle - a previously opened cellHandle that corresponds
2411 * to the cell where the group exists.
2413 * IN maxUserId - the new max user id.
2417 * No locks are held by this function
2421 * Returns != 0 upon successful completion.
2426 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2429 afs_status_t tst = 0;
2430 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2433 * Validate arguments
2436 if (!IsValidCellHandle(c_handle, &tst)) {
2437 goto fail_pts_UserMaxSet;
2440 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2443 goto fail_pts_UserMaxSet;
2447 fail_pts_UserMaxSet:
2456 * pts_UserMemberListBegin - begin iterating over the list of groups
2457 * a particular user belongs to.
2461 * IN cellHandle - a previously opened cellHandle that corresponds
2462 * to the cell where the group exists.
2464 * IN groupName - the group whose members will be returned.
2466 * OUT iterationIdP - upon successful completion contains a iterator that
2467 * can be passed to pts_GroupMemberListNext.
2471 * No locks are obtained or released by this function
2475 * Returns != 0 upon successful completion.
2480 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2481 void **iterationIdP, afs_status_p st)
2483 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2484 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2489 * pts_UserMemberListNext - get the next group a user belongs to
2493 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2495 * OUT userName - upon successful completion contains the next group a user
2500 * The iterator mutex is held during the retrieval of the next member.
2504 * Returns != 0 upon successful completion.
2509 pts_UserMemberListNext(const void *iterationId, char *userName,
2512 return pts_GroupMemberListNext(iterationId, userName, st);
2516 * pts_UserMemberListDone - finish using a user list iterator
2520 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2524 * The iterator is locked and then destroyed
2528 * Returns != 0 upon successful completion.
2532 * It is the user's responsibility to make sure pts_UserMemberListDone
2533 * is called only once for each iterator.
2537 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2539 return pts_GroupMemberListDone(iterationId, st);
2542 typedef struct owned_group_list {
2543 namelist owned_names; /* the list of character names owned by this id */
2544 prlist owned_ids; /* the list of pts ids owned by this id */
2545 afs_int32 index; /* the index into owned_names for the next group */
2546 afs_int32 owner; /* the pts id of the owner */
2547 afs_int32 more; /* the last parameter to PR_ListOwned */
2548 int finished_retrieving; /* set when we've processed the last owned_names */
2549 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2550 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2551 } owned_group_list_t, *owned_group_list_p;
2554 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2557 afs_status_t tst = 0;
2558 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2560 if (list->owned_names.namelist_val != NULL) {
2561 free(list->owned_names.namelist_val);
2564 if (list->owned_ids.prlist_val != NULL) {
2565 free(list->owned_ids.prlist_val);
2576 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2577 int *last_item_contains_data, afs_status_p st)
2580 afs_status_t tst = 0;
2581 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2584 * We really don't make an rpc for every entry we return here
2585 * since the pts interface allows several members to be returned
2586 * with one rpc, but we fake it to make the iterator happy.
2590 * Check to see if we are done retrieving data
2593 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2595 *last_item_contains_data = 0;
2596 goto fail_GetOwnedGroupRPC;
2600 * Check to see if we really need to make an rpc
2603 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2605 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2606 &list->owned_ids, &list->more);
2608 goto fail_GetOwnedGroupRPC;
2611 if (!TranslatePTSIds
2612 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2614 goto fail_GetOwnedGroupRPC;
2618 if (list->owned_names.namelist_val == NULL) {
2620 *last_item_contains_data = 0;
2621 goto fail_GetOwnedGroupRPC;
2626 * We can retrieve the next group from data we already received
2629 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2633 * Check to see if there is more data to be retrieved
2634 * We need to free up the previously retrieved data here
2635 * and then check to see if the last rpc indicated that there
2636 * were more items to retrieve.
2639 if (list->index >= list->owned_names.namelist_len) {
2640 list->owned_names.namelist_len = 0;
2641 free(list->owned_names.namelist_val);
2642 list->owned_names.namelist_val = 0;
2644 list->owned_ids.prlist_len = 0;
2645 free(list->owned_ids.prlist_val);
2646 list->owned_ids.prlist_val = 0;
2649 list->finished_retrieving = 1;
2654 fail_GetOwnedGroupRPC:
2663 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2667 afs_status_t tst = 0;
2668 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2670 strcpy((char *)dest, list->group[slot]);
2681 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2682 * a particular user owns.
2686 * IN cellHandle - a previously opened cellHandle that corresponds
2687 * to the cell where the group exists.
2689 * IN ownerName - the owner of the groups of interest.
2691 * OUT iterationIdP - upon successful completion contains a iterator that
2692 * can be passed to pts_OwnedGroupListNext.
2696 * No locks are held by this function
2700 * Returns != 0 upon successful completion.
2705 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2706 void **iterationIdP, afs_status_p st)
2709 afs_status_t tst = 0;
2710 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2711 afs_admin_iterator_p iter = malloc(sizeof(afs_admin_iterator_t));
2712 owned_group_list_p list = 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 = malloc(sizeof(afs_admin_iterator_t));
3047 pts_list_p list = malloc(sizeof(pts_list_t));
3050 * Validate arguments
3053 if (!IsValidCellHandle(c_handle, &tst)) {
3054 goto fail_pts_UserListBegin;
3057 if (iterationIdP == NULL) {
3058 tst = ADMITERATORNULL;
3059 goto fail_pts_UserListBegin;
3062 if ((iter == NULL) || (list == NULL)) {
3064 goto fail_pts_UserListBegin;
3068 * Initialize the iterator specific data
3072 list->finished_retrieving = 0;
3073 list->c_handle = c_handle;
3075 list->nextstartindex = 0;
3077 list->flag = PRUSERS;
3080 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3081 DeletePTSSpecificData, &tst)) {
3082 *iterationIdP = (void *)iter;
3086 fail_pts_UserListBegin:
3104 * pts_UserListNext - get the next user in the cell.
3108 * IN iterationId - an iterator previously returned by pts_UserListBegin
3110 * OUT groupName - upon successful completion contains the next user
3114 * The iterator mutex is held during the retrieval of the next member.
3118 * Returns != 0 upon successful completion.
3123 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3126 afs_status_t tst = 0;
3127 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3130 * Validate arguments
3133 if (iterationId == NULL) {
3134 tst = ADMITERATORNULL;
3135 goto fail_pts_UserListNext;
3138 if (userName == NULL) {
3139 tst = ADMPTSUSERNAMENULL;
3140 goto fail_pts_UserListNext;
3143 rc = IteratorNext(iter, (void *)userName, &tst);
3145 fail_pts_UserListNext:
3154 * pts_UserListDone - finish using a user list iterator
3158 * IN iterationId - an iterator previously returned by pts_UserListBegin
3162 * The iterator is locked and then destroyed
3166 * Returns != 0 upon successful completion.
3170 * It is the user's responsibility to make sure pts_UserListDone
3171 * is called only once for each iterator.
3175 pts_UserListDone(const void *iterationId, afs_status_p st)
3178 afs_status_t tst = 0;
3179 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3182 * Validate arguments
3185 if (iterationId == NULL) {
3186 tst = ADMITERATORNULL;
3187 goto fail_pts_UserListDone;
3190 rc = IteratorDone(iter, &tst);
3192 fail_pts_UserListDone:
3201 * pts_GroupListBegin - begin iterating over the list of groups
3202 * in a particular cell.
3206 * IN cellHandle - a previously opened cellHandle that corresponds
3207 * to the cell where the groups exist.
3209 * OUT iterationIdP - upon successful completion contains a iterator that
3210 * can be passed to pts_GroupListNext.
3214 * No locks are held by this function
3218 * Returns != 0 upon successful completion.
3223 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3227 afs_status_t tst = 0;
3228 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3229 afs_admin_iterator_p iter = malloc(sizeof(afs_admin_iterator_t));
3230 pts_list_p list = 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: