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 struct ubik_dbase *dbase;
90 extern afs_int32 Initdb();
92 extern afs_int32 initd;
93 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(),
94 nameToID(), Delete(), removeFromGroup();
95 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
96 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
97 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
99 #if defined(SUPERGROUPS)
100 afs_int32 listSuperGroups();
106 /* When abort, reset initd so that the header is read in on next call.
107 * Abort the transaction and return the code.
109 #define ABORT_WITH(tt,code) return(initd=0,ubik_AbortTrans(tt),code)
112 CreateOK(ut, cid, oid, flag, admin)
113 struct ubik_trans *ut;
114 afs_int32 cid; /* id of caller */
115 afs_int32 oid; /* id of owner */
116 afs_int32 flag; /* indicates type of entry */
117 int admin; /* sysadmin membership */
119 if (flag & PRFOREIGN) {
120 /* Foreign users are recognized by the '@' sign and
121 * not by the PRFOREIGN flag.
124 } else if (flag & PRGRP) {
125 /* Allow anonymous group creation only if owner specified
126 * and running noAuth.
128 if (cid == ANONYMOUSID) {
129 if ((oid == 0) || !pr_noAuth)
132 } else { /* creating a user */
133 if (!admin && !pr_noAuth)
140 WhoIsThis(acall, at, aid)
141 struct rx_call *acall;
142 struct ubik_trans *at;
146 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
147 /* returns -1 and sets aid to ANONYMOUSID on any failure */
148 register struct rx_connection *tconn;
149 register afs_int32 code;
150 char tcell[MAXKTCREALMLEN];
151 char name[MAXKTCNAMELEN];
152 char inst[MAXKTCNAMELEN];
157 tconn = rx_ConnectionOf(acall);
158 code = rx_SecurityClassOf(tconn);
161 else if (code == 1) { /* vab class */
162 goto done; /* no longer supported */
163 } else if (code == 2) { /* kad class */
164 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
165 name, inst, tcell, NULL)))
168 /* This test is unnecessary, since rxkad_GetServerInfo already check.
169 * In addition, this is wrong since exp must be unsigned. */
170 if (exp < FT_ApproxTime())
174 extern char *pr_realmName;
175 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
176 static char local_realm[AFS_REALM_SZ] = "";
177 if (!local_realm[0]) {
178 if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
179 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
183 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
184 strcasecmp(local_realm, tcell) &&
186 strcasecmp(pr_realmName, tcell))
189 strncpy(vname, name, sizeof(vname));
190 if (ilen = strlen(inst)) {
191 if (strlen(vname) + 1 + ilen >= sizeof(vname))
197 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
200 strcat(vname, tcell);
202 if (strcmp(AUTH_SUPERUSER, vname) == 0)
203 *aid = SYSADMINID; /* special case for the fileserver */
205 lcstring(vname, vname, sizeof(vname));
206 code = NameToID(at, vname, aid);
210 if (code && !pr_noAuth)
216 SPR_INewEntry(call, aname, aid, oid)
217 struct rx_call *call;
218 char aname[PR_MAXNAMELEN];
224 code = iNewEntry(call, aname, aid, oid);
225 osi_auditU(call, PTS_INewEntEvent, code, AUD_LONG, aid, AUD_STR, aname,
226 AUD_LONG, oid, AUD_END);
231 iNewEntry(call, aname, aid, oid)
232 struct rx_call *call;
233 char aname[PR_MAXNAMELEN];
237 /* used primarily for conversion - not intended to be used as usual means
238 * of entering people into the database. */
239 struct ubik_trans *tt;
240 register afs_int32 code;
247 if (code != PRSUCCESS)
249 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
252 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
254 ABORT_WITH(tt, code);
255 code = read_DbHeader(tt);
257 ABORT_WITH(tt, code);
259 code = WhoIsThis(call, tt, &cid);
261 ABORT_WITH(tt, PRPERM);
262 admin = IsAMemberOf(tt, cid, SYSADMINID);
264 /* first verify the id is good */
266 ABORT_WITH(tt, PRPERM);
269 /* only sysadmin can reuse a group id */
270 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
271 ABORT_WITH(tt, PRPERM);
273 if (FindByID(tt, aid))
274 ABORT_WITH(tt, PRIDEXIST);
276 /* check a few other things */
277 if (!CreateOK(tt, cid, oid, gflag, admin))
278 ABORT_WITH(tt, PRPERM);
280 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, cid);
281 if (code != PRSUCCESS)
282 ABORT_WITH(tt, code);
284 /* finally, commit transaction */
285 code = ubik_EndTrans(tt);
293 SPR_NewEntry(call, aname, flag, oid, aid)
294 struct rx_call *call;
295 char aname[PR_MAXNAMELEN];
302 code = newEntry(call, aname, flag, oid, aid);
303 osi_auditU(call, PTS_NewEntEvent, code, AUD_LONG, *aid, AUD_STR, aname,
304 AUD_LONG, oid, AUD_END);
309 newEntry(call, aname, flag, oid, aid)
310 struct rx_call *call;
311 char aname[PR_MAXNAMELEN];
316 register afs_int32 code;
317 struct ubik_trans *tt;
320 extern afs_int32 WhoIsThisWithName();
321 char cname[PR_MAXNAMELEN];
326 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
329 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
331 ABORT_WITH(tt, code);
332 code = read_DbHeader(tt);
334 ABORT_WITH(tt, code);
336 /* this is for cross-cell self registration. It is not added in the
337 * SPR_INewEntry because we want self-registration to only do
338 * automatic id assignment.
340 code = WhoIsThisWithName(call, tt, &cid, cname);
341 if (code != 2) { /* 2 specifies that this is a foreign cell request */
343 ABORT_WITH(tt, PRPERM);
344 admin = IsAMemberOf(tt, cid, SYSADMINID);
346 admin = (!strcmp(aname, cname)) || IsAMemberOf(tt, cid, SYSADMINID);
347 oid = cid = SYSADMINID;
349 if (!CreateOK(tt, cid, oid, flag, admin))
350 ABORT_WITH(tt, PRPERM);
352 code = CreateEntry(tt, aname, aid, 0, flag, oid, cid);
353 if (code != PRSUCCESS)
354 ABORT_WITH(tt, code);
356 code = ubik_EndTrans(tt);
365 SPR_WhereIsIt(call, aid, apos)
366 struct rx_call *call;
372 code = whereIsIt(call, aid, apos);
373 osi_auditU(call, PTS_WheIsItEvent, code, AUD_LONG, aid, AUD_LONG, *apos,
379 whereIsIt(call, aid, apos)
380 struct rx_call *call;
384 register afs_int32 code;
385 struct ubik_trans *tt;
389 if (code != PRSUCCESS)
391 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
394 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
396 ABORT_WITH(tt, code);
397 code = read_DbHeader(tt);
399 ABORT_WITH(tt, code);
401 temp = FindByID(tt, aid);
403 ABORT_WITH(tt, PRNOENT);
405 code = ubik_EndTrans(tt);
413 SPR_DumpEntry(call, apos, aentry)
414 struct rx_call *call;
416 struct prdebugentry *aentry;
420 code = dumpEntry(call, apos, aentry);
421 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
426 dumpEntry(call, apos, aentry)
427 struct rx_call *call;
429 struct prdebugentry *aentry;
431 register afs_int32 code;
433 struct ubik_trans *tt;
436 if (code != PRSUCCESS)
438 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
441 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
443 ABORT_WITH(tt, code);
444 code = read_DbHeader(tt);
446 ABORT_WITH(tt, code);
448 code = WhoIsThis(call, tt, &cid);
450 ABORT_WITH(tt, PRPERM);
451 code = pr_ReadEntry(tt, 0, apos, aentry);
453 ABORT_WITH(tt, code);
455 if (!AccessOK(tt, cid, 0, PRP_STATUS_MEM, 0))
456 ABORT_WITH(tt, PRPERM);
458 /* Since prdebugentry is in the form of a prentry not a coentry, we will
459 * return the coentry slots in network order where the string is. */
461 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
462 code = pr_ReadCoEntry(tt, 0, apos, aentry);
464 ABORT_WITH(tt, code);
467 code = ubik_EndTrans(tt);
474 SPR_AddToGroup(call, aid, gid)
475 struct rx_call *call;
481 code = addToGroup(call, aid, gid);
482 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid,
488 addToGroup(call, aid, gid)
489 struct rx_call *call;
493 register afs_int32 code;
494 struct ubik_trans *tt;
497 struct prentry tentry;
498 struct prentry uentry;
502 if (code != PRSUCCESS)
504 if (gid == ANYUSERID || gid == AUTHUSERID)
506 if (aid == ANONYMOUSID)
508 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
511 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
513 ABORT_WITH(tt, code);
514 code = read_DbHeader(tt);
516 ABORT_WITH(tt, code);
518 code = WhoIsThis(call, tt, &cid);
520 ABORT_WITH(tt, PRPERM);
521 tempu = FindByID(tt, aid);
523 ABORT_WITH(tt, PRNOENT);
524 memset(&uentry, 0, sizeof(uentry));
525 code = pr_ReadEntry(tt, 0, tempu, &uentry);
527 ABORT_WITH(tt, code);
529 #if !defined(SUPERGROUPS)
530 /* we don't allow groups as members of groups at present */
531 if (uentry.flags & PRGRP)
532 ABORT_WITH(tt, PRNOTUSER);
535 tempg = FindByID(tt, gid);
537 ABORT_WITH(tt, PRNOENT);
538 code = pr_ReadEntry(tt, 0, tempg, &tentry);
540 ABORT_WITH(tt, code);
541 /* make sure that this is a group */
542 if (!(tentry.flags & PRGRP))
543 ABORT_WITH(tt, PRNOTGROUP);
544 if (!AccessOK(tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
545 ABORT_WITH(tt, PRPERM);
547 code = AddToEntry(tt, &tentry, tempg, aid);
548 if (code != PRSUCCESS)
549 ABORT_WITH(tt, code);
551 #if defined(SUPERGROUPS)
552 if (uentry.flags & PRGRP)
553 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
556 /* now, modify the user's entry as well */
557 code = AddToEntry(tt, &uentry, tempu, gid);
558 if (code != PRSUCCESS)
559 ABORT_WITH(tt, code);
560 code = ubik_EndTrans(tt);
567 SPR_NameToID(call, aname, aid)
568 struct rx_call *call;
574 code = nameToID(call, aname, aid);
575 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
580 nameToID(call, aname, aid)
581 struct rx_call *call;
585 register afs_int32 code;
586 struct ubik_trans *tt;
591 /* Initialize return struct */
593 aid->idlist_val = NULL;
595 size = aname->namelist_len;
601 aid->idlist_val = (afs_int32 *) malloc(size * sizeof(afs_int32));
602 if (!aid->idlist_val)
606 if (code != PRSUCCESS)
608 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
611 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
613 ABORT_WITH(tt, code);
614 code = read_DbHeader(tt);
616 ABORT_WITH(tt, code);
618 for (i = 0; i < aname->namelist_len; i++) {
619 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
620 if (code != PRSUCCESS)
621 aid->idlist_val[i] = ANONYMOUSID;
623 IOMGR_Poll(), count = 0;
625 aid->idlist_len = aname->namelist_len;
627 code = ubik_EndTrans(tt);
635 * Given an array of ids, find the name for each of them.
636 * The array of ids and names is unlimited.
639 SPR_IDToName(call, aid, aname)
640 struct rx_call *call;
646 code = idToName(call, aid, aname);
647 osi_auditU(call, PTS_IdToNmEvent, code, AUD_LONG, aid, AUD_END);
652 idToName(call, aid, aname)
653 struct rx_call *call;
657 register afs_int32 code;
658 struct ubik_trans *tt;
663 /* leave this first for rpc stub */
664 size = aid->idlist_len;
669 aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
670 aname->namelist_len = 0;
671 if (aname->namelist_val == 0)
673 if (aid->idlist_len == 0)
676 return PRTOOMANY; /* rxgen will probably handle this */
679 if (code != PRSUCCESS)
681 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
684 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
686 ABORT_WITH(tt, code);
687 code = read_DbHeader(tt);
689 ABORT_WITH(tt, code);
691 for (i = 0; i < aid->idlist_len; i++) {
692 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
693 if (code != PRSUCCESS)
694 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
696 IOMGR_Poll(), count = 0;
698 aname->namelist_len = aid->idlist_len;
700 code = ubik_EndTrans(tt);
707 SPR_Delete(call, aid)
708 struct rx_call *call;
713 code = Delete(call, aid);
714 osi_auditU(call, PTS_DelEvent, code, AUD_LONG, aid, AUD_END);
720 struct rx_call *call;
723 register afs_int32 code;
724 struct ubik_trans *tt;
726 struct prentry tentry;
733 if (code != PRSUCCESS)
735 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
736 || aid == ANONYMOUSID)
738 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
741 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
743 ABORT_WITH(tt, code);
744 code = read_DbHeader(tt);
746 ABORT_WITH(tt, code);
748 code = WhoIsThis(call, tt, &cid);
750 ABORT_WITH(tt, PRPERM);
752 /* Read in entry to be deleted */
753 loc = FindByID(tt, aid);
755 ABORT_WITH(tt, PRNOENT);
756 code = pr_ReadEntry(tt, 0, loc, &tentry);
758 ABORT_WITH(tt, PRDBFAIL);
760 /* Do some access checking */
761 if (tentry.owner != cid && !IsAMemberOf(tt, cid, SYSADMINID)
762 && !IsAMemberOf(tt, cid, tentry.owner) && !pr_noAuth)
763 ABORT_WITH(tt, PRPERM);
765 /* Delete each continuation block as a separate transaction so that no one
766 * transaction become to large to complete. */
768 while (nptr != (afs_int32) NULL) {
769 struct contentry centry;
772 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
774 ABORT_WITH(tt, PRDBFAIL);
775 for (i = 0; i < COSIZE; i++) {
776 if (centry.entries[i] == PRBADID)
778 if (centry.entries[i] == 0)
780 #if defined(SUPERGROUPS)
781 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
782 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
785 code = RemoveFromEntry(tt, aid, centry.entries[i]);
787 ABORT_WITH(tt, code);
788 tentry.count--; /* maintain count */
792 tentry.next = centry.next; /* thread out this block */
793 code = FreeBlock(tt, nptr); /* free continuation block */
795 ABORT_WITH(tt, code);
796 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
798 ABORT_WITH(tt, code);
800 /* end this trans and start a new one */
801 code = ubik_EndTrans(tt);
804 IOMGR_Poll(); /* just to keep the connection alive */
805 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
808 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
810 ABORT_WITH(tt, code);
812 /* re-read entry to get consistent uptodate info */
813 loc = FindByID(tt, aid);
815 ABORT_WITH(tt, PRNOENT);
816 code = pr_ReadEntry(tt, 0, loc, &tentry);
818 ABORT_WITH(tt, PRDBFAIL);
823 #if defined(SUPERGROUPS)
824 /* Delete each continuation block as a separate transaction
825 * so that no one transaction become too large to complete. */
827 struct prentryg *tentryg = (struct prentryg *)&tentry;
828 nptr = tentryg->nextsg;
829 while (nptr != NULL) {
830 struct contentry centry;
833 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
835 ABORT_WITH(tt, PRDBFAIL);
836 for (i = 0; i < COSIZE; i++) {
837 if (centry.entries[i] == PRBADID)
839 if (centry.entries[i] == 0)
841 code = RemoveFromEntry(tt, aid, centry.entries[i]);
843 ABORT_WITH(tt, code);
844 tentryg->countsg--; /* maintain count */
848 tentryg->nextsg = centry.next; /* thread out this block */
849 code = FreeBlock(tt, nptr); /* free continuation block */
851 ABORT_WITH(tt, code);
852 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
854 ABORT_WITH(tt, code);
856 /* end this trans and start a new one */
857 code = ubik_EndTrans(tt);
860 IOMGR_Poll(); /* just to keep the connection alive */
862 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
865 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
867 ABORT_WITH(tt, code);
869 /* re-read entry to get consistent uptodate info */
870 loc = FindByID(tt, aid);
872 ABORT_WITH(tt, PRNOENT);
873 code = pr_ReadEntry(tt, 0, loc, &tentry);
875 ABORT_WITH(tt, PRDBFAIL);
877 nptr = tentryg->nextsg;
881 #endif /* SUPERGROUPS */
883 /* Then move the owned chain, except possibly ourself to the orphan list.
884 * Because this list can be very long and so exceed the size of a ubik
885 * transaction, we start a new transaction every 50 entries. */
888 while (nptr != (afs_int32) NULL) {
889 struct prentry nentry;
891 code = pr_ReadEntry(tt, 0, nptr, &nentry);
893 ABORT_WITH(tt, PRDBFAIL);
894 nptr = tentry.owned = nentry.nextOwned; /* thread out */
896 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
897 code = AddToOrphan(tt, nentry.id);
899 ABORT_WITH(tt, code);
901 if ((count & 3) == 0)
906 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
908 ABORT_WITH(tt, code);
910 /* end this trans and start a new one */
911 code = ubik_EndTrans(tt);
914 IOMGR_Poll(); /* just to keep the connection alive */
915 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
918 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
920 ABORT_WITH(tt, code);
922 /* re-read entry to get consistent uptodate info */
923 loc = FindByID(tt, aid);
925 ABORT_WITH(tt, PRNOENT);
926 code = pr_ReadEntry(tt, 0, loc, &tentry);
928 ABORT_WITH(tt, PRDBFAIL);
933 /* now do what's left of the deletion stuff */
934 code = DeleteEntry(tt, &tentry, loc);
935 if (code != PRSUCCESS)
936 ABORT_WITH(tt, code);
938 code = ubik_EndTrans(tt);
945 SPR_UpdateEntry(call, aid, name, uentry)
946 struct rx_call *call;
949 struct PrUpdateEntry *uentry;
951 register afs_int32 code;
952 struct ubik_trans *tt;
954 struct prentry tentry;
961 if (code != PRSUCCESS)
965 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
966 || aid == ANONYMOUSID)
969 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
972 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
974 ABORT_WITH(tt, code);
975 code = read_DbHeader(tt);
977 ABORT_WITH(tt, code);
979 code = WhoIsThis(call, tt, &cid);
981 ABORT_WITH(tt, PRPERM);
982 code = IsAMemberOf(tt, cid, SYSADMINID);
983 if (!code && !pr_noAuth)
984 ABORT_WITH(tt, PRPERM);
986 /* Read in entry to be deleted */
988 loc = FindByID(tt, aid);
990 loc = FindByName(tt, name, &tentry);
993 ABORT_WITH(tt, PRNOENT);
994 code = pr_ReadEntry(tt, 0, loc, &tentry);
996 ABORT_WITH(tt, PRDBFAIL);
998 if (uentry->Mask & PRUPDATE_NAMEHASH) {
1000 code = RemoveFromNameHash(tt, tentry.name, &tloc);
1001 if (code != PRSUCCESS)
1002 ABORT_WITH(tt, PRDBFAIL);
1003 code = AddToNameHash(tt, tentry.name, loc);
1005 ABORT_WITH(tt, code);
1008 if (uentry->Mask & PRUPDATE_IDHASH) {
1012 code = RemoveFromIDHash(tt, id, &tloc);
1013 if (code != PRSUCCESS)
1014 ABORT_WITH(tt, PRDBFAIL);
1015 code = AddToIDHash(tt, id, loc);
1017 ABORT_WITH(tt, code);
1020 code = ubik_EndTrans(tt);
1027 SPR_RemoveFromGroup(call, aid, gid)
1028 struct rx_call *call;
1034 code = removeFromGroup(call, aid, gid);
1035 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid,
1041 removeFromGroup(call, aid, gid)
1042 struct rx_call *call;
1046 register afs_int32 code;
1047 struct ubik_trans *tt;
1050 struct prentry uentry;
1051 struct prentry gentry;
1055 if (code != PRSUCCESS)
1057 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1060 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1062 ABORT_WITH(tt, code);
1063 code = read_DbHeader(tt);
1065 ABORT_WITH(tt, code);
1067 code = WhoIsThis(call, tt, &cid);
1069 ABORT_WITH(tt, PRPERM);
1070 tempu = FindByID(tt, aid);
1072 ABORT_WITH(tt, PRNOENT);
1073 tempg = FindByID(tt, gid);
1075 ABORT_WITH(tt, PRNOENT);
1076 memset(&uentry, 0, sizeof(uentry));
1077 memset(&gentry, 0, sizeof(gentry));
1078 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1080 ABORT_WITH(tt, code);
1081 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1083 ABORT_WITH(tt, code);
1084 if (!(gentry.flags & PRGRP))
1085 ABORT_WITH(tt, PRNOTGROUP);
1086 #if !defined(SUPERGROUPS)
1087 if (uentry.flags & PRGRP)
1088 ABORT_WITH(tt, PRNOTUSER);
1090 if (!AccessOK(tt, cid, &gentry, PRP_REMOVE_MEM, 0))
1091 ABORT_WITH(tt, PRPERM);
1092 code = RemoveFromEntry(tt, aid, gid);
1093 if (code != PRSUCCESS)
1094 ABORT_WITH(tt, code);
1095 #if defined(SUPERGROUPS)
1096 if (!(uentry.flags & PRGRP))
1098 code = RemoveFromEntry(tt, gid, aid);
1099 #if defined(SUPERGROUPS)
1101 code = RemoveFromSGEntry(tt, gid, aid);
1103 if (code != PRSUCCESS)
1104 ABORT_WITH(tt, code);
1106 code = ubik_EndTrans(tt);
1114 SPR_GetCPS(call, aid, alist, over)
1115 struct rx_call *call;
1122 code = getCPS(call, aid, alist, over);
1123 osi_auditU(call, PTS_GetCPSEvent, code, AUD_LONG, aid, AUD_END);
1128 getCPS(call, aid, alist, over)
1129 struct rx_call *call;
1134 register afs_int32 code;
1135 struct ubik_trans *tt;
1138 struct prentry tentry;
1141 alist->prlist_len = 0;
1142 alist->prlist_val = NULL;
1144 if (code != PRSUCCESS)
1146 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1149 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1151 ABORT_WITH(tt, code);
1152 code = read_DbHeader(tt);
1154 ABORT_WITH(tt, code);
1156 temp = FindByID(tt, aid);
1158 ABORT_WITH(tt, PRNOENT);
1159 code = pr_ReadEntry(tt, 0, temp, &tentry);
1161 ABORT_WITH(tt, code);
1163 /* afs does authenticate now */
1164 code = WhoIsThis(call, tt, &cid);
1165 if (code || !AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1166 ABORT_WITH(tt, PRPERM);
1168 code = GetList(tt, &tentry, alist, 1);
1169 if (code != PRSUCCESS)
1170 ABORT_WITH(tt, code);
1172 code = ubik_EndTrans(tt);
1185 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1186 if (CPS.prlist_val[i] == id)
1191 #endif /* IP_WILDCARDS */
1195 SPR_GetCPS2(call, aid, ahost, alist, over)
1196 struct rx_call *call;
1204 code = getCPS2(call, aid, ahost, alist, over);
1205 osi_auditU(call, PTS_GetCPS2Event, code, AUD_LONG, aid, AUD_HOST, ahost,
1211 getCPS2(call, aid, ahost, alist, over)
1212 struct rx_call *call;
1218 register afs_int32 code;
1219 struct ubik_trans *tt;
1222 struct prentry tentry;
1223 struct prentry host_tentry;
1226 struct in_addr iaddr;
1228 extern afs_int32 addWildCards();
1229 #endif /* IP_WILDCARDS */
1232 iaddr.s_addr = ntohl(ahost);
1233 alist->prlist_len = 0;
1234 alist->prlist_val = NULL;
1236 if (code != PRSUCCESS)
1238 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1241 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1243 ABORT_WITH(tt, code);
1244 code = read_DbHeader(tt);
1246 ABORT_WITH(tt, code);
1248 if (aid != PRBADID) {
1249 temp = FindByID(tt, aid);
1251 ABORT_WITH(tt, PRNOENT);
1252 code = pr_ReadEntry(tt, 0, temp, &tentry);
1254 ABORT_WITH(tt, code);
1256 /* afs does authenticate now */
1257 code = WhoIsThis(call, tt, &cid);
1259 || !AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1260 ABORT_WITH(tt, PRPERM);
1262 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1263 if (code == PRSUCCESS && hostid != 0) {
1264 temp = FindByID(tt, hostid);
1266 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1267 if (code == PRSUCCESS)
1270 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1272 fprintf(stderr, "FindByID Failed -- Not found\n");
1275 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1277 code = GetList(tt, &tentry, alist, 1);
1280 code = addWildCards(tt, alist, ntohl(ahost));
1281 #endif /* IP_WILDCARDS */
1282 if (code != PRSUCCESS)
1283 ABORT_WITH(tt, code);
1285 code = ubik_EndTrans(tt);
1291 SPR_GetHostCPS(call, ahost, alist, over)
1292 struct rx_call *call;
1299 code = getHostCPS(call, ahost, alist, over);
1300 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
1305 getHostCPS(call, ahost, alist, over)
1306 struct rx_call *call;
1311 register afs_int32 code, temp;
1312 struct ubik_trans *tt;
1313 struct prentry host_tentry;
1315 struct in_addr iaddr;
1317 extern afs_int32 addWildCards();
1318 #endif /* IP_WILDCARDS */
1321 iaddr.s_addr = ntohl(ahost);
1322 alist->prlist_len = 0;
1323 alist->prlist_val = NULL;
1325 if (code != PRSUCCESS)
1327 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1330 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1332 ABORT_WITH(tt, code);
1333 code = read_DbHeader(tt);
1335 ABORT_WITH(tt, code);
1337 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1338 if (code == PRSUCCESS && hostid != 0) {
1339 temp = FindByID(tt, hostid);
1341 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1342 if (code == PRSUCCESS) {
1343 code = GetList(tt, &host_tentry, alist, 0);
1347 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1349 fprintf(stderr, "FindByID Failed -- Not found\n");
1352 code = addWildCards(tt, alist, ntohl(ahost));
1353 #endif /* IP_WILDCARDS */
1355 if (code != PRSUCCESS)
1356 ABORT_WITH(tt, code);
1358 code = ubik_EndTrans(tt);
1364 SPR_ListMax(call, uid, gid)
1365 struct rx_call *call;
1371 code = listMax(call, uid, gid);
1372 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1377 listMax(call, uid, gid)
1378 struct rx_call *call;
1382 register afs_int32 code;
1383 struct ubik_trans *tt;
1386 if (code != PRSUCCESS)
1388 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1391 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1393 ABORT_WITH(tt, code);
1394 code = read_DbHeader(tt);
1396 ABORT_WITH(tt, code);
1398 code = GetMax(tt, uid, gid);
1399 if (code != PRSUCCESS)
1400 ABORT_WITH(tt, code);
1402 code = ubik_EndTrans(tt);
1409 SPR_SetMax(call, aid, gflag)
1410 struct rx_call *call;
1416 code = setMax(call, aid, gflag);
1417 osi_auditU(call, PTS_SetMaxEvent, code, AUD_LONG, aid, AUD_LONG, gflag,
1423 setMax(call, aid, gflag)
1424 struct rx_call *call;
1428 register afs_int32 code;
1429 struct ubik_trans *tt;
1433 if (code != PRSUCCESS)
1435 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1438 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1440 ABORT_WITH(tt, code);
1441 code = read_DbHeader(tt);
1443 ABORT_WITH(tt, code);
1445 code = WhoIsThis(call, tt, &cid);
1447 ABORT_WITH(tt, PRPERM);
1448 if (!AccessOK(tt, cid, 0, 0, 0))
1449 ABORT_WITH(tt, PRPERM);
1450 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1451 ABORT_WITH(tt, PRBADARG);
1453 code = SetMax(tt, aid, gflag);
1454 if (code != PRSUCCESS)
1455 ABORT_WITH(tt, code);
1457 code = ubik_EndTrans(tt);
1464 SPR_ListEntry(call, aid, aentry)
1465 struct rx_call *call;
1467 struct prcheckentry *aentry;
1471 code = listEntry(call, aid, aentry);
1472 osi_auditU(call, PTS_LstEntEvent, code, AUD_LONG, aid, AUD_END);
1477 listEntry(call, aid, aentry)
1478 struct rx_call *call;
1480 struct prcheckentry *aentry;
1482 register afs_int32 code;
1483 struct ubik_trans *tt;
1486 struct prentry tentry;
1489 if (code != PRSUCCESS)
1491 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1494 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1496 ABORT_WITH(tt, code);
1497 code = read_DbHeader(tt);
1499 ABORT_WITH(tt, code);
1501 code = WhoIsThis(call, tt, &cid);
1503 ABORT_WITH(tt, PRPERM);
1504 temp = FindByID(tt, aid);
1506 ABORT_WITH(tt, PRNOENT);
1507 code = pr_ReadEntry(tt, 0, temp, &tentry);
1509 ABORT_WITH(tt, code);
1510 if (!AccessOK(tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1511 ABORT_WITH(tt, PRPERM);
1513 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1514 if (aentry->flags == 0) {
1515 if (tentry.flags & PRGRP)
1516 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
1518 aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
1520 aentry->owner = tentry.owner;
1521 aentry->id = tentry.id;
1522 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1523 aentry->creator = tentry.creator;
1524 aentry->ngroups = tentry.ngroups;
1525 aentry->nusers = tentry.nusers;
1526 aentry->count = tentry.count;
1527 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1528 code = ubik_EndTrans(tt);
1535 SPR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1536 struct rx_call *call;
1538 afs_int32 startindex;
1539 prentries *bulkentries;
1540 afs_int32 *nextstartindex;
1544 code = listEntries(call, flag, startindex, bulkentries, nextstartindex);
1545 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1550 listEntries(call, flag, startindex, bulkentries, nextstartindex)
1551 struct rx_call *call;
1553 afs_int32 startindex;
1554 prentries *bulkentries;
1555 afs_int32 *nextstartindex;
1558 struct ubik_trans *tt;
1560 afs_int32 i, eof, pos, maxentries, f;
1561 struct prentry tentry;
1562 afs_int32 pollcount = 0;
1564 *nextstartindex = -1;
1565 bulkentries->prentries_val = 0;
1566 bulkentries->prentries_len = 0;
1569 if (code != PRSUCCESS)
1571 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1574 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1576 ABORT_WITH(tt, code);
1577 code = read_DbHeader(tt);
1579 ABORT_WITH(tt, code);
1581 /* Make sure we are an authenticated caller and that we are on the
1584 code = WhoIsThis(call, tt, &cid);
1586 ABORT_WITH(tt, PRPERM);
1587 code = IsAMemberOf(tt, cid, SYSADMINID);
1588 if (!code && !pr_noAuth)
1589 ABORT_WITH(tt, PRPERM);
1591 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1592 maxentries = eof / sizeof(struct prentry);
1593 for (i = startindex; i < maxentries; i++) {
1594 pos = i * sizeof(struct prentry) + sizeof(cheader);
1595 code = pr_ReadEntry(tt, 0, pos, &tentry);
1599 if (++pollcount > 50) {
1604 f = (tentry.flags & PRTYPE);
1605 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1606 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1607 code = put_prentries(&tentry, bulkentries);
1609 break; /* Filled return array */
1616 *nextstartindex = i;
1620 if (bulkentries->prentries_val)
1621 free(bulkentries->prentries_val);
1622 bulkentries->prentries_val = 0;
1623 bulkentries->prentries_len = 0;
1624 ABORT_WITH(tt, code);
1626 code = ubik_EndTrans(tt);
1633 #define PR_MAXENTRIES 500
1635 put_prentries(tentry, bulkentries)
1636 struct prentry *tentry;
1637 prentries *bulkentries;
1639 struct prlistentries *entry;
1641 if (bulkentries->prentries_val == 0) {
1642 bulkentries->prentries_len = 0;
1643 bulkentries->prentries_val =
1644 (struct prlistentries *)malloc(PR_MAXENTRIES *
1645 sizeof(struct prentry));
1646 if (!bulkentries->prentries_val) {
1651 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1655 entry = (struct prlistentries *)bulkentries->prentries_val;
1656 entry += bulkentries->prentries_len;
1658 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1659 if (entry->flags == 0) {
1662 flags & PRGRP) ? PRP_GROUP_DEFAULT : PRP_USER_DEFAULT) >>
1665 entry->owner = tentry->owner;
1666 entry->id = tentry->id;
1667 entry->creator = tentry->creator;
1668 entry->ngroups = tentry->ngroups;
1669 entry->nusers = tentry->nusers;
1670 entry->count = tentry->count;
1671 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1672 memset(entry->reserved, 0, sizeof(entry->reserved));
1673 bulkentries->prentries_len++;
1678 SPR_ChangeEntry(call, aid, name, oid, newid)
1679 struct rx_call *call;
1687 code = changeEntry(call, aid, name, oid, newid);
1688 osi_auditU(call, PTS_ChgEntEvent, code, AUD_LONG, aid, AUD_STR, name,
1689 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1694 changeEntry(call, aid, name, oid, newid)
1695 struct rx_call *call;
1701 register afs_int32 code;
1702 struct ubik_trans *tt;
1713 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1714 || aid == SYSADMINID)
1716 if (code != PRSUCCESS)
1718 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1721 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1723 ABORT_WITH(tt, code);
1724 code = read_DbHeader(tt);
1726 ABORT_WITH(tt, code);
1728 code = WhoIsThis(call, tt, &cid);
1730 ABORT_WITH(tt, PRPERM);
1731 pos = FindByID(tt, aid);
1733 ABORT_WITH(tt, PRNOENT);
1734 /* protection check in changeentry */
1735 code = ChangeEntry(tt, aid, cid, name, oid, newid);
1736 if (code != PRSUCCESS)
1737 ABORT_WITH(tt, code);
1739 code = ubik_EndTrans(tt);
1744 SPR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1745 struct rx_call *call;
1747 afs_int32 mask; /* specify which fields to update */
1748 afs_int32 flags, ngroups, nusers;
1749 afs_int32 spare1, spare2;
1754 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1756 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_LONG, id, AUD_END);
1761 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1762 struct rx_call *call;
1764 afs_int32 mask; /* specify which fields to update */
1765 afs_int32 flags, ngroups, nusers;
1766 afs_int32 spare1, spare2;
1768 register afs_int32 code;
1769 struct ubik_trans *tt;
1772 struct prentry tentry;
1776 return 0; /* no-op */
1780 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1782 if (code != PRSUCCESS)
1784 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1787 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1789 ABORT_WITH(tt, code);
1790 code = read_DbHeader(tt);
1792 ABORT_WITH(tt, code);
1794 code = WhoIsThis(call, tt, &cid);
1796 ABORT_WITH(tt, PRPERM);
1797 pos = FindByID(tt, id);
1799 ABORT_WITH(tt, PRNOENT);
1800 code = pr_ReadEntry(tt, 0, pos, &tentry);
1802 ABORT_WITH(tt, code);
1803 tflags = tentry.flags;
1805 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1806 if (!AccessOK(tt, cid, 0, 0, 0))
1807 ABORT_WITH(tt, PRPERM);
1808 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1809 tentry.ngroups = tentry.nusers = 20;
1812 if (!AccessOK(tt, cid, &tentry, 0, 0))
1813 ABORT_WITH(tt, PRPERM);
1816 if (mask & 0xffff) { /* if setting flag bits */
1817 afs_int32 flagsMask = mask & 0xffff;
1818 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1819 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1823 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1825 ABORT_WITH(tt, PRBADARG);
1826 tentry.ngroups = ngroups;
1830 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1832 ABORT_WITH(tt, PRBADARG);
1833 tentry.nusers = nusers;
1836 tentry.flags = tflags;
1838 code = pr_WriteEntry(tt, 0, pos, &tentry);
1840 ABORT_WITH(tt, code);
1842 code = ubik_EndTrans(tt);
1847 SPR_ListElements(call, aid, alist, over)
1848 struct rx_call *call;
1855 code = listElements(call, aid, alist, over);
1856 osi_auditU(call, PTS_LstEleEvent, code, AUD_LONG, aid, AUD_END);
1861 listElements(call, aid, alist, over)
1862 struct rx_call *call;
1867 register afs_int32 code;
1868 struct ubik_trans *tt;
1871 struct prentry tentry;
1874 alist->prlist_len = 0;
1875 alist->prlist_val = NULL;
1878 if (code != PRSUCCESS)
1880 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1883 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1885 ABORT_WITH(tt, code);
1886 code = read_DbHeader(tt);
1888 ABORT_WITH(tt, code);
1890 code = WhoIsThis(call, tt, &cid);
1892 ABORT_WITH(tt, PRPERM);
1894 temp = FindByID(tt, aid);
1896 ABORT_WITH(tt, PRNOENT);
1897 code = pr_ReadEntry(tt, 0, temp, &tentry);
1899 ABORT_WITH(tt, code);
1900 if (!AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1901 ABORT_WITH(tt, PRPERM);
1903 code = GetList(tt, &tentry, alist, 0);
1904 if (code != PRSUCCESS)
1905 ABORT_WITH(tt, code);
1907 code = ubik_EndTrans(tt);
1913 SPR_ListSuperGroups(call, aid, alist, over)
1914 struct rx_call *call;
1919 #if defined(SUPERGROUPS)
1922 code = listSuperGroups(call, aid, alist, over);
1923 osi_auditU(call, "PTS_LstSGrps", code, AUD_LONG, aid, AUD_END);
1926 return RXGEN_OPCODE;
1930 #if defined(SUPERGROUPS)
1932 listSuperGroups(call, aid, alist, over)
1933 struct rx_call *call;
1938 register afs_int32 code;
1939 struct ubik_trans *tt;
1942 struct prentry tentry;
1944 alist->prlist_len = 0;
1945 alist->prlist_val = (afs_int32 *) 0;
1948 if (code != PRSUCCESS)
1950 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1953 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1955 ABORT_WITH(tt, code);
1956 code = WhoIsThis(call, tt, &cid);
1958 ABORT_WITH(tt, PRPERM);
1960 temp = FindByID(tt, aid);
1962 ABORT_WITH(tt, PRNOENT);
1963 code = pr_ReadEntry(tt, 0, temp, &tentry);
1965 ABORT_WITH(tt, code);
1966 if (!AccessOK(tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1967 ABORT_WITH(tt, PRPERM);
1969 code = GetSGList(tt, &tentry, alist);
1971 if (code == PRTOOMANY)
1973 else if (code != PRSUCCESS)
1974 ABORT_WITH(tt, code);
1976 code = ubik_EndTrans(tt);
1982 #endif /* SUPERGROUPS */
1986 * List the entries owned by this id. If the id is zero,
1987 * return the orphans list. This will return up to PR_MAXGROUPS
1988 * at a time with the lastP available to get the rest. The
1989 * maximum value is enforced in GetOwnedChain().
1992 SPR_ListOwned(call, aid, alist, lastP)
1993 struct rx_call *call;
2000 code = listOwned(call, aid, alist, lastP);
2001 osi_auditU(call, PTS_LstOwnEvent, code, AUD_LONG, aid, AUD_END);
2006 listOwned(call, aid, alist, lastP)
2007 struct rx_call *call;
2012 register afs_int32 code;
2013 struct ubik_trans *tt;
2015 struct prentry tentry;
2019 alist->prlist_len = 0;
2020 alist->prlist_val = NULL;
2028 if (code != PRSUCCESS)
2030 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2033 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2035 ABORT_WITH(tt, code);
2036 code = read_DbHeader(tt);
2038 ABORT_WITH(tt, code);
2040 code = WhoIsThis(call, tt, &cid);
2042 ABORT_WITH(tt, PRPERM);
2045 code = pr_ReadEntry(tt, 0, start, &tentry);
2046 if (!code && (tentry.owner == aid))
2047 head = start; /* pick up where we left off */
2052 afs_int32 loc = FindByID(tt, aid);
2054 ABORT_WITH(tt, PRNOENT);
2055 code = pr_ReadEntry(tt, 0, loc, &tentry);
2057 ABORT_WITH(tt, code);
2059 if (!AccessOK(tt, cid, &tentry, -1, PRP_OWNED_ANY))
2060 ABORT_WITH(tt, PRPERM);
2061 head = tentry.owned;
2063 if (!AccessOK(tt, cid, 0, 0, 0))
2064 ABORT_WITH(tt, PRPERM);
2065 head = ntohl(cheader.orphan);
2069 code = GetOwnedChain(tt, &head, alist);
2071 if (code == PRTOOMANY)
2074 ABORT_WITH(tt, code);
2077 code = ubik_EndTrans(tt);
2082 SPR_IsAMemberOf(call, uid, gid, flag)
2083 struct rx_call *call;
2090 code = isAMemberOf(call, uid, gid, flag);
2091 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
2097 isAMemberOf(call, uid, gid, flag)
2098 struct rx_call *call;
2103 register afs_int32 code;
2104 struct ubik_trans *tt;
2107 if (code != PRSUCCESS)
2109 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2112 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2114 ABORT_WITH(tt, code);
2115 code = read_DbHeader(tt);
2117 ABORT_WITH(tt, code);
2121 afs_int32 uloc = FindByID(tt, uid);
2122 afs_int32 gloc = FindByID(tt, gid);
2123 struct prentry uentry, gentry;
2126 ABORT_WITH(tt, PRNOENT);
2127 code = WhoIsThis(call, tt, &cid);
2129 ABORT_WITH(tt, PRPERM);
2130 code = pr_ReadEntry(tt, 0, uloc, &uentry);
2132 ABORT_WITH(tt, code);
2133 code = pr_ReadEntry(tt, 0, gloc, &gentry);
2135 ABORT_WITH(tt, code);
2136 #if !defined(SUPERGROUPS)
2137 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
2138 ABORT_WITH(tt, PRBADARG);
2140 if (!(gentry.flags & PRGRP))
2141 ABORT_WITH(tt, PRBADARG);
2143 if (!AccessOK(tt, cid, &uentry, 0, PRP_MEMBER_ANY)
2144 && !AccessOK(tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2145 ABORT_WITH(tt, PRPERM);
2148 *flag = IsAMemberOf(tt, uid, gid);
2149 code = ubik_EndTrans(tt);
2168 addWildCards(tt, alist, host)
2169 struct ubik_trans *tt;
2174 struct prentry tentry;
2176 unsigned wild = htonl(0xffffff00);
2177 struct in_addr iaddr;
2179 int size = 0, i, code;
2182 while ((host = (host & wild))) {
2183 wild = htonl(ntohl(wild) << 8);
2184 iaddr.s_addr = host;
2185 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
2186 if (code == PRSUCCESS && hostid != 0) {
2187 temp = FindByID(tt, hostid);
2189 code = pr_ReadEntry(tt, 0, temp, &tentry);
2190 if (code != PRSUCCESS)
2196 wlist.prlist_len = 0;
2197 wlist.prlist_val = NULL;
2199 code = GetList(tt, &tentry, &wlist, 0);
2202 added += wlist.prlist_len;
2203 for (i = 0; i < wlist.prlist_len; i++) {
2204 if (!inCPS(*alist, wlist.prlist_val[i]))
2205 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
2206 free(wlist.prlist_val);
2210 if (wlist.prlist_val)
2211 free(wlist.prlist_val);
2214 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
2217 #endif /* IP_WILDCARDS */
2221 WhoIsThisWithName(acall, at, aid, aname)
2222 struct rx_call *acall;
2223 struct ubik_trans *at;
2227 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2228 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2229 register struct rx_connection *tconn;
2230 register afs_int32 code;
2231 char tcell[MAXKTCREALMLEN];
2232 char name[MAXKTCNAMELEN];
2233 char inst[MAXKTCNAMELEN];
2238 tconn = rx_ConnectionOf(acall);
2239 code = rx_SecurityClassOf(tconn);
2242 else if (code == 1) { /* vab class */
2243 goto done; /* no longer supported */
2244 } else if (code == 2) { /* kad class */
2247 extern char *pr_realmName;
2249 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
2250 name, inst, tcell, NULL)))
2252 strncpy(vname, name, sizeof(vname));
2253 if ((ilen = strlen(inst))) {
2254 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2257 strcat(vname, inst);
2259 if ((clen = strlen(tcell))) {
2261 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
2262 static char local_realm[AFS_REALM_SZ] = "";
2263 if (!local_realm[0]) {
2264 if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
2265 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
2269 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
2270 strcasecmp(local_realm, tcell) &&
2272 strcasecmp(pr_realmName, tcell)) {
2273 if (strlen(vname) + 1 + clen >= sizeof(vname))
2276 strcat(vname, tcell);
2277 lcstring(vname, vname, sizeof(vname));
2278 code = NameToID(at, vname, aid);
2279 strcpy(aname, vname);
2284 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2285 *aid = SYSADMINID; /* special case for the fileserver */
2287 lcstring(vname, vname, sizeof(vname));
2288 code = NameToID(at, vname, aid);
2292 if (code && !pr_noAuth)