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 (oid == ANONYMOUSID)
166 if (!admin && !pr_noAuth)
173 WhoIsThis(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid)
175 int code = WhoIsThisWithName(acall, at, aid, NULL);
176 if (code == 2 && *aid == ANONYMOUSID)
182 WritePreamble(struct ubik_trans **tt)
190 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, tt);
194 code = ubik_SetLock(*tt, 1, 1, LOCKWRITE);
198 code = read_DbHeader(*tt);
202 ubik_AbortTrans(*tt);
208 ReadPreamble(struct ubik_trans **tt)
216 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, tt);
220 code = ubik_SetLock(*tt, 1, 1, LOCKREAD);
224 code = read_DbHeader(*tt);
228 ubik_AbortTrans(*tt);
234 SPR_INewEntry(struct rx_call *call, char aname[], afs_int32 aid, afs_int32 oid)
237 afs_int32 cid = ANONYMOUSID;
239 code = iNewEntry(call, aname, aid, oid, &cid);
240 osi_auditU(call, PTS_INewEntEvent, code, AUD_ID, aid, AUD_STR, aname,
241 AUD_ID, oid, AUD_END);
242 ViceLog(5, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d\n", code, cid, aid, aname, oid));
247 iNewEntry(struct rx_call *call, char aname[], afs_int32 aid, afs_int32 oid,
250 /* used primarily for conversion - not intended to be used as usual means
251 * of entering people into the database. */
252 struct ubik_trans *tt;
259 code = WritePreamble(&tt);
263 code = WhoIsThis(call, tt, cid);
265 ABORT_WITH(tt, PRPERM);
266 admin = IsAMemberOf(tt, *cid, SYSADMINID);
268 /* first verify the id is good */
270 ABORT_WITH(tt, PRPERM);
273 /* only sysadmin can reuse a group id */
274 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
275 ABORT_WITH(tt, PRPERM);
277 if (FindByID(tt, aid))
278 ABORT_WITH(tt, PRIDEXIST);
280 /* check a few other things */
281 if (!CreateOK(tt, *cid, oid, gflag, admin))
282 ABORT_WITH(tt, PRPERM);
284 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
285 if (code != PRSUCCESS)
286 ABORT_WITH(tt, code);
288 /* finally, commit transaction */
289 code = ubik_EndTrans(tt);
297 SPR_NewEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
301 afs_int32 cid = ANONYMOUSID;
303 code = newEntry(call, aname, flag, oid, aid, &cid);
304 osi_auditU(call, PTS_NewEntEvent, code, AUD_ID, *aid, AUD_STR, aname,
305 AUD_ID, oid, AUD_END);
306 ViceLog(5, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d\n", code, cid, *aid, aname, oid));
311 newEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
312 afs_int32 *aid, afs_int32 *cid)
315 struct ubik_trans *tt;
318 char cname[PR_MAXNAMELEN];
321 code = WritePreamble(&tt);
325 /* this is for cross-cell self registration. It is not added in the
326 * SPR_INewEntry because we want self-registration to only do
327 * automatic id assignment.
329 code = WhoIsThisWithName(call, tt, cid, cname);
330 if (code && code != 2)
331 ABORT_WITH(tt, PRPERM);
332 admin = IsAMemberOf(tt, *cid, SYSADMINID);
333 if (code == 2 /* foreign cell request */) {
336 if (!restricted && (strcmp(aname, cname) == 0)) {
337 /* can't autoregister while providing an owner id */
339 ABORT_WITH(tt, PRPERM);
345 if (!CreateOK(tt, *cid, oid, flag, admin))
346 ABORT_WITH(tt, PRPERM);
348 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
350 * If this was an autoregistration then be sure to audit log
351 * the proper id as the creator.
353 if (foreign && code == 0 && *aid > 0)
355 if (code != PRSUCCESS)
356 ABORT_WITH(tt, code);
358 code = ubik_EndTrans(tt);
367 SPR_WhereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos)
370 afs_int32 cid = ANONYMOUSID;
372 code = whereIsIt(call, aid, apos, &cid);
373 osi_auditU(call, PTS_WheIsItEvent, code, AUD_ID, aid, AUD_LONG, *apos,
375 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d\n", code, cid, aid, *apos));
380 whereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos, afs_int32 *cid)
383 struct ubik_trans *tt;
386 code = ReadPreamble(&tt);
390 code = WhoIsThis(call, tt, cid);
392 ABORT_WITH(tt, PRPERM);
393 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
394 ABORT_WITH(tt, PRPERM);
396 temp = FindByID(tt, aid);
398 ABORT_WITH(tt, PRNOENT);
400 code = ubik_EndTrans(tt);
408 SPR_DumpEntry(struct rx_call *call, afs_int32 apos,
409 struct prdebugentry *aentry)
412 afs_int32 cid = ANONYMOUSID;
414 code = dumpEntry(call, apos, aentry, &cid);
415 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
416 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d\n", code, cid, apos));
421 dumpEntry(struct rx_call *call, afs_int32 apos, struct prdebugentry *aentry,
425 struct ubik_trans *tt;
427 code = ReadPreamble(&tt);
431 code = WhoIsThis(call, tt, cid);
433 ABORT_WITH(tt, PRPERM);
434 code = pr_ReadEntry(tt, 0, apos, (struct prentry *)aentry);
436 ABORT_WITH(tt, code);
438 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
439 ABORT_WITH(tt, PRPERM);
441 /* Since prdebugentry is in the form of a prentry not a coentry, we will
442 * return the coentry slots in network order where the string is. */
444 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
445 code = pr_ReadCoEntry(tt, 0, apos, aentry);
447 ABORT_WITH(tt, code);
450 code = ubik_EndTrans(tt);
457 SPR_AddToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid)
460 afs_int32 cid = ANONYMOUSID;
462 code = addToGroup(call, aid, gid, &cid);
463 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
465 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d\n", code, cid, gid, aid));
470 addToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid, afs_int32 *cid)
473 struct ubik_trans *tt;
476 struct prentry tentry;
477 struct prentry uentry;
479 if (gid == ANYUSERID || gid == AUTHUSERID)
481 if (aid == ANONYMOUSID)
484 code = WritePreamble(&tt);
488 code = WhoIsThis(call, tt, cid);
490 ABORT_WITH(tt, PRPERM);
491 tempu = FindByID(tt, aid);
493 ABORT_WITH(tt, PRNOENT);
494 memset(&uentry, 0, sizeof(uentry));
495 code = pr_ReadEntry(tt, 0, tempu, &uentry);
497 ABORT_WITH(tt, code);
499 #if !defined(SUPERGROUPS)
500 /* we don't allow groups as members of groups at present */
501 if (uentry.flags & PRGRP)
502 ABORT_WITH(tt, PRNOTUSER);
505 tempg = FindByID(tt, gid);
507 ABORT_WITH(tt, PRNOENT);
508 code = pr_ReadEntry(tt, 0, tempg, &tentry);
510 ABORT_WITH(tt, code);
511 /* make sure that this is a group */
512 if (!(tentry.flags & PRGRP))
513 ABORT_WITH(tt, PRNOTGROUP);
514 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
515 ABORT_WITH(tt, PRPERM);
517 code = AddToEntry(tt, &tentry, tempg, aid);
518 if (code != PRSUCCESS)
519 ABORT_WITH(tt, code);
521 #if defined(SUPERGROUPS)
522 if (uentry.flags & PRGRP)
523 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
526 /* now, modify the user's entry as well */
527 code = AddToEntry(tt, &uentry, tempu, gid);
528 if (code != PRSUCCESS)
529 ABORT_WITH(tt, code);
530 code = ubik_EndTrans(tt);
537 SPR_NameToID(struct rx_call *call, namelist *aname, idlist *aid)
541 code = nameToID(call, aname, aid);
542 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
543 ViceLog(125, ("PTS_NameToID: code %d\n", code));
548 nameToID(struct rx_call *call, namelist *aname, idlist *aid)
551 struct ubik_trans *tt;
556 /* Initialize return struct */
558 aid->idlist_val = NULL;
560 size = aname->namelist_len;
566 aid->idlist_val = malloc(size * sizeof(afs_int32));
567 if (!aid->idlist_val)
570 code = ReadPreamble(&tt);
574 for (i = 0; i < aname->namelist_len; i++) {
576 char *nameinst, *cell;
577 afs_int32 islocal = 1;
579 strncpy(vname, aname->namelist_val[i], sizeof(vname));
580 vname[sizeof(vname)-1] ='\0';
583 cell = strchr(vname, '@');
590 code = afsconf_IsLocalRealmMatch(prdir, &islocal, nameinst, NULL, cell);
592 ("PTS_NameToID: afsconf_IsLocalRealmMatch(); code=%d, nameinst=%s, cell=%s\n",
593 code, nameinst, cell));
596 code = NameToID(tt, nameinst, &aid->idlist_val[i]);
598 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
600 if (code != PRSUCCESS)
601 aid->idlist_val[i] = ANONYMOUSID;
602 osi_audit(PTS_NmToIdEvent, code, AUD_STR,
603 aname->namelist_val[i], AUD_ID, aid->idlist_val[i],
605 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d\n", code,
606 aname->namelist_val[i], aid->idlist_val[i]));
608 #ifndef AFS_PTHREAD_ENV
614 aid->idlist_len = aname->namelist_len;
616 code = ubik_EndTrans(tt);
624 * Given an array of ids, find the name for each of them.
625 * The array of ids and names is unlimited.
628 SPR_IDToName(struct rx_call *call, idlist *aid, namelist *aname)
631 afs_int32 cid = ANONYMOUSID;
633 code = idToName(call, aid, aname, &cid);
634 osi_auditU(call, PTS_IdToNmEvent, code, AUD_END);
635 ViceLog(125, ("PTS_IDToName: code %d\n", code));
640 idToName(struct rx_call *call, idlist *aid, namelist *aname, afs_int32 *cid)
643 struct ubik_trans *tt;
648 /* leave this first for rpc stub */
649 size = aid->idlist_len;
652 if (size < 0 || size > INT_MAX / PR_MAXNAMELEN)
654 aname->namelist_val = malloc(size * PR_MAXNAMELEN);
655 aname->namelist_len = 0;
656 if (aname->namelist_val == 0)
658 if (aid->idlist_len == 0)
661 return PRTOOMANY; /* rxgen will probably handle this */
663 code = ReadPreamble(&tt);
667 code = WhoIsThis(call, tt, cid);
669 ABORT_WITH(tt, PRPERM);
670 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
671 ABORT_WITH(tt, PRPERM);
673 for (i = 0; i < aid->idlist_len; i++) {
674 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
675 if (code != PRSUCCESS)
676 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
677 osi_audit(PTS_IdToNmEvent, code, AUD_ID, aid->idlist_val[i],
678 AUD_STR, aname->namelist_val[i], AUD_END);
679 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s\n", code,
680 aid->idlist_val[i], aname->namelist_val[i]));
682 #ifndef AFS_PTHREAD_ENV
688 aname->namelist_len = aid->idlist_len;
690 code = ubik_EndTrans(tt);
697 SPR_Delete(struct rx_call *call, afs_int32 aid)
700 afs_int32 cid = ANONYMOUSID;
702 code = Delete(call, aid, &cid);
703 osi_auditU(call, PTS_DelEvent, code, AUD_ID, aid, AUD_END);
704 ViceLog(5, ("PTS_Delete: code %d cid %d aid %d\n", code, cid, aid));
709 Delete(struct rx_call *call, afs_int32 aid, afs_int32 *cid)
712 struct ubik_trans *tt;
713 struct prentry tentry;
717 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
718 || aid == ANONYMOUSID)
721 code = WritePreamble(&tt);
725 code = WhoIsThis(call, tt, cid);
727 ABORT_WITH(tt, PRPERM);
729 /* Read in entry to be deleted */
730 loc = FindByID(tt, aid);
732 ABORT_WITH(tt, PRNOENT);
733 code = pr_ReadEntry(tt, 0, loc, &tentry);
735 ABORT_WITH(tt, PRDBFAIL);
737 /* Do some access checking */
738 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
739 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
740 ABORT_WITH(tt, PRPERM);
742 /* Delete each continuation block as a separate transaction so that no one
743 * transaction become to large to complete. */
746 struct contentry centry;
749 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
751 ABORT_WITH(tt, PRDBFAIL);
752 for (i = 0; i < COSIZE; i++) {
753 if (centry.entries[i] == PRBADID)
755 if (centry.entries[i] == 0)
757 #if defined(SUPERGROUPS)
758 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
759 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
762 code = RemoveFromEntry(tt, aid, centry.entries[i]);
764 ABORT_WITH(tt, code);
765 tentry.count--; /* maintain count */
766 #ifndef AFS_PTHREAD_ENV
771 tentry.next = centry.next; /* thread out this block */
772 code = FreeBlock(tt, nptr); /* free continuation block */
774 ABORT_WITH(tt, code);
775 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
777 ABORT_WITH(tt, code);
779 /* end this trans and start a new one */
780 code = ubik_EndTrans(tt);
783 #ifndef AFS_PTHREAD_ENV
784 IOMGR_Poll(); /* just to keep the connection alive */
786 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
789 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
791 ABORT_WITH(tt, code);
793 /* re-read entry to get consistent uptodate info */
794 loc = FindByID(tt, aid);
796 ABORT_WITH(tt, PRNOENT);
797 code = pr_ReadEntry(tt, 0, loc, &tentry);
799 ABORT_WITH(tt, PRDBFAIL);
804 #if defined(SUPERGROUPS)
805 /* Delete each continuation block as a separate transaction
806 * so that no one transaction become too large to complete. */
808 struct prentryg *tentryg = (struct prentryg *)&tentry;
809 nptr = tentryg->nextsg;
811 struct contentry centry;
814 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
816 ABORT_WITH(tt, PRDBFAIL);
817 for (i = 0; i < COSIZE; i++) {
818 if (centry.entries[i] == PRBADID)
820 if (centry.entries[i] == 0)
822 code = RemoveFromEntry(tt, aid, centry.entries[i]);
824 ABORT_WITH(tt, code);
825 tentryg->countsg--; /* maintain count */
826 #ifndef AFS_PTHREAD_ENV
831 tentryg->nextsg = centry.next; /* thread out this block */
832 code = FreeBlock(tt, nptr); /* free continuation block */
834 ABORT_WITH(tt, code);
835 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
837 ABORT_WITH(tt, code);
839 /* end this trans and start a new one */
840 code = ubik_EndTrans(tt);
843 #ifndef AFS_PTHREAD_ENV
844 IOMGR_Poll(); /* just to keep the connection alive */
847 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
850 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
852 ABORT_WITH(tt, code);
854 /* re-read entry to get consistent uptodate info */
855 loc = FindByID(tt, aid);
857 ABORT_WITH(tt, PRNOENT);
858 code = pr_ReadEntry(tt, 0, loc, &tentry);
860 ABORT_WITH(tt, PRDBFAIL);
862 nptr = tentryg->nextsg;
866 #endif /* SUPERGROUPS */
868 /* Then move the owned chain, except possibly ourself to the orphan list.
869 * Because this list can be very long and so exceed the size of a ubik
870 * transaction, we start a new transaction every 50 entries. */
874 struct prentry nentry;
876 code = pr_ReadEntry(tt, 0, nptr, &nentry);
878 ABORT_WITH(tt, PRDBFAIL);
879 nptr = tentry.owned = nentry.nextOwned; /* thread out */
881 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
882 code = AddToOrphan(tt, nentry.id);
884 ABORT_WITH(tt, code);
886 #ifndef AFS_PTHREAD_ENV
887 if ((count & 3) == 0)
893 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
895 ABORT_WITH(tt, code);
897 /* end this trans and start a new one */
898 code = ubik_EndTrans(tt);
901 #ifndef AFS_PTHREAD_ENV
902 IOMGR_Poll(); /* just to keep the connection alive */
904 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
907 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
909 ABORT_WITH(tt, code);
911 /* re-read entry to get consistent uptodate info */
912 loc = FindByID(tt, aid);
914 ABORT_WITH(tt, PRNOENT);
915 code = pr_ReadEntry(tt, 0, loc, &tentry);
917 ABORT_WITH(tt, PRDBFAIL);
922 /* now do what's left of the deletion stuff */
923 code = DeleteEntry(tt, &tentry, loc);
924 if (code != PRSUCCESS)
925 ABORT_WITH(tt, code);
927 code = ubik_EndTrans(tt);
934 SPR_UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
935 struct PrUpdateEntry *uentry)
938 afs_int32 cid = ANONYMOUSID;
940 code = UpdateEntry(call, aid, name, uentry, &cid);
941 osi_auditU(call, PTS_UpdEntEvent, code, AUD_ID, aid, AUD_STR, name, AUD_END);
942 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s\n", code, cid, aid, name));
947 UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
948 struct PrUpdateEntry *uentry, afs_int32 *cid)
951 struct ubik_trans *tt;
952 struct prentry tentry;
958 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
959 || aid == ANONYMOUSID)
963 code = WritePreamble(&tt);
967 code = WhoIsThis(call, tt, cid);
969 ABORT_WITH(tt, PRPERM);
970 code = IsAMemberOf(tt, *cid, SYSADMINID);
971 if (!code && !pr_noAuth)
972 ABORT_WITH(tt, PRPERM);
974 /* Read in entry to be deleted */
976 loc = FindByID(tt, aid);
978 loc = FindByName(tt, name, &tentry);
981 ABORT_WITH(tt, PRNOENT);
982 code = pr_ReadEntry(tt, 0, loc, &tentry);
984 ABORT_WITH(tt, PRDBFAIL);
986 if (uentry->Mask & PRUPDATE_NAMEHASH) {
988 code = RemoveFromNameHash(tt, tentry.name, &tloc);
989 if (code != PRSUCCESS)
990 ABORT_WITH(tt, PRDBFAIL);
991 code = AddToNameHash(tt, tentry.name, loc);
993 ABORT_WITH(tt, code);
996 if (uentry->Mask & PRUPDATE_IDHASH) {
1000 code = RemoveFromIDHash(tt, id, &tloc);
1001 if (code != PRSUCCESS)
1002 ABORT_WITH(tt, PRDBFAIL);
1003 code = AddToIDHash(tt, id, loc);
1005 ABORT_WITH(tt, code);
1008 code = ubik_EndTrans(tt);
1015 SPR_RemoveFromGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid)
1018 afs_int32 cid = ANONYMOUSID;
1020 code = removeFromGroup(call, aid, gid, &cid);
1021 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
1023 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d\n", code, cid, gid, aid));
1028 removeFromGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid,
1032 struct ubik_trans *tt;
1035 struct prentry uentry;
1036 struct prentry gentry;
1038 code = WritePreamble(&tt);
1042 code = WhoIsThis(call, tt, cid);
1044 ABORT_WITH(tt, PRPERM);
1045 tempu = FindByID(tt, aid);
1047 ABORT_WITH(tt, PRNOENT);
1048 tempg = FindByID(tt, gid);
1050 ABORT_WITH(tt, PRNOENT);
1051 memset(&uentry, 0, sizeof(uentry));
1052 memset(&gentry, 0, sizeof(gentry));
1053 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1055 ABORT_WITH(tt, code);
1056 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1058 ABORT_WITH(tt, code);
1059 if (!(gentry.flags & PRGRP))
1060 ABORT_WITH(tt, PRNOTGROUP);
1061 #if !defined(SUPERGROUPS)
1062 if (uentry.flags & PRGRP)
1063 ABORT_WITH(tt, PRNOTUSER);
1065 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1066 ABORT_WITH(tt, PRPERM);
1067 code = RemoveFromEntry(tt, aid, gid);
1068 if (code != PRSUCCESS)
1069 ABORT_WITH(tt, code);
1070 #if defined(SUPERGROUPS)
1071 if (!(uentry.flags & PRGRP))
1073 code = RemoveFromEntry(tt, gid, aid);
1074 #if defined(SUPERGROUPS)
1076 code = RemoveFromSGEntry(tt, gid, aid);
1078 if (code != PRSUCCESS)
1079 ABORT_WITH(tt, code);
1081 code = ubik_EndTrans(tt);
1089 SPR_GetCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over)
1092 afs_int32 cid = ANONYMOUSID;
1094 code = getCPS(call, aid, alist, over, &cid);
1095 osi_auditU(call, PTS_GetCPSEvent, code, AUD_ID, aid, AUD_END);
1096 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d\n", code, cid, aid));
1101 getCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over,
1105 struct ubik_trans *tt;
1107 struct prentry tentry;
1110 alist->prlist_len = 0;
1111 alist->prlist_val = NULL;
1113 code = ReadPreamble(&tt);
1117 code = WhoIsThis(call, tt, cid);
1119 ABORT_WITH(tt, PRPERM);
1120 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1121 ABORT_WITH(tt, PRPERM);
1123 temp = FindByID(tt, aid);
1125 ABORT_WITH(tt, PRNOENT);
1126 code = pr_ReadEntry(tt, 0, temp, &tentry);
1128 ABORT_WITH(tt, code);
1130 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1131 ABORT_WITH(tt, PRPERM);
1133 code = GetList(tt, &tentry, alist, 1);
1134 if (code != PRSUCCESS)
1135 ABORT_WITH(tt, code);
1137 code = ubik_EndTrans(tt);
1143 inCPS(prlist CPS, afs_int32 id)
1147 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1148 if (CPS.prlist_val[i] == id)
1156 SPR_GetCPS2(struct rx_call *call, afs_int32 aid, afs_int32 ahost,
1157 prlist *alist, afs_int32 *over)
1160 afs_int32 cid = ANONYMOUSID;
1162 code = getCPS2(call, aid, ahost, alist, over, &cid);
1163 osi_auditU(call, PTS_GetCPS2Event, code, AUD_ID, aid, AUD_HOST, htonl(ahost),
1165 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d\n", code, cid, aid, ahost));
1170 getCPS2(struct rx_call *call, afs_int32 aid, afs_uint32 ahost, prlist *alist,
1171 afs_int32 *over, afs_int32 *cid)
1174 struct ubik_trans *tt;
1176 struct prentry tentry;
1177 struct prentry host_tentry;
1180 struct in_addr iaddr;
1184 iaddr.s_addr = ntohl(ahost);
1185 alist->prlist_len = 0;
1186 alist->prlist_val = NULL;
1188 code = ReadPreamble(&tt);
1192 if (aid != PRBADID) {
1193 temp = FindByID(tt, aid);
1195 ABORT_WITH(tt, PRNOENT);
1196 code = pr_ReadEntry(tt, 0, temp, &tentry);
1198 ABORT_WITH(tt, code);
1200 /* afs does authenticate now */
1201 code = WhoIsThis(call, tt, cid);
1203 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1204 ABORT_WITH(tt, PRPERM);
1206 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1207 if (code == PRSUCCESS && hostid != 0) {
1208 temp = FindByID(tt, hostid);
1210 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1211 if (code == PRSUCCESS)
1214 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1216 fprintf(stderr, "FindByID Failed -- Not found\n");
1219 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1221 code = GetList(tt, &tentry, alist, 1);
1223 code = addWildCards(tt, alist, ntohl(ahost));
1224 if (code != PRSUCCESS)
1225 ABORT_WITH(tt, code);
1227 code = ubik_EndTrans(tt);
1233 SPR_GetHostCPS(struct rx_call *call, afs_int32 ahost, prlist *alist,
1237 afs_int32 cid = ANONYMOUSID;
1239 code = getHostCPS(call, ahost, alist, over, &cid);
1240 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, htonl(ahost), AUD_END);
1241 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %u (0x%x)\n", code, ahost, ahost));
1246 getHostCPS(struct rx_call *call, afs_uint32 ahost, prlist *alist,
1247 afs_int32 *over, afs_int32 *cid)
1249 afs_int32 code, temp;
1250 struct ubik_trans *tt;
1251 struct prentry host_tentry;
1253 struct in_addr iaddr;
1257 iaddr.s_addr = ntohl(ahost);
1258 alist->prlist_len = 0;
1259 alist->prlist_val = NULL;
1261 code = ReadPreamble(&tt);
1265 code = WhoIsThis(call, tt, cid);
1267 ABORT_WITH(tt, PRPERM);
1268 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1269 ABORT_WITH(tt, PRPERM);
1271 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1272 if (code == PRSUCCESS && hostid != 0) {
1273 temp = FindByID(tt, hostid);
1275 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1276 if (code == PRSUCCESS) {
1277 code = GetList(tt, &host_tentry, alist, 0);
1281 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1283 fprintf(stderr, "FindByID Failed -- Not found\n");
1285 code = addWildCards(tt, alist, ntohl(ahost));
1287 if (code != PRSUCCESS)
1288 ABORT_WITH(tt, code);
1290 code = ubik_EndTrans(tt);
1296 SPR_ListMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid)
1299 afs_int32 cid = ANONYMOUSID;
1301 code = listMax(call, uid, gid, &cid);
1302 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1303 ViceLog(125, ("PTS_ListMax: code %d\n", code));
1308 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid, afs_int32 *cid)
1311 struct ubik_trans *tt;
1313 code = ReadPreamble(&tt);
1317 code = WhoIsThis(call, tt, cid);
1319 ABORT_WITH(tt, PRPERM);
1320 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1321 ABORT_WITH(tt, PRPERM);
1323 code = GetMax(tt, uid, gid);
1324 if (code != PRSUCCESS)
1325 ABORT_WITH(tt, code);
1327 code = ubik_EndTrans(tt);
1334 SPR_SetMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag)
1337 afs_int32 cid = ANONYMOUSID;
1339 code = setMax(call, aid, gflag, &cid);
1340 osi_auditU(call, PTS_SetMaxEvent, code, AUD_ID, aid, AUD_LONG, gflag,
1342 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d\n", code, cid, aid, gflag));
1347 setMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag, afs_int32 *cid)
1350 struct ubik_trans *tt;
1352 code = WritePreamble(&tt);
1356 code = WhoIsThis(call, tt, cid);
1358 ABORT_WITH(tt, PRPERM);
1359 if (!AccessOK(tt, *cid, 0, 0, 0))
1360 ABORT_WITH(tt, PRPERM);
1361 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1362 ABORT_WITH(tt, PRBADARG);
1364 code = SetMax(tt, aid, gflag);
1365 if (code != PRSUCCESS)
1366 ABORT_WITH(tt, code);
1368 code = ubik_EndTrans(tt);
1375 SPR_ListEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry)
1378 afs_int32 cid = ANONYMOUSID;
1380 code = listEntry(call, aid, aentry, &cid);
1381 osi_auditU(call, PTS_LstEntEvent, code, AUD_ID, aid, AUD_END);
1382 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d\n", code, cid, aid));
1387 listEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry,
1391 struct ubik_trans *tt;
1393 struct prentry tentry;
1395 code = ReadPreamble(&tt);
1399 code = WhoIsThis(call, tt, cid);
1401 ABORT_WITH(tt, PRPERM);
1402 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1403 ABORT_WITH(tt, PRPERM);
1404 temp = FindByID(tt, aid);
1406 ABORT_WITH(tt, PRNOENT);
1407 code = pr_ReadEntry(tt, 0, temp, &tentry);
1409 ABORT_WITH(tt, code);
1410 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1411 ABORT_WITH(tt, PRPERM);
1413 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1414 if (aentry->flags == 0) {
1415 if (tentry.flags & PRGRP)
1416 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1418 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1420 aentry->owner = tentry.owner;
1421 aentry->id = tentry.id;
1422 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1423 aentry->creator = tentry.creator;
1424 aentry->ngroups = tentry.ngroups;
1425 aentry->nusers = tentry.nusers;
1426 aentry->count = tentry.count;
1427 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1428 code = ubik_EndTrans(tt);
1435 SPR_ListEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
1436 prentries *bulkentries, afs_int32 *nextstartindex)
1439 afs_int32 cid = ANONYMOUSID;
1441 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1442 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1443 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d\n", code, cid, flag));
1448 listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
1449 prentries *bulkentries, afs_int32 *nextstartindex, afs_int32 *cid)
1452 struct ubik_trans *tt;
1453 afs_int32 i, eof, pos, maxentries, f;
1454 struct prentry tentry;
1455 afs_int32 pollcount = 0;
1457 *nextstartindex = -1;
1458 bulkentries->prentries_val = 0;
1459 bulkentries->prentries_len = 0;
1461 code = ReadPreamble(&tt);
1465 /* Make sure we are an authenticated caller and that we are on the
1468 code = WhoIsThis(call, tt, cid);
1470 ABORT_WITH(tt, PRPERM);
1471 code = IsAMemberOf(tt, *cid, SYSADMINID);
1472 if (!code && !pr_noAuth)
1473 ABORT_WITH(tt, PRPERM);
1475 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1476 maxentries = eof / sizeof(struct prentry);
1477 for (i = startindex; i < maxentries; i++) {
1478 pos = i * sizeof(struct prentry) + sizeof(cheader);
1479 code = pr_ReadEntry(tt, 0, pos, &tentry);
1483 if (++pollcount > 50) {
1484 #ifndef AFS_PTHREAD_ENV
1490 f = (tentry.flags & PRTYPE);
1491 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1492 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1493 code = put_prentries(&tentry, bulkentries);
1495 break; /* Filled return array */
1502 *nextstartindex = i;
1506 if (bulkentries->prentries_val)
1507 free(bulkentries->prentries_val);
1508 bulkentries->prentries_val = 0;
1509 bulkentries->prentries_len = 0;
1510 ABORT_WITH(tt, code);
1512 code = ubik_EndTrans(tt);
1519 #define PR_MAXENTRIES 500
1521 put_prentries(struct prentry *tentry, prentries *bulkentries)
1523 struct prlistentries *entry;
1525 if (bulkentries->prentries_val == 0) {
1526 bulkentries->prentries_len = 0;
1527 bulkentries->prentries_val = malloc(PR_MAXENTRIES *
1528 sizeof(struct prlistentries));
1529 if (!bulkentries->prentries_val) {
1534 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1538 entry = bulkentries->prentries_val;
1539 entry += bulkentries->prentries_len;
1541 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1542 if (entry->flags == 0) {
1545 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1548 entry->owner = tentry->owner;
1549 entry->id = tentry->id;
1550 entry->creator = tentry->creator;
1551 entry->ngroups = tentry->ngroups;
1552 entry->nusers = tentry->nusers;
1553 entry->count = tentry->count;
1554 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1555 memset(entry->reserved, 0, sizeof(entry->reserved));
1556 bulkentries->prentries_len++;
1561 SPR_ChangeEntry(struct rx_call *call, afs_int32 aid, char *name, afs_int32 oid,
1565 afs_int32 cid = ANONYMOUSID;
1567 code = changeEntry(call, aid, name, oid, newid, &cid);
1568 osi_auditU(call, PTS_ChgEntEvent, code, AUD_ID, aid, AUD_STR, name,
1569 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1570 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d\n", code, cid, aid, name, oid, newid));
1575 changeEntry(struct rx_call *call, afs_int32 aid, char *name, afs_int32 oid,
1576 afs_int32 newid, afs_int32 *cid)
1579 struct ubik_trans *tt;
1586 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1587 || aid == SYSADMINID)
1590 code = WritePreamble(&tt);
1594 code = WhoIsThis(call, tt, cid);
1596 ABORT_WITH(tt, PRPERM);
1597 pos = FindByID(tt, aid);
1599 ABORT_WITH(tt, PRNOENT);
1600 /* protection check in changeentry */
1601 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1602 if (code != PRSUCCESS)
1603 ABORT_WITH(tt, code);
1605 code = ubik_EndTrans(tt);
1610 SPR_SetFieldsEntry(struct rx_call *call,
1612 afs_int32 mask, /* specify which fields to update */
1613 afs_int32 flags, afs_int32 ngroups, afs_int32 nusers,
1614 afs_int32 spare1, afs_int32 spare2)
1617 afs_int32 cid = ANONYMOUSID;
1620 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1622 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_ID, id, AUD_END);
1623 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d\n", code, cid, id));
1628 setFieldsEntry(struct rx_call *call,
1630 afs_int32 mask, /* specify which fields to update */
1631 afs_int32 flags, afs_int32 ngroups, afs_int32 nusers,
1632 afs_int32 spare1, afs_int32 spare2, afs_int32 *cid)
1635 struct ubik_trans *tt;
1637 struct prentry tentry;
1641 return 0; /* no-op */
1643 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1646 code = WritePreamble(&tt);
1650 code = WhoIsThis(call, tt, cid);
1652 ABORT_WITH(tt, PRPERM);
1653 pos = FindByID(tt, id);
1655 ABORT_WITH(tt, PRNOENT);
1656 code = pr_ReadEntry(tt, 0, pos, &tentry);
1658 ABORT_WITH(tt, code);
1659 tflags = tentry.flags;
1661 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1662 if (!AccessOK(tt, *cid, 0, 0, 0))
1663 ABORT_WITH(tt, PRPERM);
1664 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1665 tentry.ngroups = tentry.nusers = 20;
1668 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1669 ABORT_WITH(tt, PRPERM);
1672 if (mask & 0xffff) { /* if setting flag bits */
1673 afs_int32 flagsMask = mask & 0xffff;
1674 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1675 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1679 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1681 ABORT_WITH(tt, PRBADARG);
1682 tentry.ngroups = ngroups;
1686 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1688 ABORT_WITH(tt, PRBADARG);
1689 tentry.nusers = nusers;
1692 tentry.flags = tflags;
1694 code = pr_WriteEntry(tt, 0, pos, &tentry);
1696 ABORT_WITH(tt, code);
1698 code = ubik_EndTrans(tt);
1703 SPR_ListElements(struct rx_call *call, afs_int32 aid, prlist *alist,
1707 afs_int32 cid = ANONYMOUSID;
1709 code = listElements(call, aid, alist, over, &cid);
1710 osi_auditU(call, PTS_LstEleEvent, code, AUD_ID, aid, AUD_END);
1711 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d\n", code, cid, aid));
1716 listElements(struct rx_call *call, afs_int32 aid, prlist *alist,
1717 afs_int32 *over, afs_int32 *cid)
1720 struct ubik_trans *tt;
1722 struct prentry tentry;
1725 alist->prlist_len = 0;
1726 alist->prlist_val = NULL;
1728 code = ReadPreamble(&tt);
1732 code = WhoIsThis(call, tt, cid);
1734 ABORT_WITH(tt, PRPERM);
1736 temp = FindByID(tt, aid);
1738 ABORT_WITH(tt, PRNOENT);
1739 code = pr_ReadEntry(tt, 0, temp, &tentry);
1741 ABORT_WITH(tt, code);
1742 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1743 ABORT_WITH(tt, PRPERM);
1745 code = GetList(tt, &tentry, alist, 0);
1746 if (code != PRSUCCESS)
1747 ABORT_WITH(tt, code);
1749 code = ubik_EndTrans(tt);
1755 SPR_ListSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
1758 #if defined(SUPERGROUPS)
1760 afs_int32 cid = ANONYMOUSID;
1762 code = listSuperGroups(call, aid, alist, over, &cid);
1763 osi_auditU(call, PTS_LstSGrps, code, AUD_ID, aid, AUD_END);
1764 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d\n", code, cid, aid));
1767 return RXGEN_OPCODE;
1771 #if defined(SUPERGROUPS)
1773 listSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
1774 afs_int32 *over, afs_int32 *cid)
1777 struct ubik_trans *tt;
1779 struct prentry tentry;
1781 alist->prlist_len = 0;
1782 alist->prlist_val = (afs_int32 *) 0;
1784 code = ReadPreamble(&tt);
1788 code = WhoIsThis(call, tt, cid);
1790 ABORT_WITH(tt, PRPERM);
1791 if (!pr_noAuth && restrict_anonymous && *cid == ANONYMOUSID)
1792 ABORT_WITH(tt, PRPERM);
1794 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1796 ABORT_WITH(tt, code);
1798 temp = FindByID(tt, aid);
1800 ABORT_WITH(tt, PRNOENT);
1801 code = pr_ReadEntry(tt, 0, temp, &tentry);
1803 ABORT_WITH(tt, code);
1804 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1805 ABORT_WITH(tt, PRPERM);
1807 code = GetSGList(tt, &tentry, alist);
1809 if (code == PRTOOMANY)
1811 else if (code != PRSUCCESS)
1812 ABORT_WITH(tt, code);
1814 code = ubik_EndTrans(tt);
1819 #endif /* SUPERGROUPS */
1823 * List the entries owned by this id. If the id is zero,
1824 * return the orphans list. This will return up to PR_MAXGROUPS
1825 * at a time with the lastP available to get the rest. The
1826 * maximum value is enforced in GetOwnedChain().
1829 SPR_ListOwned(struct rx_call *call, afs_int32 aid, prlist *alist,
1833 afs_int32 cid = ANONYMOUSID;
1835 code = listOwned(call, aid, alist, lastP, &cid);
1836 osi_auditU(call, PTS_LstOwnEvent, code, AUD_ID, aid, AUD_END);
1837 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d\n", code, cid, aid));
1842 listOwned(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *lastP,
1846 struct ubik_trans *tt;
1847 struct prentry tentry;
1851 alist->prlist_len = 0;
1852 alist->prlist_val = NULL;
1859 code = ReadPreamble(&tt);
1863 code = WhoIsThis(call, tt, cid);
1865 ABORT_WITH(tt, PRPERM);
1868 code = pr_ReadEntry(tt, 0, start, &tentry);
1869 if (!code && (tentry.owner == aid))
1870 head = start; /* pick up where we left off */
1875 afs_int32 loc = FindByID(tt, aid);
1877 ABORT_WITH(tt, PRNOENT);
1878 code = pr_ReadEntry(tt, 0, loc, &tentry);
1880 ABORT_WITH(tt, code);
1882 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
1883 ABORT_WITH(tt, PRPERM);
1884 head = tentry.owned;
1886 if (!AccessOK(tt, *cid, 0, 0, 0))
1887 ABORT_WITH(tt, PRPERM);
1888 head = ntohl(cheader.orphan);
1892 code = GetOwnedChain(tt, &head, alist);
1894 if (code == PRTOOMANY)
1897 ABORT_WITH(tt, code);
1900 code = ubik_EndTrans(tt);
1905 SPR_IsAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid,
1909 afs_int32 cid = ANONYMOUSID;
1911 code = isAMemberOf(call, uid, gid, flag, &cid);
1912 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
1914 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d\n", code, cid, uid, gid));
1919 isAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid, afs_int32 *flag,
1923 struct ubik_trans *tt;
1925 code = ReadPreamble(&tt);
1930 afs_int32 uloc = FindByID(tt, uid);
1931 afs_int32 gloc = FindByID(tt, gid);
1932 struct prentry uentry, gentry;
1935 ABORT_WITH(tt, PRNOENT);
1936 code = WhoIsThis(call, tt, cid);
1938 ABORT_WITH(tt, PRPERM);
1939 code = pr_ReadEntry(tt, 0, uloc, &uentry);
1941 ABORT_WITH(tt, code);
1942 code = pr_ReadEntry(tt, 0, gloc, &gentry);
1944 ABORT_WITH(tt, code);
1945 #if !defined(SUPERGROUPS)
1946 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
1947 ABORT_WITH(tt, PRBADARG);
1949 if (!(gentry.flags & PRGRP))
1950 ABORT_WITH(tt, PRBADARG);
1952 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
1953 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1954 ABORT_WITH(tt, PRPERM);
1957 *flag = IsAMemberOf(tt, uid, gid);
1958 code = ubik_EndTrans(tt);
1963 addWildCards(struct ubik_trans *tt, prlist *alist, afs_uint32 host)
1966 struct prentry tentry;
1968 unsigned wild = htonl(0xffffff00);
1969 struct in_addr iaddr;
1971 int size = 0, i, code;
1975 while ((host = (host & wild))) {
1976 wild = htonl(ntohl(wild) << 8);
1977 iaddr.s_addr = host;
1978 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1979 if (code == PRSUCCESS && hostid != 0) {
1980 temp = FindByID(tt, hostid);
1982 code = pr_ReadEntry(tt, 0, temp, &tentry);
1983 if (code != PRSUCCESS)
1989 wlist.prlist_len = 0;
1990 wlist.prlist_val = NULL;
1992 code = GetList(tt, &tentry, &wlist, 0);
1995 added += wlist.prlist_len;
1996 for (i = 0; i < wlist.prlist_len; i++) {
1997 if (!inCPS(*alist, wlist.prlist_val[i]))
1998 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
1999 free(wlist.prlist_val);
2003 if (wlist.prlist_val)
2004 free(wlist.prlist_val);
2007 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
2012 WhoIsThisWithName(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid,
2015 afs_int32 islocal = 1;
2016 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2017 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2018 struct rx_connection *tconn;
2020 char tcell[MAXKTCREALMLEN];
2021 char name[MAXKTCNAMELEN];
2022 char inst[MAXKTCNAMELEN];
2027 tconn = rx_ConnectionOf(acall);
2028 code = rx_SecurityClassOf(tconn);
2029 if (code == RX_SECIDX_NULL)
2031 else if (code == RX_SECIDX_VAB) {
2032 goto done; /* no longer supported */
2033 } else if (code == RX_SECIDX_KAD) {
2034 if ((code = rxkad_GetServerInfo(rx_ConnectionOf(acall), NULL, NULL,
2035 name, inst, tcell, NULL)))
2039 code = afsconf_IsLocalRealmMatch(prdir, &islocal, name, inst, tcell);
2043 strncpy(vname, name, sizeof(vname));
2044 if ((ilen = strlen(inst))) {
2045 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2048 strcat(vname, inst);
2051 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
2054 strcat(vname, tcell);
2055 lcstring(vname, vname, sizeof(vname));
2056 NameToID(at, vname, aid);
2058 strcpy(aname, vname);
2062 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2063 *aid = SYSADMINID; /* special case for the fileserver */
2065 lcstring(vname, vname, sizeof(vname));
2066 code = NameToID(at, vname, aid);
2070 if (code && !pr_noAuth)