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>
70 #include <arpa/inet.h>
75 #include "ptprototypes.h"
76 #include "afs/audit.h"
78 #ifdef AFS_ATHENA_STDENV
83 #define IP_WILDCARDS 1 /* XXX Should be defined outside of here XXX */
85 extern int restricted;
86 extern struct ubik_dbase *dbase;
87 extern afs_int32 Initdb();
89 extern afs_int32 initd;
90 extern char *pr_realmName;
91 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(),
92 nameToID(), Delete(), removeFromGroup();
93 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
94 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
95 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
97 #if defined(SUPERGROUPS)
98 afs_int32 listSuperGroups();
103 extern int prp_group_default;
104 extern int prp_user_default;
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 (restricted && !admin)
122 if (flag & PRFOREIGN) {
123 /* Foreign users are recognized by the '@' sign and
124 * not by the PRFOREIGN flag.
127 } else if (flag & PRGRP) {
128 /* Allow anonymous group creation only if owner specified
129 * and running noAuth.
131 if (cid == ANONYMOUSID) {
132 if ((oid == 0) || !pr_noAuth)
135 } else { /* creating a user */
136 if (!admin && !pr_noAuth)
143 WhoIsThis(acall, at, aid)
144 struct rx_call *acall;
145 struct ubik_trans *at;
149 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
150 /* returns -1 and sets aid to ANONYMOUSID on any failure */
151 register struct rx_connection *tconn;
152 register afs_int32 code;
153 char tcell[MAXKTCREALMLEN];
154 char name[MAXKTCNAMELEN];
155 char inst[MAXKTCNAMELEN];
160 tconn = rx_ConnectionOf(acall);
161 code = rx_SecurityClassOf(tconn);
164 else if (code == 1) { /* vab class */
165 goto done; /* no longer supported */
166 } else if (code == 2) { /* kad class */
167 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
168 name, inst, tcell, NULL)))
171 /* This test is unnecessary, since rxkad_GetServerInfo already check.
172 * In addition, this is wrong since exp must be unsigned. */
173 if (exp < FT_ApproxTime())
177 foreign = afs_is_foreign_ticket_name(name,inst,tcell,pr_realmName);
179 strncpy(vname, name, sizeof(vname));
180 if (ilen = strlen(inst)) {
181 if (strlen(vname) + 1 + ilen >= sizeof(vname))
187 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
190 strcat(vname, tcell);
192 if (strcmp(AUTH_SUPERUSER, vname) == 0)
193 *aid = SYSADMINID; /* special case for the fileserver */
195 lcstring(vname, vname, sizeof(vname));
196 code = NameToID(at, vname, aid);
200 if (code && !pr_noAuth)
206 SPR_INewEntry(call, aname, aid, oid)
207 struct rx_call *call;
208 char aname[PR_MAXNAMELEN];
213 afs_int32 cid = ANONYMOUSID;
215 code = iNewEntry(call, aname, aid, oid, &cid);
216 osi_auditU(call, PTS_INewEntEvent, code, AUD_ID, aid, AUD_STR, aname,
217 AUD_ID, oid, AUD_END);
218 ViceLog(25, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, aid, aname, oid));
223 iNewEntry(call, aname, aid, oid, cid)
224 struct rx_call *call;
225 char aname[PR_MAXNAMELEN];
230 /* used primarily for conversion - not intended to be used as usual means
231 * of entering people into the database. */
232 struct ubik_trans *tt;
233 register afs_int32 code;
239 if (code != PRSUCCESS)
241 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
244 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
246 ABORT_WITH(tt, code);
247 code = read_DbHeader(tt);
249 ABORT_WITH(tt, code);
251 code = WhoIsThis(call, tt, cid);
253 ABORT_WITH(tt, PRPERM);
254 admin = IsAMemberOf(tt, *cid, SYSADMINID);
256 /* first verify the id is good */
258 ABORT_WITH(tt, PRPERM);
261 /* only sysadmin can reuse a group id */
262 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
263 ABORT_WITH(tt, PRPERM);
265 if (FindByID(tt, aid))
266 ABORT_WITH(tt, PRIDEXIST);
268 /* check a few other things */
269 if (!CreateOK(tt, *cid, oid, gflag, admin))
270 ABORT_WITH(tt, PRPERM);
272 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
273 if (code != PRSUCCESS)
274 ABORT_WITH(tt, code);
276 /* finally, commit transaction */
277 code = ubik_EndTrans(tt);
285 SPR_NewEntry(call, aname, flag, oid, aid)
286 struct rx_call *call;
287 char aname[PR_MAXNAMELEN];
293 afs_int32 cid = ANONYMOUSID;
295 code = newEntry(call, aname, flag, oid, aid, &cid);
296 osi_auditU(call, PTS_NewEntEvent, code, AUD_ID, *aid, AUD_STR, aname,
297 AUD_ID, oid, AUD_END);
298 ViceLog(25, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, *aid, aname, oid));
303 newEntry(call, aname, flag, oid, aid, cid)
304 struct rx_call *call;
305 char aname[PR_MAXNAMELEN];
311 register afs_int32 code;
312 struct ubik_trans *tt;
314 extern afs_int32 WhoIsThisWithName();
315 char cname[PR_MAXNAMELEN];
320 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
323 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
325 ABORT_WITH(tt, code);
326 code = read_DbHeader(tt);
328 ABORT_WITH(tt, code);
330 /* this is for cross-cell self registration. It is not added in the
331 * SPR_INewEntry because we want self-registration to only do
332 * automatic id assignment.
334 code = WhoIsThisWithName(call, tt, cid, cname);
335 if (code != 2) { /* 2 specifies that this is a foreign cell request */
337 ABORT_WITH(tt, PRPERM);
338 admin = IsAMemberOf(tt, *cid, SYSADMINID);
340 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
341 oid = *cid = SYSADMINID;
343 if (!CreateOK(tt, *cid, oid, flag, admin))
344 ABORT_WITH(tt, PRPERM);
346 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
347 if (code != PRSUCCESS)
348 ABORT_WITH(tt, code);
350 code = ubik_EndTrans(tt);
359 SPR_WhereIsIt(call, aid, apos)
360 struct rx_call *call;
365 afs_int32 cid = ANONYMOUSID;
367 code = whereIsIt(call, aid, apos, &cid);
368 osi_auditU(call, PTS_WheIsItEvent, code, AUD_ID, aid, AUD_LONG, *apos,
370 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d", code, cid, aid, *apos));
375 whereIsIt(call, aid, apos, cid)
376 struct rx_call *call;
381 register afs_int32 code;
382 struct ubik_trans *tt;
386 if (code != PRSUCCESS)
388 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
391 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
393 ABORT_WITH(tt, code);
394 code = read_DbHeader(tt);
396 ABORT_WITH(tt, code);
398 code = WhoIsThis(call, tt, cid);
400 ABORT_WITH(tt, PRPERM);
402 temp = FindByID(tt, aid);
404 ABORT_WITH(tt, PRNOENT);
406 code = ubik_EndTrans(tt);
414 SPR_DumpEntry(call, apos, aentry)
415 struct rx_call *call;
417 struct prdebugentry *aentry;
420 afs_int32 cid = ANONYMOUSID;
422 code = dumpEntry(call, apos, aentry, &cid);
423 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
424 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d", code, cid, apos));
429 dumpEntry(call, apos, aentry, cid)
430 struct rx_call *call;
432 struct prdebugentry *aentry;
435 register afs_int32 code;
436 struct ubik_trans *tt;
439 if (code != PRSUCCESS)
441 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
444 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
446 ABORT_WITH(tt, code);
447 code = read_DbHeader(tt);
449 ABORT_WITH(tt, code);
451 code = WhoIsThis(call, tt, cid);
453 ABORT_WITH(tt, PRPERM);
454 code = pr_ReadEntry(tt, 0, apos, aentry);
456 ABORT_WITH(tt, code);
458 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
459 ABORT_WITH(tt, PRPERM);
461 /* Since prdebugentry is in the form of a prentry not a coentry, we will
462 * return the coentry slots in network order where the string is. */
464 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
465 code = pr_ReadCoEntry(tt, 0, apos, aentry);
467 ABORT_WITH(tt, code);
470 code = ubik_EndTrans(tt);
477 SPR_AddToGroup(call, aid, gid)
478 struct rx_call *call;
483 afs_int32 cid = ANONYMOUSID;
485 code = addToGroup(call, aid, gid, &cid);
486 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
488 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
493 addToGroup(call, aid, gid, cid)
494 struct rx_call *call;
499 register afs_int32 code;
500 struct ubik_trans *tt;
503 struct prentry tentry;
504 struct prentry uentry;
507 if (code != PRSUCCESS)
509 if (gid == ANYUSERID || gid == AUTHUSERID)
511 if (aid == ANONYMOUSID)
513 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
516 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
518 ABORT_WITH(tt, code);
519 code = read_DbHeader(tt);
521 ABORT_WITH(tt, code);
523 code = WhoIsThis(call, tt, cid);
525 ABORT_WITH(tt, PRPERM);
526 tempu = FindByID(tt, aid);
528 ABORT_WITH(tt, PRNOENT);
529 memset(&uentry, 0, sizeof(uentry));
530 code = pr_ReadEntry(tt, 0, tempu, &uentry);
532 ABORT_WITH(tt, code);
534 #if !defined(SUPERGROUPS)
535 /* we don't allow groups as members of groups at present */
536 if (uentry.flags & PRGRP)
537 ABORT_WITH(tt, PRNOTUSER);
540 tempg = FindByID(tt, gid);
542 ABORT_WITH(tt, PRNOENT);
543 code = pr_ReadEntry(tt, 0, tempg, &tentry);
545 ABORT_WITH(tt, code);
546 /* make sure that this is a group */
547 if (!(tentry.flags & PRGRP))
548 ABORT_WITH(tt, PRNOTGROUP);
549 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
550 ABORT_WITH(tt, PRPERM);
552 code = AddToEntry(tt, &tentry, tempg, aid);
553 if (code != PRSUCCESS)
554 ABORT_WITH(tt, code);
556 #if defined(SUPERGROUPS)
557 if (uentry.flags & PRGRP)
558 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
561 /* now, modify the user's entry as well */
562 code = AddToEntry(tt, &uentry, tempu, gid);
563 if (code != PRSUCCESS)
564 ABORT_WITH(tt, code);
565 code = ubik_EndTrans(tt);
572 SPR_NameToID(call, aname, aid)
573 struct rx_call *call;
579 code = nameToID(call, aname, aid);
580 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
581 ViceLog(125, ("PTS_NameToID: code %d", code));
586 nameToID(call, aname, aid)
587 struct rx_call *call;
591 register afs_int32 code;
592 struct ubik_trans *tt;
597 /* Initialize return struct */
599 aid->idlist_val = NULL;
601 size = aname->namelist_len;
607 aid->idlist_val = (afs_int32 *) malloc(size * sizeof(afs_int32));
608 if (!aid->idlist_val)
612 if (code != PRSUCCESS)
614 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
617 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
619 ABORT_WITH(tt, code);
620 code = read_DbHeader(tt);
622 ABORT_WITH(tt, code);
624 for (i = 0; i < aname->namelist_len; i++) {
626 char *nameinst, *cell;
628 strncpy(vname, aname->namelist_val[i], sizeof(vname));
629 vname[sizeof(vname)-1] ='\0';
632 cell = strchr(vname, '@');
638 if (cell && afs_is_foreign_ticket_name(nameinst,NULL,cell,pr_realmName))
639 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
641 code = NameToID(tt, nameinst, &aid->idlist_val[i]);
643 if (code != PRSUCCESS)
644 aid->idlist_val[i] = ANONYMOUSID;
645 osi_audit(PTS_NmToIdEvent, code, AUD_STR,
646 aname->namelist_val[i], AUD_ID, aid->idlist_val[i],
648 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d", code,
649 aname->namelist_val[i], aid->idlist_val[i]));
651 IOMGR_Poll(), count = 0;
653 aid->idlist_len = aname->namelist_len;
655 code = ubik_EndTrans(tt);
663 * Given an array of ids, find the name for each of them.
664 * The array of ids and names is unlimited.
667 SPR_IDToName(call, aid, aname)
668 struct rx_call *call;
674 code = idToName(call, aid, aname);
675 osi_auditU(call, PTS_IdToNmEvent, code, AUD_END);
676 ViceLog(125, ("PTS_IDToName: code %d", code));
681 idToName(call, aid, aname)
682 struct rx_call *call;
686 register afs_int32 code;
687 struct ubik_trans *tt;
692 /* leave this first for rpc stub */
693 size = aid->idlist_len;
698 aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
699 aname->namelist_len = 0;
700 if (aname->namelist_val == 0)
702 if (aid->idlist_len == 0)
705 return PRTOOMANY; /* rxgen will probably handle this */
708 if (code != PRSUCCESS)
710 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
713 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
715 ABORT_WITH(tt, code);
716 code = read_DbHeader(tt);
718 ABORT_WITH(tt, code);
720 for (i = 0; i < aid->idlist_len; i++) {
721 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
722 if (code != PRSUCCESS)
723 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
724 osi_audit(PTS_IdToNmEvent, code, AUD_ID, aid->idlist_val[i],
725 AUD_STR, aname->namelist_val[i], AUD_END);
726 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s", code,
727 aid->idlist_val[i], aname->namelist_val[i]));
729 IOMGR_Poll(), count = 0;
731 aname->namelist_len = aid->idlist_len;
733 code = ubik_EndTrans(tt);
740 SPR_Delete(call, aid)
741 struct rx_call *call;
745 afs_int32 cid = ANONYMOUSID;
747 code = Delete(call, aid, &cid);
748 osi_auditU(call, PTS_DelEvent, code, AUD_ID, aid, AUD_END);
749 ViceLog(25, ("PTS_Delete: code %d cid %d aid %d", code, cid, aid));
754 Delete(call, aid, cid)
755 struct rx_call *call;
759 register afs_int32 code;
760 struct ubik_trans *tt;
761 struct prentry tentry;
768 if (code != PRSUCCESS)
770 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
771 || aid == ANONYMOUSID)
773 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
776 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
778 ABORT_WITH(tt, code);
779 code = read_DbHeader(tt);
781 ABORT_WITH(tt, code);
783 code = WhoIsThis(call, tt, cid);
785 ABORT_WITH(tt, PRPERM);
787 /* Read in entry to be deleted */
788 loc = FindByID(tt, aid);
790 ABORT_WITH(tt, PRNOENT);
791 code = pr_ReadEntry(tt, 0, loc, &tentry);
793 ABORT_WITH(tt, PRDBFAIL);
795 /* Do some access checking */
796 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
797 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
798 ABORT_WITH(tt, PRPERM);
800 /* Delete each continuation block as a separate transaction so that no one
801 * transaction become to large to complete. */
803 while (nptr != (afs_int32) NULL) {
804 struct contentry centry;
807 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
809 ABORT_WITH(tt, PRDBFAIL);
810 for (i = 0; i < COSIZE; i++) {
811 if (centry.entries[i] == PRBADID)
813 if (centry.entries[i] == 0)
815 #if defined(SUPERGROUPS)
816 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
817 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
820 code = RemoveFromEntry(tt, aid, centry.entries[i]);
822 ABORT_WITH(tt, code);
823 tentry.count--; /* maintain count */
827 tentry.next = centry.next; /* thread out this block */
828 code = FreeBlock(tt, nptr); /* free continuation block */
830 ABORT_WITH(tt, code);
831 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
833 ABORT_WITH(tt, code);
835 /* end this trans and start a new one */
836 code = ubik_EndTrans(tt);
839 IOMGR_Poll(); /* just to keep the connection alive */
840 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
843 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
845 ABORT_WITH(tt, code);
847 /* re-read entry to get consistent uptodate info */
848 loc = FindByID(tt, aid);
850 ABORT_WITH(tt, PRNOENT);
851 code = pr_ReadEntry(tt, 0, loc, &tentry);
853 ABORT_WITH(tt, PRDBFAIL);
858 #if defined(SUPERGROUPS)
859 /* Delete each continuation block as a separate transaction
860 * so that no one transaction become too large to complete. */
862 struct prentryg *tentryg = (struct prentryg *)&tentry;
863 nptr = tentryg->nextsg;
864 while (nptr != NULL) {
865 struct contentry centry;
868 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
870 ABORT_WITH(tt, PRDBFAIL);
871 for (i = 0; i < COSIZE; i++) {
872 if (centry.entries[i] == PRBADID)
874 if (centry.entries[i] == 0)
876 code = RemoveFromEntry(tt, aid, centry.entries[i]);
878 ABORT_WITH(tt, code);
879 tentryg->countsg--; /* maintain count */
883 tentryg->nextsg = centry.next; /* thread out this block */
884 code = FreeBlock(tt, nptr); /* free continuation block */
886 ABORT_WITH(tt, code);
887 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
889 ABORT_WITH(tt, code);
891 /* end this trans and start a new one */
892 code = ubik_EndTrans(tt);
895 IOMGR_Poll(); /* just to keep the connection alive */
897 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
900 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
902 ABORT_WITH(tt, code);
904 /* re-read entry to get consistent uptodate info */
905 loc = FindByID(tt, aid);
907 ABORT_WITH(tt, PRNOENT);
908 code = pr_ReadEntry(tt, 0, loc, &tentry);
910 ABORT_WITH(tt, PRDBFAIL);
912 nptr = tentryg->nextsg;
916 #endif /* SUPERGROUPS */
918 /* Then move the owned chain, except possibly ourself to the orphan list.
919 * Because this list can be very long and so exceed the size of a ubik
920 * transaction, we start a new transaction every 50 entries. */
923 while (nptr != (afs_int32) NULL) {
924 struct prentry nentry;
926 code = pr_ReadEntry(tt, 0, nptr, &nentry);
928 ABORT_WITH(tt, PRDBFAIL);
929 nptr = tentry.owned = nentry.nextOwned; /* thread out */
931 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
932 code = AddToOrphan(tt, nentry.id);
934 ABORT_WITH(tt, code);
936 if ((count & 3) == 0)
941 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
943 ABORT_WITH(tt, code);
945 /* end this trans and start a new one */
946 code = ubik_EndTrans(tt);
949 IOMGR_Poll(); /* just to keep the connection alive */
950 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
953 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
955 ABORT_WITH(tt, code);
957 /* re-read entry to get consistent uptodate info */
958 loc = FindByID(tt, aid);
960 ABORT_WITH(tt, PRNOENT);
961 code = pr_ReadEntry(tt, 0, loc, &tentry);
963 ABORT_WITH(tt, PRDBFAIL);
968 /* now do what's left of the deletion stuff */
969 code = DeleteEntry(tt, &tentry, loc);
970 if (code != PRSUCCESS)
971 ABORT_WITH(tt, code);
973 code = ubik_EndTrans(tt);
980 SPR_UpdateEntry(call, aid, name, uentry)
981 struct rx_call *call;
984 struct PrUpdateEntry *uentry;
987 afs_int32 cid = ANONYMOUSID;
989 code = UpdateEntry(call, aid, name, uentry, &cid);
990 osi_auditU(call, PTS_UpdEntEvent, code, AUD_ID, aid, AUD_STR, name, AUD_END);
991 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s", code, cid, aid, name));
996 UpdateEntry(call, aid, name, uentry, cid)
997 struct rx_call *call;
1000 struct PrUpdateEntry *uentry;
1003 register afs_int32 code;
1004 struct ubik_trans *tt;
1005 struct prentry tentry;
1012 if (code != PRSUCCESS)
1016 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
1017 || aid == ANONYMOUSID)
1020 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1023 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1025 ABORT_WITH(tt, code);
1026 code = read_DbHeader(tt);
1028 ABORT_WITH(tt, code);
1030 code = WhoIsThis(call, tt, cid);
1032 ABORT_WITH(tt, PRPERM);
1033 code = IsAMemberOf(tt, *cid, SYSADMINID);
1034 if (!code && !pr_noAuth)
1035 ABORT_WITH(tt, PRPERM);
1037 /* Read in entry to be deleted */
1039 loc = FindByID(tt, aid);
1041 loc = FindByName(tt, name, &tentry);
1044 ABORT_WITH(tt, PRNOENT);
1045 code = pr_ReadEntry(tt, 0, loc, &tentry);
1047 ABORT_WITH(tt, PRDBFAIL);
1049 if (uentry->Mask & PRUPDATE_NAMEHASH) {
1051 code = RemoveFromNameHash(tt, tentry.name, &tloc);
1052 if (code != PRSUCCESS)
1053 ABORT_WITH(tt, PRDBFAIL);
1054 code = AddToNameHash(tt, tentry.name, loc);
1056 ABORT_WITH(tt, code);
1059 if (uentry->Mask & PRUPDATE_IDHASH) {
1063 code = RemoveFromIDHash(tt, id, &tloc);
1064 if (code != PRSUCCESS)
1065 ABORT_WITH(tt, PRDBFAIL);
1066 code = AddToIDHash(tt, id, loc);
1068 ABORT_WITH(tt, code);
1071 code = ubik_EndTrans(tt);
1078 SPR_RemoveFromGroup(call, aid, gid)
1079 struct rx_call *call;
1084 afs_int32 cid = ANONYMOUSID;
1086 code = removeFromGroup(call, aid, gid, &cid);
1087 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
1089 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
1094 removeFromGroup(call, aid, gid, cid)
1095 struct rx_call *call;
1100 register afs_int32 code;
1101 struct ubik_trans *tt;
1104 struct prentry uentry;
1105 struct prentry gentry;
1108 if (code != PRSUCCESS)
1110 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1113 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1115 ABORT_WITH(tt, code);
1116 code = read_DbHeader(tt);
1118 ABORT_WITH(tt, code);
1120 code = WhoIsThis(call, tt, cid);
1122 ABORT_WITH(tt, PRPERM);
1123 tempu = FindByID(tt, aid);
1125 ABORT_WITH(tt, PRNOENT);
1126 tempg = FindByID(tt, gid);
1128 ABORT_WITH(tt, PRNOENT);
1129 memset(&uentry, 0, sizeof(uentry));
1130 memset(&gentry, 0, sizeof(gentry));
1131 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1133 ABORT_WITH(tt, code);
1134 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1136 ABORT_WITH(tt, code);
1137 if (!(gentry.flags & PRGRP))
1138 ABORT_WITH(tt, PRNOTGROUP);
1139 #if !defined(SUPERGROUPS)
1140 if (uentry.flags & PRGRP)
1141 ABORT_WITH(tt, PRNOTUSER);
1143 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1144 ABORT_WITH(tt, PRPERM);
1145 code = RemoveFromEntry(tt, aid, gid);
1146 if (code != PRSUCCESS)
1147 ABORT_WITH(tt, code);
1148 #if defined(SUPERGROUPS)
1149 if (!(uentry.flags & PRGRP))
1151 code = RemoveFromEntry(tt, gid, aid);
1152 #if defined(SUPERGROUPS)
1154 code = RemoveFromSGEntry(tt, gid, aid);
1156 if (code != PRSUCCESS)
1157 ABORT_WITH(tt, code);
1159 code = ubik_EndTrans(tt);
1167 SPR_GetCPS(call, aid, alist, over)
1168 struct rx_call *call;
1174 afs_int32 cid = ANONYMOUSID;
1176 code = getCPS(call, aid, alist, over, &cid);
1177 osi_auditU(call, PTS_GetCPSEvent, code, AUD_ID, aid, AUD_END);
1178 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d", code, cid, aid));
1183 getCPS(call, aid, alist, over, cid)
1184 struct rx_call *call;
1190 register afs_int32 code;
1191 struct ubik_trans *tt;
1193 struct prentry tentry;
1196 alist->prlist_len = 0;
1197 alist->prlist_val = NULL;
1199 if (code != PRSUCCESS)
1201 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1204 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1206 ABORT_WITH(tt, code);
1207 code = read_DbHeader(tt);
1209 ABORT_WITH(tt, code);
1211 temp = FindByID(tt, aid);
1213 ABORT_WITH(tt, PRNOENT);
1214 code = pr_ReadEntry(tt, 0, temp, &tentry);
1216 ABORT_WITH(tt, code);
1218 /* afs does authenticate now */
1219 code = WhoIsThis(call, tt, cid);
1220 if (code || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1221 ABORT_WITH(tt, PRPERM);
1223 code = GetList(tt, &tentry, alist, 1);
1224 if (code != PRSUCCESS)
1225 ABORT_WITH(tt, code);
1227 code = ubik_EndTrans(tt);
1240 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1241 if (CPS.prlist_val[i] == id)
1246 #endif /* IP_WILDCARDS */
1250 SPR_GetCPS2(call, aid, ahost, alist, over)
1251 struct rx_call *call;
1258 afs_int32 cid = ANONYMOUSID;
1260 code = getCPS2(call, aid, ahost, alist, over, &cid);
1261 osi_auditU(call, PTS_GetCPS2Event, code, AUD_ID, aid, AUD_HOST, ahost,
1263 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d", code, cid, aid, ahost));
1268 getCPS2(call, aid, ahost, alist, over, cid)
1269 struct rx_call *call;
1276 register afs_int32 code;
1277 struct ubik_trans *tt;
1279 struct prentry tentry;
1280 struct prentry host_tentry;
1283 struct in_addr iaddr;
1285 extern afs_int32 addWildCards();
1286 #endif /* IP_WILDCARDS */
1289 iaddr.s_addr = ntohl(ahost);
1290 alist->prlist_len = 0;
1291 alist->prlist_val = NULL;
1293 if (code != PRSUCCESS)
1295 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1298 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1300 ABORT_WITH(tt, code);
1301 code = read_DbHeader(tt);
1303 ABORT_WITH(tt, code);
1305 if (aid != PRBADID) {
1306 temp = FindByID(tt, aid);
1308 ABORT_WITH(tt, PRNOENT);
1309 code = pr_ReadEntry(tt, 0, temp, &tentry);
1311 ABORT_WITH(tt, code);
1313 /* afs does authenticate now */
1314 code = WhoIsThis(call, tt, cid);
1316 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1317 ABORT_WITH(tt, PRPERM);
1319 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1320 if (code == PRSUCCESS && hostid != 0) {
1321 temp = FindByID(tt, hostid);
1323 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1324 if (code == PRSUCCESS)
1327 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1329 fprintf(stderr, "FindByID Failed -- Not found\n");
1332 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1334 code = GetList(tt, &tentry, alist, 1);
1337 code = addWildCards(tt, alist, ntohl(ahost));
1338 #endif /* IP_WILDCARDS */
1339 if (code != PRSUCCESS)
1340 ABORT_WITH(tt, code);
1342 code = ubik_EndTrans(tt);
1348 SPR_GetHostCPS(call, ahost, alist, over)
1349 struct rx_call *call;
1356 code = getHostCPS(call, ahost, alist, over);
1357 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
1358 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d", code, ahost));
1363 getHostCPS(call, ahost, alist, over)
1364 struct rx_call *call;
1369 register afs_int32 code, temp;
1370 struct ubik_trans *tt;
1371 struct prentry host_tentry;
1373 struct in_addr iaddr;
1375 extern afs_int32 addWildCards();
1376 #endif /* IP_WILDCARDS */
1379 iaddr.s_addr = ntohl(ahost);
1380 alist->prlist_len = 0;
1381 alist->prlist_val = NULL;
1383 if (code != PRSUCCESS)
1385 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1388 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1390 ABORT_WITH(tt, code);
1391 code = read_DbHeader(tt);
1393 ABORT_WITH(tt, code);
1395 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1396 if (code == PRSUCCESS && hostid != 0) {
1397 temp = FindByID(tt, hostid);
1399 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1400 if (code == PRSUCCESS) {
1401 code = GetList(tt, &host_tentry, alist, 0);
1405 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1407 fprintf(stderr, "FindByID Failed -- Not found\n");
1410 code = addWildCards(tt, alist, ntohl(ahost));
1411 #endif /* IP_WILDCARDS */
1413 if (code != PRSUCCESS)
1414 ABORT_WITH(tt, code);
1416 code = ubik_EndTrans(tt);
1422 SPR_ListMax(call, uid, gid)
1423 struct rx_call *call;
1429 code = listMax(call, uid, gid);
1430 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1431 ViceLog(125, ("PTS_ListMax: code %d", code));
1436 listMax(call, uid, gid)
1437 struct rx_call *call;
1441 register afs_int32 code;
1442 struct ubik_trans *tt;
1445 if (code != PRSUCCESS)
1447 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1450 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1452 ABORT_WITH(tt, code);
1453 code = read_DbHeader(tt);
1455 ABORT_WITH(tt, code);
1457 code = GetMax(tt, uid, gid);
1458 if (code != PRSUCCESS)
1459 ABORT_WITH(tt, code);
1461 code = ubik_EndTrans(tt);
1468 SPR_SetMax(call, aid, gflag)
1469 struct rx_call *call;
1474 afs_int32 cid = ANONYMOUSID;
1476 code = setMax(call, aid, gflag, &cid);
1477 osi_auditU(call, PTS_SetMaxEvent, code, AUD_ID, aid, AUD_LONG, gflag,
1479 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d", code, cid, aid, gflag));
1484 setMax(call, aid, gflag, cid)
1485 struct rx_call *call;
1490 register afs_int32 code;
1491 struct ubik_trans *tt;
1494 if (code != PRSUCCESS)
1496 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1499 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1501 ABORT_WITH(tt, code);
1502 code = read_DbHeader(tt);
1504 ABORT_WITH(tt, code);
1506 code = WhoIsThis(call, tt, cid);
1508 ABORT_WITH(tt, PRPERM);
1509 if (!AccessOK(tt, *cid, 0, 0, 0))
1510 ABORT_WITH(tt, PRPERM);
1511 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1512 ABORT_WITH(tt, PRBADARG);
1514 code = SetMax(tt, aid, gflag);
1515 if (code != PRSUCCESS)
1516 ABORT_WITH(tt, code);
1518 code = ubik_EndTrans(tt);
1525 SPR_ListEntry(call, aid, aentry)
1526 struct rx_call *call;
1528 struct prcheckentry *aentry;
1531 afs_int32 cid = ANONYMOUSID;
1533 code = listEntry(call, aid, aentry, &cid);
1534 osi_auditU(call, PTS_LstEntEvent, code, AUD_ID, aid, AUD_END);
1535 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d", code, cid, aid));
1540 listEntry(call, aid, aentry, cid)
1541 struct rx_call *call;
1543 struct prcheckentry *aentry;
1546 register afs_int32 code;
1547 struct ubik_trans *tt;
1549 struct prentry tentry;
1552 if (code != PRSUCCESS)
1554 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1557 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1559 ABORT_WITH(tt, code);
1560 code = read_DbHeader(tt);
1562 ABORT_WITH(tt, code);
1564 code = WhoIsThis(call, tt, cid);
1566 ABORT_WITH(tt, PRPERM);
1567 temp = FindByID(tt, aid);
1569 ABORT_WITH(tt, PRNOENT);
1570 code = pr_ReadEntry(tt, 0, temp, &tentry);
1572 ABORT_WITH(tt, code);
1573 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1574 ABORT_WITH(tt, PRPERM);
1576 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1577 if (aentry->flags == 0) {
1578 if (tentry.flags & PRGRP)
1579 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1581 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1583 aentry->owner = tentry.owner;
1584 aentry->id = tentry.id;
1585 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1586 aentry->creator = tentry.creator;
1587 aentry->ngroups = tentry.ngroups;
1588 aentry->nusers = tentry.nusers;
1589 aentry->count = tentry.count;
1590 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1591 code = ubik_EndTrans(tt);
1598 SPR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1599 struct rx_call *call;
1601 afs_int32 startindex;
1602 prentries *bulkentries;
1603 afs_int32 *nextstartindex;
1606 afs_int32 cid = ANONYMOUSID;
1608 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1609 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1610 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d", code, cid, flag));
1615 listEntries(call, flag, startindex, bulkentries, nextstartindex, cid)
1616 struct rx_call *call;
1618 afs_int32 startindex;
1619 prentries *bulkentries;
1620 afs_int32 *nextstartindex;
1624 struct ubik_trans *tt;
1625 afs_int32 i, eof, pos, maxentries, f;
1626 struct prentry tentry;
1627 afs_int32 pollcount = 0;
1629 *nextstartindex = -1;
1630 bulkentries->prentries_val = 0;
1631 bulkentries->prentries_len = 0;
1634 if (code != PRSUCCESS)
1636 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1639 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1641 ABORT_WITH(tt, code);
1642 code = read_DbHeader(tt);
1644 ABORT_WITH(tt, code);
1646 /* Make sure we are an authenticated caller and that we are on the
1649 code = WhoIsThis(call, tt, cid);
1651 ABORT_WITH(tt, PRPERM);
1652 code = IsAMemberOf(tt, *cid, SYSADMINID);
1653 if (!code && !pr_noAuth)
1654 ABORT_WITH(tt, PRPERM);
1656 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1657 maxentries = eof / sizeof(struct prentry);
1658 for (i = startindex; i < maxentries; i++) {
1659 pos = i * sizeof(struct prentry) + sizeof(cheader);
1660 code = pr_ReadEntry(tt, 0, pos, &tentry);
1664 if (++pollcount > 50) {
1669 f = (tentry.flags & PRTYPE);
1670 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1671 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1672 code = put_prentries(&tentry, bulkentries);
1674 break; /* Filled return array */
1681 *nextstartindex = i;
1685 if (bulkentries->prentries_val)
1686 free(bulkentries->prentries_val);
1687 bulkentries->prentries_val = 0;
1688 bulkentries->prentries_len = 0;
1689 ABORT_WITH(tt, code);
1691 code = ubik_EndTrans(tt);
1698 #define PR_MAXENTRIES 500
1700 put_prentries(tentry, bulkentries)
1701 struct prentry *tentry;
1702 prentries *bulkentries;
1704 struct prlistentries *entry;
1706 if (bulkentries->prentries_val == 0) {
1707 bulkentries->prentries_len = 0;
1708 bulkentries->prentries_val =
1709 (struct prlistentries *)malloc(PR_MAXENTRIES *
1710 sizeof(struct prentry));
1711 if (!bulkentries->prentries_val) {
1716 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1720 entry = (struct prlistentries *)bulkentries->prentries_val;
1721 entry += bulkentries->prentries_len;
1723 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1724 if (entry->flags == 0) {
1727 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1730 entry->owner = tentry->owner;
1731 entry->id = tentry->id;
1732 entry->creator = tentry->creator;
1733 entry->ngroups = tentry->ngroups;
1734 entry->nusers = tentry->nusers;
1735 entry->count = tentry->count;
1736 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1737 memset(entry->reserved, 0, sizeof(entry->reserved));
1738 bulkentries->prentries_len++;
1743 SPR_ChangeEntry(call, aid, name, oid, newid)
1744 struct rx_call *call;
1751 afs_int32 cid = ANONYMOUSID;
1753 code = changeEntry(call, aid, name, oid, newid, &cid);
1754 osi_auditU(call, PTS_ChgEntEvent, code, AUD_ID, aid, AUD_STR, name,
1755 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1756 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d", code, cid, aid, name, oid, newid));
1761 changeEntry(call, aid, name, oid, newid, cid)
1762 struct rx_call *call;
1769 register afs_int32 code;
1770 struct ubik_trans *tt;
1780 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1781 || aid == SYSADMINID)
1783 if (code != PRSUCCESS)
1785 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1788 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1790 ABORT_WITH(tt, code);
1791 code = read_DbHeader(tt);
1793 ABORT_WITH(tt, code);
1795 code = WhoIsThis(call, tt, cid);
1797 ABORT_WITH(tt, PRPERM);
1798 pos = FindByID(tt, aid);
1800 ABORT_WITH(tt, PRNOENT);
1801 /* protection check in changeentry */
1802 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1803 if (code != PRSUCCESS)
1804 ABORT_WITH(tt, code);
1806 code = ubik_EndTrans(tt);
1811 SPR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1812 struct rx_call *call;
1814 afs_int32 mask; /* specify which fields to update */
1815 afs_int32 flags, ngroups, nusers;
1816 afs_int32 spare1, spare2;
1819 afs_int32 cid = ANONYMOUSID;
1822 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1824 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_ID, id, AUD_END);
1825 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d", code, cid, id));
1830 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2, cid)
1831 struct rx_call *call;
1833 afs_int32 mask; /* specify which fields to update */
1834 afs_int32 flags, ngroups, nusers;
1835 afs_int32 spare1, spare2;
1838 register afs_int32 code;
1839 struct ubik_trans *tt;
1841 struct prentry tentry;
1845 return 0; /* no-op */
1849 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1851 if (code != PRSUCCESS)
1853 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1856 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1858 ABORT_WITH(tt, code);
1859 code = read_DbHeader(tt);
1861 ABORT_WITH(tt, code);
1863 code = WhoIsThis(call, tt, cid);
1865 ABORT_WITH(tt, PRPERM);
1866 pos = FindByID(tt, id);
1868 ABORT_WITH(tt, PRNOENT);
1869 code = pr_ReadEntry(tt, 0, pos, &tentry);
1871 ABORT_WITH(tt, code);
1872 tflags = tentry.flags;
1874 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1875 if (!AccessOK(tt, *cid, 0, 0, 0))
1876 ABORT_WITH(tt, PRPERM);
1877 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1878 tentry.ngroups = tentry.nusers = 20;
1881 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1882 ABORT_WITH(tt, PRPERM);
1885 if (mask & 0xffff) { /* if setting flag bits */
1886 afs_int32 flagsMask = mask & 0xffff;
1887 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1888 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1892 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1894 ABORT_WITH(tt, PRBADARG);
1895 tentry.ngroups = ngroups;
1899 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1901 ABORT_WITH(tt, PRBADARG);
1902 tentry.nusers = nusers;
1905 tentry.flags = tflags;
1907 code = pr_WriteEntry(tt, 0, pos, &tentry);
1909 ABORT_WITH(tt, code);
1911 code = ubik_EndTrans(tt);
1916 SPR_ListElements(call, aid, alist, over)
1917 struct rx_call *call;
1923 afs_int32 cid = ANONYMOUSID;
1925 code = listElements(call, aid, alist, over, &cid);
1926 osi_auditU(call, PTS_LstEleEvent, code, AUD_ID, aid, AUD_END);
1927 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d", code, cid, aid));
1932 listElements(call, aid, alist, over, cid)
1933 struct rx_call *call;
1939 register afs_int32 code;
1940 struct ubik_trans *tt;
1942 struct prentry tentry;
1945 alist->prlist_len = 0;
1946 alist->prlist_val = NULL;
1949 if (code != PRSUCCESS)
1951 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1954 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1956 ABORT_WITH(tt, code);
1957 code = read_DbHeader(tt);
1959 ABORT_WITH(tt, code);
1961 code = WhoIsThis(call, tt, cid);
1963 ABORT_WITH(tt, PRPERM);
1965 temp = FindByID(tt, aid);
1967 ABORT_WITH(tt, PRNOENT);
1968 code = pr_ReadEntry(tt, 0, temp, &tentry);
1970 ABORT_WITH(tt, code);
1971 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1972 ABORT_WITH(tt, PRPERM);
1974 code = GetList(tt, &tentry, alist, 0);
1975 if (code != PRSUCCESS)
1976 ABORT_WITH(tt, code);
1978 code = ubik_EndTrans(tt);
1984 SPR_ListSuperGroups(call, aid, alist, over)
1985 struct rx_call *call;
1990 #if defined(SUPERGROUPS)
1992 afs_int32 cid = ANONYMOUSID;
1994 code = listSuperGroups(call, aid, alist, over, &cid);
1995 osi_auditU(call, PTS_LstSGrps, code, AUD_ID, aid, AUD_END);
1996 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d", code, cid, aid));
1999 return RXGEN_OPCODE;
2003 #if defined(SUPERGROUPS)
2005 listSuperGroups(call, aid, alist, over, cid)
2006 struct rx_call *call;
2012 register afs_int32 code;
2013 struct ubik_trans *tt;
2015 struct prentry tentry;
2017 alist->prlist_len = 0;
2018 alist->prlist_val = (afs_int32 *) 0;
2021 if (code != PRSUCCESS)
2023 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2026 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2028 ABORT_WITH(tt, code);
2029 code = WhoIsThis(call, tt, cid);
2031 ABORT_WITH(tt, PRPERM);
2033 temp = FindByID(tt, aid);
2035 ABORT_WITH(tt, PRNOENT);
2036 code = pr_ReadEntry(tt, 0, temp, &tentry);
2038 ABORT_WITH(tt, code);
2039 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2040 ABORT_WITH(tt, PRPERM);
2042 code = GetSGList(tt, &tentry, alist);
2044 if (code == PRTOOMANY)
2046 else if (code != PRSUCCESS)
2047 ABORT_WITH(tt, code);
2049 code = ubik_EndTrans(tt);
2055 #endif /* SUPERGROUPS */
2059 * List the entries owned by this id. If the id is zero,
2060 * return the orphans list. This will return up to PR_MAXGROUPS
2061 * at a time with the lastP available to get the rest. The
2062 * maximum value is enforced in GetOwnedChain().
2065 SPR_ListOwned(call, aid, alist, lastP)
2066 struct rx_call *call;
2072 afs_int32 cid = ANONYMOUSID;
2074 code = listOwned(call, aid, alist, lastP, &cid);
2075 osi_auditU(call, PTS_LstOwnEvent, code, AUD_ID, aid, AUD_END);
2076 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d", code, cid, aid));
2081 listOwned(call, aid, alist, lastP, cid)
2082 struct rx_call *call;
2088 register afs_int32 code;
2089 struct ubik_trans *tt;
2090 struct prentry tentry;
2094 alist->prlist_len = 0;
2095 alist->prlist_val = NULL;
2103 if (code != PRSUCCESS)
2105 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2108 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2110 ABORT_WITH(tt, code);
2111 code = read_DbHeader(tt);
2113 ABORT_WITH(tt, code);
2115 code = WhoIsThis(call, tt, cid);
2117 ABORT_WITH(tt, PRPERM);
2120 code = pr_ReadEntry(tt, 0, start, &tentry);
2121 if (!code && (tentry.owner == aid))
2122 head = start; /* pick up where we left off */
2127 afs_int32 loc = FindByID(tt, aid);
2129 ABORT_WITH(tt, PRNOENT);
2130 code = pr_ReadEntry(tt, 0, loc, &tentry);
2132 ABORT_WITH(tt, code);
2134 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
2135 ABORT_WITH(tt, PRPERM);
2136 head = tentry.owned;
2138 if (!AccessOK(tt, *cid, 0, 0, 0))
2139 ABORT_WITH(tt, PRPERM);
2140 head = ntohl(cheader.orphan);
2144 code = GetOwnedChain(tt, &head, alist);
2146 if (code == PRTOOMANY)
2149 ABORT_WITH(tt, code);
2152 code = ubik_EndTrans(tt);
2157 SPR_IsAMemberOf(call, uid, gid, flag)
2158 struct rx_call *call;
2164 afs_int32 cid = ANONYMOUSID;
2166 code = isAMemberOf(call, uid, gid, flag, &cid);
2167 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
2169 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d", code, cid, uid, gid));
2174 isAMemberOf(call, uid, gid, flag, cid)
2175 struct rx_call *call;
2181 register afs_int32 code;
2182 struct ubik_trans *tt;
2185 if (code != PRSUCCESS)
2187 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2190 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2192 ABORT_WITH(tt, code);
2193 code = read_DbHeader(tt);
2195 ABORT_WITH(tt, code);
2198 afs_int32 uloc = FindByID(tt, uid);
2199 afs_int32 gloc = FindByID(tt, gid);
2200 struct prentry uentry, gentry;
2203 ABORT_WITH(tt, PRNOENT);
2204 code = WhoIsThis(call, tt, cid);
2206 ABORT_WITH(tt, PRPERM);
2207 code = pr_ReadEntry(tt, 0, uloc, &uentry);
2209 ABORT_WITH(tt, code);
2210 code = pr_ReadEntry(tt, 0, gloc, &gentry);
2212 ABORT_WITH(tt, code);
2213 #if !defined(SUPERGROUPS)
2214 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
2215 ABORT_WITH(tt, PRBADARG);
2217 if (!(gentry.flags & PRGRP))
2218 ABORT_WITH(tt, PRBADARG);
2220 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
2221 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2222 ABORT_WITH(tt, PRPERM);
2225 *flag = IsAMemberOf(tt, uid, gid);
2226 code = ubik_EndTrans(tt);
2232 addWildCards(tt, alist, host)
2233 struct ubik_trans *tt;
2238 struct prentry tentry;
2240 unsigned wild = htonl(0xffffff00);
2241 struct in_addr iaddr;
2243 int size = 0, i, code;
2246 while ((host = (host & wild))) {
2247 wild = htonl(ntohl(wild) << 8);
2248 iaddr.s_addr = host;
2249 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
2250 if (code == PRSUCCESS && hostid != 0) {
2251 temp = FindByID(tt, hostid);
2253 code = pr_ReadEntry(tt, 0, temp, &tentry);
2254 if (code != PRSUCCESS)
2260 wlist.prlist_len = 0;
2261 wlist.prlist_val = NULL;
2263 code = GetList(tt, &tentry, &wlist, 0);
2266 added += wlist.prlist_len;
2267 for (i = 0; i < wlist.prlist_len; i++) {
2268 if (!inCPS(*alist, wlist.prlist_val[i]))
2269 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
2270 free(wlist.prlist_val);
2274 if (wlist.prlist_val)
2275 free(wlist.prlist_val);
2278 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
2281 #endif /* IP_WILDCARDS */
2284 WhoIsThisWithName(acall, at, aid, aname)
2285 struct rx_call *acall;
2286 struct ubik_trans *at;
2290 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2291 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2292 register struct rx_connection *tconn;
2293 register afs_int32 code;
2294 char tcell[MAXKTCREALMLEN];
2295 char name[MAXKTCNAMELEN];
2296 char inst[MAXKTCNAMELEN];
2301 tconn = rx_ConnectionOf(acall);
2302 code = rx_SecurityClassOf(tconn);
2305 else if (code == 1) { /* vab class */
2306 goto done; /* no longer supported */
2307 } else if (code == 2) { /* kad class */
2311 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
2312 name, inst, tcell, NULL)))
2316 strncpy(vname, name, sizeof(vname));
2317 if ((ilen = strlen(inst))) {
2318 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2321 strcat(vname, inst);
2323 if ((clen = strlen(tcell))) {
2324 int foreign = afs_is_foreign_ticket_name(name,inst,tcell,pr_realmName);
2327 if (strlen(vname) + 1 + clen >= sizeof(vname))
2330 strcat(vname, tcell);
2331 lcstring(vname, vname, sizeof(vname));
2332 code = NameToID(at, vname, aid);
2333 strcpy(aname, vname);
2338 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2339 *aid = SYSADMINID; /* special case for the fileserver */
2341 lcstring(vname, vname, sizeof(vname));
2342 code = NameToID(at, vname, aid);
2346 if (code && !pr_noAuth)