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();
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 foreign = afs_is_foreign_ticket_name(name,inst,tcell,pr_realmName);
185 strncpy(vname, name, sizeof(vname));
186 if (ilen = strlen(inst)) {
187 if (strlen(vname) + 1 + ilen >= sizeof(vname))
193 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname))
196 strcat(vname, tcell);
198 if (strcmp(AUTH_SUPERUSER, vname) == 0)
199 *aid = SYSADMINID; /* special case for the fileserver */
201 lcstring(vname, vname, sizeof(vname));
202 code = NameToID(at, vname, aid);
206 if (code && !pr_noAuth)
212 SPR_INewEntry(call, aname, aid, oid)
213 struct rx_call *call;
214 char aname[PR_MAXNAMELEN];
219 afs_int32 cid = ANONYMOUSID;
221 code = iNewEntry(call, aname, aid, oid, &cid);
222 osi_auditU(call, PTS_INewEntEvent, code, AUD_ID, aid, AUD_STR, aname,
223 AUD_ID, oid, AUD_END);
224 ViceLog(25, ("PTS_INewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, aid, aname, oid));
229 iNewEntry(call, aname, aid, oid, cid)
230 struct rx_call *call;
231 char aname[PR_MAXNAMELEN];
236 /* used primarily for conversion - not intended to be used as usual means
237 * of entering people into the database. */
238 struct ubik_trans *tt;
239 register afs_int32 code;
245 if (code != PRSUCCESS)
247 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
250 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
252 ABORT_WITH(tt, code);
253 code = read_DbHeader(tt);
255 ABORT_WITH(tt, code);
257 code = WhoIsThis(call, tt, cid);
259 ABORT_WITH(tt, PRPERM);
260 admin = IsAMemberOf(tt, *cid, SYSADMINID);
262 /* first verify the id is good */
264 ABORT_WITH(tt, PRPERM);
267 /* only sysadmin can reuse a group id */
268 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup) - 1))
269 ABORT_WITH(tt, PRPERM);
271 if (FindByID(tt, aid))
272 ABORT_WITH(tt, PRIDEXIST);
274 /* check a few other things */
275 if (!CreateOK(tt, *cid, oid, gflag, admin))
276 ABORT_WITH(tt, PRPERM);
278 code = CreateEntry(tt, aname, &aid, 1, gflag, oid, *cid);
279 if (code != PRSUCCESS)
280 ABORT_WITH(tt, code);
282 /* finally, commit transaction */
283 code = ubik_EndTrans(tt);
291 SPR_NewEntry(call, aname, flag, oid, aid)
292 struct rx_call *call;
293 char aname[PR_MAXNAMELEN];
299 afs_int32 cid = ANONYMOUSID;
301 code = newEntry(call, aname, flag, oid, aid, &cid);
302 osi_auditU(call, PTS_NewEntEvent, code, AUD_ID, *aid, AUD_STR, aname,
303 AUD_ID, oid, AUD_END);
304 ViceLog(25, ("PTS_NewEntry: code %d cid %d aid %d aname %s oid %d", code, cid, *aid, aname, oid));
309 newEntry(call, aname, flag, oid, aid, cid)
310 struct rx_call *call;
311 char aname[PR_MAXNAMELEN];
317 register afs_int32 code;
318 struct ubik_trans *tt;
320 extern afs_int32 WhoIsThisWithName();
321 char cname[PR_MAXNAMELEN];
326 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
329 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
331 ABORT_WITH(tt, code);
332 code = read_DbHeader(tt);
334 ABORT_WITH(tt, code);
336 /* this is for cross-cell self registration. It is not added in the
337 * SPR_INewEntry because we want self-registration to only do
338 * automatic id assignment.
340 code = WhoIsThisWithName(call, tt, cid, cname);
341 if (code != 2) { /* 2 specifies that this is a foreign cell request */
343 ABORT_WITH(tt, PRPERM);
344 admin = IsAMemberOf(tt, *cid, SYSADMINID);
346 admin = ((!restricted && !strcmp(aname, cname))) || IsAMemberOf(tt, *cid, SYSADMINID);
347 oid = *cid = SYSADMINID;
349 if (!CreateOK(tt, *cid, oid, flag, admin))
350 ABORT_WITH(tt, PRPERM);
352 code = CreateEntry(tt, aname, aid, 0, flag, oid, *cid);
353 if (code != PRSUCCESS)
354 ABORT_WITH(tt, code);
356 code = ubik_EndTrans(tt);
365 SPR_WhereIsIt(call, aid, apos)
366 struct rx_call *call;
371 afs_int32 cid = ANONYMOUSID;
373 code = whereIsIt(call, aid, apos, &cid);
374 osi_auditU(call, PTS_WheIsItEvent, code, AUD_ID, aid, AUD_LONG, *apos,
376 ViceLog(125, ("PTS_WhereIsIt: code %d cid %d aid %d apos %d", code, cid, aid, *apos));
381 whereIsIt(call, aid, apos, cid)
382 struct rx_call *call;
387 register afs_int32 code;
388 struct ubik_trans *tt;
392 if (code != PRSUCCESS)
394 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
397 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
399 ABORT_WITH(tt, code);
400 code = read_DbHeader(tt);
402 ABORT_WITH(tt, code);
404 code = WhoIsThis(call, tt, cid);
406 ABORT_WITH(tt, PRPERM);
408 temp = FindByID(tt, aid);
410 ABORT_WITH(tt, PRNOENT);
412 code = ubik_EndTrans(tt);
420 SPR_DumpEntry(call, apos, aentry)
421 struct rx_call *call;
423 struct prdebugentry *aentry;
426 afs_int32 cid = ANONYMOUSID;
428 code = dumpEntry(call, apos, aentry, &cid);
429 osi_auditU(call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
430 ViceLog(125, ("PTS_DumpEntry: code %d cid %d apos %d", code, cid, apos));
435 dumpEntry(call, apos, aentry, cid)
436 struct rx_call *call;
438 struct prdebugentry *aentry;
441 register afs_int32 code;
442 struct ubik_trans *tt;
445 if (code != PRSUCCESS)
447 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
450 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
452 ABORT_WITH(tt, code);
453 code = read_DbHeader(tt);
455 ABORT_WITH(tt, code);
457 code = WhoIsThis(call, tt, cid);
459 ABORT_WITH(tt, PRPERM);
460 code = pr_ReadEntry(tt, 0, apos, aentry);
462 ABORT_WITH(tt, code);
464 if (!AccessOK(tt, *cid, 0, PRP_STATUS_MEM, 0))
465 ABORT_WITH(tt, PRPERM);
467 /* Since prdebugentry is in the form of a prentry not a coentry, we will
468 * return the coentry slots in network order where the string is. */
470 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
471 code = pr_ReadCoEntry(tt, 0, apos, aentry);
473 ABORT_WITH(tt, code);
476 code = ubik_EndTrans(tt);
483 SPR_AddToGroup(call, aid, gid)
484 struct rx_call *call;
489 afs_int32 cid = ANONYMOUSID;
491 code = addToGroup(call, aid, gid, &cid);
492 osi_auditU(call, PTS_AdToGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
494 ViceLog(5, ("PTS_AddToGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
499 addToGroup(call, aid, gid, cid)
500 struct rx_call *call;
505 register afs_int32 code;
506 struct ubik_trans *tt;
509 struct prentry tentry;
510 struct prentry uentry;
513 if (code != PRSUCCESS)
515 if (gid == ANYUSERID || gid == AUTHUSERID)
517 if (aid == ANONYMOUSID)
519 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
522 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
524 ABORT_WITH(tt, code);
525 code = read_DbHeader(tt);
527 ABORT_WITH(tt, code);
529 code = WhoIsThis(call, tt, cid);
531 ABORT_WITH(tt, PRPERM);
532 tempu = FindByID(tt, aid);
534 ABORT_WITH(tt, PRNOENT);
535 memset(&uentry, 0, sizeof(uentry));
536 code = pr_ReadEntry(tt, 0, tempu, &uentry);
538 ABORT_WITH(tt, code);
540 #if !defined(SUPERGROUPS)
541 /* we don't allow groups as members of groups at present */
542 if (uentry.flags & PRGRP)
543 ABORT_WITH(tt, PRNOTUSER);
546 tempg = FindByID(tt, gid);
548 ABORT_WITH(tt, PRNOENT);
549 code = pr_ReadEntry(tt, 0, tempg, &tentry);
551 ABORT_WITH(tt, code);
552 /* make sure that this is a group */
553 if (!(tentry.flags & PRGRP))
554 ABORT_WITH(tt, PRNOTGROUP);
555 if (!AccessOK(tt, *cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY))
556 ABORT_WITH(tt, PRPERM);
558 code = AddToEntry(tt, &tentry, tempg, aid);
559 if (code != PRSUCCESS)
560 ABORT_WITH(tt, code);
562 #if defined(SUPERGROUPS)
563 if (uentry.flags & PRGRP)
564 code = AddToSGEntry(tt, &uentry, tempu, gid); /* mod group to be in sg */
567 /* now, modify the user's entry as well */
568 code = AddToEntry(tt, &uentry, tempu, gid);
569 if (code != PRSUCCESS)
570 ABORT_WITH(tt, code);
571 code = ubik_EndTrans(tt);
578 SPR_NameToID(call, aname, aid)
579 struct rx_call *call;
585 code = nameToID(call, aname, aid);
586 osi_auditU(call, PTS_NmToIdEvent, code, AUD_END);
587 ViceLog(125, ("PTS_NameToID: code %d", code));
592 nameToID(call, aname, aid)
593 struct rx_call *call;
597 register afs_int32 code;
598 struct ubik_trans *tt;
603 /* Initialize return struct */
605 aid->idlist_val = NULL;
607 size = aname->namelist_len;
613 aid->idlist_val = (afs_int32 *) malloc(size * sizeof(afs_int32));
614 if (!aid->idlist_val)
618 if (code != PRSUCCESS)
620 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
623 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
625 ABORT_WITH(tt, code);
626 code = read_DbHeader(tt);
628 ABORT_WITH(tt, code);
630 for (i = 0; i < aname->namelist_len; i++) {
632 char *nameinst, *cell;
634 strncpy(vname, aname->namelist_val[i], sizeof(vname));
635 vname[sizeof(vname)-1] ='\0';
638 cell = strchr(vname, '@');
644 if (cell && afs_is_foreign_ticket_name(nameinst,NULL,cell,pr_realmName))
645 code = NameToID(tt, aname->namelist_val[i], &aid->idlist_val[i]);
647 code = NameToID(tt, nameinst, &aid->idlist_val[i]);
649 if (code != PRSUCCESS)
650 aid->idlist_val[i] = ANONYMOUSID;
651 osi_audit(PTS_NmToIdEvent, code, AUD_STR,
652 aname->namelist_val[i], AUD_ID, aid->idlist_val[i],
654 ViceLog(125, ("PTS_NameToID: code %d aname %s aid %d", code,
655 aname->namelist_val[i], aid->idlist_val[i]));
657 IOMGR_Poll(), count = 0;
659 aid->idlist_len = aname->namelist_len;
661 code = ubik_EndTrans(tt);
669 * Given an array of ids, find the name for each of them.
670 * The array of ids and names is unlimited.
673 SPR_IDToName(call, aid, aname)
674 struct rx_call *call;
680 code = idToName(call, aid, aname);
681 osi_auditU(call, PTS_IdToNmEvent, code, AUD_END);
682 ViceLog(125, ("PTS_IDToName: code %d", code));
687 idToName(call, aid, aname)
688 struct rx_call *call;
692 register afs_int32 code;
693 struct ubik_trans *tt;
698 /* leave this first for rpc stub */
699 size = aid->idlist_len;
704 aname->namelist_val = (prname *) malloc(size * PR_MAXNAMELEN);
705 aname->namelist_len = 0;
706 if (aname->namelist_val == 0)
708 if (aid->idlist_len == 0)
711 return PRTOOMANY; /* rxgen will probably handle this */
714 if (code != PRSUCCESS)
716 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
719 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
721 ABORT_WITH(tt, code);
722 code = read_DbHeader(tt);
724 ABORT_WITH(tt, code);
726 for (i = 0; i < aid->idlist_len; i++) {
727 code = IDToName(tt, aid->idlist_val[i], aname->namelist_val[i]);
728 if (code != PRSUCCESS)
729 sprintf(aname->namelist_val[i], "%d", aid->idlist_val[i]);
730 osi_audit(PTS_IdToNmEvent, code, AUD_ID, aid->idlist_val[i],
731 AUD_STR, aname->namelist_val[i], AUD_END);
732 ViceLog(125, ("PTS_idToName: code %d aid %d aname %s", code,
733 aid->idlist_val[i], aname->namelist_val[i]));
735 IOMGR_Poll(), count = 0;
737 aname->namelist_len = aid->idlist_len;
739 code = ubik_EndTrans(tt);
746 SPR_Delete(call, aid)
747 struct rx_call *call;
751 afs_int32 cid = ANONYMOUSID;
753 code = Delete(call, aid, &cid);
754 osi_auditU(call, PTS_DelEvent, code, AUD_ID, aid, AUD_END);
755 ViceLog(25, ("PTS_Delete: code %d cid %d aid %d", code, cid, aid));
760 Delete(call, aid, cid)
761 struct rx_call *call;
765 register afs_int32 code;
766 struct ubik_trans *tt;
767 struct prentry tentry;
774 if (code != PRSUCCESS)
776 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
777 || aid == ANONYMOUSID)
779 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
782 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
784 ABORT_WITH(tt, code);
785 code = read_DbHeader(tt);
787 ABORT_WITH(tt, code);
789 code = WhoIsThis(call, tt, cid);
791 ABORT_WITH(tt, PRPERM);
793 /* Read in entry to be deleted */
794 loc = FindByID(tt, aid);
796 ABORT_WITH(tt, PRNOENT);
797 code = pr_ReadEntry(tt, 0, loc, &tentry);
799 ABORT_WITH(tt, PRDBFAIL);
801 /* Do some access checking */
802 if (tentry.owner != *cid && !IsAMemberOf(tt, *cid, SYSADMINID)
803 && !IsAMemberOf(tt, *cid, tentry.owner) && !pr_noAuth)
804 ABORT_WITH(tt, PRPERM);
806 /* Delete each continuation block as a separate transaction so that no one
807 * transaction become to large to complete. */
809 while (nptr != (afs_int32) NULL) {
810 struct contentry centry;
813 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
815 ABORT_WITH(tt, PRDBFAIL);
816 for (i = 0; i < COSIZE; i++) {
817 if (centry.entries[i] == PRBADID)
819 if (centry.entries[i] == 0)
821 #if defined(SUPERGROUPS)
822 if (aid < 0 && centry.entries[i] < 0) /* Supergroup */
823 code = RemoveFromSGEntry(tt, aid, centry.entries[i]);
826 code = RemoveFromEntry(tt, aid, centry.entries[i]);
828 ABORT_WITH(tt, code);
829 tentry.count--; /* maintain count */
833 tentry.next = centry.next; /* thread out this block */
834 code = FreeBlock(tt, nptr); /* free continuation block */
836 ABORT_WITH(tt, code);
837 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
839 ABORT_WITH(tt, code);
841 /* end this trans and start a new one */
842 code = ubik_EndTrans(tt);
845 IOMGR_Poll(); /* just to keep the connection alive */
846 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
849 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
851 ABORT_WITH(tt, code);
853 /* re-read entry to get consistent uptodate info */
854 loc = FindByID(tt, aid);
856 ABORT_WITH(tt, PRNOENT);
857 code = pr_ReadEntry(tt, 0, loc, &tentry);
859 ABORT_WITH(tt, PRDBFAIL);
864 #if defined(SUPERGROUPS)
865 /* Delete each continuation block as a separate transaction
866 * so that no one transaction become too large to complete. */
868 struct prentryg *tentryg = (struct prentryg *)&tentry;
869 nptr = tentryg->nextsg;
870 while (nptr != NULL) {
871 struct contentry centry;
874 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
876 ABORT_WITH(tt, PRDBFAIL);
877 for (i = 0; i < COSIZE; i++) {
878 if (centry.entries[i] == PRBADID)
880 if (centry.entries[i] == 0)
882 code = RemoveFromEntry(tt, aid, centry.entries[i]);
884 ABORT_WITH(tt, code);
885 tentryg->countsg--; /* maintain count */
889 tentryg->nextsg = centry.next; /* thread out this block */
890 code = FreeBlock(tt, nptr); /* free continuation block */
892 ABORT_WITH(tt, code);
893 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
895 ABORT_WITH(tt, code);
897 /* end this trans and start a new one */
898 code = ubik_EndTrans(tt);
901 IOMGR_Poll(); /* just to keep the connection alive */
903 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
906 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
908 ABORT_WITH(tt, code);
910 /* re-read entry to get consistent uptodate info */
911 loc = FindByID(tt, aid);
913 ABORT_WITH(tt, PRNOENT);
914 code = pr_ReadEntry(tt, 0, loc, &tentry);
916 ABORT_WITH(tt, PRDBFAIL);
918 nptr = tentryg->nextsg;
922 #endif /* SUPERGROUPS */
924 /* Then move the owned chain, except possibly ourself to the orphan list.
925 * Because this list can be very long and so exceed the size of a ubik
926 * transaction, we start a new transaction every 50 entries. */
929 while (nptr != (afs_int32) NULL) {
930 struct prentry nentry;
932 code = pr_ReadEntry(tt, 0, nptr, &nentry);
934 ABORT_WITH(tt, PRDBFAIL);
935 nptr = tentry.owned = nentry.nextOwned; /* thread out */
937 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
938 code = AddToOrphan(tt, nentry.id);
940 ABORT_WITH(tt, code);
942 if ((count & 3) == 0)
947 code = pr_WriteEntry(tt, 0, loc, &tentry); /* update main entry */
949 ABORT_WITH(tt, code);
951 /* end this trans and start a new one */
952 code = ubik_EndTrans(tt);
955 IOMGR_Poll(); /* just to keep the connection alive */
956 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
959 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
961 ABORT_WITH(tt, code);
963 /* re-read entry to get consistent uptodate info */
964 loc = FindByID(tt, aid);
966 ABORT_WITH(tt, PRNOENT);
967 code = pr_ReadEntry(tt, 0, loc, &tentry);
969 ABORT_WITH(tt, PRDBFAIL);
974 /* now do what's left of the deletion stuff */
975 code = DeleteEntry(tt, &tentry, loc);
976 if (code != PRSUCCESS)
977 ABORT_WITH(tt, code);
979 code = ubik_EndTrans(tt);
986 SPR_UpdateEntry(call, aid, name, uentry)
987 struct rx_call *call;
990 struct PrUpdateEntry *uentry;
993 afs_int32 cid = ANONYMOUSID;
995 code = UpdateEntry(call, aid, name, uentry, &cid);
996 osi_auditU(call, PTS_UpdEntEvent, code, AUD_ID, aid, AUD_STR, name, AUD_END);
997 ViceLog(5, ("PTS_UpdateEntry: code %d cid %d aid %d name %s", code, cid, aid, name));
1002 UpdateEntry(call, aid, name, uentry, cid)
1003 struct rx_call *call;
1006 struct PrUpdateEntry *uentry;
1009 register afs_int32 code;
1010 struct ubik_trans *tt;
1011 struct prentry tentry;
1018 if (code != PRSUCCESS)
1022 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID
1023 || aid == ANONYMOUSID)
1026 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1029 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1031 ABORT_WITH(tt, code);
1032 code = read_DbHeader(tt);
1034 ABORT_WITH(tt, code);
1036 code = WhoIsThis(call, tt, cid);
1038 ABORT_WITH(tt, PRPERM);
1039 code = IsAMemberOf(tt, *cid, SYSADMINID);
1040 if (!code && !pr_noAuth)
1041 ABORT_WITH(tt, PRPERM);
1043 /* Read in entry to be deleted */
1045 loc = FindByID(tt, aid);
1047 loc = FindByName(tt, name, &tentry);
1050 ABORT_WITH(tt, PRNOENT);
1051 code = pr_ReadEntry(tt, 0, loc, &tentry);
1053 ABORT_WITH(tt, PRDBFAIL);
1055 if (uentry->Mask & PRUPDATE_NAMEHASH) {
1057 code = RemoveFromNameHash(tt, tentry.name, &tloc);
1058 if (code != PRSUCCESS)
1059 ABORT_WITH(tt, PRDBFAIL);
1060 code = AddToNameHash(tt, tentry.name, loc);
1062 ABORT_WITH(tt, code);
1065 if (uentry->Mask & PRUPDATE_IDHASH) {
1069 code = RemoveFromIDHash(tt, id, &tloc);
1070 if (code != PRSUCCESS)
1071 ABORT_WITH(tt, PRDBFAIL);
1072 code = AddToIDHash(tt, id, loc);
1074 ABORT_WITH(tt, code);
1077 code = ubik_EndTrans(tt);
1084 SPR_RemoveFromGroup(call, aid, gid)
1085 struct rx_call *call;
1090 afs_int32 cid = ANONYMOUSID;
1092 code = removeFromGroup(call, aid, gid, &cid);
1093 osi_auditU(call, PTS_RmFmGrpEvent, code, AUD_ID, gid, AUD_ID, aid,
1095 ViceLog(5, ("PTS_RemoveFromGroup: code %d cid %d gid %d aid %d", code, cid, gid, aid));
1100 removeFromGroup(call, aid, gid, cid)
1101 struct rx_call *call;
1106 register afs_int32 code;
1107 struct ubik_trans *tt;
1110 struct prentry uentry;
1111 struct prentry gentry;
1114 if (code != PRSUCCESS)
1116 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1119 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1121 ABORT_WITH(tt, code);
1122 code = read_DbHeader(tt);
1124 ABORT_WITH(tt, code);
1126 code = WhoIsThis(call, tt, cid);
1128 ABORT_WITH(tt, PRPERM);
1129 tempu = FindByID(tt, aid);
1131 ABORT_WITH(tt, PRNOENT);
1132 tempg = FindByID(tt, gid);
1134 ABORT_WITH(tt, PRNOENT);
1135 memset(&uentry, 0, sizeof(uentry));
1136 memset(&gentry, 0, sizeof(gentry));
1137 code = pr_ReadEntry(tt, 0, tempu, &uentry);
1139 ABORT_WITH(tt, code);
1140 code = pr_ReadEntry(tt, 0, tempg, &gentry);
1142 ABORT_WITH(tt, code);
1143 if (!(gentry.flags & PRGRP))
1144 ABORT_WITH(tt, PRNOTGROUP);
1145 #if !defined(SUPERGROUPS)
1146 if (uentry.flags & PRGRP)
1147 ABORT_WITH(tt, PRNOTUSER);
1149 if (!AccessOK(tt, *cid, &gentry, PRP_REMOVE_MEM, 0))
1150 ABORT_WITH(tt, PRPERM);
1151 code = RemoveFromEntry(tt, aid, gid);
1152 if (code != PRSUCCESS)
1153 ABORT_WITH(tt, code);
1154 #if defined(SUPERGROUPS)
1155 if (!(uentry.flags & PRGRP))
1157 code = RemoveFromEntry(tt, gid, aid);
1158 #if defined(SUPERGROUPS)
1160 code = RemoveFromSGEntry(tt, gid, aid);
1162 if (code != PRSUCCESS)
1163 ABORT_WITH(tt, code);
1165 code = ubik_EndTrans(tt);
1173 SPR_GetCPS(call, aid, alist, over)
1174 struct rx_call *call;
1180 afs_int32 cid = ANONYMOUSID;
1182 code = getCPS(call, aid, alist, over, &cid);
1183 osi_auditU(call, PTS_GetCPSEvent, code, AUD_ID, aid, AUD_END);
1184 ViceLog(125, ("PTS_GetCPS: code %d cid %d aid %d", code, cid, aid));
1189 getCPS(call, aid, alist, over, cid)
1190 struct rx_call *call;
1196 register afs_int32 code;
1197 struct ubik_trans *tt;
1199 struct prentry tentry;
1202 alist->prlist_len = 0;
1203 alist->prlist_val = NULL;
1205 if (code != PRSUCCESS)
1207 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1210 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1212 ABORT_WITH(tt, code);
1213 code = read_DbHeader(tt);
1215 ABORT_WITH(tt, code);
1217 temp = FindByID(tt, aid);
1219 ABORT_WITH(tt, PRNOENT);
1220 code = pr_ReadEntry(tt, 0, temp, &tentry);
1222 ABORT_WITH(tt, code);
1224 /* afs does authenticate now */
1225 code = WhoIsThis(call, tt, cid);
1226 if (code || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1227 ABORT_WITH(tt, PRPERM);
1229 code = GetList(tt, &tentry, alist, 1);
1230 if (code != PRSUCCESS)
1231 ABORT_WITH(tt, code);
1233 code = ubik_EndTrans(tt);
1246 for (i = (CPS.prlist_len - 1); i >= 0; i--) {
1247 if (CPS.prlist_val[i] == id)
1252 #endif /* IP_WILDCARDS */
1256 SPR_GetCPS2(call, aid, ahost, alist, over)
1257 struct rx_call *call;
1264 afs_int32 cid = ANONYMOUSID;
1266 code = getCPS2(call, aid, ahost, alist, over, &cid);
1267 osi_auditU(call, PTS_GetCPS2Event, code, AUD_ID, aid, AUD_HOST, ahost,
1269 ViceLog(125, ("PTS_GetCPS2: code %d cid %d aid %d ahost %d", code, cid, aid, ahost));
1274 getCPS2(call, aid, ahost, alist, over, cid)
1275 struct rx_call *call;
1282 register afs_int32 code;
1283 struct ubik_trans *tt;
1285 struct prentry tentry;
1286 struct prentry host_tentry;
1289 struct in_addr iaddr;
1291 extern afs_int32 addWildCards();
1292 #endif /* IP_WILDCARDS */
1295 iaddr.s_addr = ntohl(ahost);
1296 alist->prlist_len = 0;
1297 alist->prlist_val = NULL;
1299 if (code != PRSUCCESS)
1301 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1304 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1306 ABORT_WITH(tt, code);
1307 code = read_DbHeader(tt);
1309 ABORT_WITH(tt, code);
1311 if (aid != PRBADID) {
1312 temp = FindByID(tt, aid);
1314 ABORT_WITH(tt, PRNOENT);
1315 code = pr_ReadEntry(tt, 0, temp, &tentry);
1317 ABORT_WITH(tt, code);
1319 /* afs does authenticate now */
1320 code = WhoIsThis(call, tt, cid);
1322 || !AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1323 ABORT_WITH(tt, PRPERM);
1325 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1326 if (code == PRSUCCESS && hostid != 0) {
1327 temp = FindByID(tt, hostid);
1329 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1330 if (code == PRSUCCESS)
1333 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1335 fprintf(stderr, "FindByID Failed -- Not found\n");
1338 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
1340 code = GetList(tt, &tentry, alist, 1);
1343 code = addWildCards(tt, alist, ntohl(ahost));
1344 #endif /* IP_WILDCARDS */
1345 if (code != PRSUCCESS)
1346 ABORT_WITH(tt, code);
1348 code = ubik_EndTrans(tt);
1354 SPR_GetHostCPS(call, ahost, alist, over)
1355 struct rx_call *call;
1362 code = getHostCPS(call, ahost, alist, over);
1363 osi_auditU(call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
1364 ViceLog(125, ("PTS_GetHostCPS: code %d ahost %d", code, ahost));
1369 getHostCPS(call, ahost, alist, over)
1370 struct rx_call *call;
1375 register afs_int32 code, temp;
1376 struct ubik_trans *tt;
1377 struct prentry host_tentry;
1379 struct in_addr iaddr;
1381 extern afs_int32 addWildCards();
1382 #endif /* IP_WILDCARDS */
1385 iaddr.s_addr = ntohl(ahost);
1386 alist->prlist_len = 0;
1387 alist->prlist_val = NULL;
1389 if (code != PRSUCCESS)
1391 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1394 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1396 ABORT_WITH(tt, code);
1397 code = read_DbHeader(tt);
1399 ABORT_WITH(tt, code);
1401 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1402 if (code == PRSUCCESS && hostid != 0) {
1403 temp = FindByID(tt, hostid);
1405 code = pr_ReadEntry(tt, 0, temp, &host_tentry);
1406 if (code == PRSUCCESS) {
1407 code = GetList(tt, &host_tentry, alist, 0);
1411 fprintf(stderr, "pr_ReadEntry returned %d\n", code);
1413 fprintf(stderr, "FindByID Failed -- Not found\n");
1416 code = addWildCards(tt, alist, ntohl(ahost));
1417 #endif /* IP_WILDCARDS */
1419 if (code != PRSUCCESS)
1420 ABORT_WITH(tt, code);
1422 code = ubik_EndTrans(tt);
1428 SPR_ListMax(call, uid, gid)
1429 struct rx_call *call;
1435 code = listMax(call, uid, gid);
1436 osi_auditU(call, PTS_LstMaxEvent, code, AUD_END);
1437 ViceLog(125, ("PTS_ListMax: code %d", code));
1442 listMax(call, uid, gid)
1443 struct rx_call *call;
1447 register afs_int32 code;
1448 struct ubik_trans *tt;
1451 if (code != PRSUCCESS)
1453 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1456 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1458 ABORT_WITH(tt, code);
1459 code = read_DbHeader(tt);
1461 ABORT_WITH(tt, code);
1463 code = GetMax(tt, uid, gid);
1464 if (code != PRSUCCESS)
1465 ABORT_WITH(tt, code);
1467 code = ubik_EndTrans(tt);
1474 SPR_SetMax(call, aid, gflag)
1475 struct rx_call *call;
1480 afs_int32 cid = ANONYMOUSID;
1482 code = setMax(call, aid, gflag, &cid);
1483 osi_auditU(call, PTS_SetMaxEvent, code, AUD_ID, aid, AUD_LONG, gflag,
1485 ViceLog(125, ("PTS_SetMax: code %d cid %d aid %d gflag %d", code, cid, aid, gflag));
1490 setMax(call, aid, gflag, cid)
1491 struct rx_call *call;
1496 register afs_int32 code;
1497 struct ubik_trans *tt;
1500 if (code != PRSUCCESS)
1502 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1505 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1507 ABORT_WITH(tt, code);
1508 code = read_DbHeader(tt);
1510 ABORT_WITH(tt, code);
1512 code = WhoIsThis(call, tt, cid);
1514 ABORT_WITH(tt, PRPERM);
1515 if (!AccessOK(tt, *cid, 0, 0, 0))
1516 ABORT_WITH(tt, PRPERM);
1517 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0)))
1518 ABORT_WITH(tt, PRBADARG);
1520 code = SetMax(tt, aid, gflag);
1521 if (code != PRSUCCESS)
1522 ABORT_WITH(tt, code);
1524 code = ubik_EndTrans(tt);
1531 SPR_ListEntry(call, aid, aentry)
1532 struct rx_call *call;
1534 struct prcheckentry *aentry;
1537 afs_int32 cid = ANONYMOUSID;
1539 code = listEntry(call, aid, aentry, &cid);
1540 osi_auditU(call, PTS_LstEntEvent, code, AUD_ID, aid, AUD_END);
1541 ViceLog(125, ("PTS_ListEntry: code %d cid %d aid %d", code, cid, aid));
1546 listEntry(call, aid, aentry, cid)
1547 struct rx_call *call;
1549 struct prcheckentry *aentry;
1552 register afs_int32 code;
1553 struct ubik_trans *tt;
1555 struct prentry tentry;
1558 if (code != PRSUCCESS)
1560 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1563 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1565 ABORT_WITH(tt, code);
1566 code = read_DbHeader(tt);
1568 ABORT_WITH(tt, code);
1570 code = WhoIsThis(call, tt, cid);
1572 ABORT_WITH(tt, PRPERM);
1573 temp = FindByID(tt, aid);
1575 ABORT_WITH(tt, PRNOENT);
1576 code = pr_ReadEntry(tt, 0, temp, &tentry);
1578 ABORT_WITH(tt, code);
1579 if (!AccessOK(tt, *cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1580 ABORT_WITH(tt, PRPERM);
1582 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1583 if (aentry->flags == 0) {
1584 if (tentry.flags & PRGRP)
1585 aentry->flags = prp_group_default >> PRIVATE_SHIFT;
1587 aentry->flags = prp_user_default >> PRIVATE_SHIFT;
1589 aentry->owner = tentry.owner;
1590 aentry->id = tentry.id;
1591 strncpy(aentry->name, tentry.name, PR_MAXNAMELEN);
1592 aentry->creator = tentry.creator;
1593 aentry->ngroups = tentry.ngroups;
1594 aentry->nusers = tentry.nusers;
1595 aentry->count = tentry.count;
1596 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1597 code = ubik_EndTrans(tt);
1604 SPR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1605 struct rx_call *call;
1607 afs_int32 startindex;
1608 prentries *bulkentries;
1609 afs_int32 *nextstartindex;
1612 afs_int32 cid = ANONYMOUSID;
1614 code = listEntries(call, flag, startindex, bulkentries, nextstartindex, &cid);
1615 osi_auditU(call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1616 ViceLog(125, ("PTS_ListEntries: code %d cid %d flag %d", code, cid, flag));
1621 listEntries(call, flag, startindex, bulkentries, nextstartindex, cid)
1622 struct rx_call *call;
1624 afs_int32 startindex;
1625 prentries *bulkentries;
1626 afs_int32 *nextstartindex;
1630 struct ubik_trans *tt;
1631 afs_int32 i, eof, pos, maxentries, f;
1632 struct prentry tentry;
1633 afs_int32 pollcount = 0;
1635 *nextstartindex = -1;
1636 bulkentries->prentries_val = 0;
1637 bulkentries->prentries_len = 0;
1640 if (code != PRSUCCESS)
1642 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1645 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1647 ABORT_WITH(tt, code);
1648 code = read_DbHeader(tt);
1650 ABORT_WITH(tt, code);
1652 /* Make sure we are an authenticated caller and that we are on the
1655 code = WhoIsThis(call, tt, cid);
1657 ABORT_WITH(tt, PRPERM);
1658 code = IsAMemberOf(tt, *cid, SYSADMINID);
1659 if (!code && !pr_noAuth)
1660 ABORT_WITH(tt, PRPERM);
1662 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1663 maxentries = eof / sizeof(struct prentry);
1664 for (i = startindex; i < maxentries; i++) {
1665 pos = i * sizeof(struct prentry) + sizeof(cheader);
1666 code = pr_ReadEntry(tt, 0, pos, &tentry);
1670 if (++pollcount > 50) {
1675 f = (tentry.flags & PRTYPE);
1676 if (((flag & PRUSERS) && (f == 0)) || /* User entry */
1677 ((flag & PRGROUPS) && (f & PRGRP))) { /* Group entry */
1678 code = put_prentries(&tentry, bulkentries);
1680 break; /* Filled return array */
1687 *nextstartindex = i;
1691 if (bulkentries->prentries_val)
1692 free(bulkentries->prentries_val);
1693 bulkentries->prentries_val = 0;
1694 bulkentries->prentries_len = 0;
1695 ABORT_WITH(tt, code);
1697 code = ubik_EndTrans(tt);
1704 #define PR_MAXENTRIES 500
1706 put_prentries(tentry, bulkentries)
1707 struct prentry *tentry;
1708 prentries *bulkentries;
1710 struct prlistentries *entry;
1712 if (bulkentries->prentries_val == 0) {
1713 bulkentries->prentries_len = 0;
1714 bulkentries->prentries_val =
1715 (struct prlistentries *)malloc(PR_MAXENTRIES *
1716 sizeof(struct prentry));
1717 if (!bulkentries->prentries_val) {
1722 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1726 entry = (struct prlistentries *)bulkentries->prentries_val;
1727 entry += bulkentries->prentries_len;
1729 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1730 if (entry->flags == 0) {
1733 flags & PRGRP) ? prp_group_default : prp_user_default) >>
1736 entry->owner = tentry->owner;
1737 entry->id = tentry->id;
1738 entry->creator = tentry->creator;
1739 entry->ngroups = tentry->ngroups;
1740 entry->nusers = tentry->nusers;
1741 entry->count = tentry->count;
1742 strncpy(entry->name, tentry->name, PR_MAXNAMELEN);
1743 memset(entry->reserved, 0, sizeof(entry->reserved));
1744 bulkentries->prentries_len++;
1749 SPR_ChangeEntry(call, aid, name, oid, newid)
1750 struct rx_call *call;
1757 afs_int32 cid = ANONYMOUSID;
1759 code = changeEntry(call, aid, name, oid, newid, &cid);
1760 osi_auditU(call, PTS_ChgEntEvent, code, AUD_ID, aid, AUD_STR, name,
1761 AUD_LONG, oid, AUD_LONG, newid, AUD_END);
1762 ViceLog(5, ("PTS_ChangeEntry: code %d cid %d aid %d name %s oid %d newid %d", code, cid, aid, name, oid, newid));
1767 changeEntry(call, aid, name, oid, newid, cid)
1768 struct rx_call *call;
1775 register afs_int32 code;
1776 struct ubik_trans *tt;
1786 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID
1787 || aid == SYSADMINID)
1789 if (code != PRSUCCESS)
1791 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1794 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1796 ABORT_WITH(tt, code);
1797 code = read_DbHeader(tt);
1799 ABORT_WITH(tt, code);
1801 code = WhoIsThis(call, tt, cid);
1803 ABORT_WITH(tt, PRPERM);
1804 pos = FindByID(tt, aid);
1806 ABORT_WITH(tt, PRNOENT);
1807 /* protection check in changeentry */
1808 code = ChangeEntry(tt, aid, *cid, name, oid, newid);
1809 if (code != PRSUCCESS)
1810 ABORT_WITH(tt, code);
1812 code = ubik_EndTrans(tt);
1817 SPR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
1818 struct rx_call *call;
1820 afs_int32 mask; /* specify which fields to update */
1821 afs_int32 flags, ngroups, nusers;
1822 afs_int32 spare1, spare2;
1825 afs_int32 cid = ANONYMOUSID;
1828 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1,
1830 osi_auditU(call, PTS_SetFldEntEvent, code, AUD_ID, id, AUD_END);
1831 ViceLog(5, ("PTS_SetFieldsEntry: code %d cid %d id %d", code, cid, id));
1836 setFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2, cid)
1837 struct rx_call *call;
1839 afs_int32 mask; /* specify which fields to update */
1840 afs_int32 flags, ngroups, nusers;
1841 afs_int32 spare1, spare2;
1844 register afs_int32 code;
1845 struct ubik_trans *tt;
1847 struct prentry tentry;
1851 return 0; /* no-op */
1855 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1857 if (code != PRSUCCESS)
1859 code = ubik_BeginTrans(dbase, UBIK_WRITETRANS, &tt);
1862 code = ubik_SetLock(tt, 1, 1, LOCKWRITE);
1864 ABORT_WITH(tt, code);
1865 code = read_DbHeader(tt);
1867 ABORT_WITH(tt, code);
1869 code = WhoIsThis(call, tt, cid);
1871 ABORT_WITH(tt, PRPERM);
1872 pos = FindByID(tt, id);
1874 ABORT_WITH(tt, PRNOENT);
1875 code = pr_ReadEntry(tt, 0, pos, &tentry);
1877 ABORT_WITH(tt, code);
1878 tflags = tentry.flags;
1880 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1881 if (!AccessOK(tt, *cid, 0, 0, 0))
1882 ABORT_WITH(tt, PRPERM);
1883 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1884 tentry.ngroups = tentry.nusers = 20;
1887 if (!AccessOK(tt, *cid, &tentry, 0, 0))
1888 ABORT_WITH(tt, PRPERM);
1891 if (mask & 0xffff) { /* if setting flag bits */
1892 afs_int32 flagsMask = mask & 0xffff;
1893 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1894 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1898 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1900 ABORT_WITH(tt, PRBADARG);
1901 tentry.ngroups = ngroups;
1905 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1907 ABORT_WITH(tt, PRBADARG);
1908 tentry.nusers = nusers;
1911 tentry.flags = tflags;
1913 code = pr_WriteEntry(tt, 0, pos, &tentry);
1915 ABORT_WITH(tt, code);
1917 code = ubik_EndTrans(tt);
1922 SPR_ListElements(call, aid, alist, over)
1923 struct rx_call *call;
1929 afs_int32 cid = ANONYMOUSID;
1931 code = listElements(call, aid, alist, over, &cid);
1932 osi_auditU(call, PTS_LstEleEvent, code, AUD_ID, aid, AUD_END);
1933 ViceLog(125, ("PTS_ListElements: code %d cid %d aid %d", code, cid, aid));
1938 listElements(call, aid, alist, over, cid)
1939 struct rx_call *call;
1945 register afs_int32 code;
1946 struct ubik_trans *tt;
1948 struct prentry tentry;
1951 alist->prlist_len = 0;
1952 alist->prlist_val = NULL;
1955 if (code != PRSUCCESS)
1957 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
1960 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
1962 ABORT_WITH(tt, code);
1963 code = read_DbHeader(tt);
1965 ABORT_WITH(tt, code);
1967 code = WhoIsThis(call, tt, cid);
1969 ABORT_WITH(tt, PRPERM);
1971 temp = FindByID(tt, aid);
1973 ABORT_WITH(tt, PRNOENT);
1974 code = pr_ReadEntry(tt, 0, temp, &tentry);
1976 ABORT_WITH(tt, code);
1977 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1978 ABORT_WITH(tt, PRPERM);
1980 code = GetList(tt, &tentry, alist, 0);
1981 if (code != PRSUCCESS)
1982 ABORT_WITH(tt, code);
1984 code = ubik_EndTrans(tt);
1990 SPR_ListSuperGroups(call, aid, alist, over)
1991 struct rx_call *call;
1996 #if defined(SUPERGROUPS)
1998 afs_int32 cid = ANONYMOUSID;
2000 code = listSuperGroups(call, aid, alist, over, &cid);
2001 osi_auditU(call, PTS_LstSGrps, code, AUD_ID, aid, AUD_END);
2002 ViceLog(125, ("PTS_ListSuperGroups: code %d cid %d aid %d", code, cid, aid));
2005 return RXGEN_OPCODE;
2009 #if defined(SUPERGROUPS)
2011 listSuperGroups(call, aid, alist, over, cid)
2012 struct rx_call *call;
2018 register afs_int32 code;
2019 struct ubik_trans *tt;
2021 struct prentry tentry;
2023 alist->prlist_len = 0;
2024 alist->prlist_val = (afs_int32 *) 0;
2027 if (code != PRSUCCESS)
2029 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2032 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2034 ABORT_WITH(tt, code);
2035 code = WhoIsThis(call, tt, cid);
2037 ABORT_WITH(tt, PRPERM);
2039 temp = FindByID(tt, aid);
2041 ABORT_WITH(tt, PRNOENT);
2042 code = pr_ReadEntry(tt, 0, temp, &tentry);
2044 ABORT_WITH(tt, code);
2045 if (!AccessOK(tt, *cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2046 ABORT_WITH(tt, PRPERM);
2048 code = GetSGList(tt, &tentry, alist);
2050 if (code == PRTOOMANY)
2052 else if (code != PRSUCCESS)
2053 ABORT_WITH(tt, code);
2055 code = ubik_EndTrans(tt);
2061 #endif /* SUPERGROUPS */
2065 * List the entries owned by this id. If the id is zero,
2066 * return the orphans list. This will return up to PR_MAXGROUPS
2067 * at a time with the lastP available to get the rest. The
2068 * maximum value is enforced in GetOwnedChain().
2071 SPR_ListOwned(call, aid, alist, lastP)
2072 struct rx_call *call;
2078 afs_int32 cid = ANONYMOUSID;
2080 code = listOwned(call, aid, alist, lastP, &cid);
2081 osi_auditU(call, PTS_LstOwnEvent, code, AUD_ID, aid, AUD_END);
2082 ViceLog(125, ("PTS_ListOwned: code %d cid %d aid %d", code, cid, aid));
2087 listOwned(call, aid, alist, lastP, cid)
2088 struct rx_call *call;
2094 register afs_int32 code;
2095 struct ubik_trans *tt;
2096 struct prentry tentry;
2100 alist->prlist_len = 0;
2101 alist->prlist_val = NULL;
2109 if (code != PRSUCCESS)
2111 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2114 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2116 ABORT_WITH(tt, code);
2117 code = read_DbHeader(tt);
2119 ABORT_WITH(tt, code);
2121 code = WhoIsThis(call, tt, cid);
2123 ABORT_WITH(tt, PRPERM);
2126 code = pr_ReadEntry(tt, 0, start, &tentry);
2127 if (!code && (tentry.owner == aid))
2128 head = start; /* pick up where we left off */
2133 afs_int32 loc = FindByID(tt, aid);
2135 ABORT_WITH(tt, PRNOENT);
2136 code = pr_ReadEntry(tt, 0, loc, &tentry);
2138 ABORT_WITH(tt, code);
2140 if (!AccessOK(tt, *cid, &tentry, -1, PRP_OWNED_ANY))
2141 ABORT_WITH(tt, PRPERM);
2142 head = tentry.owned;
2144 if (!AccessOK(tt, *cid, 0, 0, 0))
2145 ABORT_WITH(tt, PRPERM);
2146 head = ntohl(cheader.orphan);
2150 code = GetOwnedChain(tt, &head, alist);
2152 if (code == PRTOOMANY)
2155 ABORT_WITH(tt, code);
2158 code = ubik_EndTrans(tt);
2163 SPR_IsAMemberOf(call, uid, gid, flag)
2164 struct rx_call *call;
2170 afs_int32 cid = ANONYMOUSID;
2172 code = isAMemberOf(call, uid, gid, flag, &cid);
2173 osi_auditU(call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid,
2175 ViceLog(125, ("PTS_IsAMemberOf: code %d cid %d uid %d gid %d", code, cid, uid, gid));
2180 isAMemberOf(call, uid, gid, flag, cid)
2181 struct rx_call *call;
2187 register afs_int32 code;
2188 struct ubik_trans *tt;
2191 if (code != PRSUCCESS)
2193 code = ubik_BeginTransReadAny(dbase, UBIK_READTRANS, &tt);
2196 code = ubik_SetLock(tt, 1, 1, LOCKREAD);
2198 ABORT_WITH(tt, code);
2199 code = read_DbHeader(tt);
2201 ABORT_WITH(tt, code);
2204 afs_int32 uloc = FindByID(tt, uid);
2205 afs_int32 gloc = FindByID(tt, gid);
2206 struct prentry uentry, gentry;
2209 ABORT_WITH(tt, PRNOENT);
2210 code = WhoIsThis(call, tt, cid);
2212 ABORT_WITH(tt, PRPERM);
2213 code = pr_ReadEntry(tt, 0, uloc, &uentry);
2215 ABORT_WITH(tt, code);
2216 code = pr_ReadEntry(tt, 0, gloc, &gentry);
2218 ABORT_WITH(tt, code);
2219 #if !defined(SUPERGROUPS)
2220 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP))
2221 ABORT_WITH(tt, PRBADARG);
2223 if (!(gentry.flags & PRGRP))
2224 ABORT_WITH(tt, PRBADARG);
2226 if (!AccessOK(tt, *cid, &uentry, 0, PRP_MEMBER_ANY)
2227 && !AccessOK(tt, *cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
2228 ABORT_WITH(tt, PRPERM);
2231 *flag = IsAMemberOf(tt, uid, gid);
2232 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 */
2290 WhoIsThisWithName(acall, at, aid, aname)
2291 struct rx_call *acall;
2292 struct ubik_trans *at;
2296 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
2297 /* returns -1 and sets aid to ANONYMOUSID on any failure */
2298 register struct rx_connection *tconn;
2299 register afs_int32 code;
2300 char tcell[MAXKTCREALMLEN];
2301 char name[MAXKTCNAMELEN];
2302 char inst[MAXKTCNAMELEN];
2307 tconn = rx_ConnectionOf(acall);
2308 code = rx_SecurityClassOf(tconn);
2311 else if (code == 1) { /* vab class */
2312 goto done; /* no longer supported */
2313 } else if (code == 2) { /* kad class */
2317 if ((code = rxkad_GetServerInfo(acall->conn, NULL, 0 /*was &exp */ ,
2318 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))) {
2330 int foreign = afs_is_foreign_ticket_name(name,inst,tcell,pr_realmName);
2333 if (strlen(vname) + 1 + clen >= sizeof(vname))
2336 strcat(vname, tcell);
2337 lcstring(vname, vname, sizeof(vname));
2338 code = NameToID(at, vname, aid);
2339 strcpy(aname, vname);
2344 if (strcmp(AUTH_SUPERUSER, vname) == 0)
2345 *aid = SYSADMINID; /* special case for the fileserver */
2347 lcstring(vname, vname, sizeof(vname));
2348 code = NameToID(at, vname, aid);
2352 if (code && !pr_noAuth)