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>
18 #include "afs_ptsAdmin.h"
19 #include "../adminutil/afs_AdminInternal.h"
20 #include <afs/afs_AdminErrors.h>
21 #include <afs/afs_utilAdmin.h>
22 #include <afs/ptint.h>
23 #include <afs/ptserver.h>
26 * IsValidCellHandle - validate the cell handle for making pts
31 * IN cellHandle - a previously opened cellHandle that is to be validated.
35 * No locks are obtained or released by this function
39 * Returns != 0 upon successful completion.
44 IsValidCellHandle(const afs_cell_handle_p c_handle, afs_status_p st)
49 if (!CellHandleIsValid((void *)c_handle, &tst)) {
50 goto fail_IsValidCellHandle;
53 if (c_handle->pts_valid == 0) {
54 tst = ADMCLIENTCELLPTSINVALID;
55 goto fail_IsValidCellHandle;
58 if (c_handle->pts == NULL) {
59 tst = ADMCLIENTCELLPTSNULL;
60 goto fail_IsValidCellHandle;
65 fail_IsValidCellHandle:
75 * TranslatePTSNames - translate character representations of pts names
76 * into their numeric equivalent.
80 * IN cellHandle - a previously opened cellHandle that corresponds
81 * to the cell where the id's exist.
83 * IN names - the list of names to be translated.
85 * OUT ids - the list of translated names
89 * No locks are obtained or released by this function
93 * Returns != 0 upon successful completion.
98 TranslatePTSNames(const afs_cell_handle_p cellHandle, namelist * names,
99 idlist * ids, afs_status_p st)
102 afs_status_t tst = 0;
107 * Lowercase the names to translate
110 for (i = 0; i < names->namelist_len; i++) {
111 p = names->namelist_val[i];
118 tst = ubik_PR_NameToID(cellHandle->pts, 0, names, ids);
121 goto fail_TranslatePTSNames;
126 * Check to see if the lookup failed
129 for (i = 0; i < ids->idlist_len; i++) {
130 if (ids->idlist_val[i] == ANONYMOUSID) {
131 tst = ADMPTSFAILEDNAMETRANSLATE;
132 goto fail_TranslatePTSNames;
137 fail_TranslatePTSNames:
146 * TranslateTwoNames - translate two pts names to their pts ids.
150 * IN cellHandle - a previously opened cellHandle that corresponds
151 * to the cell where the group exists.
153 * IN id1 - one id to be translated
155 * IN error1 - the error status to be returned in the event that id1 is
158 * IN id2 - one id to be translated
160 * IN error2 - the error status to be returned in the event that id2 is
164 * OUT idlist - the list of pts id's
168 * No locks are obtained or released by this function
172 * Returns != 0 upon successful completion.
177 TranslateTwoNames(const afs_cell_handle_p c_handle, const char *id1,
178 afs_status_t error1, const char *id2, afs_status_t error2,
179 idlist * ids, afs_status_p st)
182 afs_status_t tst = 0;
184 char tmp_array[2 * PTS_MAX_NAME_LEN];
187 * Copy the group and user names in order to translate them
190 names.namelist_len = 2;
191 names.namelist_val = (prname *) & tmp_array[0];
193 strncpy(names.namelist_val[0], id1, PTS_MAX_NAME_LEN);
194 names.namelist_val[0][PTS_MAX_NAME_LEN - 1] = '\0';
195 strncpy(names.namelist_val[1], id2, PTS_MAX_NAME_LEN);
196 names.namelist_val[1][PTS_MAX_NAME_LEN - 1] = '\0';
201 * Check that user and group aren't too long
202 * This is a cheaper check than calling strlen
205 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
207 goto fail_TranslateTwoNames;
210 if (names.namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
212 goto fail_TranslateTwoNames;
216 * Translate user and group into pts ID's
219 if (TranslatePTSNames(c_handle, &names, ids, &tst) == 0) {
220 goto fail_TranslateTwoNames;
225 fail_TranslateTwoNames:
234 * TranslateOneName - translate a pts name to its pts id.
238 * IN cellHandle - a previously opened cellHandle that corresponds
239 * to the cell where the group exists.
241 * IN userName - the user to be translated.
243 * OUT idlist - the user pts id.
247 * No locks are obtained or released by this function
251 * Returns != 0 upon successful completion.
256 TranslateOneName(const afs_cell_handle_p c_handle, const char *ptsName,
257 afs_status_t tooLongError, afs_int32 * ptsId,
261 afs_status_t tst = 0;
263 char tmp_array[PTS_MAX_NAME_LEN];
267 * Copy the name in order to translate it
270 names[0].namelist_len = 1;
271 names[0].namelist_val = (prname *) & tmp_array[0];
273 strncpy((char *)names[0].namelist_val, ptsName, PTS_MAX_NAME_LEN);
274 ((char *)names[0].namelist_val)[PTS_MAX_NAME_LEN - 1] = '\0';
279 * Check that user isn't too long
280 * This is a cheaper check than calling strlen
283 if (names[0].namelist_val[0][PTS_MAX_NAME_LEN - 1] != 0) {
285 goto fail_TranslateOneName;
289 * Translate user into pts ID
292 if (TranslatePTSNames(c_handle, names, &ids, &tst) == 0) {
293 goto fail_TranslateOneName;
295 if (ids.idlist_val != NULL) {
296 *ptsId = *ids.idlist_val;
297 free(ids.idlist_val);
303 fail_TranslateOneName:
312 * TranslatePTSIds - translate numeric representations of pts names
313 * into their character equivalent.
317 * IN cellHandle - a previously opened cellHandle that corresponds
318 * to the cell where the id's exist.
320 * IN ids - the list of ids to be translated.
322 * OUT names - the list of translated names
326 * No locks are obtained or released by this function
330 * Returns != 0 upon successful completion.
335 TranslatePTSIds(const afs_cell_handle_p cellHandle, namelist * names,
336 idlist * ids, afs_status_p st)
339 afs_status_t tst = 0;
341 tst = ubik_PR_IDToName(cellHandle->pts, 0, ids, names);
344 goto fail_TranslatePTSIds;
348 fail_TranslatePTSIds:
357 * pts_GroupMemberAdd - add one member to a pts group
361 * IN cellHandle - a previously opened cellHandle that corresponds
362 * to the cell where the group exists.
364 * IN userName - the name to be added to the group.
366 * IN groupName - the group to be modified.
370 * No locks are obtained or released by this function
374 * Returns != 0 upon successful completion.
379 pts_GroupMemberAdd(const void *cellHandle, const char *userName,
380 const char *groupName, afs_status_p st)
383 afs_status_t tst = 0;
384 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
391 if (!IsValidCellHandle(c_handle, &tst)) {
392 goto fail_pts_GroupMemberAdd;
395 if ((userName == NULL) || (*userName == 0)) {
396 tst = ADMPTSUSERNAMENULL;
397 goto fail_pts_GroupMemberAdd;
400 if ((groupName == NULL) || (*groupName == 0)) {
401 tst = ADMPTSGROUPNAMENULL;
402 goto fail_pts_GroupMemberAdd;
405 if (!TranslateTwoNames
406 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
407 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
408 goto fail_pts_GroupMemberAdd;
416 ubik_PR_AddToGroup(c_handle->pts, 0, ids.idlist_val[0],
420 goto fail_pts_GroupMemberAdd;
424 fail_pts_GroupMemberAdd:
426 if (ids.idlist_val != 0) {
427 free(ids.idlist_val);
437 * pts_GroupOwnerChange - change the owner of a group
441 * IN cellHandle - a previously opened cellHandle that corresponds
442 * to the cell where the group exists.
444 * IN targetGroup - the group to be modified.
446 * IN userName - the new owner of the group.
450 * No locks are obtained or released by this function
454 * Returns != 0 upon successful completion.
459 pts_GroupOwnerChange(const void *cellHandle, const char *targetGroup,
460 const char *newOwner, afs_status_p st)
463 afs_status_t tst = 0;
464 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
471 if (!IsValidCellHandle(c_handle, &tst)) {
472 goto fail_pts_GroupOwnerChange;
475 if ((newOwner == NULL) || (*newOwner == 0)) {
476 tst = ADMPTSNEWOWNERNULL;
477 goto fail_pts_GroupOwnerChange;
480 if ((targetGroup == NULL) || (*targetGroup == 0)) {
481 tst = ADMPTSTARGETGROUPNULL;
482 goto fail_pts_GroupOwnerChange;
485 if (!TranslateTwoNames
486 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, targetGroup,
487 ADMPTSTARGETGROUPTOOLONG, &ids, &tst)) {
488 goto fail_pts_GroupOwnerChange;
496 ubik_PR_ChangeEntry(c_handle->pts, 0, ids.idlist_val[1], "",
497 ids.idlist_val[0], 0);
500 goto fail_pts_GroupOwnerChange;
504 fail_pts_GroupOwnerChange:
506 if (ids.idlist_val != 0) {
507 free(ids.idlist_val);
517 * pts_GroupCreate - create a new group
521 * IN cellHandle - a previously opened cellHandle that corresponds
522 * to the cell where the group exists.
524 * IN newGroup - the group to be created.
526 * IN newOwner - the owner of the group. Pass NULL if the current user
527 * is to be the new owner, or the character string of the owner otherwise.
529 * IN/OUT newGroupId - the pts id of the group. Pass 0 to have ptserver
530 * generate a value, != 0 to assign a value on your own. The group id
531 * that is used to create the group is copied into this parameter in the
532 * event you pass in 0.
536 * No locks are obtained or released by this function
540 * Returns != 0 upon successful completion.
545 pts_GroupCreate(const void *cellHandle, const char *newGroup,
546 const char *newOwner, int *newGroupId, afs_status_p st)
549 afs_status_t tst = 0;
550 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
551 afs_int32 newOwnerId = 0;
557 if (!IsValidCellHandle(c_handle, &tst)) {
558 goto fail_pts_GroupCreate;
561 if ((newGroup == NULL) || (*newGroup == 0)) {
562 tst = ADMPTSNEWGROUPNULL;
563 goto fail_pts_GroupCreate;
566 if (newGroupId == NULL) {
567 tst = ADMPTSNEWGROUPIDNULL;
568 goto fail_pts_GroupCreate;
571 if (*newGroupId > 0) {
572 tst = ADMPTSNEWGROUPIDPOSITIVE;
573 goto fail_pts_GroupCreate;
577 * If a newOwner was specified, validate that it exists
580 if (newOwner != NULL) {
581 if (!TranslateOneName
582 (c_handle, newOwner, ADMPTSNEWOWNERTOOLONG, &newOwnerId, &tst)) {
583 goto fail_pts_GroupCreate;
588 * We make a different rpc based upon the input to this function
591 if (*newGroupId != 0) {
593 ubik_PR_INewEntry(c_handle->pts, 0, newGroup, *newGroupId,
597 ubik_PR_NewEntry(c_handle->pts, 0, newGroup, PRGRP,
598 newOwnerId, newGroupId);
602 goto fail_pts_GroupCreate;
606 fail_pts_GroupCreate:
615 * GetGroupAccess - a small convenience function for setting
620 * IN access - a pointer to a pts_groupAccess_t to be set with the
621 * correct permission.
623 * IN flag - the current permission flag used to derive the permission.
627 * No locks are obtained or released by this function
631 * Since this function cannot fail, it returns void.
636 GetGroupAccess(pts_groupAccess_p access, afs_int32 flag)
639 *access = PTS_GROUP_OWNER_ACCESS;
641 *access = PTS_GROUP_OWNER_ACCESS;
642 } else if (flag == 1) {
643 *access = PTS_GROUP_ACCESS;
644 } else if (flag == 2) {
645 *access = PTS_GROUP_ANYUSER_ACCESS;
651 * pts_GroupGet - retrieve information about a particular group.
655 * IN cellHandle - a previously opened cellHandle that corresponds
656 * to the cell where the group exists.
658 * IN groupName - the group to retrieve.
660 * OUT groupP - a pointer to a pts_GroupEntry_t structure that upon
661 * successful completion is filled with information about groupName.
665 * No locks are obtained or released by this function
669 * Returns != 0 upon successful completion.
674 pts_GroupGet(const void *cellHandle, const char *groupName,
675 pts_GroupEntry_p groupP, afs_status_p st)
678 afs_status_t tst = 0;
679 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
680 afs_int32 groupId = 0;
683 struct prcheckentry groupEntry;
692 if (!IsValidCellHandle(c_handle, &tst)) {
693 goto fail_pts_GroupGet;
696 if ((groupName == NULL) || (*groupName == 0)) {
697 tst = ADMPTSGROUPNAMENULL;
698 goto fail_pts_GroupGet;
701 if (groupP == NULL) {
702 tst = ADMPTSGROUPPNULL;
703 goto fail_pts_GroupGet;
707 * Translate the group name into an id.
710 if (!TranslateOneName
711 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
712 goto fail_pts_GroupGet;
716 * Retrieve information about the group
719 tst = ubik_PR_ListEntry(c_handle->pts, 0, groupId, &groupEntry);
722 goto fail_pts_GroupGet;
725 groupP->membershipCount = groupEntry.count;
726 groupP->nameUid = groupEntry.id;
727 groupP->ownerUid = groupEntry.owner;
728 groupP->creatorUid = groupEntry.creator;
729 strncpy(groupP->name, groupEntry.name, PTS_MAX_NAME_LEN);
730 groupP->name[PTS_MAX_NAME_LEN - 1] = '\0';
732 * Set the access rights based upon the value of the flags member
733 * of the groupEntry struct.
735 * To the best of my ability to decypher the pts code, it looks like
736 * the rights are stored in flags as follows:
738 * I number my bits from least significant to most significant starting
742 * if bit 0 == 0 -> r access is denied
743 * if bit 0 == 1 -> r access is granted
746 * if bit 2 == 0 and bit 1 == 0 -> a access is denied
747 * if bit 2 == 0 and bit 1 == 1 -> a access is granted
748 * if bit 2 == 1 and bit 1 == 0 -> A access is granted
749 * if bit 2 == 1 and bit 1 == 1 -> this is an error
751 * membership - bits 3 and 4
752 * if bit 4 == 0 and bit 3 == 0 -> m access is denied
753 * if bit 4 == 0 and bit 3 == 1 -> m access is granted
754 * if bit 4 == 1 and bit 3 == 0 -> M access is granted
755 * if bit 4 == 1 and bit 3 == 1 -> this is an error
758 * if bit 5 == 0 -> O access is denied
759 * if bit 5 == 1 -> O access is granted
761 * status - bits 6 and 7
762 * if bit 7 == 0 and bit 6 == 0 -> s access is denied
763 * if bit 7 == 0 and bit 6 == 1 -> s access is granted
764 * if bit 7 == 1 and bit 6 == 0 -> S access is granted
765 * if bit 7 == 1 and bit 6 == 1 -> this is an error
767 * For cases where the permission doesn't make sense for the
768 * type of entry, or where an error occurs, we ignore it.
769 * This is the behavior of the pts code.
772 flags = groupEntry.flags;
774 groupP->listDelete = PTS_GROUP_ACCESS;
776 groupP->listDelete = PTS_GROUP_OWNER_ACCESS;
782 GetGroupAccess(&groupP->listAdd, twobit);
787 GetGroupAccess(&groupP->listMembership, twobit);
792 groupP->listGroupsOwned = PTS_GROUP_ANYUSER_ACCESS;
794 groupP->listGroupsOwned = PTS_GROUP_OWNER_ACCESS;
800 GetGroupAccess(&groupP->listStatus, twobit);
803 * Make another rpc and translate the owner and creator ids into
808 ids.idlist_val = ptsids;
809 ptsids[0] = groupEntry.owner;
810 ptsids[1] = groupEntry.creator;
811 names.namelist_len = 0;
812 names.namelist_val = 0;
815 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
816 goto fail_pts_GroupGet;
819 strncpy(groupP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
820 groupP->owner[PTS_MAX_NAME_LEN - 1] = '\0';
821 strncpy(groupP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
822 groupP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
823 free(names.namelist_val);
835 * EntryDelete - delete a pts entry (group or user).
839 * IN cellHandle - a previously opened cellHandle that corresponds
840 * to the cell where the group exists.
842 * IN entryName - the entry to be deleted.
844 * IN error1 - the error status to be returned in the event that entryName is
847 * IN error2 - the error status to be returned in the event that entryName is
852 * No locks are obtained or released by this function
856 * Returns != 0 upon successful completion.
861 EntryDelete(const void *cellHandle, const char *entryName,
862 afs_status_t error1, afs_status_t error2, afs_status_p st)
865 afs_status_t tst = 0;
866 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
867 afs_int32 entryId = 0;
873 if (!IsValidCellHandle(c_handle, &tst)) {
874 goto fail_EntryDelete;
877 if ((entryName == NULL) || (*entryName == 0)) {
879 goto fail_EntryDelete;
883 * Translate the entry name into an id.
886 if (!TranslateOneName(c_handle, entryName, error2, &entryId, &tst)) {
887 goto fail_EntryDelete;
894 tst = ubik_PR_Delete(c_handle->pts, 0, entryId);
897 goto fail_EntryDelete;
911 * pts_GroupDelete - delete a group
915 * IN cellHandle - a previously opened cellHandle that corresponds
916 * to the cell where the group exists.
918 * IN groupName - the group to be deleted.
922 * No locks are obtained or released by this function
926 * Returns != 0 upon successful completion.
931 pts_GroupDelete(const void *cellHandle, const char *groupName,
935 return EntryDelete(cellHandle, groupName, ADMPTSGROUPNAMENULL,
936 ADMPTSGROUPNAMETOOLONG, st);
940 * pts_GroupMaxGet - get the maximum in use group id.
944 * IN cellHandle - a previously opened cellHandle that corresponds
945 * to the cell where the group exists.
947 * OUT maxGroupId - upon successful completion contains the maximum
948 * group Id in use at the server.
952 * No locks are obtained or released by this function
956 * Returns != 0 upon successful completion.
961 pts_GroupMaxGet(const void *cellHandle, int *maxGroupId, afs_status_p st)
964 afs_status_t tst = 0;
965 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
966 afs_int32 maxUserId = 0;
972 if (!IsValidCellHandle(c_handle, &tst)) {
973 goto fail_pts_GroupMaxGet;
976 if (maxGroupId == NULL) {
977 tst = ADMPTSMAXGROUPIDNULL;
978 goto fail_pts_GroupMaxGet;
981 tst = ubik_PR_ListMax(c_handle->pts, 0, &maxUserId, maxGroupId);
984 goto fail_pts_GroupMaxGet;
988 fail_pts_GroupMaxGet:
997 * pts_GroupMaxSet - set the maximum in use group id.
1001 * IN cellHandle - a previously opened cellHandle that corresponds
1002 * to the cell where the group exists.
1004 * IN maxGroupId - the new maximum group id.
1008 * No locks are obtained or released by this function
1012 * Returns != 0 upon successful completion.
1017 pts_GroupMaxSet(const void *cellHandle, int maxGroupId, afs_status_p st)
1020 afs_status_t tst = 0;
1021 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1024 * Validate arguments
1027 if (!IsValidCellHandle(c_handle, &tst)) {
1028 goto fail_pts_GroupMaxSet;
1031 tst = ubik_PR_SetMax(c_handle->pts, 0, maxGroupId, PRGRP);
1034 goto fail_pts_GroupMaxSet;
1038 fail_pts_GroupMaxSet:
1049 * I'm not using the common iterator pattern here since the retrival
1050 * of the member list is actually accomplished in 1 rpc. There's no
1051 * sense in trying to fit this pts specific behavior into the more
1052 * generic model, so instead the Begin functions actually do all the
1053 * rpc work and the next/done functions just manipulate the retrieved
1057 typedef struct pts_group_member_list_iterator {
1060 pthread_mutex_t mutex; /* hold to manipulate this structure */
1065 } pts_group_member_list_iterator_t, *pts_group_member_list_iterator_p;
1068 * pts_GroupMemberListBegin - begin iterating over the list of members
1069 * of a particular group.
1073 * IN iter - an iterator previously returned by pts_GroupMemberListBegin
1077 * No locks are obtained or released by this function
1081 * Returns != 0 upon successful completion.
1086 IsValidPtsGroupMemberListIterator(pts_group_member_list_iterator_p iter,
1090 afs_status_t tst = 0;
1093 tst = ADMITERATORNULL;
1094 goto fail_IsValidPtsGroupMemberListIterator;
1097 if ((iter->begin_magic != BEGIN_MAGIC) || (iter->end_magic != END_MAGIC)) {
1098 tst = ADMITERATORBADMAGICNULL;
1099 goto fail_IsValidPtsGroupMemberListIterator;
1102 if (iter->is_valid == 0) {
1103 tst = ADMITERATORINVALID;
1104 goto fail_IsValidPtsGroupMemberListIterator;
1108 fail_IsValidPtsGroupMemberListIterator:
1117 * MemberListBegin - an internal function which is used to get both
1118 * the list of members in a group and the list of groups a user belongs
1123 * IN cellHandle - a previously opened cellHandle that corresponds
1124 * to the cell where the group exists.
1126 * IN name - the name whose membership will be retrieved.
1128 * OUT iterationIdP - upon successful completion contains a iterator that
1129 * can be passed to pts_GroupMemberListNext or pts_UserMemberListNext
1133 * No locks are obtained or released by this function
1137 * Returns != 0 upon successful completion.
1142 MemberListBegin(const void *cellHandle, const char *name, afs_status_t error1,
1143 afs_status_t error2, void **iterationIdP, afs_status_p st)
1146 afs_status_t tst = 0;
1147 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1148 afs_int32 groupId = 0;
1149 afs_int32 exceeded = 0;
1150 pts_group_member_list_iterator_p iter = (pts_group_member_list_iterator_p)
1151 malloc(sizeof(pts_group_member_list_iterator_t));
1152 int iter_allocated = 0;
1153 int ids_allocated = 0;
1154 int names_allocated = 0;
1155 int mutex_inited = 0;
1158 * Validate arguments
1161 if (!IsValidCellHandle(c_handle, &tst)) {
1162 goto fail_MemberListBegin;
1165 if ((name == NULL) || (*name == 0)) {
1166 tst = ADMPTSGROUPNAMENULL;
1167 goto fail_MemberListBegin;
1170 if (iterationIdP == NULL) {
1171 tst = ADMITERATORNULL;
1172 goto fail_MemberListBegin;
1177 goto fail_MemberListBegin;
1183 * Translate the name into an id.
1186 if (!TranslateOneName
1187 (c_handle, name, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1188 goto fail_MemberListBegin;
1191 if (pthread_mutex_init(&iter->mutex, 0)) {
1193 goto fail_MemberListBegin;
1198 iter->ids.prlist_len = 0;
1199 iter->ids.prlist_val = 0;
1202 ubik_PR_ListElements(c_handle->pts, 0, groupId, &iter->ids,
1206 goto fail_MemberListBegin;
1209 if (exceeded != 0) {
1210 tst = ADMPTSGROUPMEMEXCEEDED;
1211 goto fail_MemberListBegin;
1215 iter->names.namelist_len = 0;
1216 iter->names.namelist_val = 0;
1218 if (!TranslatePTSIds
1219 (c_handle, &iter->names, (idlist *) & iter->ids, &tst)) {
1220 goto fail_MemberListBegin;
1223 names_allocated = 1;
1224 iter->begin_magic = BEGIN_MAGIC;
1225 iter->end_magic = END_MAGIC;
1229 *iterationIdP = (void *)iter;
1232 fail_MemberListBegin:
1234 if (ids_allocated) {
1235 free(iter->ids.prlist_val);
1239 if (names_allocated) {
1240 free(iter->names.namelist_val);
1243 pthread_mutex_destroy(&iter->mutex);
1245 if (iter_allocated) {
1257 * pts_GroupMemberListBegin - begin iterating over the list of members
1258 * of a particular group.
1262 * IN cellHandle - a previously opened cellHandle that corresponds
1263 * to the cell where the group exists.
1265 * IN groupName - the group whose members will be returned.
1267 * OUT iterationIdP - upon successful completion contains a iterator that
1268 * can be passed to pts_GroupMemberListNext.
1272 * No locks are obtained or released by this function
1276 * Returns != 0 upon successful completion.
1281 pts_GroupMemberListBegin(const void *cellHandle, const char *groupName,
1282 void **iterationIdP, afs_status_p st)
1284 return MemberListBegin(cellHandle, groupName, ADMPTSGROUPNAMENULL,
1285 ADMPTSGROUPNAMETOOLONG, iterationIdP, st);
1289 * pts_GroupMemberListNext - get the next member of a group
1293 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1295 * OUT memberName - upon successful completion contains the next member of
1300 * The iterator mutex is held during the retrieval of the next member.
1304 * Returns != 0 upon successful completion.
1309 pts_GroupMemberListNext(const void *iterationId, char *memberName,
1313 afs_status_t tst = 0;
1314 pts_group_member_list_iterator_p iter =
1315 (pts_group_member_list_iterator_p) iterationId;
1316 int mutex_locked = 0;
1319 * Validate arguments
1323 tst = ADMITERATORNULL;
1324 goto fail_pts_GroupMemberListNext;
1327 if (memberName == NULL) {
1328 tst = ADMPTSMEMBERNAMENULL;
1329 goto fail_pts_GroupMemberListNext;
1333 * Lock the mutex and check the validity of the iterator
1336 if (pthread_mutex_lock(&iter->mutex)) {
1338 goto fail_pts_GroupMemberListNext;
1343 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1344 goto fail_pts_GroupMemberListNext;
1348 * Check to see if we've copied out all the data. If we haven't,
1349 * copy another item. If we have, mark the iterator done.
1352 if (iter->index >= iter->names.namelist_len) {
1353 tst = ADMITERATORDONE;
1354 goto fail_pts_GroupMemberListNext;
1356 strcpy(memberName, iter->names.namelist_val[iter->index]);
1361 fail_pts_GroupMemberListNext:
1364 pthread_mutex_unlock(&iter->mutex);
1374 * pts_GroupMemberListDone - finish using a member list iterator
1378 * IN iterationId - an iterator previously returned by pts_GroupMemberListBegin
1382 * The iterator is locked and then destroyed
1386 * Returns != 0 upon successful completion.
1390 * It is the user's responsibility to make sure pts_GroupMemberListDone
1391 * is called only once for each iterator.
1395 pts_GroupMemberListDone(const void *iterationId, afs_status_p st)
1398 afs_status_t tst = 0;
1399 pts_group_member_list_iterator_p iter =
1400 (pts_group_member_list_iterator_p) iterationId;
1401 int mutex_locked = 0;
1404 * Validate arguments
1408 tst = ADMITERATORNULL;
1409 goto fail_pts_GroupMemberListDone;
1413 * Lock the mutex and check the validity of the iterator
1416 if (pthread_mutex_lock(&iter->mutex)) {
1418 goto fail_pts_GroupMemberListDone;
1423 if (!IsValidPtsGroupMemberListIterator(iter, &tst)) {
1424 goto fail_pts_GroupMemberListDone;
1428 * Free the namelist and the iterator.
1431 pthread_mutex_destroy(&iter->mutex);
1434 free(iter->names.namelist_val);
1438 fail_pts_GroupMemberListDone:
1441 pthread_mutex_unlock(&iter->mutex);
1451 * pts_GroupMemberRemove - remove a member from a group.
1455 * IN cellHandle - a previously opened cellHandle that corresponds
1456 * to the cell where the group exists.
1458 * IN userName - the user to remove.
1460 * IN groupName - the group to modify
1464 * No locks are held by this function
1468 * Returns != 0 upon successful completion.
1473 pts_GroupMemberRemove(const void *cellHandle, const char *userName,
1474 const char *groupName, afs_status_p st)
1477 afs_status_t tst = 0;
1478 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1482 * Validate arguments
1485 if (!IsValidCellHandle(c_handle, &tst)) {
1486 goto fail_pts_GroupMemberRemove;
1489 if ((userName == NULL) || (*userName == 0)) {
1490 tst = ADMPTSUSERNAMENULL;
1491 goto fail_pts_GroupMemberRemove;
1494 if ((groupName == NULL) || (*groupName == 0)) {
1495 tst = ADMPTSGROUPNAMENULL;
1496 goto fail_pts_GroupMemberRemove;
1499 if (!TranslateTwoNames
1500 (c_handle, userName, ADMPTSUSERNAMETOOLONG, groupName,
1501 ADMPTSGROUPNAMETOOLONG, &ids, &tst)) {
1502 goto fail_pts_GroupMemberRemove;
1510 ubik_PR_RemoveFromGroup(c_handle->pts, 0, ids.idlist_val[0],
1514 goto fail_pts_GroupMemberRemove;
1518 fail_pts_GroupMemberRemove:
1520 if (ids.idlist_val != 0) {
1521 free(ids.idlist_val);
1531 * pts_GroupRename - change the name of a group
1535 * IN cellHandle - a previously opened cellHandle that corresponds
1536 * to the cell where the group exists.
1538 * IN oldName - the current group name
1540 * IN newName - the new group name
1544 * No locks are held by this function
1548 * Returns != 0 upon successful completion.
1553 pts_GroupRename(const void *cellHandle, const char *oldName,
1554 const char *newName, afs_status_p st)
1557 afs_status_t tst = 0;
1558 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1559 afs_int32 groupId = 0;
1562 * Validate arguments
1565 if (!IsValidCellHandle(c_handle, &tst)) {
1566 goto fail_pts_GroupRename;
1569 if ((newName == NULL) || (*newName == 0)) {
1570 tst = ADMPTSNEWNAMENULL;
1571 goto fail_pts_GroupRename;
1574 if ((oldName == NULL) || (*oldName == 0)) {
1575 tst = ADMPTSOLDNAMENULL;
1576 goto fail_pts_GroupRename;
1580 * Translate the group name into an id.
1583 if (!TranslateOneName
1584 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &groupId, &tst)) {
1585 goto fail_pts_GroupRename;
1592 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, groupId, newName, 0, 0);
1595 goto fail_pts_GroupRename;
1599 fail_pts_GroupRename:
1608 * SetGroupAccess - translate our Access notation to pts flags.
1612 * IN rights - the permissions.
1614 * OUT flags - a pointer to an afs_int32 structure that
1615 * contains the flags to pass to pts.
1619 * No locks are held by this function
1623 * Returns != 0 upon successful completion.
1628 SetGroupAccess(const pts_GroupUpdateEntry_p rights, afs_int32 * flags,
1632 afs_status_t tst = 0;
1636 if (rights->listDelete == PTS_GROUP_ACCESS) {
1638 } else if (rights->listDelete == PTS_GROUP_ANYUSER_ACCESS) {
1639 tst = ADMPTSINVALIDGROUPDELETEPERM;
1640 goto fail_SetGroupAccess;
1643 if (rights->listAdd == PTS_GROUP_ACCESS) {
1645 } else if (rights->listAdd == PTS_GROUP_ANYUSER_ACCESS) {
1649 if (rights->listMembership == PTS_GROUP_ACCESS) {
1651 } else if (rights->listMembership == PTS_GROUP_ANYUSER_ACCESS) {
1655 if (rights->listGroupsOwned == PTS_GROUP_ANYUSER_ACCESS) {
1657 } else if (rights->listGroupsOwned == PTS_GROUP_ACCESS) {
1658 tst = ADMPTSINVALIDGROUPSOWNEDPERM;
1659 goto fail_SetGroupAccess;
1662 if (rights->listStatus == PTS_GROUP_ACCESS) {
1664 } else if (rights->listStatus == PTS_GROUP_ANYUSER_ACCESS) {
1669 fail_SetGroupAccess:
1678 * pts_GroupModify - change the contents of a group entry.
1682 * IN cellHandle - a previously opened cellHandle that corresponds
1683 * to the cell where the group exists.
1685 * IN groupName - the group to change
1687 * OUT newEntryP - a pointer to a pts_GroupUpdateEntry_t structure that
1688 * contains the new information for the group.
1692 * No locks are held by this function
1696 * Returns != 0 upon successful completion.
1701 pts_GroupModify(const void *cellHandle, const char *groupName,
1702 const pts_GroupUpdateEntry_p newEntryP, afs_status_p st)
1705 afs_status_t tst = 0;
1706 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1707 afs_int32 groupId = 0;
1708 afs_int32 flags = 0;
1711 * Validate arguments
1714 if (!IsValidCellHandle(c_handle, &tst)) {
1715 goto fail_pts_GroupModify;
1718 if ((groupName == NULL) || (*groupName == 0)) {
1719 tst = ADMPTSGROUPNAMENULL;
1720 goto fail_pts_GroupModify;
1724 if (newEntryP == NULL) {
1725 tst = ADMPTSNEWENTRYPNULL;
1726 goto fail_pts_GroupModify;
1730 * Translate the group name into an id.
1733 if (!TranslateOneName
1734 (c_handle, groupName, ADMPTSGROUPNAMETOOLONG, &groupId, &tst)) {
1735 goto fail_pts_GroupModify;
1739 * Set the flags argument
1742 if (!SetGroupAccess(newEntryP, &flags, &tst)) {
1743 goto fail_pts_GroupModify;
1751 ubik_PR_SetFieldsEntry(c_handle->pts, 0, groupId, PR_SF_ALLBITS,
1755 goto fail_pts_GroupModify;
1759 fail_pts_GroupModify:
1768 * pts_UserCreate - create a new user.
1772 * IN cellHandle - a previously opened cellHandle that corresponds
1773 * to the cell where the group exists.
1775 * IN newUser - the name of the new user.
1777 * IN newUserId - the id to assign to the new user. Pass 0 to have the
1778 * id assigned by pts.
1782 * No locks are held by this function
1786 * Returns != 0 upon successful completion.
1791 pts_UserCreate(const void *cellHandle, const char *userName, int *newUserId,
1795 afs_status_t tst = 0;
1796 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1797 afs_int32 userId = 0;
1800 * Validate arguments
1803 if (!IsValidCellHandle(c_handle, &tst)) {
1804 goto fail_pts_UserCreate;
1807 if ((userName == NULL) || (*userName == 0)) {
1808 tst = ADMPTSUSERNAMENULL;
1809 goto fail_pts_UserCreate;
1812 if (newUserId == NULL) {
1813 tst = ADMPTSNEWUSERIDNULL;
1814 goto fail_pts_UserCreate;
1818 * We make a different rpc based upon the input to this function
1821 if (*newUserId != 0) {
1823 ubik_PR_INewEntry(c_handle->pts, 0, userName, *newUserId,
1827 ubik_PR_NewEntry(c_handle->pts, 0, userName, 0, 0,
1832 goto fail_pts_UserCreate;
1836 fail_pts_UserCreate:
1845 * pts_UserDelete - delete a user.
1849 * IN cellHandle - a previously opened cellHandle that corresponds
1850 * to the cell where the group exists.
1852 * IN user - the name of the user to delete.
1856 * No locks are held by this function
1860 * Returns != 0 upon successful completion.
1865 pts_UserDelete(const void *cellHandle, const char *userName, afs_status_p st)
1867 return EntryDelete(cellHandle, userName, ADMPTSUSERNAMENULL,
1868 ADMPTSUSERNAMETOOLONG, st);
1873 * GetUserAccess - a small convenience function for setting
1878 * IN access - a pointer to a pts_userAccess_t to be set with the
1879 * correct permission.
1881 * IN flag - the current permission flag used to derive the permission.
1885 * No locks are obtained or released by this function
1889 * Since this function cannot fail, it returns void.
1894 GetUserAccess(pts_userAccess_p access, afs_int32 flag)
1897 *access = PTS_USER_OWNER_ACCESS;
1899 *access = PTS_USER_ANYUSER_ACCESS;
1904 * IsAdministrator - determine if a user is an administrator.
1908 * IN cellHandle - a previously opened cellHandle that corresponds
1909 * to the cell where the group exists.
1911 * IN userEntry - the user data for the user in question.
1913 * OUT admin - set to 1 if the user is an administrator, 0 otherwise.
1917 * No locks are held by this function
1921 * Returns != 0 upon successful completion.
1926 IsAdministrator(const afs_cell_handle_p c_handle, afs_int32 userId,
1927 int *admin, afs_status_p st)
1930 afs_status_t tst = 0;
1931 afs_int32 adminId = 0;
1932 afs_int32 isAdmin = 0;
1936 if (userId == SYSADMINID) {
1939 if (!TranslateOneName
1940 (c_handle, "system:administrators", ADMPTSGROUPNAMETOOLONG,
1942 goto fail_IsAdministrator;
1945 ubik_PR_IsAMemberOf(c_handle->pts, 0, userId, adminId,
1948 goto fail_IsAdministrator;
1956 fail_IsAdministrator:
1965 * pts_UserGet - retrieve information about a particular user.
1969 * IN cellHandle - a previously opened cellHandle that corresponds
1970 * to the cell where the group exists.
1972 * IN userName - the name of the user to retrieve.
1974 * OUT userP - a pointer to a pts_UserEntry_t that is filled upon successful
1979 * No locks are held by this function
1983 * Returns != 0 upon successful completion.
1988 pts_UserGet(const void *cellHandle, const char *userName,
1989 pts_UserEntry_p userP, afs_status_p st)
1992 afs_status_t tst = 0;
1993 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
1994 struct prcheckentry userEntry;
1995 afs_int32 userId = 0;
1999 afs_int32 ptsids[2];
2005 * Validate arguments
2008 if (!IsValidCellHandle(c_handle, &tst)) {
2009 goto fail_pts_UserGet;
2012 if ((userName == NULL) || (*userName == 0)) {
2013 tst = ADMPTSUSERNAMENULL;
2014 goto fail_pts_UserGet;
2017 if (userP == NULL) {
2018 tst = ADMPTSUSERPNULL;
2019 goto fail_pts_UserGet;
2023 * Translate the group name into an id.
2026 if (!TranslateOneName
2027 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2028 goto fail_pts_UserGet;
2032 * Retrieve information about the group
2035 tst = ubik_PR_ListEntry(c_handle->pts, 0, userId, &userEntry);
2038 goto fail_pts_UserGet;
2041 userP->groupMembershipCount = userEntry.count;
2042 userP->groupCreationQuota = userEntry.ngroups;
2044 * The administrator id, or any member of "system:administrators"
2045 * has unlimited group creation quota. Denote this by setting
2049 if (!IsAdministrator(c_handle, userEntry.id, &admin, &tst)) {
2050 goto fail_pts_UserGet;
2054 userP->groupCreationQuota = -1;
2057 userP->nameUid = userEntry.id;
2058 userP->ownerUid = userEntry.owner;
2059 userP->creatorUid = userEntry.creator;
2060 strncpy(userP->name, userEntry.name, PTS_MAX_NAME_LEN);
2061 userP->name[PTS_MAX_NAME_LEN - 1] = '\0';
2064 * The permission bits are described in the GroupGet function above.
2065 * The user entry only uses 3 of the 5 permissions, so we shift
2066 * past the unused entries.
2069 flags = userEntry.flags;
2073 GetUserAccess(&userP->listMembership, twobit);
2078 userP->listGroupsOwned = PTS_USER_ANYUSER_ACCESS;
2080 userP->listGroupsOwned = PTS_USER_OWNER_ACCESS;
2086 GetUserAccess(&userP->listStatus, twobit);
2089 * Make another rpc and translate the owner and creator ids into
2090 * character strings.
2094 ids.idlist_val = ptsids;
2095 ptsids[0] = userEntry.owner;
2096 ptsids[1] = userEntry.creator;
2097 names.namelist_len = 0;
2098 names.namelist_val = 0;
2101 if (!TranslatePTSIds(c_handle, &names, &ids, &tst)) {
2102 goto fail_pts_UserGet;
2105 strncpy(userP->owner, names.namelist_val[0], PTS_MAX_NAME_LEN);
2106 userP->owner[PTS_MAX_NAME_LEN - 1] ='\0';
2107 strncpy(userP->creator, names.namelist_val[1], PTS_MAX_NAME_LEN);
2108 userP->creator[PTS_MAX_NAME_LEN - 1] = '\0';
2109 free(names.namelist_val);
2121 * pts_UserRename - rename a user.
2125 * IN cellHandle - a previously opened cellHandle that corresponds
2126 * to the cell where the group exists.
2128 * IN oldName - the name of the user to rename.
2130 * IN newName - the new user name.
2134 * No locks are held by this function
2138 * Returns != 0 upon successful completion.
2143 pts_UserRename(const void *cellHandle, const char *oldName,
2144 const char *newName, afs_status_p st)
2147 afs_status_t tst = 0;
2148 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2149 afs_int32 userId = 0;
2152 * Validate arguments
2155 if (!IsValidCellHandle(c_handle, &tst)) {
2156 goto fail_pts_UserRename;
2159 if ((oldName == NULL) || (*oldName == 0)) {
2160 tst = ADMPTSOLDNAMENULL;
2161 goto fail_pts_UserRename;
2164 if ((newName == NULL) || (*newName == 0)) {
2165 tst = ADMPTSNEWNAMENULL;
2166 goto fail_pts_UserRename;
2170 * Translate the user name into an id.
2173 if (!TranslateOneName
2174 (c_handle, oldName, ADMPTSOLDNAMETOOLONG, &userId, &tst)) {
2175 goto fail_pts_UserRename;
2182 tst = ubik_PR_ChangeEntry(c_handle->pts, 0, userId, newName, 0, 0);
2185 goto fail_pts_UserRename;
2189 fail_pts_UserRename:
2198 * SetUserAccess - translate our Access notation to pts flags.
2202 * IN userP - the user structure that contains the new permissions.
2204 * OUT flags - a pointer to an afs_int32 structure that
2205 * contains the flags to pass to pts.
2209 * No locks are held by this function
2213 * Returns != 0 upon successful completion.
2218 SetUserAccess(const pts_UserUpdateEntry_p userP, afs_int32 * flags,
2222 afs_status_t tst = 0;
2226 if (userP->listMembership == PTS_USER_ANYUSER_ACCESS) {
2230 if (userP->listGroupsOwned == PTS_USER_ANYUSER_ACCESS) {
2234 if (userP->listStatus == PTS_USER_ANYUSER_ACCESS) {
2247 * pts_UserModify - update a user entry.
2251 * IN cellHandle - a previously opened cellHandle that corresponds
2252 * to the cell where the group exists.
2254 * IN userName - the name of the user to update.
2256 * IN newEntryP - a pointer to a pts_UserUpdateEntry_t that contains the
2257 * new information for user.
2261 * No locks are held by this function
2265 * Returns != 0 upon successful completion.
2270 pts_UserModify(const void *cellHandle, const char *userName,
2271 const pts_UserUpdateEntry_p newEntryP, afs_status_p st)
2274 afs_status_t tst = 0;
2275 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2276 afs_int32 userId = 0;
2277 afs_int32 newQuota = 0;
2279 afs_int32 flags = 0;
2282 * Validate arguments
2285 if (!IsValidCellHandle(c_handle, &tst)) {
2286 goto fail_pts_UserModify;
2289 if ((userName == NULL) || (*userName == 0)) {
2290 tst = ADMPTSUSERNAMENULL;
2291 goto fail_pts_UserModify;
2294 if (newEntryP == NULL) {
2295 tst = ADMPTSNEWENTRYPNULL;
2296 goto fail_pts_UserModify;
2300 * Translate the user name into an id.
2303 if (!TranslateOneName
2304 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &userId, &tst)) {
2305 goto fail_pts_UserModify;
2309 if (newEntryP->flag & PTS_USER_UPDATE_GROUP_CREATE_QUOTA) {
2310 mask |= PR_SF_NGROUPS;
2311 newQuota = newEntryP->groupCreationQuota;
2314 if (newEntryP->flag & PTS_USER_UPDATE_PERMISSIONS) {
2315 mask |= PR_SF_ALLBITS;
2316 if (!SetUserAccess(newEntryP, &flags, &tst)) {
2317 goto fail_pts_UserModify;
2326 ubik_PR_SetFieldsEntry(c_handle->pts, 0, userId, mask, flags,
2330 goto fail_pts_UserModify;
2334 fail_pts_UserModify:
2343 * pts_UserMaxGet - get the maximum in use user id.
2347 * IN cellHandle - a previously opened cellHandle that corresponds
2348 * to the cell where the group exists.
2350 * OUT maxUserId - upon successful completion contains the max in use id.
2354 * No locks are held by this function
2358 * Returns != 0 upon successful completion.
2363 pts_UserMaxGet(const void *cellHandle, int *maxUserId, afs_status_p st)
2366 afs_status_t tst = 0;
2367 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2368 afs_int32 maxGroupId = 0;
2371 * Validate arguments
2374 if (!IsValidCellHandle(c_handle, &tst)) {
2375 goto fail_pts_UserMaxGet;
2378 if (maxUserId == NULL) {
2379 tst = ADMPTSMAXUSERIDNULL;
2380 goto fail_pts_UserMaxGet;
2383 tst = ubik_PR_ListMax(c_handle->pts, 0, maxUserId, &maxGroupId);
2386 goto fail_pts_UserMaxGet;
2390 fail_pts_UserMaxGet:
2399 * pts_UserMaxSet - set the maximum user id.
2403 * IN cellHandle - a previously opened cellHandle that corresponds
2404 * to the cell where the group exists.
2406 * IN maxUserId - the new max user id.
2410 * No locks are held by this function
2414 * Returns != 0 upon successful completion.
2419 pts_UserMaxSet(const void *cellHandle, int maxUserId, afs_status_p st)
2422 afs_status_t tst = 0;
2423 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2426 * Validate arguments
2429 if (!IsValidCellHandle(c_handle, &tst)) {
2430 goto fail_pts_UserMaxSet;
2433 tst = ubik_PR_SetMax(c_handle->pts, 0, maxUserId, 0);
2436 goto fail_pts_UserMaxSet;
2440 fail_pts_UserMaxSet:
2449 * pts_UserMemberListBegin - begin iterating over the list of groups
2450 * a particular user belongs to.
2454 * IN cellHandle - a previously opened cellHandle that corresponds
2455 * to the cell where the group exists.
2457 * IN groupName - the group whose members will be returned.
2459 * OUT iterationIdP - upon successful completion contains a iterator that
2460 * can be passed to pts_GroupMemberListNext.
2464 * No locks are obtained or released by this function
2468 * Returns != 0 upon successful completion.
2473 pts_UserMemberListBegin(const void *cellHandle, const char *userName,
2474 void **iterationIdP, afs_status_p st)
2476 return MemberListBegin(cellHandle, userName, ADMPTSUSERNAMENULL,
2477 ADMPTSUSERNAMETOOLONG, iterationIdP, st);
2482 * pts_UserMemberListNext - get the next group a user belongs to
2486 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2488 * OUT userName - upon successful completion contains the next group a user
2493 * The iterator mutex is held during the retrieval of the next member.
2497 * Returns != 0 upon successful completion.
2502 pts_UserMemberListNext(const void *iterationId, char *userName,
2505 return pts_GroupMemberListNext(iterationId, userName, st);
2509 * pts_UserMemberListDone - finish using a user list iterator
2513 * IN iterationId - an iterator previously returned by pts_UserMemberListBegin
2517 * The iterator is locked and then destroyed
2521 * Returns != 0 upon successful completion.
2525 * It is the user's responsibility to make sure pts_UserMemberListDone
2526 * is called only once for each iterator.
2530 pts_UserMemberListDone(const void *iterationId, afs_status_p st)
2532 return pts_GroupMemberListDone(iterationId, st);
2535 typedef struct owned_group_list {
2536 namelist owned_names; /* the list of character names owned by this id */
2537 prlist owned_ids; /* the list of pts ids owned by this id */
2538 afs_int32 index; /* the index into owned_names for the next group */
2539 afs_int32 owner; /* the pts id of the owner */
2540 afs_int32 more; /* the last parameter to PR_ListOwned */
2541 int finished_retrieving; /* set when we've processed the last owned_names */
2542 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2543 char group[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of names */
2544 } owned_group_list_t, *owned_group_list_p;
2547 DeleteOwnedGroupSpecificData(void *rpc_specific, afs_status_p st)
2550 afs_status_t tst = 0;
2551 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2553 if (list->owned_names.namelist_val != NULL) {
2554 free(list->owned_names.namelist_val);
2557 if (list->owned_ids.prlist_val != NULL) {
2558 free(list->owned_ids.prlist_val);
2569 GetOwnedGroupRPC(void *rpc_specific, int slot, int *last_item,
2570 int *last_item_contains_data, afs_status_p st)
2573 afs_status_t tst = 0;
2574 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2577 * We really don't make an rpc for every entry we return here
2578 * since the pts interface allows several members to be returned
2579 * with one rpc, but we fake it to make the iterator happy.
2583 * Check to see if we are done retrieving data
2586 if ((list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2588 *last_item_contains_data = 0;
2589 goto fail_GetOwnedGroupRPC;
2593 * Check to see if we really need to make an rpc
2596 if ((!list->finished_retrieving) && (list->owned_names.namelist_len == 0)) {
2598 ubik_PR_ListOwned(list->c_handle->pts, 0, list->owner,
2599 &list->owned_ids, &list->more);
2601 goto fail_GetOwnedGroupRPC;
2604 if (!TranslatePTSIds
2605 (list->c_handle, &list->owned_names, (idlist *) & list->owned_ids,
2607 goto fail_GetOwnedGroupRPC;
2611 if (list->owned_names.namelist_val == NULL) {
2613 *last_item_contains_data = 0;
2614 goto fail_GetOwnedGroupRPC;
2619 * We can retrieve the next group from data we already received
2622 strcpy(list->group[slot], list->owned_names.namelist_val[list->index]);
2626 * Check to see if there is more data to be retrieved
2627 * We need to free up the previously retrieved data here
2628 * and then check to see if the last rpc indicated that there
2629 * were more items to retrieve.
2632 if (list->index >= list->owned_names.namelist_len) {
2633 list->owned_names.namelist_len = 0;
2634 free(list->owned_names.namelist_val);
2635 list->owned_names.namelist_val = 0;
2637 list->owned_ids.prlist_len = 0;
2638 free(list->owned_ids.prlist_val);
2639 list->owned_ids.prlist_val = 0;
2642 list->finished_retrieving = 1;
2647 fail_GetOwnedGroupRPC:
2656 GetOwnedGroupFromCache(void *rpc_specific, int slot, void *dest,
2660 afs_status_t tst = 0;
2661 owned_group_list_p list = (owned_group_list_p) rpc_specific;
2663 strcpy((char *)dest, list->group[slot]);
2674 * pts_OwnedGroupListBegin - begin iterating over the list of groups
2675 * a particular user owns.
2679 * IN cellHandle - a previously opened cellHandle that corresponds
2680 * to the cell where the group exists.
2682 * IN ownerName - the owner of the groups of interest.
2684 * OUT iterationIdP - upon successful completion contains a iterator that
2685 * can be passed to pts_OwnedGroupListNext.
2689 * No locks are held by this function
2693 * Returns != 0 upon successful completion.
2698 pts_OwnedGroupListBegin(const void *cellHandle, const char *userName,
2699 void **iterationIdP, afs_status_p st)
2702 afs_status_t tst = 0;
2703 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
2704 afs_admin_iterator_p iter =
2705 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
2706 owned_group_list_p list =
2707 (owned_group_list_p) malloc(sizeof(owned_group_list_t));
2710 * Validate arguments
2713 if (!IsValidCellHandle(c_handle, &tst)) {
2714 goto fail_pts_OwnedGroupListBegin;
2717 if ((userName == NULL) || (*userName == 0)) {
2718 tst = ADMPTSUSERNAMENULL;
2719 goto fail_pts_OwnedGroupListBegin;
2722 if (iterationIdP == NULL) {
2723 tst = ADMITERATORNULL;
2724 goto fail_pts_OwnedGroupListBegin;
2727 if ((iter == NULL) || (list == NULL)) {
2729 goto fail_pts_OwnedGroupListBegin;
2733 * Initialize the iterator specific data
2737 list->finished_retrieving = 0;
2738 list->c_handle = c_handle;
2739 list->owned_names.namelist_len = 0;
2740 list->owned_names.namelist_val = 0;
2741 list->owned_ids.prlist_len = 0;
2742 list->owned_ids.prlist_val = 0;
2745 * Translate the user name into an id.
2748 if (!TranslateOneName
2749 (c_handle, userName, ADMPTSUSERNAMETOOLONG, &list->owner, &tst)) {
2750 goto fail_pts_OwnedGroupListBegin;
2754 (iter, (void *)list, GetOwnedGroupRPC, GetOwnedGroupFromCache, NULL,
2755 DeleteOwnedGroupSpecificData, &tst)) {
2756 *iterationIdP = (void *)iter;
2760 fail_pts_OwnedGroupListBegin:
2778 * pts_OwnedGroupListNext - get the next group a user owns.
2782 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2784 * OUT groupName - upon successful completion contains the next group a user
2789 * The iterator mutex is held during the retrieval of the next member.
2793 * Returns != 0 upon successful completion.
2798 pts_OwnedGroupListNext(const void *iterationId, char *groupName,
2802 afs_status_t tst = 0;
2803 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2806 * Validate arguments
2809 if (iterationId == NULL) {
2810 tst = ADMITERATORNULL;
2811 goto fail_pts_OwnedGroupListNext;
2814 if (groupName == NULL) {
2815 tst = ADMPTSGROUPNAMENULL;
2816 goto fail_pts_OwnedGroupListNext;
2819 rc = IteratorNext(iter, (void *)groupName, &tst);
2821 fail_pts_OwnedGroupListNext:
2830 * pts_OwnedGroupListDone - finish using a group list iterator
2834 * IN iterationId - an iterator previously returned by pts_OwnedGroupListBegin
2838 * The iterator is locked and then destroyed
2842 * Returns != 0 upon successful completion.
2846 * It is the user's responsibility to make sure pts_OwnedGroupListDone
2847 * is called only once for each iterator.
2851 pts_OwnedGroupListDone(const void *iterationId, afs_status_p st)
2854 afs_status_t tst = 0;
2855 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
2858 * Validate arguments
2861 if (iterationId == NULL) {
2862 tst = ADMITERATORNULL;
2863 goto fail_pts_OwnedGroupListDone;
2866 rc = IteratorDone(iter, &tst);
2868 fail_pts_OwnedGroupListDone:
2876 typedef struct pts_list {
2877 prlistentries *names; /* the current list of pts names in this cell */
2878 prlistentries *currName; /* the current pts entry */
2879 afs_int32 index; /* the index into names for the next pts entry */
2880 afs_int32 nextstartindex; /* the next start index for the RPC */
2881 afs_int32 nentries; /* the number of entries in names */
2882 afs_int32 flag; /* the type of the list */
2883 int finished_retrieving; /* set when we've processed the last owned_names */
2884 afs_cell_handle_p c_handle; /* ubik client to pts server's from c_handle */
2885 char entries[CACHED_ITEMS][PTS_MAX_NAME_LEN]; /* cache of pts names */
2886 } pts_list_t, *pts_list_p;
2889 DeletePTSSpecificData(void *rpc_specific, afs_status_p st)
2892 afs_status_t tst = 0;
2893 pts_list_p list = (pts_list_p) rpc_specific;
2908 GetPTSRPC(void *rpc_specific, int slot, int *last_item,
2909 int *last_item_contains_data, afs_status_p st)
2912 afs_status_t tst = 0;
2913 pts_list_p list = (pts_list_p) rpc_specific;
2916 * We really don't make an rpc for every entry we return here
2917 * since the pts interface allows several members to be returned
2918 * with one rpc, but we fake it to make the iterator happy.
2922 * Check to see if we are done retrieving data
2925 if (list->finished_retrieving) {
2927 *last_item_contains_data = 0;
2928 goto fail_GetPTSRPC;
2932 * Check to see if we really need to make an rpc
2935 if ((!list->finished_retrieving) && (list->index >= list->nentries)) {
2936 afs_int32 start = list->nextstartindex;
2937 prentries bulkentries;
2938 list->nextstartindex = -1;
2939 bulkentries.prentries_val = 0;
2940 bulkentries.prentries_len = 0;
2943 ubik_PR_ListEntries(list->c_handle->pts, 0, list->flag,
2944 start, &bulkentries, &(list->nextstartindex));
2947 goto fail_GetPTSRPC;
2950 list->nentries = bulkentries.prentries_len;
2951 list->names = bulkentries.prentries_val;
2954 list->currName = list->names;
2959 * We can retrieve the next entry from data we already received
2962 strcpy(list->entries[slot], list->currName->name);
2968 * Check to see if there is more data to be retrieved
2969 * We need to free up the previously retrieved data here
2970 * and then check to see if the last rpc indicated that there
2971 * were more items to retrieve.
2974 if (list->index >= list->nentries) {
2980 if (list->nextstartindex == -1) {
2981 list->finished_retrieving = 1;
2996 GetPTSFromCache(void *rpc_specific, int slot, void *dest, afs_status_p st)
2999 afs_status_t tst = 0;
3000 pts_list_p list = (pts_list_p) rpc_specific;
3002 strcpy((char *)dest, list->entries[slot]);
3013 * pts_UserListBegin - begin iterating over the list of users
3014 * in a particular cell
3018 * IN cellHandle - a previously opened cellHandle that corresponds
3019 * to the cell where the users exist.
3021 * OUT iterationIdP - upon successful completion contains a iterator that
3022 * can be passed to pts_UserListNext.
3026 * No locks are held by this function
3030 * Returns != 0 upon successful completion.
3035 pts_UserListBegin(const void *cellHandle, void **iterationIdP,
3039 afs_status_t tst = 0;
3040 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3041 afs_admin_iterator_p iter =
3042 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3043 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3046 * Validate arguments
3049 if (!IsValidCellHandle(c_handle, &tst)) {
3050 goto fail_pts_UserListBegin;
3053 if (iterationIdP == NULL) {
3054 tst = ADMITERATORNULL;
3055 goto fail_pts_UserListBegin;
3058 if ((iter == NULL) || (list == NULL)) {
3060 goto fail_pts_UserListBegin;
3064 * Initialize the iterator specific data
3068 list->finished_retrieving = 0;
3069 list->c_handle = c_handle;
3071 list->nextstartindex = 0;
3073 list->flag = PRUSERS;
3076 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3077 DeletePTSSpecificData, &tst)) {
3078 *iterationIdP = (void *)iter;
3082 fail_pts_UserListBegin:
3100 * pts_UserListNext - get the next user in the cell.
3104 * IN iterationId - an iterator previously returned by pts_UserListBegin
3106 * OUT groupName - upon successful completion contains the next user
3110 * The iterator mutex is held during the retrieval of the next member.
3114 * Returns != 0 upon successful completion.
3119 pts_UserListNext(const void *iterationId, char *userName, afs_status_p st)
3122 afs_status_t tst = 0;
3123 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3126 * Validate arguments
3129 if (iterationId == NULL) {
3130 tst = ADMITERATORNULL;
3131 goto fail_pts_UserListNext;
3134 if (userName == NULL) {
3135 tst = ADMPTSUSERNAMENULL;
3136 goto fail_pts_UserListNext;
3139 rc = IteratorNext(iter, (void *)userName, &tst);
3141 fail_pts_UserListNext:
3150 * pts_UserListDone - finish using a user list iterator
3154 * IN iterationId - an iterator previously returned by pts_UserListBegin
3158 * The iterator is locked and then destroyed
3162 * Returns != 0 upon successful completion.
3166 * It is the user's responsibility to make sure pts_UserListDone
3167 * is called only once for each iterator.
3171 pts_UserListDone(const void *iterationId, afs_status_p st)
3174 afs_status_t tst = 0;
3175 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3178 * Validate arguments
3181 if (iterationId == NULL) {
3182 tst = ADMITERATORNULL;
3183 goto fail_pts_UserListDone;
3186 rc = IteratorDone(iter, &tst);
3188 fail_pts_UserListDone:
3197 * pts_GroupListBegin - begin iterating over the list of groups
3198 * in a particular cell.
3202 * IN cellHandle - a previously opened cellHandle that corresponds
3203 * to the cell where the groups exist.
3205 * OUT iterationIdP - upon successful completion contains a iterator that
3206 * can be passed to pts_GroupListNext.
3210 * No locks are held by this function
3214 * Returns != 0 upon successful completion.
3219 pts_GroupListBegin(const void *cellHandle, void **iterationIdP,
3223 afs_status_t tst = 0;
3224 afs_cell_handle_p c_handle = (afs_cell_handle_p) cellHandle;
3225 afs_admin_iterator_p iter =
3226 (afs_admin_iterator_p) malloc(sizeof(afs_admin_iterator_t));
3227 pts_list_p list = (pts_list_p) malloc(sizeof(pts_list_t));
3230 * Validate arguments
3233 if (!IsValidCellHandle(c_handle, &tst)) {
3234 goto fail_pts_GroupListBegin;
3237 if (iterationIdP == NULL) {
3238 tst = ADMITERATORNULL;
3239 goto fail_pts_GroupListBegin;
3242 if ((iter == NULL) || (list == NULL)) {
3244 goto fail_pts_GroupListBegin;
3248 * Initialize the iterator specific data
3252 list->finished_retrieving = 0;
3253 list->c_handle = c_handle;
3255 list->nextstartindex = 0;
3257 list->flag = PRGROUPS;
3260 (iter, (void *)list, GetPTSRPC, GetPTSFromCache, NULL,
3261 DeletePTSSpecificData, &tst)) {
3262 *iterationIdP = (void *)iter;
3266 fail_pts_GroupListBegin:
3284 * pts_UserListNext - get the next group in a cell.
3288 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3290 * OUT groupName - upon successful completion contains the next group
3294 * The iterator mutex is held during the retrieval of the next member.
3298 * Returns != 0 upon successful completion.
3303 pts_GroupListNext(const void *iterationId, char *groupName, afs_status_p st)
3306 afs_status_t tst = 0;
3307 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3310 * Validate arguments
3313 if (iterationId == NULL) {
3314 tst = ADMITERATORNULL;
3315 goto fail_pts_GroupListNext;
3318 if (groupName == NULL) {
3319 tst = ADMPTSGROUPNAMENULL;
3320 goto fail_pts_GroupListNext;
3323 rc = IteratorNext(iter, (void *)groupName, &tst);
3325 fail_pts_GroupListNext:
3334 * pts_GroupListDone - finish using a group list iterator
3338 * IN iterationId - an iterator previously returned by pts_GroupListBegin
3342 * The iterator is locked and then destroyed
3346 * Returns != 0 upon successful completion.
3350 * It is the user's responsibility to make sure pts_GroupListDone
3351 * is called only once for each iterator.
3355 pts_GroupListDone(const void *iterationId, afs_status_p st)
3358 afs_status_t tst = 0;
3359 afs_admin_iterator_p iter = (afs_admin_iterator_p) iterationId;
3362 * Validate arguments
3365 if (iterationId == NULL) {
3366 tst = ADMITERATORNULL;
3367 goto fail_pts_GroupListDone;
3370 rc = IteratorDone(iter, &tst);
3372 fail_pts_GroupListDone: