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 struct ubik_dbase *dbase;
76 extern int prp_group_default;
77 extern int prp_user_default;
78 extern struct afsconf_dir *prdir;
80 static afs_int32 iNewEntry(struct rx_call *call, char aname[], afs_int32 aid,
81 afs_int32 oid, afs_int32 *cid);
82 static afs_int32 newEntry(struct rx_call *call, char aname[], afs_int32 flag,
83 afs_int32 oid, afs_int32 *aid, afs_int32 *cid);
84 static afs_int32 whereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos,
86 static afs_int32 dumpEntry(struct rx_call *call, afs_int32 apos,
87 struct prdebugentry *aentry, afs_int32 *cid);
88 static afs_int32 addToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid,
90 static afs_int32 nameToID(struct rx_call *call, namelist *aname, idlist *aid);
91 static afs_int32 idToName(struct rx_call *call, idlist *aid, namelist *aname);
92 static afs_int32 Delete(struct rx_call *call, afs_int32 aid, afs_int32 *cid);
93 static afs_int32 UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
94 struct PrUpdateEntry *uentry, afs_int32 *cid);
95 static afs_int32 removeFromGroup(struct rx_call *call, afs_int32 aid,
96 afs_int32 gid, afs_int32 *cid);
97 static afs_int32 getCPS(struct rx_call *call, afs_int32 aid, prlist *alist,
98 afs_int32 *over, afs_int32 *cid);
99 static afs_int32 getCPS2(struct rx_call *call, afs_int32 aid, afs_uint32 ahost,
100 prlist *alist, afs_int32 *over, afs_int32 *cid);
101 static afs_int32 getHostCPS(struct rx_call *call, afs_uint32 ahost,
102 prlist *alist, afs_int32 *over);
103 static afs_int32 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid);
104 static afs_int32 setMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag,
106 static afs_int32 listEntry(struct rx_call *call, afs_int32 aid,
107 struct prcheckentry *aentry, afs_int32 *cid);
108 static afs_int32 listEntries(struct rx_call *call, afs_int32 flag,
109 afs_int32 startindex, prentries *bulkentries,
110 afs_int32 *nextstartindex, afs_int32 *cid);
111 static afs_int32 put_prentries(struct prentry *tentry, prentries *bulkentries);
112 static afs_int32 changeEntry(struct rx_call *call, afs_int32 aid, char *name,
113 afs_int32 oid, afs_int32 newid, afs_int32 *cid);
114 static afs_int32 setFieldsEntry(struct rx_call *call, afs_int32 id,
115 afs_int32 mask, afs_int32 flags,
116 afs_int32 ngroups, afs_int32 nusers,
117 afs_int32 spare1, afs_int32 spare2,
119 static afs_int32 listElements(struct rx_call *call, afs_int32 aid,
120 prlist *alist, afs_int32 *over, afs_int32 *cid);
121 #if defined(SUPERGROUPS)
122 static afs_int32 listSuperGroups(struct rx_call *call, afs_int32 aid,
123 prlist *alist, afs_int32 *over,
126 static afs_int32 listOwned(struct rx_call *call, afs_int32 aid, prlist *alist,
127 afs_int32 *lastP, afs_int32 *cid);
128 static afs_int32 isAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid,
129 afs_int32 *flag, afs_int32 *cid);
130 static afs_int32 addWildCards(struct ubik_trans *tt, prlist *alist,
132 static afs_int32 WhoIsThisWithName(struct rx_call *acall,
133 struct ubik_trans *at, afs_int32 *aid,
136 /* when we abort, the ubik cachedVersion will be reset, so we'll read in the
137 * header on the next call.
138 * Abort the transaction and return the code.
140 #define ABORT_WITH(tt,code) return(ubik_AbortTrans(tt),code)
143 CreateOK(struct ubik_trans *ut, afs_int32 cid, afs_int32 oid, afs_int32 flag,
146 if (restricted && !admin)
149 if (flag & PRFOREIGN) {
150 /* Foreign users are recognized by the '@' sign and
151 * not by the PRFOREIGN flag.
154 } else if (flag & PRGRP) {
155 /* Allow anonymous group creation only if owner specified
156 * and running noAuth.
158 if (cid == ANONYMOUSID) {
159 if ((oid == 0) || !pr_noAuth)
162 } else { /* creating a user */
163 if (!admin && !pr_noAuth)
170 WhoIsThis(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid)
172 int code = WhoIsThisWithName(acall, at, aid, NULL);
173 if (code == 2 && *aid == ANONYMOUSID)
179 WritePreamble(struct ubik_trans **tt)
187 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, tt);
191 code = ubik_SetLock(*tt, 1, 1, LOCKWRITE);
195 code = read_DbHeader(*tt);
199 ubik_AbortTrans(*tt);
205 ReadPreamble(struct ubik_trans **tt)
213 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, tt);
217 code = ubik_SetLock(*tt, 1, 1, LOCKREAD);
221 code = read_DbHeader(*tt);
225 ubik_AbortTrans(*tt);
231 SPR_INewEntry(struct rx_call *call, char aname[], afs_int32 aid, afs_int32 oid)
234 afs_int32 cid = ANONYMOUSID;
236 code = iNewEntry(call, aname, aid, oid, &cid);
237 osi_auditU(call, PTS_INewEntEvent, code, AUD_ID, aid, AUD_STR, aname,
238 AUD_ID, oid, AUD_END);
239 ViceLog(5, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d\n", code, cid, aid, aname, oid));
244 iNewEntry(struct rx_call *call, char aname[], afs_int32 aid, afs_int32 oid,
247 /* used primarily for conversion - not intended to be used as usual means
248 * of entering people into the database. */
249 struct ubik_trans *tt;
256 code = WritePreamble(&tt);
260 code = WhoIsThis(call, tt, cid);
262 ABORT_WITH(tt, PRPERM);
263 admin = IsAMemberOf(tt, *cid, SYSADMINID);
265 /* first verify the id is good */
267 ABORT_WITH(tt, PRPERM);
270 /* only sysadmin can reuse a group id */
271 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
272 ABORT_WITH(tt, PRPERM);
274 if (FindByID(tt, aid))
275 ABORT_WITH(tt, PRIDEXIST);
277 /* check a few other things */
278 if (!CreateOK(tt, *cid, oid, gflag, admin))
279 ABORT_WITH(tt, PRPERM);
281 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
282 if (code != PRSUCCESS)
283 ABORT_WITH(tt, code);
285 /* finally, commit transaction */
286 code = ubik_EndTrans(tt);
294 SPR_NewEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
298 afs_int32 cid = ANONYMOUSID;
300 code = newEntry(call, aname, flag, oid, aid, &cid);
301 osi_auditU(call, PTS_NewEntEvent, code, AUD_ID, *aid, AUD_STR, aname,
302 AUD_ID, oid, AUD_END);
303 ViceLog(5, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d\n", code, cid, *aid, aname, oid));
308 newEntry(struct rx_call *call, char aname[], afs_int32 flag, afs_int32 oid,
309 afs_int32 *aid, afs_int32 *cid)
312 struct ubik_trans *tt;
314 char cname[PR_MAXNAMELEN];
317 code = WritePreamble(&tt);
321 /* this is for cross-cell self registration. It is not added in the
322 * SPR_INewEntry because we want self-registration to only do
323 * automatic id assignment.
325 code = WhoIsThisWithName(call, tt, cid, cname);
326 if (code != 2) { /* 2 specifies that this is a foreign cell request */
328 ABORT_WITH(tt, PRPERM);
329 admin = IsAMemberOf(tt, *cid, SYSADMINID);
331 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
332 oid = *cid = SYSADMINID;
334 if (!CreateOK(tt, *cid, oid, flag, admin))
335 ABORT_WITH(tt, PRPERM);
337 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
338 if (code != PRSUCCESS)
339 ABORT_WITH(tt, code);
341 code = ubik_EndTrans(tt);
350 SPR_WhereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos)
353 afs_int32 cid = ANONYMOUSID;
355 code = whereIsIt(call, aid, apos, &cid);
356 osi_auditU(call, PTS_WheIsItEvent, code, AUD_ID, aid, AUD_LONG, *apos,
358 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d\n", code, cid, aid, *apos));
363 whereIsIt(struct rx_call *call, afs_int32 aid, afs_int32 *apos, afs_int32 *cid)
366 struct ubik_trans *tt;
369 code = ReadPreamble(&tt);
373 code = WhoIsThis(call, tt, cid);
375 ABORT_WITH(tt, PRPERM);
377 temp = FindByID(tt, aid);
379 ABORT_WITH(tt, PRNOENT);
381 code = ubik_EndTrans(tt);
389 SPR_DumpEntry(struct rx_call *call, afs_int32 apos,
390 struct prdebugentry *aentry)
393 afs_int32 cid = ANONYMOUSID;
395 code = dumpEntry(call, apos, aentry, &cid);
396 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
397 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d\n", code, cid, apos));
402 dumpEntry(struct rx_call *call, afs_int32 apos, struct prdebugentry *aentry,
406 struct ubik_trans *tt;
408 code = ReadPreamble(&tt);
412 code = WhoIsThis(call, tt, cid);
414 ABORT_WITH(tt, PRPERM);
415 code = pr_ReadEntry(tt, 0, apos, (struct prentry *)aentry);
417 ABORT_WITH(tt, code);
419 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
420 ABORT_WITH(tt, PRPERM);
422 /* Since prdebugentry is in the form of a prentry not a coentry, we will
423 * return the coentry slots in network order where the string is. */
425 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
426 code = pr_ReadCoEntry(tt, 0, apos, aentry);
428 ABORT_WITH(tt, code);
431 code = ubik_EndTrans(tt);
438 SPR_AddToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid)
441 afs_int32 cid = ANONYMOUSID;
443 code = addToGroup(call, aid, gid, &cid);
444 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
446 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d\n", code, cid, gid, aid));
451 addToGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid, afs_int32 *cid)
454 struct ubik_trans *tt;
457 struct prentry tentry;
458 struct prentry uentry;
460 if (gid == ANYUSERID || gid == AUTHUSERID)
462 if (aid == ANONYMOUSID)
465 code = WritePreamble(&tt);
469 code = WhoIsThis(call, tt, cid);
471 ABORT_WITH(tt, PRPERM);
472 tempu = FindByID(tt, aid);
474 ABORT_WITH(tt, PRNOENT);
475 memset(&uentry, 0, sizeof(uentry));
476 code = pr_ReadEntry(tt, 0, tempu, &uentry);
478 ABORT_WITH(tt, code);
480 #if !defined(SUPERGROUPS)
481 /* we don't allow groups as members of groups at present */
482 if (uentry.flags & PRGRP)
483 ABORT_WITH(tt, PRNOTUSER);
486 tempg = FindByID(tt, gid);
488 ABORT_WITH(tt, PRNOENT);
489 code = pr_ReadEntry(tt, 0, tempg, &tentry);
491 ABORT_WITH(tt, code);
492 /* make sure that this is a group */
493 if (!(tentry.flags & PRGRP))
494 ABORT_WITH(tt, PRNOTGROUP);
495 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
496 ABORT_WITH(tt, PRPERM);
498 code = AddToEntry(tt, &tentry, tempg, aid);
499 if (code != PRSUCCESS)
500 ABORT_WITH(tt, code);
502 #if defined(SUPERGROUPS)
503 if (uentry.flags & PRGRP)
504 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
507 /* now, modify the user's entry as well */
508 code = AddToEntry(tt, &uentry, tempu, gid);
509 if (code != PRSUCCESS)
510 ABORT_WITH(tt, code);
511 code = ubik_EndTrans(tt);
518 SPR_NameToID(struct rx_call *call, namelist *aname, idlist *aid)
522 code = nameToID(call, aname, aid);
523 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
524 ViceLog(125, ("PTS_NameToID: code %d\n", code));
529 nameToID(struct rx_call *call, namelist *aname, idlist *aid)
532 struct ubik_trans *tt;
537 /* Initialize return struct */
539 aid->idlist_val = NULL;
541 size = aname->namelist_len;
547 aid->idlist_val = malloc(size * sizeof(afs_int32));
548 if (!aid->idlist_val)
551 code = ReadPreamble(&tt);
555 for (i = 0; i < aname->namelist_len; i++) {
557 char *nameinst, *cell;
558 afs_int32 islocal = 1;
560 strncpy(vname, aname->namelist_val[i], sizeof(vname));
561 vname[sizeof(vname)-1] ='\0';
564 cell = strchr(vname, '@');
571 code = afsconf_IsLocalRealmMatch(prdir, &islocal, nameinst, NULL, cell);
573 ("PTS_NameToID: afsconf_IsLocalRealmMatch(); code=%d, nameinst=%s, cell=%s\n",
574 code, nameinst, cell));
577 code = NameToID(tt, nameinst, &aid->idlist_val[i]);
579 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
581 if (code != PRSUCCESS)
582 aid->idlist_val[i] = ANONYMOUSID;
583 osi_audit(PTS_NmToIdEvent, code, AUD_STR,
584 aname->namelist_val[i], AUD_ID, aid->idlist_val[i],
586 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d\n", code,
587 aname->namelist_val[i], aid->idlist_val[i]));
589 #ifndef AFS_PTHREAD_ENV
595 aid->idlist_len = aname->namelist_len;
597 code = ubik_EndTrans(tt);
605 * Given an array of ids, find the name for each of them.
606 * The array of ids and names is unlimited.
609 SPR_IDToName(struct rx_call *call, idlist *aid, namelist *aname)
613 code = idToName(call, aid, aname);
614 osi_auditU(call, PTS_IdToNmEvent, code, AUD_END);
615 ViceLog(125, ("PTS_IDToName: code %d\n", code));
620 idToName(struct rx_call *call, idlist *aid, namelist *aname)
623 struct ubik_trans *tt;
628 /* leave this first for rpc stub */
629 size = aid->idlist_len;
634 aname->namelist_val = malloc(size * PR_MAXNAMELEN);
635 aname->namelist_len = 0;
636 if (aname->namelist_val == 0)
638 if (aid->idlist_len == 0)
641 return PRTOOMANY; /* rxgen will probably handle this */
643 code = ReadPreamble(&tt);
647 for (i = 0; i < aid->idlist_len; i++) {
648 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
649 if (code != PRSUCCESS)
650 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
651 osi_audit(PTS_IdToNmEvent, code, AUD_ID, aid->idlist_val[i],
652 AUD_STR, aname->namelist_val[i], AUD_END);
653 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s\n", code,
654 aid->idlist_val[i], aname->namelist_val[i]));
656 #ifndef AFS_PTHREAD_ENV
662 aname->namelist_len = aid->idlist_len;
664 code = ubik_EndTrans(tt);
671 SPR_Delete(struct rx_call *call, afs_int32 aid)
674 afs_int32 cid = ANONYMOUSID;
676 code = Delete(call, aid, &cid);
677 osi_auditU(call, PTS_DelEvent, code, AUD_ID, aid, AUD_END);
678 ViceLog(5, ("PTS_Delete: code %d cid %d aid %d\n", code, cid, aid));
683 Delete(struct rx_call *call, afs_int32 aid, afs_int32 *cid)
686 struct ubik_trans *tt;
687 struct prentry tentry;
691 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
692 || aid == ANONYMOUSID)
695 code = WritePreamble(&tt);
699 code = WhoIsThis(call, tt, cid);
701 ABORT_WITH(tt, PRPERM);
703 /* Read in entry to be deleted */
704 loc = FindByID(tt, aid);
706 ABORT_WITH(tt, PRNOENT);
707 code = pr_ReadEntry(tt, 0, loc, &tentry);
709 ABORT_WITH(tt, PRDBFAIL);
711 /* Do some access checking */
712 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
713 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
714 ABORT_WITH(tt, PRPERM);
716 /* Delete each continuation block as a separate transaction so that no one
717 * transaction become to large to complete. */
720 struct contentry centry;
723 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
725 ABORT_WITH(tt, PRDBFAIL);
726 for (i = 0; i < COSIZE; i++) {
727 if (centry.entries[i] == PRBADID)
729 if (centry.entries[i] == 0)
731 #if defined(SUPERGROUPS)
732 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
733 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
736 code = RemoveFromEntry(tt, aid, centry.entries[i]);
738 ABORT_WITH(tt, code);
739 tentry.count--; /* maintain count */
740 #ifndef AFS_PTHREAD_ENV
745 tentry.next = centry.next; /* thread out this block */
746 code = FreeBlock(tt, nptr); /* free continuation block */
748 ABORT_WITH(tt, code);
749 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
751 ABORT_WITH(tt, code);
753 /* end this trans and start a new one */
754 code = ubik_EndTrans(tt);
757 #ifndef AFS_PTHREAD_ENV
758 IOMGR_Poll(); /* just to keep the connection alive */
760 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
763 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
765 ABORT_WITH(tt, code);
767 /* re-read entry to get consistent uptodate info */
768 loc = FindByID(tt, aid);
770 ABORT_WITH(tt, PRNOENT);
771 code = pr_ReadEntry(tt, 0, loc, &tentry);
773 ABORT_WITH(tt, PRDBFAIL);
778 #if defined(SUPERGROUPS)
779 /* Delete each continuation block as a separate transaction
780 * so that no one transaction become too large to complete. */
782 struct prentryg *tentryg = (struct prentryg *)&tentry;
783 nptr = tentryg->nextsg;
785 struct contentry centry;
788 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
790 ABORT_WITH(tt, PRDBFAIL);
791 for (i = 0; i < COSIZE; i++) {
792 if (centry.entries[i] == PRBADID)
794 if (centry.entries[i] == 0)
796 code = RemoveFromEntry(tt, aid, centry.entries[i]);
798 ABORT_WITH(tt, code);
799 tentryg->countsg--; /* maintain count */
800 #ifndef AFS_PTHREAD_ENV
805 tentryg->nextsg = centry.next; /* thread out this block */
806 code = FreeBlock(tt, nptr); /* free continuation block */
808 ABORT_WITH(tt, code);
809 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
811 ABORT_WITH(tt, code);
813 /* end this trans and start a new one */
814 code = ubik_EndTrans(tt);
817 #ifndef AFS_PTHREAD_ENV
818 IOMGR_Poll(); /* just to keep the connection alive */
821 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
824 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
826 ABORT_WITH(tt, code);
828 /* re-read entry to get consistent uptodate info */
829 loc = FindByID(tt, aid);
831 ABORT_WITH(tt, PRNOENT);
832 code = pr_ReadEntry(tt, 0, loc, &tentry);
834 ABORT_WITH(tt, PRDBFAIL);
836 nptr = tentryg->nextsg;
840 #endif /* SUPERGROUPS */
842 /* Then move the owned chain, except possibly ourself to the orphan list.
843 * Because this list can be very long and so exceed the size of a ubik
844 * transaction, we start a new transaction every 50 entries. */
848 struct prentry nentry;
850 code = pr_ReadEntry(tt, 0, nptr, &nentry);
852 ABORT_WITH(tt, PRDBFAIL);
853 nptr = tentry.owned = nentry.nextOwned; /* thread out */
855 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
856 code = AddToOrphan(tt, nentry.id);
858 ABORT_WITH(tt, code);
860 #ifndef AFS_PTHREAD_ENV
861 if ((count & 3) == 0)
867 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
869 ABORT_WITH(tt, code);
871 /* end this trans and start a new one */
872 code = ubik_EndTrans(tt);
875 #ifndef AFS_PTHREAD_ENV
876 IOMGR_Poll(); /* just to keep the connection alive */
878 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
881 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
883 ABORT_WITH(tt, code);
885 /* re-read entry to get consistent uptodate info */
886 loc = FindByID(tt, aid);
888 ABORT_WITH(tt, PRNOENT);
889 code = pr_ReadEntry(tt, 0, loc, &tentry);
891 ABORT_WITH(tt, PRDBFAIL);
896 /* now do what's left of the deletion stuff */
897 code = DeleteEntry(tt, &tentry, loc);
898 if (code != PRSUCCESS)
899 ABORT_WITH(tt, code);
901 code = ubik_EndTrans(tt);
908 SPR_UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
909 struct PrUpdateEntry *uentry)
912 afs_int32 cid = ANONYMOUSID;
914 code = UpdateEntry(call, aid, name, uentry, &cid);
915 osi_auditU(call, PTS_UpdEntEvent, code, AUD_ID, aid, AUD_STR, name, AUD_END);
916 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s\n", code, cid, aid, name));
921 UpdateEntry(struct rx_call *call, afs_int32 aid, char *name,
922 struct PrUpdateEntry *uentry, afs_int32 *cid)
925 struct ubik_trans *tt;
926 struct prentry tentry;
932 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
933 || aid == ANONYMOUSID)
937 code = WritePreamble(&tt);
941 code = WhoIsThis(call, tt, cid);
943 ABORT_WITH(tt, PRPERM);
944 code = IsAMemberOf(tt, *cid, SYSADMINID);
945 if (!code && !pr_noAuth)
946 ABORT_WITH(tt, PRPERM);
948 /* Read in entry to be deleted */
950 loc = FindByID(tt, aid);
952 loc = FindByName(tt, name, &tentry);
955 ABORT_WITH(tt, PRNOENT);
956 code = pr_ReadEntry(tt, 0, loc, &tentry);
958 ABORT_WITH(tt, PRDBFAIL);
960 if (uentry->Mask & PRUPDATE_NAMEHASH) {
962 code = RemoveFromNameHash(tt, tentry.name, &tloc);
963 if (code != PRSUCCESS)
964 ABORT_WITH(tt, PRDBFAIL);
965 code = AddToNameHash(tt, tentry.name, loc);
967 ABORT_WITH(tt, code);
970 if (uentry->Mask & PRUPDATE_IDHASH) {
974 code = RemoveFromIDHash(tt, id, &tloc);
975 if (code != PRSUCCESS)
976 ABORT_WITH(tt, PRDBFAIL);
977 code = AddToIDHash(tt, id, loc);
979 ABORT_WITH(tt, code);
982 code = ubik_EndTrans(tt);
989 SPR_RemoveFromGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid)
992 afs_int32 cid = ANONYMOUSID;
994 code = removeFromGroup(call, aid, gid, &cid);
995 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
997 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d\n", code, cid, gid, aid));
1002 removeFromGroup(struct rx_call *call, afs_int32 aid, afs_int32 gid,
1006 struct ubik_trans *tt;
1009 struct prentry uentry;
1010 struct prentry gentry;
1012 code = WritePreamble(&tt);
1016 code = WhoIsThis(call, tt, cid);
1018 ABORT_WITH(tt, PRPERM);
1019 tempu = FindByID(tt, aid);
1021 ABORT_WITH(tt, PRNOENT);
1022 tempg = FindByID(tt, gid);
1024 ABORT_WITH(tt, PRNOENT);
1025 memset(&uentry, 0, sizeof(uentry));
1026 memset(&gentry, 0, sizeof(gentry));
1027 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1029 ABORT_WITH(tt, code);
1030 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1032 ABORT_WITH(tt, code);
1033 if (!(gentry.flags & PRGRP))
1034 ABORT_WITH(tt, PRNOTGROUP);
1035 #if !defined(SUPERGROUPS)
1036 if (uentry.flags & PRGRP)
1037 ABORT_WITH(tt, PRNOTUSER);
1039 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1040 ABORT_WITH(tt, PRPERM);
1041 code = RemoveFromEntry(tt, aid, gid);
1042 if (code != PRSUCCESS)
1043 ABORT_WITH(tt, code);
1044 #if defined(SUPERGROUPS)
1045 if (!(uentry.flags & PRGRP))
1047 code = RemoveFromEntry(tt, gid, aid);
1048 #if defined(SUPERGROUPS)
1050 code = RemoveFromSGEntry(tt, gid, aid);
1052 if (code != PRSUCCESS)
1053 ABORT_WITH(tt, code);
1055 code = ubik_EndTrans(tt);
1063 SPR_GetCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over)
1066 afs_int32 cid = ANONYMOUSID;
1068 code = getCPS(call, aid, alist, over, &cid);
1069 osi_auditU(call, PTS_GetCPSEvent, code, AUD_ID, aid, AUD_END);
1070 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d\n", code, cid, aid));
1075 getCPS(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *over,
1079 struct ubik_trans *tt;
1081 struct prentry tentry;
1084 alist->prlist_len = 0;
1085 alist->prlist_val = NULL;
1087 code = ReadPreamble(&tt);
1091 temp = FindByID(tt, aid);
1093 ABORT_WITH(tt, PRNOENT);
1094 code = pr_ReadEntry(tt, 0, temp, &tentry);
1096 ABORT_WITH(tt, code);
1098 /* afs does authenticate now */
1099 code = WhoIsThis(call, tt, cid);
1100 if (code || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1101 ABORT_WITH(tt, PRPERM);
1103 code = GetList(tt, &tentry, alist, 1);
1104 if (code != PRSUCCESS)
1105 ABORT_WITH(tt, code);
1107 code = ubik_EndTrans(tt);
1113 inCPS(prlist CPS, afs_int32 id)
1117 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1118 if (CPS.prlist_val[i] == id)
1126 SPR_GetCPS2(struct rx_call *call, afs_int32 aid, afs_int32 ahost,
1127 prlist *alist, afs_int32 *over)
1130 afs_int32 cid = ANONYMOUSID;
1132 code = getCPS2(call, aid, ahost, alist, over, &cid);
1133 osi_auditU(call, PTS_GetCPS2Event, code, AUD_ID, aid, AUD_HOST, htonl(ahost),
1135 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d\n", code, cid, aid, ahost));
1140 getCPS2(struct rx_call *call, afs_int32 aid, afs_uint32 ahost, prlist *alist,
1141 afs_int32 *over, afs_int32 *cid)
1144 struct ubik_trans *tt;
1146 struct prentry tentry;
1147 struct prentry host_tentry;
1150 struct in_addr iaddr;
1154 iaddr.s_addr = ntohl(ahost);
1155 alist->prlist_len = 0;
1156 alist->prlist_val = NULL;
1158 code = ReadPreamble(&tt);
1162 if (aid != PRBADID) {
1163 temp = FindByID(tt, aid);
1165 ABORT_WITH(tt, PRNOENT);
1166 code = pr_ReadEntry(tt, 0, temp, &tentry);
1168 ABORT_WITH(tt, code);
1170 /* afs does authenticate now */
1171 code = WhoIsThis(call, tt, cid);
1173 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1174 ABORT_WITH(tt, PRPERM);
1176 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1177 if (code == PRSUCCESS && hostid != 0) {
1178 temp = FindByID(tt, hostid);
1180 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1181 if (code == PRSUCCESS)
1184 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1186 fprintf(stderr, "FindByID Failed -- Not found\n");
1189 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1191 code = GetList(tt, &tentry, alist, 1);
1193 code = addWildCards(tt, alist, ntohl(ahost));
1194 if (code != PRSUCCESS)
1195 ABORT_WITH(tt, code);
1197 code = ubik_EndTrans(tt);
1203 SPR_GetHostCPS(struct rx_call *call, afs_int32 ahost, prlist *alist,
1208 code = getHostCPS(call, ahost, alist, over);
1209 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, htonl(ahost), AUD_END);
1210 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d\n", code, ahost));
1215 getHostCPS(struct rx_call *call, afs_uint32 ahost, prlist *alist,
1218 afs_int32 code, temp;
1219 struct ubik_trans *tt;
1220 struct prentry host_tentry;
1222 struct in_addr iaddr;
1226 iaddr.s_addr = ntohl(ahost);
1227 alist->prlist_len = 0;
1228 alist->prlist_val = NULL;
1230 code = ReadPreamble(&tt);
1234 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1235 if (code == PRSUCCESS && hostid != 0) {
1236 temp = FindByID(tt, hostid);
1238 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1239 if (code == PRSUCCESS) {
1240 code = GetList(tt, &host_tentry, alist, 0);
1244 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1246 fprintf(stderr, "FindByID Failed -- Not found\n");
1248 code = addWildCards(tt, alist, ntohl(ahost));
1250 if (code != PRSUCCESS)
1251 ABORT_WITH(tt, code);
1253 code = ubik_EndTrans(tt);
1259 SPR_ListMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid)
1263 code = listMax(call, uid, gid);
1264 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1265 ViceLog(125, ("PTS_ListMax: code %d\n", code));
1270 listMax(struct rx_call *call, afs_int32 *uid, afs_int32 *gid)
1273 struct ubik_trans *tt;
1275 code = ReadPreamble(&tt);
1279 code = GetMax(tt, uid, gid);
1280 if (code != PRSUCCESS)
1281 ABORT_WITH(tt, code);
1283 code = ubik_EndTrans(tt);
1290 SPR_SetMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag)
1293 afs_int32 cid = ANONYMOUSID;
1295 code = setMax(call, aid, gflag, &cid);
1296 osi_auditU(call, PTS_SetMaxEvent, code, AUD_ID, aid, AUD_LONG, gflag,
1298 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d\n", code, cid, aid, gflag));
1303 setMax(struct rx_call *call, afs_int32 aid, afs_int32 gflag, afs_int32 *cid)
1306 struct ubik_trans *tt;
1308 code = WritePreamble(&tt);
1312 code = WhoIsThis(call, tt, cid);
1314 ABORT_WITH(tt, PRPERM);
1315 if (!AccessOK(tt, *cid, 0, 0, 0))
1316 ABORT_WITH(tt, PRPERM);
1317 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1318 ABORT_WITH(tt, PRBADARG);
1320 code = SetMax(tt, aid, gflag);
1321 if (code != PRSUCCESS)
1322 ABORT_WITH(tt, code);
1324 code = ubik_EndTrans(tt);
1331 SPR_ListEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry)
1334 afs_int32 cid = ANONYMOUSID;
1336 code = listEntry(call, aid, aentry, &cid);
1337 osi_auditU(call, PTS_LstEntEvent, code, AUD_ID, aid, AUD_END);
1338 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d\n", code, cid, aid));
1343 listEntry(struct rx_call *call, afs_int32 aid, struct prcheckentry *aentry,
1347 struct ubik_trans *tt;
1349 struct prentry tentry;
1351 code = ReadPreamble(&tt);
1355 code = WhoIsThis(call, tt, cid);
1357 ABORT_WITH(tt, PRPERM);
1358 temp = FindByID(tt, aid);
1360 ABORT_WITH(tt, PRNOENT);
1361 code = pr_ReadEntry(tt, 0, temp, &tentry);
1363 ABORT_WITH(tt, code);
1364 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1365 ABORT_WITH(tt, PRPERM);
1367 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1368 if (aentry->flags == 0) {
1369 if (tentry.flags & PRGRP)
1370 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1372 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1374 aentry->owner = tentry.owner;
1375 aentry->id = tentry.id;
1376 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1377 aentry->creator = tentry.creator;
1378 aentry->ngroups = tentry.ngroups;
1379 aentry->nusers = tentry.nusers;
1380 aentry->count = tentry.count;
1381 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1382 code = ubik_EndTrans(tt);
1389 SPR_ListEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
1390 prentries *bulkentries, afs_int32 *nextstartindex)
1393 afs_int32 cid = ANONYMOUSID;
1395 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1396 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1397 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d\n", code, cid, flag));
1402 listEntries(struct rx_call *call, afs_int32 flag, afs_int32 startindex,
1403 prentries *bulkentries, afs_int32 *nextstartindex, afs_int32 *cid)
1406 struct ubik_trans *tt;
1407 afs_int32 i, eof, pos, maxentries, f;
1408 struct prentry tentry;
1409 afs_int32 pollcount = 0;
1411 *nextstartindex = -1;
1412 bulkentries->prentries_val = 0;
1413 bulkentries->prentries_len = 0;
1415 code = ReadPreamble(&tt);
1419 /* Make sure we are an authenticated caller and that we are on the
1422 code = WhoIsThis(call, tt, cid);
1424 ABORT_WITH(tt, PRPERM);
1425 code = IsAMemberOf(tt, *cid, SYSADMINID);
1426 if (!code && !pr_noAuth)
1427 ABORT_WITH(tt, PRPERM);
1429 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1430 maxentries = eof / sizeof(struct prentry);
1431 for (i = startindex; i < maxentries; i++) {
1432 pos = i * sizeof(struct prentry) + sizeof(cheader);
1433 code = pr_ReadEntry(tt, 0, pos, &tentry);
1437 if (++pollcount > 50) {
1438 #ifndef AFS_PTHREAD_ENV
1444 f = (tentry.flags & PRTYPE);
1445 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1446 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1447 code = put_prentries(&tentry, bulkentries);
1449 break; /* Filled return array */
1456 *nextstartindex = i;
1460 if (bulkentries->prentries_val)
1461 free(bulkentries->prentries_val);
1462 bulkentries->prentries_val = 0;
1463 bulkentries->prentries_len = 0;
1464 ABORT_WITH(tt, code);
1466 code = ubik_EndTrans(tt);
1473 #define PR_MAXENTRIES 500
1475 put_prentries(struct prentry *tentry, prentries *bulkentries)
1477 struct prlistentries *entry;
1479 if (bulkentries->prentries_val == 0) {
1480 bulkentries->prentries_len = 0;
1481 bulkentries->prentries_val = malloc(PR_MAXENTRIES *
1482 sizeof(struct prlistentries));
1483 if (!bulkentries->prentries_val) {
1488 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1492 entry = bulkentries->prentries_val;
1493 entry += bulkentries->prentries_len;
1495 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1496 if (entry->flags == 0) {
1499 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1502 entry->owner = tentry->owner;
1503 entry->id = tentry->id;
1504 entry->creator = tentry->creator;
1505 entry->ngroups = tentry->ngroups;
1506 entry->nusers = tentry->nusers;
1507 entry->count = tentry->count;
1508 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1509 memset(entry->reserved, 0, sizeof(entry->reserved));
1510 bulkentries->prentries_len++;
1515 SPR_ChangeEntry(struct rx_call *call, afs_int32 aid, char *name, afs_int32 oid,
1519 afs_int32 cid = ANONYMOUSID;
1521 code = changeEntry(call, aid, name, oid, newid, &cid);
1522 osi_auditU(call, PTS_ChgEntEvent, code, AUD_ID, aid, AUD_STR, name,
1523 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1524 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d\n", code, cid, aid, name, oid, newid));
1529 changeEntry(struct rx_call *call, afs_int32 aid, char *name, afs_int32 oid,
1530 afs_int32 newid, afs_int32 *cid)
1533 struct ubik_trans *tt;
1540 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1541 || aid == SYSADMINID)
1544 code = WritePreamble(&tt);
1548 code = WhoIsThis(call, tt, cid);
1550 ABORT_WITH(tt, PRPERM);
1551 pos = FindByID(tt, aid);
1553 ABORT_WITH(tt, PRNOENT);
1554 /* protection check in changeentry */
1555 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1556 if (code != PRSUCCESS)
1557 ABORT_WITH(tt, code);
1559 code = ubik_EndTrans(tt);
1564 SPR_SetFieldsEntry(struct rx_call *call,
1566 afs_int32 mask, /* specify which fields to update */
1567 afs_int32 flags, afs_int32 ngroups, afs_int32 nusers,
1568 afs_int32 spare1, afs_int32 spare2)
1571 afs_int32 cid = ANONYMOUSID;
1574 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1576 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_ID, id, AUD_END);
1577 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d\n", code, cid, id));
1582 setFieldsEntry(struct rx_call *call,
1584 afs_int32 mask, /* specify which fields to update */
1585 afs_int32 flags, afs_int32 ngroups, afs_int32 nusers,
1586 afs_int32 spare1, afs_int32 spare2, afs_int32 *cid)
1589 struct ubik_trans *tt;
1591 struct prentry tentry;
1595 return 0; /* no-op */
1597 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1600 code = WritePreamble(&tt);
1604 code = WhoIsThis(call, tt, cid);
1606 ABORT_WITH(tt, PRPERM);
1607 pos = FindByID(tt, id);
1609 ABORT_WITH(tt, PRNOENT);
1610 code = pr_ReadEntry(tt, 0, pos, &tentry);
1612 ABORT_WITH(tt, code);
1613 tflags = tentry.flags;
1615 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1616 if (!AccessOK(tt, *cid, 0, 0, 0))
1617 ABORT_WITH(tt, PRPERM);
1618 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1619 tentry.ngroups = tentry.nusers = 20;
1622 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1623 ABORT_WITH(tt, PRPERM);
1626 if (mask & 0xffff) { /* if setting flag bits */
1627 afs_int32 flagsMask = mask & 0xffff;
1628 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1629 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1633 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1635 ABORT_WITH(tt, PRBADARG);
1636 tentry.ngroups = ngroups;
1640 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1642 ABORT_WITH(tt, PRBADARG);
1643 tentry.nusers = nusers;
1646 tentry.flags = tflags;
1648 code = pr_WriteEntry(tt, 0, pos, &tentry);
1650 ABORT_WITH(tt, code);
1652 code = ubik_EndTrans(tt);
1657 SPR_ListElements(struct rx_call *call, afs_int32 aid, prlist *alist,
1661 afs_int32 cid = ANONYMOUSID;
1663 code = listElements(call, aid, alist, over, &cid);
1664 osi_auditU(call, PTS_LstEleEvent, code, AUD_ID, aid, AUD_END);
1665 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d\n", code, cid, aid));
1670 listElements(struct rx_call *call, afs_int32 aid, prlist *alist,
1671 afs_int32 *over, afs_int32 *cid)
1674 struct ubik_trans *tt;
1676 struct prentry tentry;
1679 alist->prlist_len = 0;
1680 alist->prlist_val = NULL;
1682 code = ReadPreamble(&tt);
1686 code = WhoIsThis(call, tt, cid);
1688 ABORT_WITH(tt, PRPERM);
1690 temp = FindByID(tt, aid);
1692 ABORT_WITH(tt, PRNOENT);
1693 code = pr_ReadEntry(tt, 0, temp, &tentry);
1695 ABORT_WITH(tt, code);
1696 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1697 ABORT_WITH(tt, PRPERM);
1699 code = GetList(tt, &tentry, alist, 0);
1700 if (code != PRSUCCESS)
1701 ABORT_WITH(tt, code);
1703 code = ubik_EndTrans(tt);
1709 SPR_ListSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
1712 #if defined(SUPERGROUPS)
1714 afs_int32 cid = ANONYMOUSID;
1716 code = listSuperGroups(call, aid, alist, over, &cid);
1717 osi_auditU(call, PTS_LstSGrps, code, AUD_ID, aid, AUD_END);
1718 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d\n", code, cid, aid));
1721 return RXGEN_OPCODE;
1725 #if defined(SUPERGROUPS)
1727 listSuperGroups(struct rx_call *call, afs_int32 aid, prlist *alist,
1728 afs_int32 *over, afs_int32 *cid)
1731 struct ubik_trans *tt;
1733 struct prentry tentry;
1735 alist->prlist_len = 0;
1736 alist->prlist_val = (afs_int32 *) 0;
1738 code = ReadPreamble(&tt);
1742 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1744 ABORT_WITH(tt, code);
1745 code = WhoIsThis(call, tt, cid);
1747 ABORT_WITH(tt, PRPERM);
1749 temp = FindByID(tt, aid);
1751 ABORT_WITH(tt, PRNOENT);
1752 code = pr_ReadEntry(tt, 0, temp, &tentry);
1754 ABORT_WITH(tt, code);
1755 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1756 ABORT_WITH(tt, PRPERM);
1758 code = GetSGList(tt, &tentry, alist);
1760 if (code == PRTOOMANY)
1762 else if (code != PRSUCCESS)
1763 ABORT_WITH(tt, code);
1765 code = ubik_EndTrans(tt);
1770 #endif /* SUPERGROUPS */
1774 * List the entries owned by this id. If the id is zero,
1775 * return the orphans list. This will return up to PR_MAXGROUPS
1776 * at a time with the lastP available to get the rest. The
1777 * maximum value is enforced in GetOwnedChain().
1780 SPR_ListOwned(struct rx_call *call, afs_int32 aid, prlist *alist,
1784 afs_int32 cid = ANONYMOUSID;
1786 code = listOwned(call, aid, alist, lastP, &cid);
1787 osi_auditU(call, PTS_LstOwnEvent, code, AUD_ID, aid, AUD_END);
1788 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d\n", code, cid, aid));
1793 listOwned(struct rx_call *call, afs_int32 aid, prlist *alist, afs_int32 *lastP,
1797 struct ubik_trans *tt;
1798 struct prentry tentry;
1802 alist->prlist_len = 0;
1803 alist->prlist_val = NULL;
1810 code = ReadPreamble(&tt);
1814 code = WhoIsThis(call, tt, cid);
1816 ABORT_WITH(tt, PRPERM);
1819 code = pr_ReadEntry(tt, 0, start, &tentry);
1820 if (!code && (tentry.owner == aid))
1821 head = start; /* pick up where we left off */
1826 afs_int32 loc = FindByID(tt, aid);
1828 ABORT_WITH(tt, PRNOENT);
1829 code = pr_ReadEntry(tt, 0, loc, &tentry);
1831 ABORT_WITH(tt, code);
1833 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
1834 ABORT_WITH(tt, PRPERM);
1835 head = tentry.owned;
1837 if (!AccessOK(tt, *cid, 0, 0, 0))
1838 ABORT_WITH(tt, PRPERM);
1839 head = ntohl(cheader.orphan);
1843 code = GetOwnedChain(tt, &head, alist);
1845 if (code == PRTOOMANY)
1848 ABORT_WITH(tt, code);
1851 code = ubik_EndTrans(tt);
1856 SPR_IsAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid,
1860 afs_int32 cid = ANONYMOUSID;
1862 code = isAMemberOf(call, uid, gid, flag, &cid);
1863 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
1865 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d\n", code, cid, uid, gid));
1870 isAMemberOf(struct rx_call *call, afs_int32 uid, afs_int32 gid, afs_int32 *flag,
1874 struct ubik_trans *tt;
1876 code = ReadPreamble(&tt);
1881 afs_int32 uloc = FindByID(tt, uid);
1882 afs_int32 gloc = FindByID(tt, gid);
1883 struct prentry uentry, gentry;
1886 ABORT_WITH(tt, PRNOENT);
1887 code = WhoIsThis(call, tt, cid);
1889 ABORT_WITH(tt, PRPERM);
1890 code = pr_ReadEntry(tt, 0, uloc, &uentry);
1892 ABORT_WITH(tt, code);
1893 code = pr_ReadEntry(tt, 0, gloc, &gentry);
1895 ABORT_WITH(tt, code);
1896 #if !defined(SUPERGROUPS)
1897 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
1898 ABORT_WITH(tt, PRBADARG);
1900 if (!(gentry.flags & PRGRP))
1901 ABORT_WITH(tt, PRBADARG);
1903 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
1904 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1905 ABORT_WITH(tt, PRPERM);
1908 *flag = IsAMemberOf(tt, uid, gid);
1909 code = ubik_EndTrans(tt);
1914 addWildCards(struct ubik_trans *tt, prlist *alist, afs_uint32 host)
1917 struct prentry tentry;
1919 unsigned wild = htonl(0xffffff00);
1920 struct in_addr iaddr;
1922 int size = 0, i, code;
1926 while ((host = (host & wild))) {
1927 wild = htonl(ntohl(wild) << 8);
1928 iaddr.s_addr = host;
1929 code = NameToID(tt, afs_inet_ntoa_r(iaddr.s_addr, hoststr), &hostid);
1930 if (code == PRSUCCESS && hostid != 0) {
1931 temp = FindByID(tt, hostid);
1933 code = pr_ReadEntry(tt, 0, temp, &tentry);
1934 if (code != PRSUCCESS)
1940 wlist.prlist_len = 0;
1941 wlist.prlist_val = NULL;
1943 code = GetList(tt, &tentry, &wlist, 0);
1946 added += wlist.prlist_len;
1947 for (i = 0; i < wlist.prlist_len; i++) {
1948 if (!inCPS(*alist, wlist.prlist_val[i]))
1949 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
1950 free(wlist.prlist_val);
1954 if (wlist.prlist_val)
1955 free(wlist.prlist_val);
1958 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
1963 WhoIsThisWithName(struct rx_call *acall, struct ubik_trans *at, afs_int32 *aid,
1966 afs_int32 islocal = 1;
1967 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
1968 /* returns -1 and sets aid to ANONYMOUSID on any failure */
1969 struct rx_connection *tconn;
1971 char tcell[MAXKTCREALMLEN];
1972 char name[MAXKTCNAMELEN];
1973 char inst[MAXKTCNAMELEN];
1978 tconn = rx_ConnectionOf(acall);
1979 code = rx_SecurityClassOf(tconn);
1982 else if (code == 1) { /* vab class */
1983 goto done; /* no longer supported */
1984 } else if (code == 2) { /* kad class */
1985 if ((code = rxkad_GetServerInfo(rx_ConnectionOf(acall), NULL, NULL,
1986 name, inst, tcell, NULL)))
1990 code = afsconf_IsLocalRealmMatch(prdir, &islocal, name, inst, tcell);
1994 strncpy(vname, name, sizeof(vname));
1995 if ((ilen = strlen(inst))) {
1996 if (strlen(vname) + 1 + ilen >= sizeof(vname))
1999 strcat(vname, inst);
2002 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
2005 strcat(vname, tcell);
2006 lcstring(vname, vname, sizeof(vname));
2007 NameToID(at, vname, aid);
2009 strcpy(aname, vname);
2013 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2014 *aid = SYSADMINID; /* special case for the fileserver */
2016 lcstring(vname, vname, sizeof(vname));
2017 code = NameToID(at, vname, aid);
2021 if (code && !pr_noAuth)