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>
69 #include <netinet/in.h>
80 #include "afs/audit.h"
82 #ifdef AFS_ATHENA_STDENV
87 #define IP_WILDCARDS 1 /* XXX Should be defined outside of here XXX */
89 extern int restricted;
90 extern struct ubik_dbase *dbase;
91 extern afs_int32 Initdb();
93 extern afs_int32 initd;
94 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(),
95 nameToID(), Delete(), removeFromGroup();
96 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
97 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
98 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
100 #if defined(SUPERGROUPS)
101 afs_int32 listSuperGroups();
107 extern int prp_group_default;
108 extern int prp_user_default;
110 /* When abort, reset initd so that the header is read in on next call.
111 * Abort the transaction and return the code.
113 #define ABORT_WITH(tt,code) return(initd=0,ubik_AbortTrans(tt),code)
116 CreateOK(ut, cid, oid, flag, admin)
117 struct ubik_trans *ut;
118 afs_int32 cid; /* id of caller */
119 afs_int32 oid; /* id of owner */
120 afs_int32 flag; /* indicates type of entry */
121 int admin; /* sysadmin membership */
123 if (restricted && !admin)
126 if (flag & PRFOREIGN) {
127 /* Foreign users are recognized by the '@' sign and
128 * not by the PRFOREIGN flag.
131 } else if (flag & PRGRP) {
132 /* Allow anonymous group creation only if owner specified
133 * and running noAuth.
135 if (cid == ANONYMOUSID) {
136 if ((oid == 0) || !pr_noAuth)
139 } else { /* creating a user */
140 if (!admin && !pr_noAuth)
147 WhoIsThis(acall, at, aid)
148 struct rx_call *acall;
149 struct ubik_trans *at;
153 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
154 /* returns -1 and sets aid to ANONYMOUSID on any failure */
155 register struct rx_connection *tconn;
156 register afs_int32 code;
157 char tcell[MAXKTCREALMLEN];
158 char name[MAXKTCNAMELEN];
159 char inst[MAXKTCNAMELEN];
164 tconn = rx_ConnectionOf(acall);
165 code = rx_SecurityClassOf(tconn);
168 else if (code == 1) { /* vab class */
169 goto done; /* no longer supported */
170 } else if (code == 2) { /* kad class */
171 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
172 name, inst, tcell, NULL)))
175 /* This test is unnecessary, since rxkad_GetServerInfo already check.
176 * In addition, this is wrong since exp must be unsigned. */
177 if (exp < FT_ApproxTime())
181 extern char *pr_realmName;
182 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
183 static char local_realm[AFS_REALM_SZ] = "";
184 if (!local_realm[0]) {
185 if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
186 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
190 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
191 strcasecmp(local_realm, tcell) &&
193 strcasecmp(pr_realmName, tcell))
196 strncpy(vname, name, sizeof(vname));
197 if (ilen = strlen(inst)) {
198 if (strlen(vname) + 1 + ilen >= sizeof(vname))
204 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
207 strcat(vname, tcell);
209 if (strcmp(AUTH_SUPERUSER, vname) == 0)
210 *aid = SYSADMINID; /* special case for the fileserver */
212 lcstring(vname, vname, sizeof(vname));
213 code = NameToID(at, vname, aid);
217 if (code && !pr_noAuth)
223 SPR_INewEntry(call, aname, aid, oid)
224 struct rx_call *call;
225 char aname[PR_MAXNAMELEN];
231 code = iNewEntry(call, aname, aid, oid);
232 osi_auditU(call, PTS_INewEntEvent, code, AUD_LONG, aid, AUD_STR, aname,
233 AUD_LONG, oid, AUD_END);
238 iNewEntry(call, aname, aid, oid)
239 struct rx_call *call;
240 char aname[PR_MAXNAMELEN];
244 /* used primarily for conversion - not intended to be used as usual means
245 * of entering people into the database. */
246 struct ubik_trans *tt;
247 register afs_int32 code;
254 if (code != PRSUCCESS)
256 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
259 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
261 ABORT_WITH(tt, code);
262 code = read_DbHeader(tt);
264 ABORT_WITH(tt, code);
266 code = WhoIsThis(call, tt, &cid);
268 ABORT_WITH(tt, PRPERM);
269 admin = IsAMemberOf(tt, cid, SYSADMINID);
271 /* first verify the id is good */
273 ABORT_WITH(tt, PRPERM);
276 /* only sysadmin can reuse a group id */
277 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
278 ABORT_WITH(tt, PRPERM);
280 if (FindByID(tt, aid))
281 ABORT_WITH(tt, PRIDEXIST);
283 /* check a few other things */
284 if (!CreateOK(tt, cid, oid, gflag, admin))
285 ABORT_WITH(tt, PRPERM);
287 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, cid);
288 if (code != PRSUCCESS)
289 ABORT_WITH(tt, code);
291 /* finally, commit transaction */
292 code = ubik_EndTrans(tt);
300 SPR_NewEntry(call, aname, flag, oid, aid)
301 struct rx_call *call;
302 char aname[PR_MAXNAMELEN];
309 code = newEntry(call, aname, flag, oid, aid);
310 osi_auditU(call, PTS_NewEntEvent, code, AUD_LONG, *aid, AUD_STR, aname,
311 AUD_LONG, oid, AUD_END);
316 newEntry(call, aname, flag, oid, aid)
317 struct rx_call *call;
318 char aname[PR_MAXNAMELEN];
323 register afs_int32 code;
324 struct ubik_trans *tt;
327 extern afs_int32 WhoIsThisWithName();
328 char cname[PR_MAXNAMELEN];
333 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
336 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
338 ABORT_WITH(tt, code);
339 code = read_DbHeader(tt);
341 ABORT_WITH(tt, code);
343 /* this is for cross-cell self registration. It is not added in the
344 * SPR_INewEntry because we want self-registration to only do
345 * automatic id assignment.
347 code = WhoIsThisWithName(call, tt, &cid, cname);
348 if (code != 2) { /* 2 specifies that this is a foreign cell request */
350 ABORT_WITH(tt, PRPERM);
351 admin = IsAMemberOf(tt, cid, SYSADMINID);
353 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, cid, SYSADMINID);
354 oid = cid = SYSADMINID;
356 if (!CreateOK(tt, cid, oid, flag, admin))
357 ABORT_WITH(tt, PRPERM);
359 code = CreateEntry(tt, aname, aid, 0, flag, oid, cid);
360 if (code != PRSUCCESS)
361 ABORT_WITH(tt, code);
363 code = ubik_EndTrans(tt);
372 SPR_WhereIsIt(call, aid, apos)
373 struct rx_call *call;
379 code = whereIsIt(call, aid, apos);
380 osi_auditU(call, PTS_WheIsItEvent, code, AUD_LONG, aid, AUD_LONG, *apos,
386 whereIsIt(call, aid, apos)
387 struct rx_call *call;
391 register afs_int32 code;
392 struct ubik_trans *tt;
396 if (code != PRSUCCESS)
398 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
401 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
403 ABORT_WITH(tt, code);
404 code = read_DbHeader(tt);
406 ABORT_WITH(tt, code);
408 temp = FindByID(tt, aid);
410 ABORT_WITH(tt, PRNOENT);
412 code = ubik_EndTrans(tt);
420 SPR_DumpEntry(call, apos, aentry)
421 struct rx_call *call;
423 struct prdebugentry *aentry;
427 code = dumpEntry(call, apos, aentry);
428 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
433 dumpEntry(call, apos, aentry)
434 struct rx_call *call;
436 struct prdebugentry *aentry;
438 register afs_int32 code;
440 struct ubik_trans *tt;
443 if (code != PRSUCCESS)
445 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
448 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
450 ABORT_WITH(tt, code);
451 code = read_DbHeader(tt);
453 ABORT_WITH(tt, code);
455 code = WhoIsThis(call, tt, &cid);
457 ABORT_WITH(tt, PRPERM);
458 code = pr_ReadEntry(tt, 0, apos, aentry);
460 ABORT_WITH(tt, code);
462 if (!AccessOK(tt, cid, 0, PRP_STATUS_MEM, 0))
463 ABORT_WITH(tt, PRPERM);
465 /* Since prdebugentry is in the form of a prentry not a coentry, we will
466 * return the coentry slots in network order where the string is. */
468 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
469 code = pr_ReadCoEntry(tt, 0, apos, aentry);
471 ABORT_WITH(tt, code);
474 code = ubik_EndTrans(tt);
481 SPR_AddToGroup(call, aid, gid)
482 struct rx_call *call;
488 code = addToGroup(call, aid, gid);
489 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid,
495 addToGroup(call, aid, gid)
496 struct rx_call *call;
500 register afs_int32 code;
501 struct ubik_trans *tt;
504 struct prentry tentry;
505 struct prentry uentry;
509 if (code != PRSUCCESS)
511 if (gid == ANYUSERID || gid == AUTHUSERID)
513 if (aid == ANONYMOUSID)
515 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
518 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
520 ABORT_WITH(tt, code);
521 code = read_DbHeader(tt);
523 ABORT_WITH(tt, code);
525 code = WhoIsThis(call, tt, &cid);
527 ABORT_WITH(tt, PRPERM);
528 tempu = FindByID(tt, aid);
530 ABORT_WITH(tt, PRNOENT);
531 memset(&uentry, 0, sizeof(uentry));
532 code = pr_ReadEntry(tt, 0, tempu, &uentry);
534 ABORT_WITH(tt, code);
536 #if !defined(SUPERGROUPS)
537 /* we don't allow groups as members of groups at present */
538 if (uentry.flags & PRGRP)
539 ABORT_WITH(tt, PRNOTUSER);
542 tempg = FindByID(tt, gid);
544 ABORT_WITH(tt, PRNOENT);
545 code = pr_ReadEntry(tt, 0, tempg, &tentry);
547 ABORT_WITH(tt, code);
548 /* make sure that this is a group */
549 if (!(tentry.flags & PRGRP))
550 ABORT_WITH(tt, PRNOTGROUP);
551 if (!AccessOK(tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
552 ABORT_WITH(tt, PRPERM);
554 code = AddToEntry(tt, &tentry, tempg, aid);
555 if (code != PRSUCCESS)
556 ABORT_WITH(tt, code);
558 #if defined(SUPERGROUPS)
559 if (uentry.flags & PRGRP)
560 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
563 /* now, modify the user's entry as well */
564 code = AddToEntry(tt, &uentry, tempu, gid);
565 if (code != PRSUCCESS)
566 ABORT_WITH(tt, code);
567 code = ubik_EndTrans(tt);
574 SPR_NameToID(call, aname, aid)
575 struct rx_call *call;
581 code = nameToID(call, aname, aid);
582 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
587 nameToID(call, aname, aid)
588 struct rx_call *call;
592 register afs_int32 code;
593 struct ubik_trans *tt;
598 /* Initialize return struct */
600 aid->idlist_val = NULL;
602 size = aname->namelist_len;
608 aid->idlist_val = (afs_int32 *) malloc(size * sizeof(afs_int32));
609 if (!aid->idlist_val)
613 if (code != PRSUCCESS)
615 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
618 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
620 ABORT_WITH(tt, code);
621 code = read_DbHeader(tt);
623 ABORT_WITH(tt, code);
625 for (i = 0; i < aname->namelist_len; i++) {
626 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
627 if (code != PRSUCCESS)
628 aid->idlist_val[i] = ANONYMOUSID;
630 IOMGR_Poll(), count = 0;
632 aid->idlist_len = aname->namelist_len;
634 code = ubik_EndTrans(tt);
642 * Given an array of ids, find the name for each of them.
643 * The array of ids and names is unlimited.
646 SPR_IDToName(call, aid, aname)
647 struct rx_call *call;
653 code = idToName(call, aid, aname);
654 osi_auditU(call, PTS_IdToNmEvent, code, AUD_LONG, aid, AUD_END);
659 idToName(call, aid, aname)
660 struct rx_call *call;
664 register afs_int32 code;
665 struct ubik_trans *tt;
670 /* leave this first for rpc stub */
671 size = aid->idlist_len;
676 aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
677 aname->namelist_len = 0;
678 if (aname->namelist_val == 0)
680 if (aid->idlist_len == 0)
683 return PRTOOMANY; /* rxgen will probably handle this */
686 if (code != PRSUCCESS)
688 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
691 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
693 ABORT_WITH(tt, code);
694 code = read_DbHeader(tt);
696 ABORT_WITH(tt, code);
698 for (i = 0; i < aid->idlist_len; i++) {
699 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
700 if (code != PRSUCCESS)
701 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
703 IOMGR_Poll(), count = 0;
705 aname->namelist_len = aid->idlist_len;
707 code = ubik_EndTrans(tt);
714 SPR_Delete(call, aid)
715 struct rx_call *call;
720 code = Delete(call, aid);
721 osi_auditU(call, PTS_DelEvent, code, AUD_LONG, aid, AUD_END);
727 struct rx_call *call;
730 register afs_int32 code;
731 struct ubik_trans *tt;
733 struct prentry tentry;
740 if (code != PRSUCCESS)
742 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
743 || aid == ANONYMOUSID)
745 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
748 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
750 ABORT_WITH(tt, code);
751 code = read_DbHeader(tt);
753 ABORT_WITH(tt, code);
755 code = WhoIsThis(call, tt, &cid);
757 ABORT_WITH(tt, PRPERM);
759 /* Read in entry to be deleted */
760 loc = FindByID(tt, aid);
762 ABORT_WITH(tt, PRNOENT);
763 code = pr_ReadEntry(tt, 0, loc, &tentry);
765 ABORT_WITH(tt, PRDBFAIL);
767 /* Do some access checking */
768 if (tentry.owner != cid && !IsAMemberOf(tt, cid, SYSADMINID)
769 && !IsAMemberOf(tt, cid, tentry.owner) && !pr_noAuth)
770 ABORT_WITH(tt, PRPERM);
772 /* Delete each continuation block as a separate transaction so that no one
773 * transaction become to large to complete. */
775 while (nptr != (afs_int32) NULL) {
776 struct contentry centry;
779 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
781 ABORT_WITH(tt, PRDBFAIL);
782 for (i = 0; i < COSIZE; i++) {
783 if (centry.entries[i] == PRBADID)
785 if (centry.entries[i] == 0)
787 #if defined(SUPERGROUPS)
788 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
789 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
792 code = RemoveFromEntry(tt, aid, centry.entries[i]);
794 ABORT_WITH(tt, code);
795 tentry.count--; /* maintain count */
799 tentry.next = centry.next; /* thread out this block */
800 code = FreeBlock(tt, nptr); /* free continuation block */
802 ABORT_WITH(tt, code);
803 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
805 ABORT_WITH(tt, code);
807 /* end this trans and start a new one */
808 code = ubik_EndTrans(tt);
811 IOMGR_Poll(); /* just to keep the connection alive */
812 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
815 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
817 ABORT_WITH(tt, code);
819 /* re-read entry to get consistent uptodate info */
820 loc = FindByID(tt, aid);
822 ABORT_WITH(tt, PRNOENT);
823 code = pr_ReadEntry(tt, 0, loc, &tentry);
825 ABORT_WITH(tt, PRDBFAIL);
830 #if defined(SUPERGROUPS)
831 /* Delete each continuation block as a separate transaction
832 * so that no one transaction become too large to complete. */
834 struct prentryg *tentryg = (struct prentryg *)&tentry;
835 nptr = tentryg->nextsg;
836 while (nptr != NULL) {
837 struct contentry centry;
840 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
842 ABORT_WITH(tt, PRDBFAIL);
843 for (i = 0; i < COSIZE; i++) {
844 if (centry.entries[i] == PRBADID)
846 if (centry.entries[i] == 0)
848 code = RemoveFromEntry(tt, aid, centry.entries[i]);
850 ABORT_WITH(tt, code);
851 tentryg->countsg--; /* maintain count */
855 tentryg->nextsg = centry.next; /* thread out this block */
856 code = FreeBlock(tt, nptr); /* free continuation block */
858 ABORT_WITH(tt, code);
859 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
861 ABORT_WITH(tt, code);
863 /* end this trans and start a new one */
864 code = ubik_EndTrans(tt);
867 IOMGR_Poll(); /* just to keep the connection alive */
869 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
872 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
874 ABORT_WITH(tt, code);
876 /* re-read entry to get consistent uptodate info */
877 loc = FindByID(tt, aid);
879 ABORT_WITH(tt, PRNOENT);
880 code = pr_ReadEntry(tt, 0, loc, &tentry);
882 ABORT_WITH(tt, PRDBFAIL);
884 nptr = tentryg->nextsg;
888 #endif /* SUPERGROUPS */
890 /* Then move the owned chain, except possibly ourself to the orphan list.
891 * Because this list can be very long and so exceed the size of a ubik
892 * transaction, we start a new transaction every 50 entries. */
895 while (nptr != (afs_int32) NULL) {
896 struct prentry nentry;
898 code = pr_ReadEntry(tt, 0, nptr, &nentry);
900 ABORT_WITH(tt, PRDBFAIL);
901 nptr = tentry.owned = nentry.nextOwned; /* thread out */
903 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
904 code = AddToOrphan(tt, nentry.id);
906 ABORT_WITH(tt, code);
908 if ((count & 3) == 0)
913 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
915 ABORT_WITH(tt, code);
917 /* end this trans and start a new one */
918 code = ubik_EndTrans(tt);
921 IOMGR_Poll(); /* just to keep the connection alive */
922 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
925 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
927 ABORT_WITH(tt, code);
929 /* re-read entry to get consistent uptodate info */
930 loc = FindByID(tt, aid);
932 ABORT_WITH(tt, PRNOENT);
933 code = pr_ReadEntry(tt, 0, loc, &tentry);
935 ABORT_WITH(tt, PRDBFAIL);
940 /* now do what's left of the deletion stuff */
941 code = DeleteEntry(tt, &tentry, loc);
942 if (code != PRSUCCESS)
943 ABORT_WITH(tt, code);
945 code = ubik_EndTrans(tt);
952 SPR_UpdateEntry(call, aid, name, uentry)
953 struct rx_call *call;
956 struct PrUpdateEntry *uentry;
958 register afs_int32 code;
959 struct ubik_trans *tt;
961 struct prentry tentry;
968 if (code != PRSUCCESS)
972 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
973 || aid == ANONYMOUSID)
976 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
979 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
981 ABORT_WITH(tt, code);
982 code = read_DbHeader(tt);
984 ABORT_WITH(tt, code);
986 code = WhoIsThis(call, tt, &cid);
988 ABORT_WITH(tt, PRPERM);
989 code = IsAMemberOf(tt, cid, SYSADMINID);
990 if (!code && !pr_noAuth)
991 ABORT_WITH(tt, PRPERM);
993 /* Read in entry to be deleted */
995 loc = FindByID(tt, aid);
997 loc = FindByName(tt, name, &tentry);
1000 ABORT_WITH(tt, PRNOENT);
1001 code = pr_ReadEntry(tt, 0, loc, &tentry);
1003 ABORT_WITH(tt, PRDBFAIL);
1005 if (uentry->Mask & PRUPDATE_NAMEHASH) {
1007 code = RemoveFromNameHash(tt, tentry.name, &tloc);
1008 if (code != PRSUCCESS)
1009 ABORT_WITH(tt, PRDBFAIL);
1010 code = AddToNameHash(tt, tentry.name, loc);
1012 ABORT_WITH(tt, code);
1015 if (uentry->Mask & PRUPDATE_IDHASH) {
1019 code = RemoveFromIDHash(tt, id, &tloc);
1020 if (code != PRSUCCESS)
1021 ABORT_WITH(tt, PRDBFAIL);
1022 code = AddToIDHash(tt, id, loc);
1024 ABORT_WITH(tt, code);
1027 code = ubik_EndTrans(tt);
1034 SPR_RemoveFromGroup(call, aid, gid)
1035 struct rx_call *call;
1041 code = removeFromGroup(call, aid, gid);
1042 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid,
1048 removeFromGroup(call, aid, gid)
1049 struct rx_call *call;
1053 register afs_int32 code;
1054 struct ubik_trans *tt;
1057 struct prentry uentry;
1058 struct prentry gentry;
1062 if (code != PRSUCCESS)
1064 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1067 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1069 ABORT_WITH(tt, code);
1070 code = read_DbHeader(tt);
1072 ABORT_WITH(tt, code);
1074 code = WhoIsThis(call, tt, &cid);
1076 ABORT_WITH(tt, PRPERM);
1077 tempu = FindByID(tt, aid);
1079 ABORT_WITH(tt, PRNOENT);
1080 tempg = FindByID(tt, gid);
1082 ABORT_WITH(tt, PRNOENT);
1083 memset(&uentry, 0, sizeof(uentry));
1084 memset(&gentry, 0, sizeof(gentry));
1085 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1087 ABORT_WITH(tt, code);
1088 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1090 ABORT_WITH(tt, code);
1091 if (!(gentry.flags & PRGRP))
1092 ABORT_WITH(tt, PRNOTGROUP);
1093 #if !defined(SUPERGROUPS)
1094 if (uentry.flags & PRGRP)
1095 ABORT_WITH(tt, PRNOTUSER);
1097 if (!AccessOK(tt, cid, &gentry, PRP_REMOVE_MEM, 0))
1098 ABORT_WITH(tt, PRPERM);
1099 code = RemoveFromEntry(tt, aid, gid);
1100 if (code != PRSUCCESS)
1101 ABORT_WITH(tt, code);
1102 #if defined(SUPERGROUPS)
1103 if (!(uentry.flags & PRGRP))
1105 code = RemoveFromEntry(tt, gid, aid);
1106 #if defined(SUPERGROUPS)
1108 code = RemoveFromSGEntry(tt, gid, aid);
1110 if (code != PRSUCCESS)
1111 ABORT_WITH(tt, code);
1113 code = ubik_EndTrans(tt);
1121 SPR_GetCPS(call, aid, alist, over)
1122 struct rx_call *call;
1129 code = getCPS(call, aid, alist, over);
1130 osi_auditU(call, PTS_GetCPSEvent, code, AUD_LONG, aid, AUD_END);
1135 getCPS(call, aid, alist, over)
1136 struct rx_call *call;
1141 register afs_int32 code;
1142 struct ubik_trans *tt;
1145 struct prentry tentry;
1148 alist->prlist_len = 0;
1149 alist->prlist_val = NULL;
1151 if (code != PRSUCCESS)
1153 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1156 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1158 ABORT_WITH(tt, code);
1159 code = read_DbHeader(tt);
1161 ABORT_WITH(tt, code);
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);
1172 if (code || !AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1173 ABORT_WITH(tt, PRPERM);
1175 code = GetList(tt, &tentry, alist, 1);
1176 if (code != PRSUCCESS)
1177 ABORT_WITH(tt, code);
1179 code = ubik_EndTrans(tt);
1192 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1193 if (CPS.prlist_val[i] == id)
1198 #endif /* IP_WILDCARDS */
1202 SPR_GetCPS2(call, aid, ahost, alist, over)
1203 struct rx_call *call;
1211 code = getCPS2(call, aid, ahost, alist, over);
1212 osi_auditU(call, PTS_GetCPS2Event, code, AUD_LONG, aid, AUD_HOST, ahost,
1218 getCPS2(call, aid, ahost, alist, over)
1219 struct rx_call *call;
1225 register afs_int32 code;
1226 struct ubik_trans *tt;
1229 struct prentry tentry;
1230 struct prentry host_tentry;
1233 struct in_addr iaddr;
1235 extern afs_int32 addWildCards();
1236 #endif /* IP_WILDCARDS */
1239 iaddr.s_addr = ntohl(ahost);
1240 alist->prlist_len = 0;
1241 alist->prlist_val = NULL;
1243 if (code != PRSUCCESS)
1245 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1248 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1250 ABORT_WITH(tt, code);
1251 code = read_DbHeader(tt);
1253 ABORT_WITH(tt, code);
1255 if (aid != PRBADID) {
1256 temp = FindByID(tt, aid);
1258 ABORT_WITH(tt, PRNOENT);
1259 code = pr_ReadEntry(tt, 0, temp, &tentry);
1261 ABORT_WITH(tt, code);
1263 /* afs does authenticate now */
1264 code = WhoIsThis(call, tt, &cid);
1266 || !AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1267 ABORT_WITH(tt, PRPERM);
1269 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1270 if (code == PRSUCCESS && hostid != 0) {
1271 temp = FindByID(tt, hostid);
1273 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1274 if (code == PRSUCCESS)
1277 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1279 fprintf(stderr, "FindByID Failed -- Not found\n");
1282 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1284 code = GetList(tt, &tentry, alist, 1);
1287 code = addWildCards(tt, alist, ntohl(ahost));
1288 #endif /* IP_WILDCARDS */
1289 if (code != PRSUCCESS)
1290 ABORT_WITH(tt, code);
1292 code = ubik_EndTrans(tt);
1298 SPR_GetHostCPS(call, ahost, alist, over)
1299 struct rx_call *call;
1306 code = getHostCPS(call, ahost, alist, over);
1307 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
1312 getHostCPS(call, ahost, alist, over)
1313 struct rx_call *call;
1318 register afs_int32 code, temp;
1319 struct ubik_trans *tt;
1320 struct prentry host_tentry;
1322 struct in_addr iaddr;
1324 extern afs_int32 addWildCards();
1325 #endif /* IP_WILDCARDS */
1328 iaddr.s_addr = ntohl(ahost);
1329 alist->prlist_len = 0;
1330 alist->prlist_val = NULL;
1332 if (code != PRSUCCESS)
1334 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1337 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1339 ABORT_WITH(tt, code);
1340 code = read_DbHeader(tt);
1342 ABORT_WITH(tt, code);
1344 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1345 if (code == PRSUCCESS && hostid != 0) {
1346 temp = FindByID(tt, hostid);
1348 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1349 if (code == PRSUCCESS) {
1350 code = GetList(tt, &host_tentry, alist, 0);
1354 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1356 fprintf(stderr, "FindByID Failed -- Not found\n");
1359 code = addWildCards(tt, alist, ntohl(ahost));
1360 #endif /* IP_WILDCARDS */
1362 if (code != PRSUCCESS)
1363 ABORT_WITH(tt, code);
1365 code = ubik_EndTrans(tt);
1371 SPR_ListMax(call, uid, gid)
1372 struct rx_call *call;
1378 code = listMax(call, uid, gid);
1379 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1384 listMax(call, uid, gid)
1385 struct rx_call *call;
1389 register afs_int32 code;
1390 struct ubik_trans *tt;
1393 if (code != PRSUCCESS)
1395 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1398 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1400 ABORT_WITH(tt, code);
1401 code = read_DbHeader(tt);
1403 ABORT_WITH(tt, code);
1405 code = GetMax(tt, uid, gid);
1406 if (code != PRSUCCESS)
1407 ABORT_WITH(tt, code);
1409 code = ubik_EndTrans(tt);
1416 SPR_SetMax(call, aid, gflag)
1417 struct rx_call *call;
1423 code = setMax(call, aid, gflag);
1424 osi_auditU(call, PTS_SetMaxEvent, code, AUD_LONG, aid, AUD_LONG, gflag,
1430 setMax(call, aid, gflag)
1431 struct rx_call *call;
1435 register afs_int32 code;
1436 struct ubik_trans *tt;
1440 if (code != PRSUCCESS)
1442 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1445 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1447 ABORT_WITH(tt, code);
1448 code = read_DbHeader(tt);
1450 ABORT_WITH(tt, code);
1452 code = WhoIsThis(call, tt, &cid);
1454 ABORT_WITH(tt, PRPERM);
1455 if (!AccessOK(tt, cid, 0, 0, 0))
1456 ABORT_WITH(tt, PRPERM);
1457 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1458 ABORT_WITH(tt, PRBADARG);
1460 code = SetMax(tt, aid, gflag);
1461 if (code != PRSUCCESS)
1462 ABORT_WITH(tt, code);
1464 code = ubik_EndTrans(tt);
1471 SPR_ListEntry(call, aid, aentry)
1472 struct rx_call *call;
1474 struct prcheckentry *aentry;
1478 code = listEntry(call, aid, aentry);
1479 osi_auditU(call, PTS_LstEntEvent, code, AUD_LONG, aid, AUD_END);
1484 listEntry(call, aid, aentry)
1485 struct rx_call *call;
1487 struct prcheckentry *aentry;
1489 register afs_int32 code;
1490 struct ubik_trans *tt;
1493 struct prentry tentry;
1496 if (code != PRSUCCESS)
1498 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1501 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1503 ABORT_WITH(tt, code);
1504 code = read_DbHeader(tt);
1506 ABORT_WITH(tt, code);
1508 code = WhoIsThis(call, tt, &cid);
1510 ABORT_WITH(tt, PRPERM);
1511 temp = FindByID(tt, aid);
1513 ABORT_WITH(tt, PRNOENT);
1514 code = pr_ReadEntry(tt, 0, temp, &tentry);
1516 ABORT_WITH(tt, code);
1517 if (!AccessOK(tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1518 ABORT_WITH(tt, PRPERM);
1520 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1521 if (aentry->flags == 0) {
1522 if (tentry.flags & PRGRP)
1523 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1525 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1527 aentry->owner = tentry.owner;
1528 aentry->id = tentry.id;
1529 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1530 aentry->creator = tentry.creator;
1531 aentry->ngroups = tentry.ngroups;
1532 aentry->nusers = tentry.nusers;
1533 aentry->count = tentry.count;
1534 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1535 code = ubik_EndTrans(tt);
1542 SPR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1543 struct rx_call *call;
1545 afs_int32 startindex;
1546 prentries *bulkentries;
1547 afs_int32 *nextstartindex;
1551 code = listEntries(call, flag, startindex, bulkentries, nextstartindex);
1552 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1557 listEntries(call, flag, startindex, bulkentries, nextstartindex)
1558 struct rx_call *call;
1560 afs_int32 startindex;
1561 prentries *bulkentries;
1562 afs_int32 *nextstartindex;
1565 struct ubik_trans *tt;
1567 afs_int32 i, eof, pos, maxentries, f;
1568 struct prentry tentry;
1569 afs_int32 pollcount = 0;
1571 *nextstartindex = -1;
1572 bulkentries->prentries_val = 0;
1573 bulkentries->prentries_len = 0;
1576 if (code != PRSUCCESS)
1578 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1581 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1583 ABORT_WITH(tt, code);
1584 code = read_DbHeader(tt);
1586 ABORT_WITH(tt, code);
1588 /* Make sure we are an authenticated caller and that we are on the
1591 code = WhoIsThis(call, tt, &cid);
1593 ABORT_WITH(tt, PRPERM);
1594 code = IsAMemberOf(tt, cid, SYSADMINID);
1595 if (!code && !pr_noAuth)
1596 ABORT_WITH(tt, PRPERM);
1598 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1599 maxentries = eof / sizeof(struct prentry);
1600 for (i = startindex; i < maxentries; i++) {
1601 pos = i * sizeof(struct prentry) + sizeof(cheader);
1602 code = pr_ReadEntry(tt, 0, pos, &tentry);
1606 if (++pollcount > 50) {
1611 f = (tentry.flags & PRTYPE);
1612 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1613 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1614 code = put_prentries(&tentry, bulkentries);
1616 break; /* Filled return array */
1623 *nextstartindex = i;
1627 if (bulkentries->prentries_val)
1628 free(bulkentries->prentries_val);
1629 bulkentries->prentries_val = 0;
1630 bulkentries->prentries_len = 0;
1631 ABORT_WITH(tt, code);
1633 code = ubik_EndTrans(tt);
1640 #define PR_MAXENTRIES 500
1642 put_prentries(tentry, bulkentries)
1643 struct prentry *tentry;
1644 prentries *bulkentries;
1646 struct prlistentries *entry;
1648 if (bulkentries->prentries_val == 0) {
1649 bulkentries->prentries_len = 0;
1650 bulkentries->prentries_val =
1651 (struct prlistentries *)malloc(PR_MAXENTRIES *
1652 sizeof(struct prentry));
1653 if (!bulkentries->prentries_val) {
1658 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1662 entry = (struct prlistentries *)bulkentries->prentries_val;
1663 entry += bulkentries->prentries_len;
1665 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1666 if (entry->flags == 0) {
1669 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1672 entry->owner = tentry->owner;
1673 entry->id = tentry->id;
1674 entry->creator = tentry->creator;
1675 entry->ngroups = tentry->ngroups;
1676 entry->nusers = tentry->nusers;
1677 entry->count = tentry->count;
1678 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1679 memset(entry->reserved, 0, sizeof(entry->reserved));
1680 bulkentries->prentries_len++;
1685 SPR_ChangeEntry(call, aid, name, oid, newid)
1686 struct rx_call *call;
1694 code = changeEntry(call, aid, name, oid, newid);
1695 osi_auditU(call, PTS_ChgEntEvent, code, AUD_LONG, aid, AUD_STR, name,
1696 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1701 changeEntry(call, aid, name, oid, newid)
1702 struct rx_call *call;
1708 register afs_int32 code;
1709 struct ubik_trans *tt;
1720 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1721 || aid == SYSADMINID)
1723 if (code != PRSUCCESS)
1725 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1728 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1730 ABORT_WITH(tt, code);
1731 code = read_DbHeader(tt);
1733 ABORT_WITH(tt, code);
1735 code = WhoIsThis(call, tt, &cid);
1737 ABORT_WITH(tt, PRPERM);
1738 pos = FindByID(tt, aid);
1740 ABORT_WITH(tt, PRNOENT);
1741 /* protection check in changeentry */
1742 code = ChangeEntry(tt, aid, cid, name, oid, newid);
1743 if (code != PRSUCCESS)
1744 ABORT_WITH(tt, code);
1746 code = ubik_EndTrans(tt);
1751 SPR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1752 struct rx_call *call;
1754 afs_int32 mask; /* specify which fields to update */
1755 afs_int32 flags, ngroups, nusers;
1756 afs_int32 spare1, spare2;
1761 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1763 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_LONG, id, AUD_END);
1768 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1769 struct rx_call *call;
1771 afs_int32 mask; /* specify which fields to update */
1772 afs_int32 flags, ngroups, nusers;
1773 afs_int32 spare1, spare2;
1775 register afs_int32 code;
1776 struct ubik_trans *tt;
1779 struct prentry tentry;
1783 return 0; /* no-op */
1787 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1789 if (code != PRSUCCESS)
1791 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1794 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1796 ABORT_WITH(tt, code);
1797 code = read_DbHeader(tt);
1799 ABORT_WITH(tt, code);
1801 code = WhoIsThis(call, tt, &cid);
1803 ABORT_WITH(tt, PRPERM);
1804 pos = FindByID(tt, id);
1806 ABORT_WITH(tt, PRNOENT);
1807 code = pr_ReadEntry(tt, 0, pos, &tentry);
1809 ABORT_WITH(tt, code);
1810 tflags = tentry.flags;
1812 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1813 if (!AccessOK(tt, cid, 0, 0, 0))
1814 ABORT_WITH(tt, PRPERM);
1815 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1816 tentry.ngroups = tentry.nusers = 20;
1819 if (!AccessOK(tt, cid, &tentry, 0, 0))
1820 ABORT_WITH(tt, PRPERM);
1823 if (mask & 0xffff) { /* if setting flag bits */
1824 afs_int32 flagsMask = mask & 0xffff;
1825 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1826 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1830 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1832 ABORT_WITH(tt, PRBADARG);
1833 tentry.ngroups = ngroups;
1837 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1839 ABORT_WITH(tt, PRBADARG);
1840 tentry.nusers = nusers;
1843 tentry.flags = tflags;
1845 code = pr_WriteEntry(tt, 0, pos, &tentry);
1847 ABORT_WITH(tt, code);
1849 code = ubik_EndTrans(tt);
1854 SPR_ListElements(call, aid, alist, over)
1855 struct rx_call *call;
1862 code = listElements(call, aid, alist, over);
1863 osi_auditU(call, PTS_LstEleEvent, code, AUD_LONG, aid, AUD_END);
1868 listElements(call, aid, alist, over)
1869 struct rx_call *call;
1874 register afs_int32 code;
1875 struct ubik_trans *tt;
1878 struct prentry tentry;
1881 alist->prlist_len = 0;
1882 alist->prlist_val = NULL;
1885 if (code != PRSUCCESS)
1887 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1890 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1892 ABORT_WITH(tt, code);
1893 code = read_DbHeader(tt);
1895 ABORT_WITH(tt, code);
1897 code = WhoIsThis(call, tt, &cid);
1899 ABORT_WITH(tt, PRPERM);
1901 temp = FindByID(tt, aid);
1903 ABORT_WITH(tt, PRNOENT);
1904 code = pr_ReadEntry(tt, 0, temp, &tentry);
1906 ABORT_WITH(tt, code);
1907 if (!AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1908 ABORT_WITH(tt, PRPERM);
1910 code = GetList(tt, &tentry, alist, 0);
1911 if (code != PRSUCCESS)
1912 ABORT_WITH(tt, code);
1914 code = ubik_EndTrans(tt);
1920 SPR_ListSuperGroups(call, aid, alist, over)
1921 struct rx_call *call;
1926 #if defined(SUPERGROUPS)
1929 code = listSuperGroups(call, aid, alist, over);
1930 osi_auditU(call, "PTS_LstSGrps", code, AUD_LONG, aid, AUD_END);
1933 return RXGEN_OPCODE;
1937 #if defined(SUPERGROUPS)
1939 listSuperGroups(call, aid, alist, over)
1940 struct rx_call *call;
1945 register afs_int32 code;
1946 struct ubik_trans *tt;
1949 struct prentry tentry;
1951 alist->prlist_len = 0;
1952 alist->prlist_val = (afs_int32 *) 0;
1955 if (code != PRSUCCESS)
1957 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1960 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1962 ABORT_WITH(tt, code);
1963 code = WhoIsThis(call, tt, &cid);
1965 ABORT_WITH(tt, PRPERM);
1967 temp = FindByID(tt, aid);
1969 ABORT_WITH(tt, PRNOENT);
1970 code = pr_ReadEntry(tt, 0, temp, &tentry);
1972 ABORT_WITH(tt, code);
1973 if (!AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1974 ABORT_WITH(tt, PRPERM);
1976 code = GetSGList(tt, &tentry, alist);
1978 if (code == PRTOOMANY)
1980 else if (code != PRSUCCESS)
1981 ABORT_WITH(tt, code);
1983 code = ubik_EndTrans(tt);
1989 #endif /* SUPERGROUPS */
1993 * List the entries owned by this id. If the id is zero,
1994 * return the orphans list. This will return up to PR_MAXGROUPS
1995 * at a time with the lastP available to get the rest. The
1996 * maximum value is enforced in GetOwnedChain().
1999 SPR_ListOwned(call, aid, alist, lastP)
2000 struct rx_call *call;
2007 code = listOwned(call, aid, alist, lastP);
2008 osi_auditU(call, PTS_LstOwnEvent, code, AUD_LONG, aid, AUD_END);
2013 listOwned(call, aid, alist, lastP)
2014 struct rx_call *call;
2019 register afs_int32 code;
2020 struct ubik_trans *tt;
2022 struct prentry tentry;
2026 alist->prlist_len = 0;
2027 alist->prlist_val = NULL;
2035 if (code != PRSUCCESS)
2037 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2040 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2042 ABORT_WITH(tt, code);
2043 code = read_DbHeader(tt);
2045 ABORT_WITH(tt, code);
2047 code = WhoIsThis(call, tt, &cid);
2049 ABORT_WITH(tt, PRPERM);
2052 code = pr_ReadEntry(tt, 0, start, &tentry);
2053 if (!code && (tentry.owner == aid))
2054 head = start; /* pick up where we left off */
2059 afs_int32 loc = FindByID(tt, aid);
2061 ABORT_WITH(tt, PRNOENT);
2062 code = pr_ReadEntry(tt, 0, loc, &tentry);
2064 ABORT_WITH(tt, code);
2066 if (!AccessOK(tt, cid, &tentry, -1, PRP_OWNED_ANY))
2067 ABORT_WITH(tt, PRPERM);
2068 head = tentry.owned;
2070 if (!AccessOK(tt, cid, 0, 0, 0))
2071 ABORT_WITH(tt, PRPERM);
2072 head = ntohl(cheader.orphan);
2076 code = GetOwnedChain(tt, &head, alist);
2078 if (code == PRTOOMANY)
2081 ABORT_WITH(tt, code);
2084 code = ubik_EndTrans(tt);
2089 SPR_IsAMemberOf(call, uid, gid, flag)
2090 struct rx_call *call;
2097 code = isAMemberOf(call, uid, gid, flag);
2098 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
2104 isAMemberOf(call, uid, gid, flag)
2105 struct rx_call *call;
2110 register afs_int32 code;
2111 struct ubik_trans *tt;
2114 if (code != PRSUCCESS)
2116 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2119 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2121 ABORT_WITH(tt, code);
2122 code = read_DbHeader(tt);
2124 ABORT_WITH(tt, code);
2128 afs_int32 uloc = FindByID(tt, uid);
2129 afs_int32 gloc = FindByID(tt, gid);
2130 struct prentry uentry, gentry;
2133 ABORT_WITH(tt, PRNOENT);
2134 code = WhoIsThis(call, tt, &cid);
2136 ABORT_WITH(tt, PRPERM);
2137 code = pr_ReadEntry(tt, 0, uloc, &uentry);
2139 ABORT_WITH(tt, code);
2140 code = pr_ReadEntry(tt, 0, gloc, &gentry);
2142 ABORT_WITH(tt, code);
2143 #if !defined(SUPERGROUPS)
2144 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
2145 ABORT_WITH(tt, PRBADARG);
2147 if (!(gentry.flags & PRGRP))
2148 ABORT_WITH(tt, PRBADARG);
2150 if (!AccessOK(tt, cid, &uentry, 0, PRP_MEMBER_ANY)
2151 && !AccessOK(tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2152 ABORT_WITH(tt, PRPERM);
2155 *flag = IsAMemberOf(tt, uid, gid);
2156 code = ubik_EndTrans(tt);
2175 addWildCards(tt, alist, host)
2176 struct ubik_trans *tt;
2181 struct prentry tentry;
2183 unsigned wild = htonl(0xffffff00);
2184 struct in_addr iaddr;
2186 int size = 0, i, code;
2189 while ((host = (host & wild))) {
2190 wild = htonl(ntohl(wild) << 8);
2191 iaddr.s_addr = host;
2192 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
2193 if (code == PRSUCCESS && hostid != 0) {
2194 temp = FindByID(tt, hostid);
2196 code = pr_ReadEntry(tt, 0, temp, &tentry);
2197 if (code != PRSUCCESS)
2203 wlist.prlist_len = 0;
2204 wlist.prlist_val = NULL;
2206 code = GetList(tt, &tentry, &wlist, 0);
2209 added += wlist.prlist_len;
2210 for (i = 0; i < wlist.prlist_len; i++) {
2211 if (!inCPS(*alist, wlist.prlist_val[i]))
2212 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
2213 free(wlist.prlist_val);
2217 if (wlist.prlist_val)
2218 free(wlist.prlist_val);
2221 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
2224 #endif /* IP_WILDCARDS */
2228 WhoIsThisWithName(acall, at, aid, aname)
2229 struct rx_call *acall;
2230 struct ubik_trans *at;
2234 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2235 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2236 register struct rx_connection *tconn;
2237 register afs_int32 code;
2238 char tcell[MAXKTCREALMLEN];
2239 char name[MAXKTCNAMELEN];
2240 char inst[MAXKTCNAMELEN];
2245 tconn = rx_ConnectionOf(acall);
2246 code = rx_SecurityClassOf(tconn);
2249 else if (code == 1) { /* vab class */
2250 goto done; /* no longer supported */
2251 } else if (code == 2) { /* kad class */
2254 extern char *pr_realmName;
2256 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
2257 name, inst, tcell, NULL)))
2259 strncpy(vname, name, sizeof(vname));
2260 if ((ilen = strlen(inst))) {
2261 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2264 strcat(vname, inst);
2266 if ((clen = strlen(tcell))) {
2268 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
2269 static char local_realm[AFS_REALM_SZ] = "";
2270 if (!local_realm[0]) {
2271 if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
2272 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
2276 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
2277 strcasecmp(local_realm, tcell) &&
2279 strcasecmp(pr_realmName, tcell)) {
2280 if (strlen(vname) + 1 + clen >= sizeof(vname))
2283 strcat(vname, tcell);
2284 lcstring(vname, vname, sizeof(vname));
2285 code = NameToID(at, vname, aid);
2286 strcpy(aname, vname);
2291 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2292 *aid = SYSADMINID; /* special case for the fileserver */
2294 lcstring(vname, vname, sizeof(vname));
2295 code = NameToID(at, vname, aid);
2299 if (code && !pr_noAuth)