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
11 * (3) function addToGroup
13 * 1. Eliminate the code that tests for adding groups
14 * to groups. This is an error in normal AFS.
15 * 2. If adding a group to a group call AddToSGEntry
16 * to add the id of the group it's a member of.
20 * 1. Print a messsage if an error is returned from
21 * FindByID() and PTDEBUG is defined.
22 * 2. If removing a group from a group call
23 * RemoveFromSGEntry to remove the id of the
24 * group it's a member of.
25 * 3. Remove supergroup continuation records.
27 * (5) function RemoveFromGroup
29 * 1. Eliminate the code that tests for adding groups
30 * to groups. This is an error in normal AFS.
31 * 2. If removing a group from a group call
32 * RemoveFromSGEntry to remove the id of the
33 * group it's a member of.
35 * (6) Add new functions PR_ListSuperGroups and
38 * (7) function isAMemberOf
40 * 1. Allow groups to be members of groups.
42 * Transarc does not currently use opcodes past 520, but
43 * they *could* decide at any time to use more opcodes.
44 * If they did, then one part of our local mods,
45 * ListSupergroups, would break. I've therefore
46 * renumbered it to 530, and put logic in to enable the
47 * old opcode to work (for now).
50 #include <afsconfig.h>
51 #include <afs/param.h>
60 #include <afs/afsutil.h>
66 #include <afs/cellconfig.h>
70 #include "ptprototypes.h"
71 #include "afs/audit.h"
73 extern int restricted;
74 extern int restrict_anonymous;
75 extern struct ubik_dbase *dbase;
77 extern int prp_group_default;
78 extern int prp_user_default;
79 extern struct afsconf_dir *prdir;
81 static afs_int32 iNewEntry(struct rx_call *call, char aname[], afs_int32 aid,
82 afs_int32 oid, afs_int32 *cid);
83 static afs_int32 newEntry(struct rx_call *call, char aname[], afs_int32 flag,
84 afs_int32 oid, afs_int32 *aid, afs_int32 *cid);
85 static afs_int32 whereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos,
87 static afs_int32 dumpEntry(struct rx_call *call, afs_int32 apos,
88 struct prdebugentry *aentry, afs_int32 *cid);
89 static afs_int32 addToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid,
91 static afs_int32 nameToID(struct rx_call *call, namelist *aname, idlist *aid);
92 static afs_int32 idToName(struct rx_call *call, idlist *aid, namelist *aname, afs_int32 *cid);
93 static afs_int32 Delete(struct rx_call *call, afs_int32 aid, afs_int32 *cid);
94 static afs_int32 UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
95 struct PrUpdateEntry *uentry, afs_int32 *cid);
96 static afs_int32 removeFromGroup(struct rx_call *call, afs_int32 aid,
97 afs_int32 gid, afs_int32 *cid);
98 static afs_int32 getCPS(struct rx_call *call, afs_int32 aid, prlist *alist,
99 afs_int32 *over, afs_int32 *cid);
100 static afs_int32 getCPS2(struct rx_call *call, afs_int32 aid, afs_uint32 ahost,
101 prlist *alist, afs_int32 *over, afs_int32 *cid);
102 static afs_int32 getHostCPS(struct rx_call *call, afs_uint32 ahost,
103 prlist *alist, afs_int32 *over, afs_int32 *cid);
104 static afs_int32 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid, afs_int32 *cid);
105 static afs_int32 setMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag,
107 static afs_int32 listEntry(struct rx_call *call, afs_int32 aid,
108 struct prcheckentry *aentry, afs_int32 *cid);
109 static afs_int32 listEntries(struct rx_call *call, afs_int32 flag,
110 afs_int32 startindex, prentries *bulkentries,
111 afs_int32 *nextstartindex, afs_int32 *cid);
112 static afs_int32 put_prentries(struct prentry *tentry, prentries *bulkentries);
113 static afs_int32 changeEntry(struct rx_call *call, afs_int32 aid, char *name,
114 afs_int32 oid, afs_int32 newid, afs_int32 *cid);
115 static afs_int32 setFieldsEntry(struct rx_call *call, afs_int32 id,
116 afs_int32 mask, afs_int32 flags,
117 afs_int32 ngroups, afs_int32 nusers,
118 afs_int32 spare1, afs_int32 spare2,
120 static afs_int32 listElements(struct rx_call *call, afs_int32 aid,
121 prlist *alist, afs_int32 *over, afs_int32 *cid);
122 #if defined(SUPERGROUPS)
123 static afs_int32 listSuperGroups(struct rx_call *call, afs_int32 aid,
124 prlist *alist, afs_int32 *over,
127 static afs_int32 listOwned(struct rx_call *call, afs_int32 aid, prlist *alist,
128 afs_int32 *lastP, afs_int32 *cid);
129 static afs_int32 isAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid,
130 afs_int32 *flag, afs_int32 *cid);
131 static afs_int32 addWildCards(struct ubik_trans *tt, prlist *alist,
133 static afs_int32 WhoIsThisWithName(struct rx_call *acall,
134 struct ubik_trans *at, afs_int32 *aid,
137 /* when we abort, the ubik cachedVersion will be reset, so we'll read in the
138 * header on the next call.
139 * Abort the transaction and return the code.
141 #define ABORT_WITH(tt,code) return(ubik_AbortTrans(tt),code)
144 CreateOK(struct ubik_trans *ut, afs_int32 cid, afs_int32 oid, afs_int32 flag,
147 if (restricted && !admin)
150 if (flag & PRFOREIGN) {
151 /* Foreign users are recognized by the '@' sign and
152 * not by the PRFOREIGN flag.
155 } else if (flag & PRGRP) {
156 /* Allow anonymous group creation only if owner specified
157 * and running noAuth.
159 if (cid == ANONYMOUSID) {
160 if ((oid == 0) || !pr_noAuth)
163 } else { /* creating a user */
164 if (!admin && !pr_noAuth)
171 WhoIsThis(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid)
173 int code = WhoIsThisWithName(acall, at, aid, NULL);
174 if (code == 2 && *aid == ANONYMOUSID)
180 WritePreamble(struct ubik_trans **tt)
188 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, tt);
192 code = ubik_SetLock(*tt, 1, 1, LOCKWRITE);
196 code = read_DbHeader(*tt);
200 ubik_AbortTrans(*tt);
206 ReadPreamble(struct ubik_trans **tt)
214 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, tt);
218 code = ubik_SetLock(*tt, 1, 1, LOCKREAD);
222 code = read_DbHeader(*tt);
226 ubik_AbortTrans(*tt);
232 SPR_INewEntry(struct rx_call *call, char aname[], afs_int32 aid, afs_int32 oid)
235 afs_int32 cid = ANONYMOUSID;
237 code = iNewEntry(call, aname, aid, oid, &cid);
238 osi_auditU(call, PTS_INewEntEvent, code, AUD_ID, aid, AUD_STR, aname,
239 AUD_ID, oid, AUD_END);
240 ViceLog(5, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d\n", code, cid, aid, aname, oid));
245 iNewEntry(struct rx_call *call, char aname[], afs_int32 aid, afs_int32 oid,
248 /* used primarily for conversion - not intended to be used as usual means
249 * of entering people into the database. */
250 struct ubik_trans *tt;
257 code = WritePreamble(&tt);
261 code = WhoIsThis(call, tt, cid);
263 ABORT_WITH(tt, PRPERM);
264 admin = IsAMemberOf(tt, *cid, SYSADMINID);
266 /* first verify the id is good */
268 ABORT_WITH(tt, PRPERM);
271 /* only sysadmin can reuse a group id */
272 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
273 ABORT_WITH(tt, PRPERM);
275 if (FindByID(tt, aid))
276 ABORT_WITH(tt, PRIDEXIST);
278 /* check a few other things */
279 if (!CreateOK(tt, *cid, oid, gflag, admin))
280 ABORT_WITH(tt, PRPERM);
282 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
283 if (code != PRSUCCESS)
284 ABORT_WITH(tt, code);
286 /* finally, commit transaction */
287 code = ubik_EndTrans(tt);
295 SPR_NewEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
299 afs_int32 cid = ANONYMOUSID;
301 code = newEntry(call, aname, flag, oid, aid, &cid);
302 osi_auditU(call, PTS_NewEntEvent, code, AUD_ID, *aid, AUD_STR, aname,
303 AUD_ID, oid, AUD_END);
304 ViceLog(5, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d\n", code, cid, *aid, aname, oid));
309 newEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
310 afs_int32 *aid, afs_int32 *cid)
313 struct ubik_trans *tt;
315 char cname[PR_MAXNAMELEN];
318 code = WritePreamble(&tt);
322 /* this is for cross-cell self registration. It is not added in the
323 * SPR_INewEntry because we want self-registration to only do
324 * automatic id assignment.
326 code = WhoIsThisWithName(call, tt, cid, cname);
327 if (code != 2) { /* 2 specifies that this is a foreign cell request */
329 ABORT_WITH(tt, PRPERM);
330 admin = IsAMemberOf(tt, *cid, SYSADMINID);
332 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
333 oid = *cid = SYSADMINID;
335 if (!CreateOK(tt, *cid, oid, flag, admin))
336 ABORT_WITH(tt, PRPERM);
338 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
339 if (code != PRSUCCESS)
340 ABORT_WITH(tt, code);
342 code = ubik_EndTrans(tt);
351 SPR_WhereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos)
354 afs_int32 cid = ANONYMOUSID;
356 code = whereIsIt(call, aid, apos, &cid);
357 osi_auditU(call, PTS_WheIsItEvent, code, AUD_ID, aid, AUD_LONG, *apos,
359 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d\n", code, cid, aid, *apos));
364 whereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos, afs_int32 *cid)
367 struct ubik_trans *tt;
370 code = ReadPreamble(&tt);
374 code = WhoIsThis(call, tt, cid);
376 ABORT_WITH(tt, PRPERM);
377 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
378 ABORT_WITH(tt, PRPERM);
380 temp = FindByID(tt, aid);
382 ABORT_WITH(tt, PRNOENT);
384 code = ubik_EndTrans(tt);
392 SPR_DumpEntry(struct rx_call *call, afs_int32 apos,
393 struct prdebugentry *aentry)
396 afs_int32 cid = ANONYMOUSID;
398 code = dumpEntry(call, apos, aentry, &cid);
399 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
400 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d\n", code, cid, apos));
405 dumpEntry(struct rx_call *call, afs_int32 apos, struct prdebugentry *aentry,
409 struct ubik_trans *tt;
411 code = ReadPreamble(&tt);
415 code = WhoIsThis(call, tt, cid);
417 ABORT_WITH(tt, PRPERM);
418 code = pr_ReadEntry(tt, 0, apos, (struct prentry *)aentry);
420 ABORT_WITH(tt, code);
422 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
423 ABORT_WITH(tt, PRPERM);
425 /* Since prdebugentry is in the form of a prentry not a coentry, we will
426 * return the coentry slots in network order where the string is. */
428 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
429 code = pr_ReadCoEntry(tt, 0, apos, aentry);
431 ABORT_WITH(tt, code);
434 code = ubik_EndTrans(tt);
441 SPR_AddToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid)
444 afs_int32 cid = ANONYMOUSID;
446 code = addToGroup(call, aid, gid, &cid);
447 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
449 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d\n", code, cid, gid, aid));
454 addToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid, afs_int32 *cid)
457 struct ubik_trans *tt;
460 struct prentry tentry;
461 struct prentry uentry;
463 if (gid == ANYUSERID || gid == AUTHUSERID)
465 if (aid == ANONYMOUSID)
468 code = WritePreamble(&tt);
472 code = WhoIsThis(call, tt, cid);
474 ABORT_WITH(tt, PRPERM);
475 tempu = FindByID(tt, aid);
477 ABORT_WITH(tt, PRNOENT);
478 memset(&uentry, 0, sizeof(uentry));
479 code = pr_ReadEntry(tt, 0, tempu, &uentry);
481 ABORT_WITH(tt, code);
483 #if !defined(SUPERGROUPS)
484 /* we don't allow groups as members of groups at present */
485 if (uentry.flags & PRGRP)
486 ABORT_WITH(tt, PRNOTUSER);
489 tempg = FindByID(tt, gid);
491 ABORT_WITH(tt, PRNOENT);
492 code = pr_ReadEntry(tt, 0, tempg, &tentry);
494 ABORT_WITH(tt, code);
495 /* make sure that this is a group */
496 if (!(tentry.flags & PRGRP))
497 ABORT_WITH(tt, PRNOTGROUP);
498 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
499 ABORT_WITH(tt, PRPERM);
501 code = AddToEntry(tt, &tentry, tempg, aid);
502 if (code != PRSUCCESS)
503 ABORT_WITH(tt, code);
505 #if defined(SUPERGROUPS)
506 if (uentry.flags & PRGRP)
507 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
510 /* now, modify the user's entry as well */
511 code = AddToEntry(tt, &uentry, tempu, gid);
512 if (code != PRSUCCESS)
513 ABORT_WITH(tt, code);
514 code = ubik_EndTrans(tt);
521 SPR_NameToID(struct rx_call *call, namelist *aname, idlist *aid)
525 code = nameToID(call, aname, aid);
526 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
527 ViceLog(125, ("PTS_NameToID: code %d\n", code));
532 nameToID(struct rx_call *call, namelist *aname, idlist *aid)
535 struct ubik_trans *tt;
540 /* Initialize return struct */
542 aid->idlist_val = NULL;
544 size = aname->namelist_len;
550 aid->idlist_val = malloc(size * sizeof(afs_int32));
551 if (!aid->idlist_val)
554 code = ReadPreamble(&tt);
558 for (i = 0; i < aname->namelist_len; i++) {
560 char *nameinst, *cell;
561 afs_int32 islocal = 1;
563 strncpy(vname, aname->namelist_val[i], sizeof(vname));
564 vname[sizeof(vname)-1] ='\0';
567 cell = strchr(vname, '@');
574 code = afsconf_IsLocalRealmMatch(prdir, &islocal, nameinst, NULL, cell);
576 ("PTS_NameToID: afsconf_IsLocalRealmMatch(); code=%d, nameinst=%s, cell=%s\n",
577 code, nameinst, cell));
580 code = NameToID(tt, nameinst, &aid->idlist_val[i]);
582 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
584 if (code != PRSUCCESS)
585 aid->idlist_val[i] = ANONYMOUSID;
586 osi_audit(PTS_NmToIdEvent, code, AUD_STR,
587 aname->namelist_val[i], AUD_ID, aid->idlist_val[i],
589 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d\n", code,
590 aname->namelist_val[i], aid->idlist_val[i]));
592 #ifndef AFS_PTHREAD_ENV
598 aid->idlist_len = aname->namelist_len;
600 code = ubik_EndTrans(tt);
608 * Given an array of ids, find the name for each of them.
609 * The array of ids and names is unlimited.
612 SPR_IDToName(struct rx_call *call, idlist *aid, namelist *aname)
615 afs_int32 cid = ANONYMOUSID;
617 code = idToName(call, aid, aname, &cid);
618 osi_auditU(call, PTS_IdToNmEvent, code, AUD_END);
619 ViceLog(125, ("PTS_IDToName: code %d\n", code));
624 idToName(struct rx_call *call, idlist *aid, namelist *aname, afs_int32 *cid)
627 struct ubik_trans *tt;
632 /* leave this first for rpc stub */
633 size = aid->idlist_len;
636 if (size < 0 || size > INT_MAX / PR_MAXNAMELEN)
638 aname->namelist_val = malloc(size * PR_MAXNAMELEN);
639 aname->namelist_len = 0;
640 if (aname->namelist_val == 0)
642 if (aid->idlist_len == 0)
645 return PRTOOMANY; /* rxgen will probably handle this */
647 code = ReadPreamble(&tt);
651 code = WhoIsThis(call, tt, cid);
653 ABORT_WITH(tt, PRPERM);
654 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
655 ABORT_WITH(tt, PRPERM);
657 for (i = 0; i < aid->idlist_len; i++) {
658 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
659 if (code != PRSUCCESS)
660 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
661 osi_audit(PTS_IdToNmEvent, code, AUD_ID, aid->idlist_val[i],
662 AUD_STR, aname->namelist_val[i], AUD_END);
663 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s\n", code,
664 aid->idlist_val[i], aname->namelist_val[i]));
666 #ifndef AFS_PTHREAD_ENV
672 aname->namelist_len = aid->idlist_len;
674 code = ubik_EndTrans(tt);
681 SPR_Delete(struct rx_call *call, afs_int32 aid)
684 afs_int32 cid = ANONYMOUSID;
686 code = Delete(call, aid, &cid);
687 osi_auditU(call, PTS_DelEvent, code, AUD_ID, aid, AUD_END);
688 ViceLog(5, ("PTS_Delete: code %d cid %d aid %d\n", code, cid, aid));
693 Delete(struct rx_call *call, afs_int32 aid, afs_int32 *cid)
696 struct ubik_trans *tt;
697 struct prentry tentry;
701 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
702 || aid == ANONYMOUSID)
705 code = WritePreamble(&tt);
709 code = WhoIsThis(call, tt, cid);
711 ABORT_WITH(tt, PRPERM);
713 /* Read in entry to be deleted */
714 loc = FindByID(tt, aid);
716 ABORT_WITH(tt, PRNOENT);
717 code = pr_ReadEntry(tt, 0, loc, &tentry);
719 ABORT_WITH(tt, PRDBFAIL);
721 /* Do some access checking */
722 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
723 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
724 ABORT_WITH(tt, PRPERM);
726 /* Delete each continuation block as a separate transaction so that no one
727 * transaction become to large to complete. */
730 struct contentry centry;
733 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
735 ABORT_WITH(tt, PRDBFAIL);
736 for (i = 0; i < COSIZE; i++) {
737 if (centry.entries[i] == PRBADID)
739 if (centry.entries[i] == 0)
741 #if defined(SUPERGROUPS)
742 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
743 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
746 code = RemoveFromEntry(tt, aid, centry.entries[i]);
748 ABORT_WITH(tt, code);
749 tentry.count--; /* maintain count */
750 #ifndef AFS_PTHREAD_ENV
755 tentry.next = centry.next; /* thread out this block */
756 code = FreeBlock(tt, nptr); /* free continuation block */
758 ABORT_WITH(tt, code);
759 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
761 ABORT_WITH(tt, code);
763 /* end this trans and start a new one */
764 code = ubik_EndTrans(tt);
767 #ifndef AFS_PTHREAD_ENV
768 IOMGR_Poll(); /* just to keep the connection alive */
770 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
773 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
775 ABORT_WITH(tt, code);
777 /* re-read entry to get consistent uptodate info */
778 loc = FindByID(tt, aid);
780 ABORT_WITH(tt, PRNOENT);
781 code = pr_ReadEntry(tt, 0, loc, &tentry);
783 ABORT_WITH(tt, PRDBFAIL);
788 #if defined(SUPERGROUPS)
789 /* Delete each continuation block as a separate transaction
790 * so that no one transaction become too large to complete. */
792 struct prentryg *tentryg = (struct prentryg *)&tentry;
793 nptr = tentryg->nextsg;
795 struct contentry centry;
798 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
800 ABORT_WITH(tt, PRDBFAIL);
801 for (i = 0; i < COSIZE; i++) {
802 if (centry.entries[i] == PRBADID)
804 if (centry.entries[i] == 0)
806 code = RemoveFromEntry(tt, aid, centry.entries[i]);
808 ABORT_WITH(tt, code);
809 tentryg->countsg--; /* maintain count */
810 #ifndef AFS_PTHREAD_ENV
815 tentryg->nextsg = centry.next; /* thread out this block */
816 code = FreeBlock(tt, nptr); /* free continuation block */
818 ABORT_WITH(tt, code);
819 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
821 ABORT_WITH(tt, code);
823 /* end this trans and start a new one */
824 code = ubik_EndTrans(tt);
827 #ifndef AFS_PTHREAD_ENV
828 IOMGR_Poll(); /* just to keep the connection alive */
831 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
834 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
836 ABORT_WITH(tt, code);
838 /* re-read entry to get consistent uptodate info */
839 loc = FindByID(tt, aid);
841 ABORT_WITH(tt, PRNOENT);
842 code = pr_ReadEntry(tt, 0, loc, &tentry);
844 ABORT_WITH(tt, PRDBFAIL);
846 nptr = tentryg->nextsg;
850 #endif /* SUPERGROUPS */
852 /* Then move the owned chain, except possibly ourself to the orphan list.
853 * Because this list can be very long and so exceed the size of a ubik
854 * transaction, we start a new transaction every 50 entries. */
858 struct prentry nentry;
860 code = pr_ReadEntry(tt, 0, nptr, &nentry);
862 ABORT_WITH(tt, PRDBFAIL);
863 nptr = tentry.owned = nentry.nextOwned; /* thread out */
865 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
866 code = AddToOrphan(tt, nentry.id);
868 ABORT_WITH(tt, code);
870 #ifndef AFS_PTHREAD_ENV
871 if ((count & 3) == 0)
877 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
879 ABORT_WITH(tt, code);
881 /* end this trans and start a new one */
882 code = ubik_EndTrans(tt);
885 #ifndef AFS_PTHREAD_ENV
886 IOMGR_Poll(); /* just to keep the connection alive */
888 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
891 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
893 ABORT_WITH(tt, code);
895 /* re-read entry to get consistent uptodate info */
896 loc = FindByID(tt, aid);
898 ABORT_WITH(tt, PRNOENT);
899 code = pr_ReadEntry(tt, 0, loc, &tentry);
901 ABORT_WITH(tt, PRDBFAIL);
906 /* now do what's left of the deletion stuff */
907 code = DeleteEntry(tt, &tentry, loc);
908 if (code != PRSUCCESS)
909 ABORT_WITH(tt, code);
911 code = ubik_EndTrans(tt);
918 SPR_UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
919 struct PrUpdateEntry *uentry)
922 afs_int32 cid = ANONYMOUSID;
924 code = UpdateEntry(call, aid, name, uentry, &cid);
925 osi_auditU(call, PTS_UpdEntEvent, code, AUD_ID, aid, AUD_STR, name, AUD_END);
926 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s\n", code, cid, aid, name));
931 UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
932 struct PrUpdateEntry *uentry, afs_int32 *cid)
935 struct ubik_trans *tt;
936 struct prentry tentry;
942 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
943 || aid == ANONYMOUSID)
947 code = WritePreamble(&tt);
951 code = WhoIsThis(call, tt, cid);
953 ABORT_WITH(tt, PRPERM);
954 code = IsAMemberOf(tt, *cid, SYSADMINID);
955 if (!code && !pr_noAuth)
956 ABORT_WITH(tt, PRPERM);
958 /* Read in entry to be deleted */
960 loc = FindByID(tt, aid);
962 loc = FindByName(tt, name, &tentry);
965 ABORT_WITH(tt, PRNOENT);
966 code = pr_ReadEntry(tt, 0, loc, &tentry);
968 ABORT_WITH(tt, PRDBFAIL);
970 if (uentry->Mask & PRUPDATE_NAMEHASH) {
972 code = RemoveFromNameHash(tt, tentry.name, &tloc);
973 if (code != PRSUCCESS)
974 ABORT_WITH(tt, PRDBFAIL);
975 code = AddToNameHash(tt, tentry.name, loc);
977 ABORT_WITH(tt, code);
980 if (uentry->Mask & PRUPDATE_IDHASH) {
984 code = RemoveFromIDHash(tt, id, &tloc);
985 if (code != PRSUCCESS)
986 ABORT_WITH(tt, PRDBFAIL);
987 code = AddToIDHash(tt, id, loc);
989 ABORT_WITH(tt, code);
992 code = ubik_EndTrans(tt);
999 SPR_RemoveFromGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid)
1002 afs_int32 cid = ANONYMOUSID;
1004 code = removeFromGroup(call, aid, gid, &cid);
1005 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
1007 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d\n", code, cid, gid, aid));
1012 removeFromGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid,
1016 struct ubik_trans *tt;
1019 struct prentry uentry;
1020 struct prentry gentry;
1022 code = WritePreamble(&tt);
1026 code = WhoIsThis(call, tt, cid);
1028 ABORT_WITH(tt, PRPERM);
1029 tempu = FindByID(tt, aid);
1031 ABORT_WITH(tt, PRNOENT);
1032 tempg = FindByID(tt, gid);
1034 ABORT_WITH(tt, PRNOENT);
1035 memset(&uentry, 0, sizeof(uentry));
1036 memset(&gentry, 0, sizeof(gentry));
1037 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1039 ABORT_WITH(tt, code);
1040 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1042 ABORT_WITH(tt, code);
1043 if (!(gentry.flags & PRGRP))
1044 ABORT_WITH(tt, PRNOTGROUP);
1045 #if !defined(SUPERGROUPS)
1046 if (uentry.flags & PRGRP)
1047 ABORT_WITH(tt, PRNOTUSER);
1049 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1050 ABORT_WITH(tt, PRPERM);
1051 code = RemoveFromEntry(tt, aid, gid);
1052 if (code != PRSUCCESS)
1053 ABORT_WITH(tt, code);
1054 #if defined(SUPERGROUPS)
1055 if (!(uentry.flags & PRGRP))
1057 code = RemoveFromEntry(tt, gid, aid);
1058 #if defined(SUPERGROUPS)
1060 code = RemoveFromSGEntry(tt, gid, aid);
1062 if (code != PRSUCCESS)
1063 ABORT_WITH(tt, code);
1065 code = ubik_EndTrans(tt);
1073 SPR_GetCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over)
1076 afs_int32 cid = ANONYMOUSID;
1078 code = getCPS(call, aid, alist, over, &cid);
1079 osi_auditU(call, PTS_GetCPSEvent, code, AUD_ID, aid, AUD_END);
1080 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d\n", code, cid, aid));
1085 getCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over,
1089 struct ubik_trans *tt;
1091 struct prentry tentry;
1094 alist->prlist_len = 0;
1095 alist->prlist_val = NULL;
1097 code = ReadPreamble(&tt);
1101 code = WhoIsThis(call, tt, cid);
1103 ABORT_WITH(tt, PRPERM);
1104 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1105 ABORT_WITH(tt, PRPERM);
1107 temp = FindByID(tt, aid);
1109 ABORT_WITH(tt, PRNOENT);
1110 code = pr_ReadEntry(tt, 0, temp, &tentry);
1112 ABORT_WITH(tt, code);
1114 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1115 ABORT_WITH(tt, PRPERM);
1117 code = GetList(tt, &tentry, alist, 1);
1118 if (code != PRSUCCESS)
1119 ABORT_WITH(tt, code);
1121 code = ubik_EndTrans(tt);
1127 inCPS(prlist CPS, afs_int32 id)
1131 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1132 if (CPS.prlist_val[i] == id)
1140 SPR_GetCPS2(struct rx_call *call, afs_int32 aid, afs_int32 ahost,
1141 prlist *alist, afs_int32 *over)
1144 afs_int32 cid = ANONYMOUSID;
1146 code = getCPS2(call, aid, ahost, alist, over, &cid);
1147 osi_auditU(call, PTS_GetCPS2Event, code, AUD_ID, aid, AUD_HOST, htonl(ahost),
1149 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d\n", code, cid, aid, ahost));
1154 getCPS2(struct rx_call *call, afs_int32 aid, afs_uint32 ahost, prlist *alist,
1155 afs_int32 *over, afs_int32 *cid)
1158 struct ubik_trans *tt;
1160 struct prentry tentry;
1161 struct prentry host_tentry;
1164 struct in_addr iaddr;
1168 iaddr.s_addr = ntohl(ahost);
1169 alist->prlist_len = 0;
1170 alist->prlist_val = NULL;
1172 code = ReadPreamble(&tt);
1176 if (aid != PRBADID) {
1177 temp = FindByID(tt, aid);
1179 ABORT_WITH(tt, PRNOENT);
1180 code = pr_ReadEntry(tt, 0, temp, &tentry);
1182 ABORT_WITH(tt, code);
1184 /* afs does authenticate now */
1185 code = WhoIsThis(call, tt, cid);
1187 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1188 ABORT_WITH(tt, PRPERM);
1190 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1191 if (code == PRSUCCESS && hostid != 0) {
1192 temp = FindByID(tt, hostid);
1194 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1195 if (code == PRSUCCESS)
1198 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1200 fprintf(stderr, "FindByID Failed -- Not found\n");
1203 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1205 code = GetList(tt, &tentry, alist, 1);
1207 code = addWildCards(tt, alist, ntohl(ahost));
1208 if (code != PRSUCCESS)
1209 ABORT_WITH(tt, code);
1211 code = ubik_EndTrans(tt);
1217 SPR_GetHostCPS(struct rx_call *call, afs_int32 ahost, prlist *alist,
1221 afs_int32 cid = ANONYMOUSID;
1223 code = getHostCPS(call, ahost, alist, over, &cid);
1224 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, htonl(ahost), AUD_END);
1225 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d\n", code, ahost));
1230 getHostCPS(struct rx_call *call, afs_uint32 ahost, prlist *alist,
1231 afs_int32 *over, afs_int32 *cid)
1233 afs_int32 code, temp;
1234 struct ubik_trans *tt;
1235 struct prentry host_tentry;
1237 struct in_addr iaddr;
1241 iaddr.s_addr = ntohl(ahost);
1242 alist->prlist_len = 0;
1243 alist->prlist_val = NULL;
1245 code = ReadPreamble(&tt);
1249 code = WhoIsThis(call, tt, cid);
1251 ABORT_WITH(tt, PRPERM);
1252 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1253 ABORT_WITH(tt, PRPERM);
1255 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1256 if (code == PRSUCCESS && hostid != 0) {
1257 temp = FindByID(tt, hostid);
1259 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1260 if (code == PRSUCCESS) {
1261 code = GetList(tt, &host_tentry, alist, 0);
1265 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1267 fprintf(stderr, "FindByID Failed -- Not found\n");
1269 code = addWildCards(tt, alist, ntohl(ahost));
1271 if (code != PRSUCCESS)
1272 ABORT_WITH(tt, code);
1274 code = ubik_EndTrans(tt);
1280 SPR_ListMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid)
1283 afs_int32 cid = ANONYMOUSID;
1285 code = listMax(call, uid, gid, &cid);
1286 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1287 ViceLog(125, ("PTS_ListMax: code %d\n", code));
1292 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid, afs_int32 *cid)
1295 struct ubik_trans *tt;
1297 code = ReadPreamble(&tt);
1301 code = WhoIsThis(call, tt, cid);
1303 ABORT_WITH(tt, PRPERM);
1304 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1305 ABORT_WITH(tt, PRPERM);
1307 code = GetMax(tt, uid, gid);
1308 if (code != PRSUCCESS)
1309 ABORT_WITH(tt, code);
1311 code = ubik_EndTrans(tt);
1318 SPR_SetMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag)
1321 afs_int32 cid = ANONYMOUSID;
1323 code = setMax(call, aid, gflag, &cid);
1324 osi_auditU(call, PTS_SetMaxEvent, code, AUD_ID, aid, AUD_LONG, gflag,
1326 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d\n", code, cid, aid, gflag));
1331 setMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag, afs_int32 *cid)
1334 struct ubik_trans *tt;
1336 code = WritePreamble(&tt);
1340 code = WhoIsThis(call, tt, cid);
1342 ABORT_WITH(tt, PRPERM);
1343 if (!AccessOK(tt, *cid, 0, 0, 0))
1344 ABORT_WITH(tt, PRPERM);
1345 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1346 ABORT_WITH(tt, PRBADARG);
1348 code = SetMax(tt, aid, gflag);
1349 if (code != PRSUCCESS)
1350 ABORT_WITH(tt, code);
1352 code = ubik_EndTrans(tt);
1359 SPR_ListEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry)
1362 afs_int32 cid = ANONYMOUSID;
1364 code = listEntry(call, aid, aentry, &cid);
1365 osi_auditU(call, PTS_LstEntEvent, code, AUD_ID, aid, AUD_END);
1366 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d\n", code, cid, aid));
1371 listEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry,
1375 struct ubik_trans *tt;
1377 struct prentry tentry;
1379 code = ReadPreamble(&tt);
1383 code = WhoIsThis(call, tt, cid);
1385 ABORT_WITH(tt, PRPERM);
1386 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1387 ABORT_WITH(tt, PRPERM);
1388 temp = FindByID(tt, aid);
1390 ABORT_WITH(tt, PRNOENT);
1391 code = pr_ReadEntry(tt, 0, temp, &tentry);
1393 ABORT_WITH(tt, code);
1394 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1395 ABORT_WITH(tt, PRPERM);
1397 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1398 if (aentry->flags == 0) {
1399 if (tentry.flags & PRGRP)
1400 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1402 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1404 aentry->owner = tentry.owner;
1405 aentry->id = tentry.id;
1406 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1407 aentry->creator = tentry.creator;
1408 aentry->ngroups = tentry.ngroups;
1409 aentry->nusers = tentry.nusers;
1410 aentry->count = tentry.count;
1411 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1412 code = ubik_EndTrans(tt);
1419 SPR_ListEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
1420 prentries *bulkentries, afs_int32 *nextstartindex)
1423 afs_int32 cid = ANONYMOUSID;
1425 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1426 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1427 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d\n", code, cid, flag));
1432 listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
1433 prentries *bulkentries, afs_int32 *nextstartindex, afs_int32 *cid)
1436 struct ubik_trans *tt;
1437 afs_int32 i, eof, pos, maxentries, f;
1438 struct prentry tentry;
1439 afs_int32 pollcount = 0;
1441 *nextstartindex = -1;
1442 bulkentries->prentries_val = 0;
1443 bulkentries->prentries_len = 0;
1445 code = ReadPreamble(&tt);
1449 /* Make sure we are an authenticated caller and that we are on the
1452 code = WhoIsThis(call, tt, cid);
1454 ABORT_WITH(tt, PRPERM);
1455 code = IsAMemberOf(tt, *cid, SYSADMINID);
1456 if (!code && !pr_noAuth)
1457 ABORT_WITH(tt, PRPERM);
1459 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1460 maxentries = eof / sizeof(struct prentry);
1461 for (i = startindex; i < maxentries; i++) {
1462 pos = i * sizeof(struct prentry) + sizeof(cheader);
1463 code = pr_ReadEntry(tt, 0, pos, &tentry);
1467 if (++pollcount > 50) {
1468 #ifndef AFS_PTHREAD_ENV
1474 f = (tentry.flags & PRTYPE);
1475 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1476 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1477 code = put_prentries(&tentry, bulkentries);
1479 break; /* Filled return array */
1486 *nextstartindex = i;
1490 if (bulkentries->prentries_val)
1491 free(bulkentries->prentries_val);
1492 bulkentries->prentries_val = 0;
1493 bulkentries->prentries_len = 0;
1494 ABORT_WITH(tt, code);
1496 code = ubik_EndTrans(tt);
1503 #define PR_MAXENTRIES 500
1505 put_prentries(struct prentry *tentry, prentries *bulkentries)
1507 struct prlistentries *entry;
1509 if (bulkentries->prentries_val == 0) {
1510 bulkentries->prentries_len = 0;
1511 bulkentries->prentries_val = malloc(PR_MAXENTRIES *
1512 sizeof(struct prlistentries));
1513 if (!bulkentries->prentries_val) {
1518 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1522 entry = bulkentries->prentries_val;
1523 entry += bulkentries->prentries_len;
1525 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1526 if (entry->flags == 0) {
1529 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1532 entry->owner = tentry->owner;
1533 entry->id = tentry->id;
1534 entry->creator = tentry->creator;
1535 entry->ngroups = tentry->ngroups;
1536 entry->nusers = tentry->nusers;
1537 entry->count = tentry->count;
1538 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1539 memset(entry->reserved, 0, sizeof(entry->reserved));
1540 bulkentries->prentries_len++;
1545 SPR_ChangeEntry(struct rx_call *call, afs_int32 aid, char *name, afs_int32 oid,
1549 afs_int32 cid = ANONYMOUSID;
1551 code = changeEntry(call, aid, name, oid, newid, &cid);
1552 osi_auditU(call, PTS_ChgEntEvent, code, AUD_ID, aid, AUD_STR, name,
1553 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1554 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d\n", code, cid, aid, name, oid, newid));
1559 changeEntry(struct rx_call *call, afs_int32 aid, char *name, afs_int32 oid,
1560 afs_int32 newid, afs_int32 *cid)
1563 struct ubik_trans *tt;
1570 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1571 || aid == SYSADMINID)
1574 code = WritePreamble(&tt);
1578 code = WhoIsThis(call, tt, cid);
1580 ABORT_WITH(tt, PRPERM);
1581 pos = FindByID(tt, aid);
1583 ABORT_WITH(tt, PRNOENT);
1584 /* protection check in changeentry */
1585 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1586 if (code != PRSUCCESS)
1587 ABORT_WITH(tt, code);
1589 code = ubik_EndTrans(tt);
1594 SPR_SetFieldsEntry(struct rx_call *call,
1596 afs_int32 mask, /* specify which fields to update */
1597 afs_int32 flags, afs_int32 ngroups, afs_int32 nusers,
1598 afs_int32 spare1, afs_int32 spare2)
1601 afs_int32 cid = ANONYMOUSID;
1604 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1606 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_ID, id, AUD_END);
1607 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d\n", code, cid, id));
1612 setFieldsEntry(struct rx_call *call,
1614 afs_int32 mask, /* specify which fields to update */
1615 afs_int32 flags, afs_int32 ngroups, afs_int32 nusers,
1616 afs_int32 spare1, afs_int32 spare2, afs_int32 *cid)
1619 struct ubik_trans *tt;
1621 struct prentry tentry;
1625 return 0; /* no-op */
1627 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1630 code = WritePreamble(&tt);
1634 code = WhoIsThis(call, tt, cid);
1636 ABORT_WITH(tt, PRPERM);
1637 pos = FindByID(tt, id);
1639 ABORT_WITH(tt, PRNOENT);
1640 code = pr_ReadEntry(tt, 0, pos, &tentry);
1642 ABORT_WITH(tt, code);
1643 tflags = tentry.flags;
1645 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1646 if (!AccessOK(tt, *cid, 0, 0, 0))
1647 ABORT_WITH(tt, PRPERM);
1648 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1649 tentry.ngroups = tentry.nusers = 20;
1652 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1653 ABORT_WITH(tt, PRPERM);
1656 if (mask & 0xffff) { /* if setting flag bits */
1657 afs_int32 flagsMask = mask & 0xffff;
1658 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1659 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1663 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1665 ABORT_WITH(tt, PRBADARG);
1666 tentry.ngroups = ngroups;
1670 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1672 ABORT_WITH(tt, PRBADARG);
1673 tentry.nusers = nusers;
1676 tentry.flags = tflags;
1678 code = pr_WriteEntry(tt, 0, pos, &tentry);
1680 ABORT_WITH(tt, code);
1682 code = ubik_EndTrans(tt);
1687 SPR_ListElements(struct rx_call *call, afs_int32 aid, prlist *alist,
1691 afs_int32 cid = ANONYMOUSID;
1693 code = listElements(call, aid, alist, over, &cid);
1694 osi_auditU(call, PTS_LstEleEvent, code, AUD_ID, aid, AUD_END);
1695 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d\n", code, cid, aid));
1700 listElements(struct rx_call *call, afs_int32 aid, prlist *alist,
1701 afs_int32 *over, afs_int32 *cid)
1704 struct ubik_trans *tt;
1706 struct prentry tentry;
1709 alist->prlist_len = 0;
1710 alist->prlist_val = NULL;
1712 code = ReadPreamble(&tt);
1716 code = WhoIsThis(call, tt, cid);
1718 ABORT_WITH(tt, PRPERM);
1720 temp = FindByID(tt, aid);
1722 ABORT_WITH(tt, PRNOENT);
1723 code = pr_ReadEntry(tt, 0, temp, &tentry);
1725 ABORT_WITH(tt, code);
1726 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1727 ABORT_WITH(tt, PRPERM);
1729 code = GetList(tt, &tentry, alist, 0);
1730 if (code != PRSUCCESS)
1731 ABORT_WITH(tt, code);
1733 code = ubik_EndTrans(tt);
1739 SPR_ListSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
1742 #if defined(SUPERGROUPS)
1744 afs_int32 cid = ANONYMOUSID;
1746 code = listSuperGroups(call, aid, alist, over, &cid);
1747 osi_auditU(call, PTS_LstSGrps, code, AUD_ID, aid, AUD_END);
1748 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d\n", code, cid, aid));
1751 return RXGEN_OPCODE;
1755 #if defined(SUPERGROUPS)
1757 listSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
1758 afs_int32 *over, afs_int32 *cid)
1761 struct ubik_trans *tt;
1763 struct prentry tentry;
1765 alist->prlist_len = 0;
1766 alist->prlist_val = (afs_int32 *) 0;
1768 code = ReadPreamble(&tt);
1772 code = WhoIsThis(call, tt, cid);
1774 ABORT_WITH(tt, PRPERM);
1775 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1776 ABORT_WITH(tt, PRPERM);
1778 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1780 ABORT_WITH(tt, code);
1782 temp = FindByID(tt, aid);
1784 ABORT_WITH(tt, PRNOENT);
1785 code = pr_ReadEntry(tt, 0, temp, &tentry);
1787 ABORT_WITH(tt, code);
1788 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1789 ABORT_WITH(tt, PRPERM);
1791 code = GetSGList(tt, &tentry, alist);
1793 if (code == PRTOOMANY)
1795 else if (code != PRSUCCESS)
1796 ABORT_WITH(tt, code);
1798 code = ubik_EndTrans(tt);
1803 #endif /* SUPERGROUPS */
1807 * List the entries owned by this id. If the id is zero,
1808 * return the orphans list. This will return up to PR_MAXGROUPS
1809 * at a time with the lastP available to get the rest. The
1810 * maximum value is enforced in GetOwnedChain().
1813 SPR_ListOwned(struct rx_call *call, afs_int32 aid, prlist *alist,
1817 afs_int32 cid = ANONYMOUSID;
1819 code = listOwned(call, aid, alist, lastP, &cid);
1820 osi_auditU(call, PTS_LstOwnEvent, code, AUD_ID, aid, AUD_END);
1821 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d\n", code, cid, aid));
1826 listOwned(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *lastP,
1830 struct ubik_trans *tt;
1831 struct prentry tentry;
1835 alist->prlist_len = 0;
1836 alist->prlist_val = NULL;
1843 code = ReadPreamble(&tt);
1847 code = WhoIsThis(call, tt, cid);
1849 ABORT_WITH(tt, PRPERM);
1852 code = pr_ReadEntry(tt, 0, start, &tentry);
1853 if (!code && (tentry.owner == aid))
1854 head = start; /* pick up where we left off */
1859 afs_int32 loc = FindByID(tt, aid);
1861 ABORT_WITH(tt, PRNOENT);
1862 code = pr_ReadEntry(tt, 0, loc, &tentry);
1864 ABORT_WITH(tt, code);
1866 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
1867 ABORT_WITH(tt, PRPERM);
1868 head = tentry.owned;
1870 if (!AccessOK(tt, *cid, 0, 0, 0))
1871 ABORT_WITH(tt, PRPERM);
1872 head = ntohl(cheader.orphan);
1876 code = GetOwnedChain(tt, &head, alist);
1878 if (code == PRTOOMANY)
1881 ABORT_WITH(tt, code);
1884 code = ubik_EndTrans(tt);
1889 SPR_IsAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid,
1893 afs_int32 cid = ANONYMOUSID;
1895 code = isAMemberOf(call, uid, gid, flag, &cid);
1896 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
1898 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d\n", code, cid, uid, gid));
1903 isAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid, afs_int32 *flag,
1907 struct ubik_trans *tt;
1909 code = ReadPreamble(&tt);
1914 afs_int32 uloc = FindByID(tt, uid);
1915 afs_int32 gloc = FindByID(tt, gid);
1916 struct prentry uentry, gentry;
1919 ABORT_WITH(tt, PRNOENT);
1920 code = WhoIsThis(call, tt, cid);
1922 ABORT_WITH(tt, PRPERM);
1923 code = pr_ReadEntry(tt, 0, uloc, &uentry);
1925 ABORT_WITH(tt, code);
1926 code = pr_ReadEntry(tt, 0, gloc, &gentry);
1928 ABORT_WITH(tt, code);
1929 #if !defined(SUPERGROUPS)
1930 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
1931 ABORT_WITH(tt, PRBADARG);
1933 if (!(gentry.flags & PRGRP))
1934 ABORT_WITH(tt, PRBADARG);
1936 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
1937 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1938 ABORT_WITH(tt, PRPERM);
1941 *flag = IsAMemberOf(tt, uid, gid);
1942 code = ubik_EndTrans(tt);
1947 addWildCards(struct ubik_trans *tt, prlist *alist, afs_uint32 host)
1950 struct prentry tentry;
1952 unsigned wild = htonl(0xffffff00);
1953 struct in_addr iaddr;
1955 int size = 0, i, code;
1959 while ((host = (host & wild))) {
1960 wild = htonl(ntohl(wild) << 8);
1961 iaddr.s_addr = host;
1962 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1963 if (code == PRSUCCESS && hostid != 0) {
1964 temp = FindByID(tt, hostid);
1966 code = pr_ReadEntry(tt, 0, temp, &tentry);
1967 if (code != PRSUCCESS)
1973 wlist.prlist_len = 0;
1974 wlist.prlist_val = NULL;
1976 code = GetList(tt, &tentry, &wlist, 0);
1979 added += wlist.prlist_len;
1980 for (i = 0; i < wlist.prlist_len; i++) {
1981 if (!inCPS(*alist, wlist.prlist_val[i]))
1982 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
1983 free(wlist.prlist_val);
1987 if (wlist.prlist_val)
1988 free(wlist.prlist_val);
1991 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
1996 WhoIsThisWithName(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid,
1999 afs_int32 islocal = 1;
2000 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2001 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2002 struct rx_connection *tconn;
2004 char tcell[MAXKTCREALMLEN];
2005 char name[MAXKTCNAMELEN];
2006 char inst[MAXKTCNAMELEN];
2011 tconn = rx_ConnectionOf(acall);
2012 code = rx_SecurityClassOf(tconn);
2015 else if (code == 1) { /* vab class */
2016 goto done; /* no longer supported */
2017 } else if (code == 2) { /* kad class */
2018 if ((code = rxkad_GetServerInfo(rx_ConnectionOf(acall), NULL, NULL,
2019 name, inst, tcell, NULL)))
2023 code = afsconf_IsLocalRealmMatch(prdir, &islocal, name, inst, tcell);
2027 strncpy(vname, name, sizeof(vname));
2028 if ((ilen = strlen(inst))) {
2029 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2032 strcat(vname, inst);
2035 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
2038 strcat(vname, tcell);
2039 lcstring(vname, vname, sizeof(vname));
2040 NameToID(at, vname, aid);
2042 strcpy(aname, vname);
2046 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2047 *aid = SYSADMINID; /* special case for the fileserver */
2049 lcstring(vname, vname, sizeof(vname));
2050 code = NameToID(at, vname, aid);
2054 if (code && !pr_noAuth)