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>
81 #include "ptprototypes.h"
82 #include "afs/audit.h"
84 #ifdef AFS_ATHENA_STDENV
89 #define IP_WILDCARDS 1 /* XXX Should be defined outside of here XXX */
91 extern int restricted;
92 extern struct ubik_dbase *dbase;
93 extern afs_int32 Initdb();
95 extern afs_int32 initd;
96 extern char *pr_realmName;
97 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(),
98 nameToID(), Delete(), removeFromGroup();
99 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
100 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
101 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
103 #if defined(SUPERGROUPS)
104 afs_int32 listSuperGroups();
110 extern int prp_group_default;
111 extern int prp_user_default;
113 /* When abort, reset initd so that the header is read in on next call.
114 * Abort the transaction and return the code.
116 #define ABORT_WITH(tt,code) return(initd=0,ubik_AbortTrans(tt),code)
119 CreateOK(ut, cid, oid, flag, admin)
120 struct ubik_trans *ut;
121 afs_int32 cid; /* id of caller */
122 afs_int32 oid; /* id of owner */
123 afs_int32 flag; /* indicates type of entry */
124 int admin; /* sysadmin membership */
126 if (restricted && !admin)
129 if (flag & PRFOREIGN) {
130 /* Foreign users are recognized by the '@' sign and
131 * not by the PRFOREIGN flag.
134 } else if (flag & PRGRP) {
135 /* Allow anonymous group creation only if owner specified
136 * and running noAuth.
138 if (cid == ANONYMOUSID) {
139 if ((oid == 0) || !pr_noAuth)
142 } else { /* creating a user */
143 if (!admin && !pr_noAuth)
150 WhoIsThis(acall, at, aid)
151 struct rx_call *acall;
152 struct ubik_trans *at;
156 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
157 /* returns -1 and sets aid to ANONYMOUSID on any failure */
158 register struct rx_connection *tconn;
159 register afs_int32 code;
160 char tcell[MAXKTCREALMLEN];
161 char name[MAXKTCNAMELEN];
162 char inst[MAXKTCNAMELEN];
167 tconn = rx_ConnectionOf(acall);
168 code = rx_SecurityClassOf(tconn);
171 else if (code == 1) { /* vab class */
172 goto done; /* no longer supported */
173 } else if (code == 2) { /* kad class */
174 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
175 name, inst, tcell, NULL)))
178 /* This test is unnecessary, since rxkad_GetServerInfo already check.
179 * In addition, this is wrong since exp must be unsigned. */
180 if (exp < FT_ApproxTime())
184 foreign = afs_is_foreign_ticket_name(tcell,name,inst,pr_realmName);
186 strncpy(vname, name, sizeof(vname));
187 if (ilen = strlen(inst)) {
188 if (strlen(vname) + 1 + ilen >= sizeof(vname))
194 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
197 strcat(vname, tcell);
199 if (strcmp(AUTH_SUPERUSER, vname) == 0)
200 *aid = SYSADMINID; /* special case for the fileserver */
202 lcstring(vname, vname, sizeof(vname));
203 code = NameToID(at, vname, aid);
207 if (code && !pr_noAuth)
213 SPR_INewEntry(call, aname, aid, oid)
214 struct rx_call *call;
215 char aname[PR_MAXNAMELEN];
220 afs_int32 cid = ANONYMOUSID;
222 code = iNewEntry(call, aname, aid, oid, &cid);
223 osi_auditU(call, PTS_INewEntEvent, code, AUD_ID, aid, AUD_STR, aname,
224 AUD_ID, oid, AUD_END);
225 ViceLog(25, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, aid, aname, oid));
230 iNewEntry(call, aname, aid, oid, cid)
231 struct rx_call *call;
232 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;
246 if (code != PRSUCCESS)
248 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
251 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
253 ABORT_WITH(tt, code);
254 code = read_DbHeader(tt);
256 ABORT_WITH(tt, code);
258 code = WhoIsThis(call, tt, cid);
260 ABORT_WITH(tt, PRPERM);
261 admin = IsAMemberOf(tt, *cid, SYSADMINID);
263 /* first verify the id is good */
265 ABORT_WITH(tt, PRPERM);
268 /* only sysadmin can reuse a group id */
269 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
270 ABORT_WITH(tt, PRPERM);
272 if (FindByID(tt, aid))
273 ABORT_WITH(tt, PRIDEXIST);
275 /* check a few other things */
276 if (!CreateOK(tt, *cid, oid, gflag, admin))
277 ABORT_WITH(tt, PRPERM);
279 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
280 if (code != PRSUCCESS)
281 ABORT_WITH(tt, code);
283 /* finally, commit transaction */
284 code = ubik_EndTrans(tt);
292 SPR_NewEntry(call, aname, flag, oid, aid)
293 struct rx_call *call;
294 char aname[PR_MAXNAMELEN];
300 afs_int32 cid = ANONYMOUSID;
302 code = newEntry(call, aname, flag, oid, aid, &cid);
303 osi_auditU(call, PTS_NewEntEvent, code, AUD_ID, *aid, AUD_STR, aname,
304 AUD_ID, oid, AUD_END);
305 ViceLog(25, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, *aid, aname, oid));
310 newEntry(call, aname, flag, oid, aid, cid)
311 struct rx_call *call;
312 char aname[PR_MAXNAMELEN];
318 register afs_int32 code;
319 struct ubik_trans *tt;
321 extern afs_int32 WhoIsThisWithName();
322 char cname[PR_MAXNAMELEN];
327 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
330 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
332 ABORT_WITH(tt, code);
333 code = read_DbHeader(tt);
335 ABORT_WITH(tt, code);
337 /* this is for cross-cell self registration. It is not added in the
338 * SPR_INewEntry because we want self-registration to only do
339 * automatic id assignment.
341 code = WhoIsThisWithName(call, tt, cid, cname);
342 if (code != 2) { /* 2 specifies that this is a foreign cell request */
344 ABORT_WITH(tt, PRPERM);
345 admin = IsAMemberOf(tt, *cid, SYSADMINID);
347 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
348 oid = *cid = SYSADMINID;
350 if (!CreateOK(tt, *cid, oid, flag, admin))
351 ABORT_WITH(tt, PRPERM);
353 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
354 if (code != PRSUCCESS)
355 ABORT_WITH(tt, code);
357 code = ubik_EndTrans(tt);
366 SPR_WhereIsIt(call, aid, apos)
367 struct rx_call *call;
372 afs_int32 cid = ANONYMOUSID;
374 code = whereIsIt(call, aid, apos, &cid);
375 osi_auditU(call, PTS_WheIsItEvent, code, AUD_ID, aid, AUD_LONG, *apos,
377 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d", code, cid, aid, *apos));
382 whereIsIt(call, aid, apos, cid)
383 struct rx_call *call;
388 register afs_int32 code;
389 struct ubik_trans *tt;
393 if (code != PRSUCCESS)
395 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
398 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
400 ABORT_WITH(tt, code);
401 code = read_DbHeader(tt);
403 ABORT_WITH(tt, code);
405 code = WhoIsThis(call, tt, cid);
407 ABORT_WITH(tt, PRPERM);
409 temp = FindByID(tt, aid);
411 ABORT_WITH(tt, PRNOENT);
413 code = ubik_EndTrans(tt);
421 SPR_DumpEntry(call, apos, aentry)
422 struct rx_call *call;
424 struct prdebugentry *aentry;
427 afs_int32 cid = ANONYMOUSID;
429 code = dumpEntry(call, apos, aentry, &cid);
430 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
431 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d", code, cid, apos));
436 dumpEntry(call, apos, aentry, cid)
437 struct rx_call *call;
439 struct prdebugentry *aentry;
442 register afs_int32 code;
443 struct ubik_trans *tt;
446 if (code != PRSUCCESS)
448 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
451 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
453 ABORT_WITH(tt, code);
454 code = read_DbHeader(tt);
456 ABORT_WITH(tt, code);
458 code = WhoIsThis(call, tt, cid);
460 ABORT_WITH(tt, PRPERM);
461 code = pr_ReadEntry(tt, 0, apos, aentry);
463 ABORT_WITH(tt, code);
465 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
466 ABORT_WITH(tt, PRPERM);
468 /* Since prdebugentry is in the form of a prentry not a coentry, we will
469 * return the coentry slots in network order where the string is. */
471 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
472 code = pr_ReadCoEntry(tt, 0, apos, aentry);
474 ABORT_WITH(tt, code);
477 code = ubik_EndTrans(tt);
484 SPR_AddToGroup(call, aid, gid)
485 struct rx_call *call;
490 afs_int32 cid = ANONYMOUSID;
492 code = addToGroup(call, aid, gid, &cid);
493 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
495 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
500 addToGroup(call, aid, gid, cid)
501 struct rx_call *call;
506 register afs_int32 code;
507 struct ubik_trans *tt;
510 struct prentry tentry;
511 struct prentry uentry;
514 if (code != PRSUCCESS)
516 if (gid == ANYUSERID || gid == AUTHUSERID)
518 if (aid == ANONYMOUSID)
520 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
523 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
525 ABORT_WITH(tt, code);
526 code = read_DbHeader(tt);
528 ABORT_WITH(tt, code);
530 code = WhoIsThis(call, tt, cid);
532 ABORT_WITH(tt, PRPERM);
533 tempu = FindByID(tt, aid);
535 ABORT_WITH(tt, PRNOENT);
536 memset(&uentry, 0, sizeof(uentry));
537 code = pr_ReadEntry(tt, 0, tempu, &uentry);
539 ABORT_WITH(tt, code);
541 #if !defined(SUPERGROUPS)
542 /* we don't allow groups as members of groups at present */
543 if (uentry.flags & PRGRP)
544 ABORT_WITH(tt, PRNOTUSER);
547 tempg = FindByID(tt, gid);
549 ABORT_WITH(tt, PRNOENT);
550 code = pr_ReadEntry(tt, 0, tempg, &tentry);
552 ABORT_WITH(tt, code);
553 /* make sure that this is a group */
554 if (!(tentry.flags & PRGRP))
555 ABORT_WITH(tt, PRNOTGROUP);
556 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
557 ABORT_WITH(tt, PRPERM);
559 code = AddToEntry(tt, &tentry, tempg, aid);
560 if (code != PRSUCCESS)
561 ABORT_WITH(tt, code);
563 #if defined(SUPERGROUPS)
564 if (uentry.flags & PRGRP)
565 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
568 /* now, modify the user's entry as well */
569 code = AddToEntry(tt, &uentry, tempu, gid);
570 if (code != PRSUCCESS)
571 ABORT_WITH(tt, code);
572 code = ubik_EndTrans(tt);
579 SPR_NameToID(call, aname, aid)
580 struct rx_call *call;
586 code = nameToID(call, aname, aid);
587 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
588 ViceLog(125, ("PTS_NameToID: code %d", code));
593 nameToID(call, aname, aid)
594 struct rx_call *call;
598 register afs_int32 code;
599 struct ubik_trans *tt;
604 /* Initialize return struct */
606 aid->idlist_val = NULL;
608 size = aname->namelist_len;
614 aid->idlist_val = (afs_int32 *) malloc(size * sizeof(afs_int32));
615 if (!aid->idlist_val)
619 if (code != PRSUCCESS)
621 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
624 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
626 ABORT_WITH(tt, code);
627 code = read_DbHeader(tt);
629 ABORT_WITH(tt, code);
631 for (i = 0; i < aname->namelist_len; i++) {
632 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
633 if (code != PRSUCCESS)
634 aid->idlist_val[i] = ANONYMOUSID;
635 osi_audit(PTS_NmToIdEvent, code, AUD_STR,
636 aname->namelist_val[i], AUD_ID, aid->idlist_val[i],
638 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d", code,
639 aname->namelist_val[i], aid->idlist_val[i]));
641 IOMGR_Poll(), count = 0;
643 aid->idlist_len = aname->namelist_len;
645 code = ubik_EndTrans(tt);
653 * Given an array of ids, find the name for each of them.
654 * The array of ids and names is unlimited.
657 SPR_IDToName(call, aid, aname)
658 struct rx_call *call;
664 code = idToName(call, aid, aname);
665 osi_auditU(call, PTS_IdToNmEvent, code, AUD_END);
666 ViceLog(125, ("PTS_IDToName: code %d", code));
671 idToName(call, aid, aname)
672 struct rx_call *call;
676 register afs_int32 code;
677 struct ubik_trans *tt;
682 /* leave this first for rpc stub */
683 size = aid->idlist_len;
688 aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
689 aname->namelist_len = 0;
690 if (aname->namelist_val == 0)
692 if (aid->idlist_len == 0)
695 return PRTOOMANY; /* rxgen will probably handle this */
698 if (code != PRSUCCESS)
700 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
703 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
705 ABORT_WITH(tt, code);
706 code = read_DbHeader(tt);
708 ABORT_WITH(tt, code);
710 for (i = 0; i < aid->idlist_len; i++) {
711 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
712 if (code != PRSUCCESS)
713 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
714 osi_audit(PTS_IdToNmEvent, code, AUD_ID, aid->idlist_val[i],
715 AUD_STR, aname->namelist_val[i], AUD_END);
716 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s", code,
717 aid->idlist_val[i], aname->namelist_val[i]));
719 IOMGR_Poll(), count = 0;
721 aname->namelist_len = aid->idlist_len;
723 code = ubik_EndTrans(tt);
730 SPR_Delete(call, aid)
731 struct rx_call *call;
735 afs_int32 cid = ANONYMOUSID;
737 code = Delete(call, aid, &cid);
738 osi_auditU(call, PTS_DelEvent, code, AUD_ID, aid, AUD_END);
739 ViceLog(25, ("PTS_Delete: code %d cid %d aid %d", code, cid, aid));
744 Delete(call, aid, cid)
745 struct rx_call *call;
749 register afs_int32 code;
750 struct ubik_trans *tt;
751 struct prentry tentry;
758 if (code != PRSUCCESS)
760 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
761 || aid == ANONYMOUSID)
763 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
766 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
768 ABORT_WITH(tt, code);
769 code = read_DbHeader(tt);
771 ABORT_WITH(tt, code);
773 code = WhoIsThis(call, tt, cid);
775 ABORT_WITH(tt, PRPERM);
777 /* Read in entry to be deleted */
778 loc = FindByID(tt, aid);
780 ABORT_WITH(tt, PRNOENT);
781 code = pr_ReadEntry(tt, 0, loc, &tentry);
783 ABORT_WITH(tt, PRDBFAIL);
785 /* Do some access checking */
786 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
787 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
788 ABORT_WITH(tt, PRPERM);
790 /* Delete each continuation block as a separate transaction so that no one
791 * transaction become to large to complete. */
793 while (nptr != (afs_int32) NULL) {
794 struct contentry centry;
797 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
799 ABORT_WITH(tt, PRDBFAIL);
800 for (i = 0; i < COSIZE; i++) {
801 if (centry.entries[i] == PRBADID)
803 if (centry.entries[i] == 0)
805 #if defined(SUPERGROUPS)
806 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
807 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
810 code = RemoveFromEntry(tt, aid, centry.entries[i]);
812 ABORT_WITH(tt, code);
813 tentry.count--; /* maintain count */
817 tentry.next = centry.next; /* thread out this block */
818 code = FreeBlock(tt, nptr); /* free continuation block */
820 ABORT_WITH(tt, code);
821 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
823 ABORT_WITH(tt, code);
825 /* end this trans and start a new one */
826 code = ubik_EndTrans(tt);
829 IOMGR_Poll(); /* just to keep the connection alive */
830 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
833 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
835 ABORT_WITH(tt, code);
837 /* re-read entry to get consistent uptodate info */
838 loc = FindByID(tt, aid);
840 ABORT_WITH(tt, PRNOENT);
841 code = pr_ReadEntry(tt, 0, loc, &tentry);
843 ABORT_WITH(tt, PRDBFAIL);
848 #if defined(SUPERGROUPS)
849 /* Delete each continuation block as a separate transaction
850 * so that no one transaction become too large to complete. */
852 struct prentryg *tentryg = (struct prentryg *)&tentry;
853 nptr = tentryg->nextsg;
854 while (nptr != NULL) {
855 struct contentry centry;
858 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
860 ABORT_WITH(tt, PRDBFAIL);
861 for (i = 0; i < COSIZE; i++) {
862 if (centry.entries[i] == PRBADID)
864 if (centry.entries[i] == 0)
866 code = RemoveFromEntry(tt, aid, centry.entries[i]);
868 ABORT_WITH(tt, code);
869 tentryg->countsg--; /* maintain count */
873 tentryg->nextsg = centry.next; /* thread out this block */
874 code = FreeBlock(tt, nptr); /* free continuation block */
876 ABORT_WITH(tt, code);
877 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
879 ABORT_WITH(tt, code);
881 /* end this trans and start a new one */
882 code = ubik_EndTrans(tt);
885 IOMGR_Poll(); /* just to keep the connection alive */
887 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
890 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
892 ABORT_WITH(tt, code);
894 /* re-read entry to get consistent uptodate info */
895 loc = FindByID(tt, aid);
897 ABORT_WITH(tt, PRNOENT);
898 code = pr_ReadEntry(tt, 0, loc, &tentry);
900 ABORT_WITH(tt, PRDBFAIL);
902 nptr = tentryg->nextsg;
906 #endif /* SUPERGROUPS */
908 /* Then move the owned chain, except possibly ourself to the orphan list.
909 * Because this list can be very long and so exceed the size of a ubik
910 * transaction, we start a new transaction every 50 entries. */
913 while (nptr != (afs_int32) NULL) {
914 struct prentry nentry;
916 code = pr_ReadEntry(tt, 0, nptr, &nentry);
918 ABORT_WITH(tt, PRDBFAIL);
919 nptr = tentry.owned = nentry.nextOwned; /* thread out */
921 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
922 code = AddToOrphan(tt, nentry.id);
924 ABORT_WITH(tt, code);
926 if ((count & 3) == 0)
931 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
933 ABORT_WITH(tt, code);
935 /* end this trans and start a new one */
936 code = ubik_EndTrans(tt);
939 IOMGR_Poll(); /* just to keep the connection alive */
940 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
943 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
945 ABORT_WITH(tt, code);
947 /* re-read entry to get consistent uptodate info */
948 loc = FindByID(tt, aid);
950 ABORT_WITH(tt, PRNOENT);
951 code = pr_ReadEntry(tt, 0, loc, &tentry);
953 ABORT_WITH(tt, PRDBFAIL);
958 /* now do what's left of the deletion stuff */
959 code = DeleteEntry(tt, &tentry, loc);
960 if (code != PRSUCCESS)
961 ABORT_WITH(tt, code);
963 code = ubik_EndTrans(tt);
970 SPR_UpdateEntry(call, aid, name, uentry)
971 struct rx_call *call;
974 struct PrUpdateEntry *uentry;
977 afs_int32 cid = ANONYMOUSID;
979 code = UpdateEntry(call, aid, name, uentry, &cid);
980 osi_auditU(call, PTS_UpdEntEvent, code, AUD_ID, aid, AUD_STR, name, AUD_END);
981 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s", code, cid, aid, name));
986 UpdateEntry(call, aid, name, uentry, cid)
987 struct rx_call *call;
990 struct PrUpdateEntry *uentry;
993 register afs_int32 code;
994 struct ubik_trans *tt;
995 struct prentry tentry;
1002 if (code != PRSUCCESS)
1006 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
1007 || aid == ANONYMOUSID)
1010 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1013 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1015 ABORT_WITH(tt, code);
1016 code = read_DbHeader(tt);
1018 ABORT_WITH(tt, code);
1020 code = WhoIsThis(call, tt, cid);
1022 ABORT_WITH(tt, PRPERM);
1023 code = IsAMemberOf(tt, *cid, SYSADMINID);
1024 if (!code && !pr_noAuth)
1025 ABORT_WITH(tt, PRPERM);
1027 /* Read in entry to be deleted */
1029 loc = FindByID(tt, aid);
1031 loc = FindByName(tt, name, &tentry);
1034 ABORT_WITH(tt, PRNOENT);
1035 code = pr_ReadEntry(tt, 0, loc, &tentry);
1037 ABORT_WITH(tt, PRDBFAIL);
1039 if (uentry->Mask & PRUPDATE_NAMEHASH) {
1041 code = RemoveFromNameHash(tt, tentry.name, &tloc);
1042 if (code != PRSUCCESS)
1043 ABORT_WITH(tt, PRDBFAIL);
1044 code = AddToNameHash(tt, tentry.name, loc);
1046 ABORT_WITH(tt, code);
1049 if (uentry->Mask & PRUPDATE_IDHASH) {
1053 code = RemoveFromIDHash(tt, id, &tloc);
1054 if (code != PRSUCCESS)
1055 ABORT_WITH(tt, PRDBFAIL);
1056 code = AddToIDHash(tt, id, loc);
1058 ABORT_WITH(tt, code);
1061 code = ubik_EndTrans(tt);
1068 SPR_RemoveFromGroup(call, aid, gid)
1069 struct rx_call *call;
1074 afs_int32 cid = ANONYMOUSID;
1076 code = removeFromGroup(call, aid, gid, &cid);
1077 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
1079 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
1084 removeFromGroup(call, aid, gid, cid)
1085 struct rx_call *call;
1090 register afs_int32 code;
1091 struct ubik_trans *tt;
1094 struct prentry uentry;
1095 struct prentry gentry;
1098 if (code != PRSUCCESS)
1100 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1103 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1105 ABORT_WITH(tt, code);
1106 code = read_DbHeader(tt);
1108 ABORT_WITH(tt, code);
1110 code = WhoIsThis(call, tt, cid);
1112 ABORT_WITH(tt, PRPERM);
1113 tempu = FindByID(tt, aid);
1115 ABORT_WITH(tt, PRNOENT);
1116 tempg = FindByID(tt, gid);
1118 ABORT_WITH(tt, PRNOENT);
1119 memset(&uentry, 0, sizeof(uentry));
1120 memset(&gentry, 0, sizeof(gentry));
1121 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1123 ABORT_WITH(tt, code);
1124 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1126 ABORT_WITH(tt, code);
1127 if (!(gentry.flags & PRGRP))
1128 ABORT_WITH(tt, PRNOTGROUP);
1129 #if !defined(SUPERGROUPS)
1130 if (uentry.flags & PRGRP)
1131 ABORT_WITH(tt, PRNOTUSER);
1133 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1134 ABORT_WITH(tt, PRPERM);
1135 code = RemoveFromEntry(tt, aid, gid);
1136 if (code != PRSUCCESS)
1137 ABORT_WITH(tt, code);
1138 #if defined(SUPERGROUPS)
1139 if (!(uentry.flags & PRGRP))
1141 code = RemoveFromEntry(tt, gid, aid);
1142 #if defined(SUPERGROUPS)
1144 code = RemoveFromSGEntry(tt, gid, aid);
1146 if (code != PRSUCCESS)
1147 ABORT_WITH(tt, code);
1149 code = ubik_EndTrans(tt);
1157 SPR_GetCPS(call, aid, alist, over)
1158 struct rx_call *call;
1164 afs_int32 cid = ANONYMOUSID;
1166 code = getCPS(call, aid, alist, over, &cid);
1167 osi_auditU(call, PTS_GetCPSEvent, code, AUD_ID, aid, AUD_END);
1168 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d", code, cid, aid));
1173 getCPS(call, aid, alist, over, cid)
1174 struct rx_call *call;
1180 register afs_int32 code;
1181 struct ubik_trans *tt;
1183 struct prentry tentry;
1186 alist->prlist_len = 0;
1187 alist->prlist_val = NULL;
1189 if (code != PRSUCCESS)
1191 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1194 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1196 ABORT_WITH(tt, code);
1197 code = read_DbHeader(tt);
1199 ABORT_WITH(tt, code);
1201 temp = FindByID(tt, aid);
1203 ABORT_WITH(tt, PRNOENT);
1204 code = pr_ReadEntry(tt, 0, temp, &tentry);
1206 ABORT_WITH(tt, code);
1208 /* afs does authenticate now */
1209 code = WhoIsThis(call, tt, cid);
1210 if (code || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1211 ABORT_WITH(tt, PRPERM);
1213 code = GetList(tt, &tentry, alist, 1);
1214 if (code != PRSUCCESS)
1215 ABORT_WITH(tt, code);
1217 code = ubik_EndTrans(tt);
1230 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1231 if (CPS.prlist_val[i] == id)
1236 #endif /* IP_WILDCARDS */
1240 SPR_GetCPS2(call, aid, ahost, alist, over)
1241 struct rx_call *call;
1248 afs_int32 cid = ANONYMOUSID;
1250 code = getCPS2(call, aid, ahost, alist, over, &cid);
1251 osi_auditU(call, PTS_GetCPS2Event, code, AUD_ID, aid, AUD_HOST, ahost,
1253 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d", code, cid, aid, ahost));
1258 getCPS2(call, aid, ahost, alist, over, cid)
1259 struct rx_call *call;
1266 register afs_int32 code;
1267 struct ubik_trans *tt;
1269 struct prentry tentry;
1270 struct prentry host_tentry;
1273 struct in_addr iaddr;
1275 extern afs_int32 addWildCards();
1276 #endif /* IP_WILDCARDS */
1279 iaddr.s_addr = ntohl(ahost);
1280 alist->prlist_len = 0;
1281 alist->prlist_val = NULL;
1283 if (code != PRSUCCESS)
1285 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1288 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1290 ABORT_WITH(tt, code);
1291 code = read_DbHeader(tt);
1293 ABORT_WITH(tt, code);
1295 if (aid != PRBADID) {
1296 temp = FindByID(tt, aid);
1298 ABORT_WITH(tt, PRNOENT);
1299 code = pr_ReadEntry(tt, 0, temp, &tentry);
1301 ABORT_WITH(tt, code);
1303 /* afs does authenticate now */
1304 code = WhoIsThis(call, tt, cid);
1306 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1307 ABORT_WITH(tt, PRPERM);
1309 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1310 if (code == PRSUCCESS && hostid != 0) {
1311 temp = FindByID(tt, hostid);
1313 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1314 if (code == PRSUCCESS)
1317 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1319 fprintf(stderr, "FindByID Failed -- Not found\n");
1322 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1324 code = GetList(tt, &tentry, alist, 1);
1327 code = addWildCards(tt, alist, ntohl(ahost));
1328 #endif /* IP_WILDCARDS */
1329 if (code != PRSUCCESS)
1330 ABORT_WITH(tt, code);
1332 code = ubik_EndTrans(tt);
1338 SPR_GetHostCPS(call, ahost, alist, over)
1339 struct rx_call *call;
1346 code = getHostCPS(call, ahost, alist, over);
1347 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
1348 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d", code, ahost));
1353 getHostCPS(call, ahost, alist, over)
1354 struct rx_call *call;
1359 register afs_int32 code, temp;
1360 struct ubik_trans *tt;
1361 struct prentry host_tentry;
1363 struct in_addr iaddr;
1365 extern afs_int32 addWildCards();
1366 #endif /* IP_WILDCARDS */
1369 iaddr.s_addr = ntohl(ahost);
1370 alist->prlist_len = 0;
1371 alist->prlist_val = NULL;
1373 if (code != PRSUCCESS)
1375 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1378 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1380 ABORT_WITH(tt, code);
1381 code = read_DbHeader(tt);
1383 ABORT_WITH(tt, code);
1385 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1386 if (code == PRSUCCESS && hostid != 0) {
1387 temp = FindByID(tt, hostid);
1389 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1390 if (code == PRSUCCESS) {
1391 code = GetList(tt, &host_tentry, alist, 0);
1395 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1397 fprintf(stderr, "FindByID Failed -- Not found\n");
1400 code = addWildCards(tt, alist, ntohl(ahost));
1401 #endif /* IP_WILDCARDS */
1403 if (code != PRSUCCESS)
1404 ABORT_WITH(tt, code);
1406 code = ubik_EndTrans(tt);
1412 SPR_ListMax(call, uid, gid)
1413 struct rx_call *call;
1419 code = listMax(call, uid, gid);
1420 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1421 ViceLog(125, ("PTS_ListMax: code %d", code));
1426 listMax(call, uid, gid)
1427 struct rx_call *call;
1431 register afs_int32 code;
1432 struct ubik_trans *tt;
1435 if (code != PRSUCCESS)
1437 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1440 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1442 ABORT_WITH(tt, code);
1443 code = read_DbHeader(tt);
1445 ABORT_WITH(tt, code);
1447 code = GetMax(tt, uid, gid);
1448 if (code != PRSUCCESS)
1449 ABORT_WITH(tt, code);
1451 code = ubik_EndTrans(tt);
1458 SPR_SetMax(call, aid, gflag)
1459 struct rx_call *call;
1464 afs_int32 cid = ANONYMOUSID;
1466 code = setMax(call, aid, gflag, &cid);
1467 osi_auditU(call, PTS_SetMaxEvent, code, AUD_ID, aid, AUD_LONG, gflag,
1469 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d", code, cid, aid, gflag));
1474 setMax(call, aid, gflag, cid)
1475 struct rx_call *call;
1480 register afs_int32 code;
1481 struct ubik_trans *tt;
1484 if (code != PRSUCCESS)
1486 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1489 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1491 ABORT_WITH(tt, code);
1492 code = read_DbHeader(tt);
1494 ABORT_WITH(tt, code);
1496 code = WhoIsThis(call, tt, cid);
1498 ABORT_WITH(tt, PRPERM);
1499 if (!AccessOK(tt, *cid, 0, 0, 0))
1500 ABORT_WITH(tt, PRPERM);
1501 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1502 ABORT_WITH(tt, PRBADARG);
1504 code = SetMax(tt, aid, gflag);
1505 if (code != PRSUCCESS)
1506 ABORT_WITH(tt, code);
1508 code = ubik_EndTrans(tt);
1515 SPR_ListEntry(call, aid, aentry)
1516 struct rx_call *call;
1518 struct prcheckentry *aentry;
1521 afs_int32 cid = ANONYMOUSID;
1523 code = listEntry(call, aid, aentry, &cid);
1524 osi_auditU(call, PTS_LstEntEvent, code, AUD_ID, aid, AUD_END);
1525 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d", code, cid, aid));
1530 listEntry(call, aid, aentry, cid)
1531 struct rx_call *call;
1533 struct prcheckentry *aentry;
1536 register afs_int32 code;
1537 struct ubik_trans *tt;
1539 struct prentry tentry;
1542 if (code != PRSUCCESS)
1544 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1547 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1549 ABORT_WITH(tt, code);
1550 code = read_DbHeader(tt);
1552 ABORT_WITH(tt, code);
1554 code = WhoIsThis(call, tt, cid);
1556 ABORT_WITH(tt, PRPERM);
1557 temp = FindByID(tt, aid);
1559 ABORT_WITH(tt, PRNOENT);
1560 code = pr_ReadEntry(tt, 0, temp, &tentry);
1562 ABORT_WITH(tt, code);
1563 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1564 ABORT_WITH(tt, PRPERM);
1566 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1567 if (aentry->flags == 0) {
1568 if (tentry.flags & PRGRP)
1569 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1571 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1573 aentry->owner = tentry.owner;
1574 aentry->id = tentry.id;
1575 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1576 aentry->creator = tentry.creator;
1577 aentry->ngroups = tentry.ngroups;
1578 aentry->nusers = tentry.nusers;
1579 aentry->count = tentry.count;
1580 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1581 code = ubik_EndTrans(tt);
1588 SPR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1589 struct rx_call *call;
1591 afs_int32 startindex;
1592 prentries *bulkentries;
1593 afs_int32 *nextstartindex;
1596 afs_int32 cid = ANONYMOUSID;
1598 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1599 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1600 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d", code, cid, flag));
1605 listEntries(call, flag, startindex, bulkentries, nextstartindex, cid)
1606 struct rx_call *call;
1608 afs_int32 startindex;
1609 prentries *bulkentries;
1610 afs_int32 *nextstartindex;
1614 struct ubik_trans *tt;
1615 afs_int32 i, eof, pos, maxentries, f;
1616 struct prentry tentry;
1617 afs_int32 pollcount = 0;
1619 *nextstartindex = -1;
1620 bulkentries->prentries_val = 0;
1621 bulkentries->prentries_len = 0;
1624 if (code != PRSUCCESS)
1626 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1629 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1631 ABORT_WITH(tt, code);
1632 code = read_DbHeader(tt);
1634 ABORT_WITH(tt, code);
1636 /* Make sure we are an authenticated caller and that we are on the
1639 code = WhoIsThis(call, tt, cid);
1641 ABORT_WITH(tt, PRPERM);
1642 code = IsAMemberOf(tt, *cid, SYSADMINID);
1643 if (!code && !pr_noAuth)
1644 ABORT_WITH(tt, PRPERM);
1646 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1647 maxentries = eof / sizeof(struct prentry);
1648 for (i = startindex; i < maxentries; i++) {
1649 pos = i * sizeof(struct prentry) + sizeof(cheader);
1650 code = pr_ReadEntry(tt, 0, pos, &tentry);
1654 if (++pollcount > 50) {
1659 f = (tentry.flags & PRTYPE);
1660 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1661 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1662 code = put_prentries(&tentry, bulkentries);
1664 break; /* Filled return array */
1671 *nextstartindex = i;
1675 if (bulkentries->prentries_val)
1676 free(bulkentries->prentries_val);
1677 bulkentries->prentries_val = 0;
1678 bulkentries->prentries_len = 0;
1679 ABORT_WITH(tt, code);
1681 code = ubik_EndTrans(tt);
1688 #define PR_MAXENTRIES 500
1690 put_prentries(tentry, bulkentries)
1691 struct prentry *tentry;
1692 prentries *bulkentries;
1694 struct prlistentries *entry;
1696 if (bulkentries->prentries_val == 0) {
1697 bulkentries->prentries_len = 0;
1698 bulkentries->prentries_val =
1699 (struct prlistentries *)malloc(PR_MAXENTRIES *
1700 sizeof(struct prentry));
1701 if (!bulkentries->prentries_val) {
1706 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1710 entry = (struct prlistentries *)bulkentries->prentries_val;
1711 entry += bulkentries->prentries_len;
1713 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1714 if (entry->flags == 0) {
1717 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1720 entry->owner = tentry->owner;
1721 entry->id = tentry->id;
1722 entry->creator = tentry->creator;
1723 entry->ngroups = tentry->ngroups;
1724 entry->nusers = tentry->nusers;
1725 entry->count = tentry->count;
1726 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1727 memset(entry->reserved, 0, sizeof(entry->reserved));
1728 bulkentries->prentries_len++;
1733 SPR_ChangeEntry(call, aid, name, oid, newid)
1734 struct rx_call *call;
1741 afs_int32 cid = ANONYMOUSID;
1743 code = changeEntry(call, aid, name, oid, newid, &cid);
1744 osi_auditU(call, PTS_ChgEntEvent, code, AUD_ID, aid, AUD_STR, name,
1745 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1746 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d", code, cid, aid, name, oid, newid));
1751 changeEntry(call, aid, name, oid, newid, cid)
1752 struct rx_call *call;
1759 register afs_int32 code;
1760 struct ubik_trans *tt;
1770 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1771 || aid == SYSADMINID)
1773 if (code != PRSUCCESS)
1775 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1778 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1780 ABORT_WITH(tt, code);
1781 code = read_DbHeader(tt);
1783 ABORT_WITH(tt, code);
1785 code = WhoIsThis(call, tt, cid);
1787 ABORT_WITH(tt, PRPERM);
1788 pos = FindByID(tt, aid);
1790 ABORT_WITH(tt, PRNOENT);
1791 /* protection check in changeentry */
1792 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1793 if (code != PRSUCCESS)
1794 ABORT_WITH(tt, code);
1796 code = ubik_EndTrans(tt);
1801 SPR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1802 struct rx_call *call;
1804 afs_int32 mask; /* specify which fields to update */
1805 afs_int32 flags, ngroups, nusers;
1806 afs_int32 spare1, spare2;
1809 afs_int32 cid = ANONYMOUSID;
1812 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1814 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_ID, id, AUD_END);
1815 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d", code, cid, id));
1820 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2, cid)
1821 struct rx_call *call;
1823 afs_int32 mask; /* specify which fields to update */
1824 afs_int32 flags, ngroups, nusers;
1825 afs_int32 spare1, spare2;
1828 register afs_int32 code;
1829 struct ubik_trans *tt;
1831 struct prentry tentry;
1835 return 0; /* no-op */
1839 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1841 if (code != PRSUCCESS)
1843 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1846 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1848 ABORT_WITH(tt, code);
1849 code = read_DbHeader(tt);
1851 ABORT_WITH(tt, code);
1853 code = WhoIsThis(call, tt, cid);
1855 ABORT_WITH(tt, PRPERM);
1856 pos = FindByID(tt, id);
1858 ABORT_WITH(tt, PRNOENT);
1859 code = pr_ReadEntry(tt, 0, pos, &tentry);
1861 ABORT_WITH(tt, code);
1862 tflags = tentry.flags;
1864 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1865 if (!AccessOK(tt, *cid, 0, 0, 0))
1866 ABORT_WITH(tt, PRPERM);
1867 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1868 tentry.ngroups = tentry.nusers = 20;
1871 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1872 ABORT_WITH(tt, PRPERM);
1875 if (mask & 0xffff) { /* if setting flag bits */
1876 afs_int32 flagsMask = mask & 0xffff;
1877 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1878 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1882 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1884 ABORT_WITH(tt, PRBADARG);
1885 tentry.ngroups = ngroups;
1889 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1891 ABORT_WITH(tt, PRBADARG);
1892 tentry.nusers = nusers;
1895 tentry.flags = tflags;
1897 code = pr_WriteEntry(tt, 0, pos, &tentry);
1899 ABORT_WITH(tt, code);
1901 code = ubik_EndTrans(tt);
1906 SPR_ListElements(call, aid, alist, over)
1907 struct rx_call *call;
1913 afs_int32 cid = ANONYMOUSID;
1915 code = listElements(call, aid, alist, over, &cid);
1916 osi_auditU(call, PTS_LstEleEvent, code, AUD_ID, aid, AUD_END);
1917 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d", code, cid, aid));
1922 listElements(call, aid, alist, over, cid)
1923 struct rx_call *call;
1929 register afs_int32 code;
1930 struct ubik_trans *tt;
1932 struct prentry tentry;
1935 alist->prlist_len = 0;
1936 alist->prlist_val = NULL;
1939 if (code != PRSUCCESS)
1941 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1944 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1946 ABORT_WITH(tt, code);
1947 code = read_DbHeader(tt);
1949 ABORT_WITH(tt, code);
1951 code = WhoIsThis(call, tt, cid);
1953 ABORT_WITH(tt, PRPERM);
1955 temp = FindByID(tt, aid);
1957 ABORT_WITH(tt, PRNOENT);
1958 code = pr_ReadEntry(tt, 0, temp, &tentry);
1960 ABORT_WITH(tt, code);
1961 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1962 ABORT_WITH(tt, PRPERM);
1964 code = GetList(tt, &tentry, alist, 0);
1965 if (code != PRSUCCESS)
1966 ABORT_WITH(tt, code);
1968 code = ubik_EndTrans(tt);
1974 SPR_ListSuperGroups(call, aid, alist, over)
1975 struct rx_call *call;
1980 #if defined(SUPERGROUPS)
1982 afs_int32 cid = ANONYMOUSID;
1984 code = listSuperGroups(call, aid, alist, over, &cid);
1985 osi_auditU(call, PTS_LstSGrps, code, AUD_ID, aid, AUD_END);
1986 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d", code, cid, aid));
1989 return RXGEN_OPCODE;
1993 #if defined(SUPERGROUPS)
1995 listSuperGroups(call, aid, alist, over, cid)
1996 struct rx_call *call;
2002 register afs_int32 code;
2003 struct ubik_trans *tt;
2005 struct prentry tentry;
2007 alist->prlist_len = 0;
2008 alist->prlist_val = (afs_int32 *) 0;
2011 if (code != PRSUCCESS)
2013 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2016 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2018 ABORT_WITH(tt, code);
2019 code = WhoIsThis(call, tt, cid);
2021 ABORT_WITH(tt, PRPERM);
2023 temp = FindByID(tt, aid);
2025 ABORT_WITH(tt, PRNOENT);
2026 code = pr_ReadEntry(tt, 0, temp, &tentry);
2028 ABORT_WITH(tt, code);
2029 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2030 ABORT_WITH(tt, PRPERM);
2032 code = GetSGList(tt, &tentry, alist);
2034 if (code == PRTOOMANY)
2036 else if (code != PRSUCCESS)
2037 ABORT_WITH(tt, code);
2039 code = ubik_EndTrans(tt);
2045 #endif /* SUPERGROUPS */
2049 * List the entries owned by this id. If the id is zero,
2050 * return the orphans list. This will return up to PR_MAXGROUPS
2051 * at a time with the lastP available to get the rest. The
2052 * maximum value is enforced in GetOwnedChain().
2055 SPR_ListOwned(call, aid, alist, lastP)
2056 struct rx_call *call;
2062 afs_int32 cid = ANONYMOUSID;
2064 code = listOwned(call, aid, alist, lastP, &cid);
2065 osi_auditU(call, PTS_LstOwnEvent, code, AUD_ID, aid, AUD_END);
2066 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d", code, cid, aid));
2071 listOwned(call, aid, alist, lastP, cid)
2072 struct rx_call *call;
2078 register afs_int32 code;
2079 struct ubik_trans *tt;
2080 struct prentry tentry;
2084 alist->prlist_len = 0;
2085 alist->prlist_val = NULL;
2093 if (code != PRSUCCESS)
2095 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2098 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2100 ABORT_WITH(tt, code);
2101 code = read_DbHeader(tt);
2103 ABORT_WITH(tt, code);
2105 code = WhoIsThis(call, tt, cid);
2107 ABORT_WITH(tt, PRPERM);
2110 code = pr_ReadEntry(tt, 0, start, &tentry);
2111 if (!code && (tentry.owner == aid))
2112 head = start; /* pick up where we left off */
2117 afs_int32 loc = FindByID(tt, aid);
2119 ABORT_WITH(tt, PRNOENT);
2120 code = pr_ReadEntry(tt, 0, loc, &tentry);
2122 ABORT_WITH(tt, code);
2124 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
2125 ABORT_WITH(tt, PRPERM);
2126 head = tentry.owned;
2128 if (!AccessOK(tt, *cid, 0, 0, 0))
2129 ABORT_WITH(tt, PRPERM);
2130 head = ntohl(cheader.orphan);
2134 code = GetOwnedChain(tt, &head, alist);
2136 if (code == PRTOOMANY)
2139 ABORT_WITH(tt, code);
2142 code = ubik_EndTrans(tt);
2147 SPR_IsAMemberOf(call, uid, gid, flag)
2148 struct rx_call *call;
2154 afs_int32 cid = ANONYMOUSID;
2156 code = isAMemberOf(call, uid, gid, flag, &cid);
2157 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
2159 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d", code, cid, uid, gid));
2164 isAMemberOf(call, uid, gid, flag, cid)
2165 struct rx_call *call;
2171 register afs_int32 code;
2172 struct ubik_trans *tt;
2175 if (code != PRSUCCESS)
2177 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2180 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2182 ABORT_WITH(tt, code);
2183 code = read_DbHeader(tt);
2185 ABORT_WITH(tt, code);
2188 afs_int32 uloc = FindByID(tt, uid);
2189 afs_int32 gloc = FindByID(tt, gid);
2190 struct prentry uentry, gentry;
2193 ABORT_WITH(tt, PRNOENT);
2194 code = WhoIsThis(call, tt, cid);
2196 ABORT_WITH(tt, PRPERM);
2197 code = pr_ReadEntry(tt, 0, uloc, &uentry);
2199 ABORT_WITH(tt, code);
2200 code = pr_ReadEntry(tt, 0, gloc, &gentry);
2202 ABORT_WITH(tt, code);
2203 #if !defined(SUPERGROUPS)
2204 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
2205 ABORT_WITH(tt, PRBADARG);
2207 if (!(gentry.flags & PRGRP))
2208 ABORT_WITH(tt, PRBADARG);
2210 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
2211 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2212 ABORT_WITH(tt, PRPERM);
2215 *flag = IsAMemberOf(tt, uid, gid);
2216 code = ubik_EndTrans(tt);
2235 addWildCards(tt, alist, host)
2236 struct ubik_trans *tt;
2241 struct prentry tentry;
2243 unsigned wild = htonl(0xffffff00);
2244 struct in_addr iaddr;
2246 int size = 0, i, code;
2249 while ((host = (host & wild))) {
2250 wild = htonl(ntohl(wild) << 8);
2251 iaddr.s_addr = host;
2252 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
2253 if (code == PRSUCCESS && hostid != 0) {
2254 temp = FindByID(tt, hostid);
2256 code = pr_ReadEntry(tt, 0, temp, &tentry);
2257 if (code != PRSUCCESS)
2263 wlist.prlist_len = 0;
2264 wlist.prlist_val = NULL;
2266 code = GetList(tt, &tentry, &wlist, 0);
2269 added += wlist.prlist_len;
2270 for (i = 0; i < wlist.prlist_len; i++) {
2271 if (!inCPS(*alist, wlist.prlist_val[i]))
2272 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
2273 free(wlist.prlist_val);
2277 if (wlist.prlist_val)
2278 free(wlist.prlist_val);
2281 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
2284 #endif /* IP_WILDCARDS */
2287 WhoIsThisWithName(acall, at, aid, aname)
2288 struct rx_call *acall;
2289 struct ubik_trans *at;
2293 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2294 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2295 register struct rx_connection *tconn;
2296 register afs_int32 code;
2297 char tcell[MAXKTCREALMLEN];
2298 char name[MAXKTCNAMELEN];
2299 char inst[MAXKTCNAMELEN];
2304 tconn = rx_ConnectionOf(acall);
2305 code = rx_SecurityClassOf(tconn);
2308 else if (code == 1) { /* vab class */
2309 goto done; /* no longer supported */
2310 } else if (code == 2) { /* kad class */
2314 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
2315 name, inst, tcell, NULL)))
2319 strncpy(vname, name, sizeof(vname));
2320 if ((ilen = strlen(inst))) {
2321 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2324 strcat(vname, inst);
2326 if ((clen = strlen(tcell))) {
2327 int foreign = afs_is_foreign_ticket_name(tcell,name,inst,pr_realmName);
2330 if (strlen(vname) + 1 + clen >= sizeof(vname))
2333 strcat(vname, tcell);
2334 lcstring(vname, vname, sizeof(vname));
2335 code = NameToID(at, vname, aid);
2336 strcpy(aname, vname);
2341 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2342 *aid = SYSADMINID; /* special case for the fileserver */
2344 lcstring(vname, vname, sizeof(vname));
2345 code = NameToID(at, vname, aid);
2349 if (code && !pr_noAuth)