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 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(),
97 nameToID(), Delete(), removeFromGroup();
98 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
99 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
100 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
102 #if defined(SUPERGROUPS)
103 afs_int32 listSuperGroups();
109 extern int prp_group_default;
110 extern int prp_user_default;
112 /* When abort, reset initd so that the header is read in on next call.
113 * Abort the transaction and return the code.
115 #define ABORT_WITH(tt,code) return(initd=0,ubik_AbortTrans(tt),code)
118 CreateOK(ut, cid, oid, flag, admin)
119 struct ubik_trans *ut;
120 afs_int32 cid; /* id of caller */
121 afs_int32 oid; /* id of owner */
122 afs_int32 flag; /* indicates type of entry */
123 int admin; /* sysadmin membership */
125 if (restricted && !admin)
128 if (flag & PRFOREIGN) {
129 /* Foreign users are recognized by the '@' sign and
130 * not by the PRFOREIGN flag.
133 } else if (flag & PRGRP) {
134 /* Allow anonymous group creation only if owner specified
135 * and running noAuth.
137 if (cid == ANONYMOUSID) {
138 if ((oid == 0) || !pr_noAuth)
141 } else { /* creating a user */
142 if (!admin && !pr_noAuth)
149 WhoIsThis(acall, at, aid)
150 struct rx_call *acall;
151 struct ubik_trans *at;
155 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
156 /* returns -1 and sets aid to ANONYMOUSID on any failure */
157 register struct rx_connection *tconn;
158 register afs_int32 code;
159 char tcell[MAXKTCREALMLEN];
160 char name[MAXKTCNAMELEN];
161 char inst[MAXKTCNAMELEN];
166 tconn = rx_ConnectionOf(acall);
167 code = rx_SecurityClassOf(tconn);
170 else if (code == 1) { /* vab class */
171 goto done; /* no longer supported */
172 } else if (code == 2) { /* kad class */
173 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
174 name, inst, tcell, NULL)))
177 /* This test is unnecessary, since rxkad_GetServerInfo already check.
178 * In addition, this is wrong since exp must be unsigned. */
179 if (exp < FT_ApproxTime())
183 extern char *pr_realmName;
184 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
185 static char local_realm[AFS_REALM_SZ] = "";
186 if (!local_realm[0]) {
187 if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
188 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
192 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
193 strcasecmp(local_realm, tcell) &&
195 strcasecmp(pr_realmName, tcell))
198 strncpy(vname, name, sizeof(vname));
199 if (ilen = strlen(inst)) {
200 if (strlen(vname) + 1 + ilen >= sizeof(vname))
206 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
209 strcat(vname, tcell);
211 if (strcmp(AUTH_SUPERUSER, vname) == 0)
212 *aid = SYSADMINID; /* special case for the fileserver */
214 lcstring(vname, vname, sizeof(vname));
215 code = NameToID(at, vname, aid);
219 if (code && !pr_noAuth)
225 SPR_INewEntry(call, aname, aid, oid)
226 struct rx_call *call;
227 char aname[PR_MAXNAMELEN];
232 afs_int32 cid = ANONYMOUSID;
234 code = iNewEntry(call, aname, aid, oid, &cid);
235 osi_auditU(call, PTS_INewEntEvent, code, AUD_LONG, aid, AUD_STR, aname,
236 AUD_LONG, oid, AUD_END);
237 ViceLog(5, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, aid, aname, oid));
242 iNewEntry(call, aname, aid, oid, cid)
243 struct rx_call *call;
244 char aname[PR_MAXNAMELEN];
249 /* used primarily for conversion - not intended to be used as usual means
250 * of entering people into the database. */
251 struct ubik_trans *tt;
252 register afs_int32 code;
258 if (code != PRSUCCESS)
260 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
263 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
265 ABORT_WITH(tt, code);
266 code = read_DbHeader(tt);
268 ABORT_WITH(tt, code);
270 code = WhoIsThis(call, tt, cid);
272 ABORT_WITH(tt, PRPERM);
273 admin = IsAMemberOf(tt, *cid, SYSADMINID);
275 /* first verify the id is good */
277 ABORT_WITH(tt, PRPERM);
280 /* only sysadmin can reuse a group id */
281 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
282 ABORT_WITH(tt, PRPERM);
284 if (FindByID(tt, aid))
285 ABORT_WITH(tt, PRIDEXIST);
287 /* check a few other things */
288 if (!CreateOK(tt, *cid, oid, gflag, admin))
289 ABORT_WITH(tt, PRPERM);
291 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
292 if (code != PRSUCCESS)
293 ABORT_WITH(tt, code);
295 /* finally, commit transaction */
296 code = ubik_EndTrans(tt);
304 SPR_NewEntry(call, aname, flag, oid, aid)
305 struct rx_call *call;
306 char aname[PR_MAXNAMELEN];
312 afs_int32 cid = ANONYMOUSID;
314 code = newEntry(call, aname, flag, oid, aid, &cid);
315 osi_auditU(call, PTS_NewEntEvent, code, AUD_LONG, *aid, AUD_STR, aname,
316 AUD_LONG, oid, AUD_END);
317 ViceLog(5, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, *aid, aname, oid));
322 newEntry(call, aname, flag, oid, aid, cid)
323 struct rx_call *call;
324 char aname[PR_MAXNAMELEN];
330 register afs_int32 code;
331 struct ubik_trans *tt;
333 extern afs_int32 WhoIsThisWithName();
334 char cname[PR_MAXNAMELEN];
339 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
342 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
344 ABORT_WITH(tt, code);
345 code = read_DbHeader(tt);
347 ABORT_WITH(tt, code);
349 /* this is for cross-cell self registration. It is not added in the
350 * SPR_INewEntry because we want self-registration to only do
351 * automatic id assignment.
353 code = WhoIsThisWithName(call, tt, cid, cname);
354 if (code != 2) { /* 2 specifies that this is a foreign cell request */
356 ABORT_WITH(tt, PRPERM);
357 admin = IsAMemberOf(tt, *cid, SYSADMINID);
359 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
360 oid = *cid = SYSADMINID;
362 if (!CreateOK(tt, *cid, oid, flag, admin))
363 ABORT_WITH(tt, PRPERM);
365 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
366 if (code != PRSUCCESS)
367 ABORT_WITH(tt, code);
369 code = ubik_EndTrans(tt);
378 SPR_WhereIsIt(call, aid, apos)
379 struct rx_call *call;
384 afs_int32 cid = ANONYMOUSID;
386 code = whereIsIt(call, aid, apos, &cid);
387 osi_auditU(call, PTS_WheIsItEvent, code, AUD_LONG, aid, AUD_LONG, *apos,
389 ViceLog(5, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d", code, cid, aid, *apos));
394 whereIsIt(call, aid, apos, cid)
395 struct rx_call *call;
400 register afs_int32 code;
401 struct ubik_trans *tt;
405 if (code != PRSUCCESS)
407 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
410 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
412 ABORT_WITH(tt, code);
413 code = read_DbHeader(tt);
415 ABORT_WITH(tt, code);
417 code = WhoIsThis(call, tt, cid);
419 ABORT_WITH(tt, PRPERM);
421 temp = FindByID(tt, aid);
423 ABORT_WITH(tt, PRNOENT);
425 code = ubik_EndTrans(tt);
433 SPR_DumpEntry(call, apos, aentry)
434 struct rx_call *call;
436 struct prdebugentry *aentry;
439 afs_int32 cid = ANONYMOUSID;
441 code = dumpEntry(call, apos, aentry, &cid);
442 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
443 ViceLog(5, ("PTS_DumpEntry: code %d cid %d apos %d", code, cid, apos));
448 dumpEntry(call, apos, aentry, cid)
449 struct rx_call *call;
451 struct prdebugentry *aentry;
454 register afs_int32 code;
455 struct ubik_trans *tt;
458 if (code != PRSUCCESS)
460 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
463 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
465 ABORT_WITH(tt, code);
466 code = read_DbHeader(tt);
468 ABORT_WITH(tt, code);
470 code = WhoIsThis(call, tt, cid);
472 ABORT_WITH(tt, PRPERM);
473 code = pr_ReadEntry(tt, 0, apos, aentry);
475 ABORT_WITH(tt, code);
477 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
478 ABORT_WITH(tt, PRPERM);
480 /* Since prdebugentry is in the form of a prentry not a coentry, we will
481 * return the coentry slots in network order where the string is. */
483 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
484 code = pr_ReadCoEntry(tt, 0, apos, aentry);
486 ABORT_WITH(tt, code);
489 code = ubik_EndTrans(tt);
496 SPR_AddToGroup(call, aid, gid)
497 struct rx_call *call;
502 afs_int32 cid = ANONYMOUSID;
504 code = addToGroup(call, aid, gid, &cid);
505 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid,
507 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
512 addToGroup(call, aid, gid, cid)
513 struct rx_call *call;
518 register afs_int32 code;
519 struct ubik_trans *tt;
522 struct prentry tentry;
523 struct prentry uentry;
526 if (code != PRSUCCESS)
528 if (gid == ANYUSERID || gid == AUTHUSERID)
530 if (aid == ANONYMOUSID)
532 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
535 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
537 ABORT_WITH(tt, code);
538 code = read_DbHeader(tt);
540 ABORT_WITH(tt, code);
542 code = WhoIsThis(call, tt, cid);
544 ABORT_WITH(tt, PRPERM);
545 tempu = FindByID(tt, aid);
547 ABORT_WITH(tt, PRNOENT);
548 memset(&uentry, 0, sizeof(uentry));
549 code = pr_ReadEntry(tt, 0, tempu, &uentry);
551 ABORT_WITH(tt, code);
553 #if !defined(SUPERGROUPS)
554 /* we don't allow groups as members of groups at present */
555 if (uentry.flags & PRGRP)
556 ABORT_WITH(tt, PRNOTUSER);
559 tempg = FindByID(tt, gid);
561 ABORT_WITH(tt, PRNOENT);
562 code = pr_ReadEntry(tt, 0, tempg, &tentry);
564 ABORT_WITH(tt, code);
565 /* make sure that this is a group */
566 if (!(tentry.flags & PRGRP))
567 ABORT_WITH(tt, PRNOTGROUP);
568 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
569 ABORT_WITH(tt, PRPERM);
571 code = AddToEntry(tt, &tentry, tempg, aid);
572 if (code != PRSUCCESS)
573 ABORT_WITH(tt, code);
575 #if defined(SUPERGROUPS)
576 if (uentry.flags & PRGRP)
577 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
580 /* now, modify the user's entry as well */
581 code = AddToEntry(tt, &uentry, tempu, gid);
582 if (code != PRSUCCESS)
583 ABORT_WITH(tt, code);
584 code = ubik_EndTrans(tt);
591 SPR_NameToID(call, aname, aid)
592 struct rx_call *call;
598 code = nameToID(call, aname, aid);
599 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
600 ViceLog(5, ("PTS_NameToID: code %d aname %s aid %d", code, aname, aid));
605 nameToID(call, aname, aid)
606 struct rx_call *call;
610 register afs_int32 code;
611 struct ubik_trans *tt;
616 /* Initialize return struct */
618 aid->idlist_val = NULL;
620 size = aname->namelist_len;
626 aid->idlist_val = (afs_int32 *) malloc(size * sizeof(afs_int32));
627 if (!aid->idlist_val)
631 if (code != PRSUCCESS)
633 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
636 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
638 ABORT_WITH(tt, code);
639 code = read_DbHeader(tt);
641 ABORT_WITH(tt, code);
643 for (i = 0; i < aname->namelist_len; i++) {
644 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
645 if (code != PRSUCCESS)
646 aid->idlist_val[i] = ANONYMOUSID;
648 IOMGR_Poll(), count = 0;
650 aid->idlist_len = aname->namelist_len;
652 code = ubik_EndTrans(tt);
660 * Given an array of ids, find the name for each of them.
661 * The array of ids and names is unlimited.
664 SPR_IDToName(call, aid, aname)
665 struct rx_call *call;
671 code = idToName(call, aid, aname);
672 osi_auditU(call, PTS_IdToNmEvent, code, AUD_LONG, aid, AUD_END);
673 ViceLog(5, ("PTS_IDToName: code %d aid %d aname %s", code, aid, aname));
678 idToName(call, aid, aname)
679 struct rx_call *call;
683 register afs_int32 code;
684 struct ubik_trans *tt;
689 /* leave this first for rpc stub */
690 size = aid->idlist_len;
695 aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
696 aname->namelist_len = 0;
697 if (aname->namelist_val == 0)
699 if (aid->idlist_len == 0)
702 return PRTOOMANY; /* rxgen will probably handle this */
705 if (code != PRSUCCESS)
707 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
710 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
712 ABORT_WITH(tt, code);
713 code = read_DbHeader(tt);
715 ABORT_WITH(tt, code);
717 for (i = 0; i < aid->idlist_len; i++) {
718 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
719 if (code != PRSUCCESS)
720 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
722 IOMGR_Poll(), count = 0;
724 aname->namelist_len = aid->idlist_len;
726 code = ubik_EndTrans(tt);
733 SPR_Delete(call, aid)
734 struct rx_call *call;
738 afs_int32 cid = ANONYMOUSID;
740 code = Delete(call, aid, &cid);
741 osi_auditU(call, PTS_DelEvent, code, AUD_LONG, aid, AUD_END);
742 ViceLog(5, ("PTS_Delete: code %d cid %d aid %d", code, cid, aid));
747 Delete(call, aid, cid)
748 struct rx_call *call;
752 register afs_int32 code;
753 struct ubik_trans *tt;
754 struct prentry tentry;
761 if (code != PRSUCCESS)
763 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
764 || aid == ANONYMOUSID)
766 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
769 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
771 ABORT_WITH(tt, code);
772 code = read_DbHeader(tt);
774 ABORT_WITH(tt, code);
776 code = WhoIsThis(call, tt, cid);
778 ABORT_WITH(tt, PRPERM);
780 /* Read in entry to be deleted */
781 loc = FindByID(tt, aid);
783 ABORT_WITH(tt, PRNOENT);
784 code = pr_ReadEntry(tt, 0, loc, &tentry);
786 ABORT_WITH(tt, PRDBFAIL);
788 /* Do some access checking */
789 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
790 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
791 ABORT_WITH(tt, PRPERM);
793 /* Delete each continuation block as a separate transaction so that no one
794 * transaction become to large to complete. */
796 while (nptr != (afs_int32) NULL) {
797 struct contentry centry;
800 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
802 ABORT_WITH(tt, PRDBFAIL);
803 for (i = 0; i < COSIZE; i++) {
804 if (centry.entries[i] == PRBADID)
806 if (centry.entries[i] == 0)
808 #if defined(SUPERGROUPS)
809 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
810 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
813 code = RemoveFromEntry(tt, aid, centry.entries[i]);
815 ABORT_WITH(tt, code);
816 tentry.count--; /* maintain count */
820 tentry.next = centry.next; /* thread out this block */
821 code = FreeBlock(tt, nptr); /* free continuation block */
823 ABORT_WITH(tt, code);
824 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
826 ABORT_WITH(tt, code);
828 /* end this trans and start a new one */
829 code = ubik_EndTrans(tt);
832 IOMGR_Poll(); /* just to keep the connection alive */
833 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
836 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
838 ABORT_WITH(tt, code);
840 /* re-read entry to get consistent uptodate info */
841 loc = FindByID(tt, aid);
843 ABORT_WITH(tt, PRNOENT);
844 code = pr_ReadEntry(tt, 0, loc, &tentry);
846 ABORT_WITH(tt, PRDBFAIL);
851 #if defined(SUPERGROUPS)
852 /* Delete each continuation block as a separate transaction
853 * so that no one transaction become too large to complete. */
855 struct prentryg *tentryg = (struct prentryg *)&tentry;
856 nptr = tentryg->nextsg;
857 while (nptr != NULL) {
858 struct contentry centry;
861 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
863 ABORT_WITH(tt, PRDBFAIL);
864 for (i = 0; i < COSIZE; i++) {
865 if (centry.entries[i] == PRBADID)
867 if (centry.entries[i] == 0)
869 code = RemoveFromEntry(tt, aid, centry.entries[i]);
871 ABORT_WITH(tt, code);
872 tentryg->countsg--; /* maintain count */
876 tentryg->nextsg = centry.next; /* thread out this block */
877 code = FreeBlock(tt, nptr); /* free continuation block */
879 ABORT_WITH(tt, code);
880 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
882 ABORT_WITH(tt, code);
884 /* end this trans and start a new one */
885 code = ubik_EndTrans(tt);
888 IOMGR_Poll(); /* just to keep the connection alive */
890 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
893 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
895 ABORT_WITH(tt, code);
897 /* re-read entry to get consistent uptodate info */
898 loc = FindByID(tt, aid);
900 ABORT_WITH(tt, PRNOENT);
901 code = pr_ReadEntry(tt, 0, loc, &tentry);
903 ABORT_WITH(tt, PRDBFAIL);
905 nptr = tentryg->nextsg;
909 #endif /* SUPERGROUPS */
911 /* Then move the owned chain, except possibly ourself to the orphan list.
912 * Because this list can be very long and so exceed the size of a ubik
913 * transaction, we start a new transaction every 50 entries. */
916 while (nptr != (afs_int32) NULL) {
917 struct prentry nentry;
919 code = pr_ReadEntry(tt, 0, nptr, &nentry);
921 ABORT_WITH(tt, PRDBFAIL);
922 nptr = tentry.owned = nentry.nextOwned; /* thread out */
924 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
925 code = AddToOrphan(tt, nentry.id);
927 ABORT_WITH(tt, code);
929 if ((count & 3) == 0)
934 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
936 ABORT_WITH(tt, code);
938 /* end this trans and start a new one */
939 code = ubik_EndTrans(tt);
942 IOMGR_Poll(); /* just to keep the connection alive */
943 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
946 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
948 ABORT_WITH(tt, code);
950 /* re-read entry to get consistent uptodate info */
951 loc = FindByID(tt, aid);
953 ABORT_WITH(tt, PRNOENT);
954 code = pr_ReadEntry(tt, 0, loc, &tentry);
956 ABORT_WITH(tt, PRDBFAIL);
961 /* now do what's left of the deletion stuff */
962 code = DeleteEntry(tt, &tentry, loc);
963 if (code != PRSUCCESS)
964 ABORT_WITH(tt, code);
966 code = ubik_EndTrans(tt);
973 SPR_UpdateEntry(call, aid, name, uentry)
974 struct rx_call *call;
977 struct PrUpdateEntry *uentry;
980 afs_int32 cid = ANONYMOUSID;
982 code = UpdateEntry(call, aid, name, uentry, &cid);
983 osi_auditU(call, PTS_UpdEntEvent, code, AUD_LONG, aid, AUD_STR, name, AUD_END);
984 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s", code, cid, aid, name));
989 UpdateEntry(call, aid, name, uentry, cid)
990 struct rx_call *call;
993 struct PrUpdateEntry *uentry;
996 register afs_int32 code;
997 struct ubik_trans *tt;
998 struct prentry tentry;
1005 if (code != PRSUCCESS)
1009 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
1010 || aid == ANONYMOUSID)
1013 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1016 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1018 ABORT_WITH(tt, code);
1019 code = read_DbHeader(tt);
1021 ABORT_WITH(tt, code);
1023 code = WhoIsThis(call, tt, cid);
1025 ABORT_WITH(tt, PRPERM);
1026 code = IsAMemberOf(tt, *cid, SYSADMINID);
1027 if (!code && !pr_noAuth)
1028 ABORT_WITH(tt, PRPERM);
1030 /* Read in entry to be deleted */
1032 loc = FindByID(tt, aid);
1034 loc = FindByName(tt, name, &tentry);
1037 ABORT_WITH(tt, PRNOENT);
1038 code = pr_ReadEntry(tt, 0, loc, &tentry);
1040 ABORT_WITH(tt, PRDBFAIL);
1042 if (uentry->Mask & PRUPDATE_NAMEHASH) {
1044 code = RemoveFromNameHash(tt, tentry.name, &tloc);
1045 if (code != PRSUCCESS)
1046 ABORT_WITH(tt, PRDBFAIL);
1047 code = AddToNameHash(tt, tentry.name, loc);
1049 ABORT_WITH(tt, code);
1052 if (uentry->Mask & PRUPDATE_IDHASH) {
1056 code = RemoveFromIDHash(tt, id, &tloc);
1057 if (code != PRSUCCESS)
1058 ABORT_WITH(tt, PRDBFAIL);
1059 code = AddToIDHash(tt, id, loc);
1061 ABORT_WITH(tt, code);
1064 code = ubik_EndTrans(tt);
1071 SPR_RemoveFromGroup(call, aid, gid)
1072 struct rx_call *call;
1077 afs_int32 cid = ANONYMOUSID;
1079 code = removeFromGroup(call, aid, gid, &cid);
1080 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid,
1082 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
1087 removeFromGroup(call, aid, gid, cid)
1088 struct rx_call *call;
1093 register afs_int32 code;
1094 struct ubik_trans *tt;
1097 struct prentry uentry;
1098 struct prentry gentry;
1101 if (code != PRSUCCESS)
1103 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1106 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1108 ABORT_WITH(tt, code);
1109 code = read_DbHeader(tt);
1111 ABORT_WITH(tt, code);
1113 code = WhoIsThis(call, tt, cid);
1115 ABORT_WITH(tt, PRPERM);
1116 tempu = FindByID(tt, aid);
1118 ABORT_WITH(tt, PRNOENT);
1119 tempg = FindByID(tt, gid);
1121 ABORT_WITH(tt, PRNOENT);
1122 memset(&uentry, 0, sizeof(uentry));
1123 memset(&gentry, 0, sizeof(gentry));
1124 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1126 ABORT_WITH(tt, code);
1127 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1129 ABORT_WITH(tt, code);
1130 if (!(gentry.flags & PRGRP))
1131 ABORT_WITH(tt, PRNOTGROUP);
1132 #if !defined(SUPERGROUPS)
1133 if (uentry.flags & PRGRP)
1134 ABORT_WITH(tt, PRNOTUSER);
1136 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1137 ABORT_WITH(tt, PRPERM);
1138 code = RemoveFromEntry(tt, aid, gid);
1139 if (code != PRSUCCESS)
1140 ABORT_WITH(tt, code);
1141 #if defined(SUPERGROUPS)
1142 if (!(uentry.flags & PRGRP))
1144 code = RemoveFromEntry(tt, gid, aid);
1145 #if defined(SUPERGROUPS)
1147 code = RemoveFromSGEntry(tt, gid, aid);
1149 if (code != PRSUCCESS)
1150 ABORT_WITH(tt, code);
1152 code = ubik_EndTrans(tt);
1160 SPR_GetCPS(call, aid, alist, over)
1161 struct rx_call *call;
1167 afs_int32 cid = ANONYMOUSID;
1169 code = getCPS(call, aid, alist, over, &cid);
1170 osi_auditU(call, PTS_GetCPSEvent, code, AUD_LONG, aid, AUD_END);
1171 ViceLog(5, ("PTS_GetCPS: code %d cid %d aid %d", code, cid, aid));
1176 getCPS(call, aid, alist, over, cid)
1177 struct rx_call *call;
1183 register afs_int32 code;
1184 struct ubik_trans *tt;
1186 struct prentry tentry;
1189 alist->prlist_len = 0;
1190 alist->prlist_val = NULL;
1192 if (code != PRSUCCESS)
1194 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1197 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1199 ABORT_WITH(tt, code);
1200 code = read_DbHeader(tt);
1202 ABORT_WITH(tt, code);
1204 temp = FindByID(tt, aid);
1206 ABORT_WITH(tt, PRNOENT);
1207 code = pr_ReadEntry(tt, 0, temp, &tentry);
1209 ABORT_WITH(tt, code);
1211 /* afs does authenticate now */
1212 code = WhoIsThis(call, tt, cid);
1213 if (code || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1214 ABORT_WITH(tt, PRPERM);
1216 code = GetList(tt, &tentry, alist, 1);
1217 if (code != PRSUCCESS)
1218 ABORT_WITH(tt, code);
1220 code = ubik_EndTrans(tt);
1233 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1234 if (CPS.prlist_val[i] == id)
1239 #endif /* IP_WILDCARDS */
1243 SPR_GetCPS2(call, aid, ahost, alist, over)
1244 struct rx_call *call;
1251 afs_int32 cid = ANONYMOUSID;
1253 code = getCPS2(call, aid, ahost, alist, over, &cid);
1254 osi_auditU(call, PTS_GetCPS2Event, code, AUD_LONG, aid, AUD_HOST, ahost,
1256 ViceLog(5, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d", code, cid, aid, ahost));
1261 getCPS2(call, aid, ahost, alist, over, cid)
1262 struct rx_call *call;
1269 register afs_int32 code;
1270 struct ubik_trans *tt;
1272 struct prentry tentry;
1273 struct prentry host_tentry;
1276 struct in_addr iaddr;
1278 extern afs_int32 addWildCards();
1279 #endif /* IP_WILDCARDS */
1282 iaddr.s_addr = ntohl(ahost);
1283 alist->prlist_len = 0;
1284 alist->prlist_val = NULL;
1286 if (code != PRSUCCESS)
1288 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1291 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1293 ABORT_WITH(tt, code);
1294 code = read_DbHeader(tt);
1296 ABORT_WITH(tt, code);
1298 if (aid != PRBADID) {
1299 temp = FindByID(tt, aid);
1301 ABORT_WITH(tt, PRNOENT);
1302 code = pr_ReadEntry(tt, 0, temp, &tentry);
1304 ABORT_WITH(tt, code);
1306 /* afs does authenticate now */
1307 code = WhoIsThis(call, tt, cid);
1309 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1310 ABORT_WITH(tt, PRPERM);
1312 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1313 if (code == PRSUCCESS && hostid != 0) {
1314 temp = FindByID(tt, hostid);
1316 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1317 if (code == PRSUCCESS)
1320 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1322 fprintf(stderr, "FindByID Failed -- Not found\n");
1325 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1327 code = GetList(tt, &tentry, alist, 1);
1330 code = addWildCards(tt, alist, ntohl(ahost));
1331 #endif /* IP_WILDCARDS */
1332 if (code != PRSUCCESS)
1333 ABORT_WITH(tt, code);
1335 code = ubik_EndTrans(tt);
1341 SPR_GetHostCPS(call, ahost, alist, over)
1342 struct rx_call *call;
1349 code = getHostCPS(call, ahost, alist, over);
1350 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
1351 ViceLog(5, ("PTS_GetHostCPS: code %d ahost %d", code, ahost));
1356 getHostCPS(call, ahost, alist, over)
1357 struct rx_call *call;
1362 register afs_int32 code, temp;
1363 struct ubik_trans *tt;
1364 struct prentry host_tentry;
1366 struct in_addr iaddr;
1368 extern afs_int32 addWildCards();
1369 #endif /* IP_WILDCARDS */
1372 iaddr.s_addr = ntohl(ahost);
1373 alist->prlist_len = 0;
1374 alist->prlist_val = NULL;
1376 if (code != PRSUCCESS)
1378 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1381 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1383 ABORT_WITH(tt, code);
1384 code = read_DbHeader(tt);
1386 ABORT_WITH(tt, code);
1388 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1389 if (code == PRSUCCESS && hostid != 0) {
1390 temp = FindByID(tt, hostid);
1392 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1393 if (code == PRSUCCESS) {
1394 code = GetList(tt, &host_tentry, alist, 0);
1398 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1400 fprintf(stderr, "FindByID Failed -- Not found\n");
1403 code = addWildCards(tt, alist, ntohl(ahost));
1404 #endif /* IP_WILDCARDS */
1406 if (code != PRSUCCESS)
1407 ABORT_WITH(tt, code);
1409 code = ubik_EndTrans(tt);
1415 SPR_ListMax(call, uid, gid)
1416 struct rx_call *call;
1422 code = listMax(call, uid, gid);
1423 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1424 ViceLog(5, ("PTS_ListMax: code %d", code));
1429 listMax(call, uid, gid)
1430 struct rx_call *call;
1434 register afs_int32 code;
1435 struct ubik_trans *tt;
1438 if (code != PRSUCCESS)
1440 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1443 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1445 ABORT_WITH(tt, code);
1446 code = read_DbHeader(tt);
1448 ABORT_WITH(tt, code);
1450 code = GetMax(tt, uid, gid);
1451 if (code != PRSUCCESS)
1452 ABORT_WITH(tt, code);
1454 code = ubik_EndTrans(tt);
1461 SPR_SetMax(call, aid, gflag)
1462 struct rx_call *call;
1467 afs_int32 cid = ANONYMOUSID;
1469 code = setMax(call, aid, gflag, &cid);
1470 osi_auditU(call, PTS_SetMaxEvent, code, AUD_LONG, aid, AUD_LONG, gflag,
1472 ViceLog(5, ("PTS_SetMax: code %d cid %d aid %d gflag %d", code, cid, aid, gflag));
1477 setMax(call, aid, gflag, cid)
1478 struct rx_call *call;
1483 register afs_int32 code;
1484 struct ubik_trans *tt;
1487 if (code != PRSUCCESS)
1489 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1492 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1494 ABORT_WITH(tt, code);
1495 code = read_DbHeader(tt);
1497 ABORT_WITH(tt, code);
1499 code = WhoIsThis(call, tt, cid);
1501 ABORT_WITH(tt, PRPERM);
1502 if (!AccessOK(tt, *cid, 0, 0, 0))
1503 ABORT_WITH(tt, PRPERM);
1504 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1505 ABORT_WITH(tt, PRBADARG);
1507 code = SetMax(tt, aid, gflag);
1508 if (code != PRSUCCESS)
1509 ABORT_WITH(tt, code);
1511 code = ubik_EndTrans(tt);
1518 SPR_ListEntry(call, aid, aentry)
1519 struct rx_call *call;
1521 struct prcheckentry *aentry;
1524 afs_int32 cid = ANONYMOUSID;
1526 code = listEntry(call, aid, aentry, cid);
1527 osi_auditU(call, PTS_LstEntEvent, code, AUD_LONG, aid, AUD_END);
1528 ViceLog(5, ("PTS_ListEntry: code %d cid %d aid %d", code, cid, aid));
1533 listEntry(call, aid, aentry, cid)
1534 struct rx_call *call;
1536 struct prcheckentry *aentry;
1539 register afs_int32 code;
1540 struct ubik_trans *tt;
1542 struct prentry tentry;
1545 if (code != PRSUCCESS)
1547 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1550 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1552 ABORT_WITH(tt, code);
1553 code = read_DbHeader(tt);
1555 ABORT_WITH(tt, code);
1557 code = WhoIsThis(call, tt, cid);
1559 ABORT_WITH(tt, PRPERM);
1560 temp = FindByID(tt, aid);
1562 ABORT_WITH(tt, PRNOENT);
1563 code = pr_ReadEntry(tt, 0, temp, &tentry);
1565 ABORT_WITH(tt, code);
1566 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1567 ABORT_WITH(tt, PRPERM);
1569 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1570 if (aentry->flags == 0) {
1571 if (tentry.flags & PRGRP)
1572 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1574 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1576 aentry->owner = tentry.owner;
1577 aentry->id = tentry.id;
1578 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1579 aentry->creator = tentry.creator;
1580 aentry->ngroups = tentry.ngroups;
1581 aentry->nusers = tentry.nusers;
1582 aentry->count = tentry.count;
1583 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1584 code = ubik_EndTrans(tt);
1591 SPR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1592 struct rx_call *call;
1594 afs_int32 startindex;
1595 prentries *bulkentries;
1596 afs_int32 *nextstartindex;
1599 afs_int32 cid = ANONYMOUSID;
1601 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1602 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1603 ViceLog(5, ("PTS_ListEntries: code %d cid %d flag %d", code, cid, flag));
1608 listEntries(call, flag, startindex, bulkentries, nextstartindex, cid)
1609 struct rx_call *call;
1611 afs_int32 startindex;
1612 prentries *bulkentries;
1613 afs_int32 *nextstartindex;
1617 struct ubik_trans *tt;
1618 afs_int32 i, eof, pos, maxentries, f;
1619 struct prentry tentry;
1620 afs_int32 pollcount = 0;
1622 *nextstartindex = -1;
1623 bulkentries->prentries_val = 0;
1624 bulkentries->prentries_len = 0;
1627 if (code != PRSUCCESS)
1629 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1632 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1634 ABORT_WITH(tt, code);
1635 code = read_DbHeader(tt);
1637 ABORT_WITH(tt, code);
1639 /* Make sure we are an authenticated caller and that we are on the
1642 code = WhoIsThis(call, tt, cid);
1644 ABORT_WITH(tt, PRPERM);
1645 code = IsAMemberOf(tt, *cid, SYSADMINID);
1646 if (!code && !pr_noAuth)
1647 ABORT_WITH(tt, PRPERM);
1649 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1650 maxentries = eof / sizeof(struct prentry);
1651 for (i = startindex; i < maxentries; i++) {
1652 pos = i * sizeof(struct prentry) + sizeof(cheader);
1653 code = pr_ReadEntry(tt, 0, pos, &tentry);
1657 if (++pollcount > 50) {
1662 f = (tentry.flags & PRTYPE);
1663 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1664 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1665 code = put_prentries(&tentry, bulkentries);
1667 break; /* Filled return array */
1674 *nextstartindex = i;
1678 if (bulkentries->prentries_val)
1679 free(bulkentries->prentries_val);
1680 bulkentries->prentries_val = 0;
1681 bulkentries->prentries_len = 0;
1682 ABORT_WITH(tt, code);
1684 code = ubik_EndTrans(tt);
1691 #define PR_MAXENTRIES 500
1693 put_prentries(tentry, bulkentries)
1694 struct prentry *tentry;
1695 prentries *bulkentries;
1697 struct prlistentries *entry;
1699 if (bulkentries->prentries_val == 0) {
1700 bulkentries->prentries_len = 0;
1701 bulkentries->prentries_val =
1702 (struct prlistentries *)malloc(PR_MAXENTRIES *
1703 sizeof(struct prentry));
1704 if (!bulkentries->prentries_val) {
1709 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1713 entry = (struct prlistentries *)bulkentries->prentries_val;
1714 entry += bulkentries->prentries_len;
1716 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1717 if (entry->flags == 0) {
1720 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1723 entry->owner = tentry->owner;
1724 entry->id = tentry->id;
1725 entry->creator = tentry->creator;
1726 entry->ngroups = tentry->ngroups;
1727 entry->nusers = tentry->nusers;
1728 entry->count = tentry->count;
1729 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1730 memset(entry->reserved, 0, sizeof(entry->reserved));
1731 bulkentries->prentries_len++;
1736 SPR_ChangeEntry(call, aid, name, oid, newid)
1737 struct rx_call *call;
1744 afs_int32 cid = ANONYMOUSID;
1746 code = changeEntry(call, aid, name, oid, newid, &cid);
1747 osi_auditU(call, PTS_ChgEntEvent, code, AUD_LONG, aid, AUD_STR, name,
1748 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1749 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d", code, cid, aid, name, oid, newid));
1754 changeEntry(call, aid, name, oid, newid, cid)
1755 struct rx_call *call;
1762 register afs_int32 code;
1763 struct ubik_trans *tt;
1773 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1774 || aid == SYSADMINID)
1776 if (code != PRSUCCESS)
1778 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1781 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1783 ABORT_WITH(tt, code);
1784 code = read_DbHeader(tt);
1786 ABORT_WITH(tt, code);
1788 code = WhoIsThis(call, tt, cid);
1790 ABORT_WITH(tt, PRPERM);
1791 pos = FindByID(tt, aid);
1793 ABORT_WITH(tt, PRNOENT);
1794 /* protection check in changeentry */
1795 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1796 if (code != PRSUCCESS)
1797 ABORT_WITH(tt, code);
1799 code = ubik_EndTrans(tt);
1804 SPR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1805 struct rx_call *call;
1807 afs_int32 mask; /* specify which fields to update */
1808 afs_int32 flags, ngroups, nusers;
1809 afs_int32 spare1, spare2;
1812 afs_int32 cid = ANONYMOUSID;
1815 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1817 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_LONG, id, AUD_END);
1818 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d", code, cid, id));
1823 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2, cid)
1824 struct rx_call *call;
1826 afs_int32 mask; /* specify which fields to update */
1827 afs_int32 flags, ngroups, nusers;
1828 afs_int32 spare1, spare2;
1831 register afs_int32 code;
1832 struct ubik_trans *tt;
1834 struct prentry tentry;
1838 return 0; /* no-op */
1842 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1844 if (code != PRSUCCESS)
1846 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1849 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1851 ABORT_WITH(tt, code);
1852 code = read_DbHeader(tt);
1854 ABORT_WITH(tt, code);
1856 code = WhoIsThis(call, tt, cid);
1858 ABORT_WITH(tt, PRPERM);
1859 pos = FindByID(tt, id);
1861 ABORT_WITH(tt, PRNOENT);
1862 code = pr_ReadEntry(tt, 0, pos, &tentry);
1864 ABORT_WITH(tt, code);
1865 tflags = tentry.flags;
1867 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1868 if (!AccessOK(tt, *cid, 0, 0, 0))
1869 ABORT_WITH(tt, PRPERM);
1870 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1871 tentry.ngroups = tentry.nusers = 20;
1874 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1875 ABORT_WITH(tt, PRPERM);
1878 if (mask & 0xffff) { /* if setting flag bits */
1879 afs_int32 flagsMask = mask & 0xffff;
1880 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1881 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1885 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1887 ABORT_WITH(tt, PRBADARG);
1888 tentry.ngroups = ngroups;
1892 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1894 ABORT_WITH(tt, PRBADARG);
1895 tentry.nusers = nusers;
1898 tentry.flags = tflags;
1900 code = pr_WriteEntry(tt, 0, pos, &tentry);
1902 ABORT_WITH(tt, code);
1904 code = ubik_EndTrans(tt);
1909 SPR_ListElements(call, aid, alist, over)
1910 struct rx_call *call;
1916 afs_int32 cid = ANONYMOUSID;
1918 code = listElements(call, aid, alist, over, &cid);
1919 osi_auditU(call, PTS_LstEleEvent, code, AUD_LONG, aid, AUD_END);
1920 ViceLog(5, ("PTS_ListElements: code %d cid %d aid %d", code, cid, aid));
1925 listElements(call, aid, alist, over, cid)
1926 struct rx_call *call;
1932 register afs_int32 code;
1933 struct ubik_trans *tt;
1935 struct prentry tentry;
1938 alist->prlist_len = 0;
1939 alist->prlist_val = NULL;
1942 if (code != PRSUCCESS)
1944 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1947 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1949 ABORT_WITH(tt, code);
1950 code = read_DbHeader(tt);
1952 ABORT_WITH(tt, code);
1954 code = WhoIsThis(call, tt, cid);
1956 ABORT_WITH(tt, PRPERM);
1958 temp = FindByID(tt, aid);
1960 ABORT_WITH(tt, PRNOENT);
1961 code = pr_ReadEntry(tt, 0, temp, &tentry);
1963 ABORT_WITH(tt, code);
1964 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1965 ABORT_WITH(tt, PRPERM);
1967 code = GetList(tt, &tentry, alist, 0);
1968 if (code != PRSUCCESS)
1969 ABORT_WITH(tt, code);
1971 code = ubik_EndTrans(tt);
1977 SPR_ListSuperGroups(call, aid, alist, over)
1978 struct rx_call *call;
1983 #if defined(SUPERGROUPS)
1985 afs_int32 cid = ANONYMOUSID;
1987 code = listSuperGroups(call, aid, alist, over, &cid);
1988 osi_auditU(call, "PTS_LstSGrps", code, AUD_LONG, aid, AUD_END);
1989 ViceLog(5, ("PTS_ListSuperGroups: code %d cid %d aid %d", code, cid, aid));
1992 return RXGEN_OPCODE;
1996 #if defined(SUPERGROUPS)
1998 listSuperGroups(call, aid, alist, over, cid)
1999 struct rx_call *call;
2005 register afs_int32 code;
2006 struct ubik_trans *tt;
2008 struct prentry tentry;
2010 alist->prlist_len = 0;
2011 alist->prlist_val = (afs_int32 *) 0;
2014 if (code != PRSUCCESS)
2016 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2019 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2021 ABORT_WITH(tt, code);
2022 code = WhoIsThis(call, tt, cid);
2024 ABORT_WITH(tt, PRPERM);
2026 temp = FindByID(tt, aid);
2028 ABORT_WITH(tt, PRNOENT);
2029 code = pr_ReadEntry(tt, 0, temp, &tentry);
2031 ABORT_WITH(tt, code);
2032 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2033 ABORT_WITH(tt, PRPERM);
2035 code = GetSGList(tt, &tentry, alist);
2037 if (code == PRTOOMANY)
2039 else if (code != PRSUCCESS)
2040 ABORT_WITH(tt, code);
2042 code = ubik_EndTrans(tt);
2048 #endif /* SUPERGROUPS */
2052 * List the entries owned by this id. If the id is zero,
2053 * return the orphans list. This will return up to PR_MAXGROUPS
2054 * at a time with the lastP available to get the rest. The
2055 * maximum value is enforced in GetOwnedChain().
2058 SPR_ListOwned(call, aid, alist, lastP)
2059 struct rx_call *call;
2065 afs_int32 cid = ANONYMOUSID;
2067 code = listOwned(call, aid, alist, lastP, &cid);
2068 osi_auditU(call, PTS_LstOwnEvent, code, AUD_LONG, aid, AUD_END);
2069 ViceLog(5, ("PTS_ListOwned: code %d cid %d aid %d", code, cid, aid));
2074 listOwned(call, aid, alist, lastP, cid)
2075 struct rx_call *call;
2081 register afs_int32 code;
2082 struct ubik_trans *tt;
2083 struct prentry tentry;
2087 alist->prlist_len = 0;
2088 alist->prlist_val = NULL;
2096 if (code != PRSUCCESS)
2098 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2101 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2103 ABORT_WITH(tt, code);
2104 code = read_DbHeader(tt);
2106 ABORT_WITH(tt, code);
2108 code = WhoIsThis(call, tt, cid);
2110 ABORT_WITH(tt, PRPERM);
2113 code = pr_ReadEntry(tt, 0, start, &tentry);
2114 if (!code && (tentry.owner == aid))
2115 head = start; /* pick up where we left off */
2120 afs_int32 loc = FindByID(tt, aid);
2122 ABORT_WITH(tt, PRNOENT);
2123 code = pr_ReadEntry(tt, 0, loc, &tentry);
2125 ABORT_WITH(tt, code);
2127 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
2128 ABORT_WITH(tt, PRPERM);
2129 head = tentry.owned;
2131 if (!AccessOK(tt, *cid, 0, 0, 0))
2132 ABORT_WITH(tt, PRPERM);
2133 head = ntohl(cheader.orphan);
2137 code = GetOwnedChain(tt, &head, alist);
2139 if (code == PRTOOMANY)
2142 ABORT_WITH(tt, code);
2145 code = ubik_EndTrans(tt);
2150 SPR_IsAMemberOf(call, uid, gid, flag)
2151 struct rx_call *call;
2157 afs_int32 cid = ANONYMOUSID;
2159 code = isAMemberOf(call, uid, gid, flag, &cid);
2160 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
2162 ViceLog(5, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d", code, cid, uid, gid));
2167 isAMemberOf(call, uid, gid, flag, cid)
2168 struct rx_call *call;
2174 register afs_int32 code;
2175 struct ubik_trans *tt;
2178 if (code != PRSUCCESS)
2180 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2183 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2185 ABORT_WITH(tt, code);
2186 code = read_DbHeader(tt);
2188 ABORT_WITH(tt, code);
2191 afs_int32 uloc = FindByID(tt, uid);
2192 afs_int32 gloc = FindByID(tt, gid);
2193 struct prentry uentry, gentry;
2196 ABORT_WITH(tt, PRNOENT);
2197 code = WhoIsThis(call, tt, cid);
2199 ABORT_WITH(tt, PRPERM);
2200 code = pr_ReadEntry(tt, 0, uloc, &uentry);
2202 ABORT_WITH(tt, code);
2203 code = pr_ReadEntry(tt, 0, gloc, &gentry);
2205 ABORT_WITH(tt, code);
2206 #if !defined(SUPERGROUPS)
2207 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
2208 ABORT_WITH(tt, PRBADARG);
2210 if (!(gentry.flags & PRGRP))
2211 ABORT_WITH(tt, PRBADARG);
2213 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
2214 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2215 ABORT_WITH(tt, PRPERM);
2218 *flag = IsAMemberOf(tt, uid, gid);
2219 code = ubik_EndTrans(tt);
2238 addWildCards(tt, alist, host)
2239 struct ubik_trans *tt;
2244 struct prentry tentry;
2246 unsigned wild = htonl(0xffffff00);
2247 struct in_addr iaddr;
2249 int size = 0, i, code;
2252 while ((host = (host & wild))) {
2253 wild = htonl(ntohl(wild) << 8);
2254 iaddr.s_addr = host;
2255 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
2256 if (code == PRSUCCESS && hostid != 0) {
2257 temp = FindByID(tt, hostid);
2259 code = pr_ReadEntry(tt, 0, temp, &tentry);
2260 if (code != PRSUCCESS)
2266 wlist.prlist_len = 0;
2267 wlist.prlist_val = NULL;
2269 code = GetList(tt, &tentry, &wlist, 0);
2272 added += wlist.prlist_len;
2273 for (i = 0; i < wlist.prlist_len; i++) {
2274 if (!inCPS(*alist, wlist.prlist_val[i]))
2275 if ((code = AddToPRList(alist, &size, wlist.prlist_val[i]))) {
2276 free(wlist.prlist_val);
2280 if (wlist.prlist_val)
2281 free(wlist.prlist_val);
2284 qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
2287 #endif /* IP_WILDCARDS */
2291 WhoIsThisWithName(acall, at, aid, aname)
2292 struct rx_call *acall;
2293 struct ubik_trans *at;
2297 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2298 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2299 register struct rx_connection *tconn;
2300 register afs_int32 code;
2301 char tcell[MAXKTCREALMLEN];
2302 char name[MAXKTCNAMELEN];
2303 char inst[MAXKTCNAMELEN];
2308 tconn = rx_ConnectionOf(acall);
2309 code = rx_SecurityClassOf(tconn);
2312 else if (code == 1) { /* vab class */
2313 goto done; /* no longer supported */
2314 } else if (code == 2) { /* kad class */
2317 extern char *pr_realmName;
2319 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
2320 name, inst, tcell, NULL)))
2322 strncpy(vname, name, sizeof(vname));
2323 if ((ilen = strlen(inst))) {
2324 if (strlen(vname) + 1 + ilen >= sizeof(vname))
2327 strcat(vname, inst);
2329 if ((clen = strlen(tcell))) {
2331 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
2332 static char local_realm[AFS_REALM_SZ] = "";
2333 if (!local_realm[0]) {
2334 if (afs_krb_get_lrealm(local_realm, 0) != 0 /*KSUCCESS*/)
2335 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
2339 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
2340 strcasecmp(local_realm, tcell) &&
2342 strcasecmp(pr_realmName, tcell)) {
2343 if (strlen(vname) + 1 + clen >= sizeof(vname))
2346 strcat(vname, tcell);
2347 lcstring(vname, vname, sizeof(vname));
2348 code = NameToID(at, vname, aid);
2349 strcpy(aname, vname);
2354 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2355 *aid = SYSADMINID; /* special case for the fileserver */
2357 lcstring(vname, vname, sizeof(vname));
2358 code = NameToID(at, vname, aid);
2362 if (code && !pr_noAuth)