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
10 #include <afsconfig.h>
11 #include <afs/param.h>
19 #include <afs/afsutil.h>
28 #include <netinet/in.h>
39 #include "afs/audit.h"
41 #ifdef AFS_ATHENA_STDENV
46 #define IP_WILDCARDS 1 /* XXX Should be defined outside of here XXX */
48 extern struct ubik_dbase *dbase;
49 extern afs_int32 Initdb();
51 extern afs_int32 initd;
52 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(), nameToID(), Delete(), removeFromGroup();
53 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
54 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
55 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
60 /* When abort, reset initd so that the header is read in on next call.
61 * Abort the transarction and return the code.
63 #define ABORT_WITH(tt,code) return(initd=0,ubik_AbortTrans(tt),code)
65 static int CreateOK (ut, cid, oid, flag, admin)
66 struct ubik_trans *ut;
67 afs_int32 cid; /* id of caller */
68 afs_int32 oid; /* id of owner */
69 afs_int32 flag; /* indicates type of entry */
70 int admin; /* sysadmin membership */
72 if (flag & PRFOREIGN) {
73 /* Foreign users are recognized by the '@' sign and
74 * not by the PRFOREIGN flag.
78 else if (flag & PRGRP) {
79 /* Allow anonymous group creation only if owner specified
82 if (cid == ANONYMOUSID) {
83 if ((oid == 0) || !pr_noAuth) return 0;
86 else { /* creating a user */
87 if (!admin && !pr_noAuth) return 0;
92 afs_int32 WhoIsThis (acall, at, aid)
93 struct rx_call *acall;
94 struct ubik_trans *at;
98 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
99 /* returns -1 and sets aid to ANONYMOUSID on any failure */
100 register struct rx_connection *tconn;
101 register afs_int32 code;
102 char tcell[MAXKTCREALMLEN];
103 char name[MAXKTCNAMELEN];
104 char inst[MAXKTCNAMELEN];
109 tconn = rx_ConnectionOf(acall);
110 code = rx_SecurityClassOf(tconn);
111 if (code == 0) return 0;
112 else if (code == 1) { /* vab class */
113 goto done; /* no longer supported */
115 else if (code == 2) { /* kad class */
116 if ((code = rxkad_GetServerInfo
117 (acall->conn, (afs_int32 *) 0, 0/*was &exp*/,
118 name, inst, tcell, (afs_int32 *) 0)))
121 /* This test is unnecessary, since rxkad_GetServerInfo already check.
122 * In addition, this is wrong since exp must be unsigned. */
123 if (exp < FT_ApproxTime()) goto done;
125 if (strlen (tcell)) {
126 extern char *pr_realmName;
127 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
128 static char local_realm[AFS_REALM_SZ] = "";
129 if (!local_realm[0]) {
130 if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
131 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
135 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
136 strcasecmp (local_realm, tcell) &&
138 strcasecmp (pr_realmName, tcell))
141 strncpy (vname, name, sizeof(vname));
142 if (ilen = strlen (inst)) {
143 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
145 strcat (vname, inst);
148 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname)) goto done;
150 strcat (vname, tcell);
152 if (strcmp (AUTH_SUPERUSER, vname) == 0)
153 *aid = SYSADMINID; /* special case for the fileserver */
155 lcstring(vname, vname, sizeof(vname));
156 code = NameToID(at,vname,aid);
160 if (code && !pr_noAuth) return -1;
164 afs_int32 PR_INewEntry (call,aname,aid,oid)
165 struct rx_call *call;
166 char aname[PR_MAXNAMELEN];
172 code = iNewEntry (call,aname,aid,oid);
173 osi_auditU (call, PTS_INewEntEvent, code, AUD_LONG, aid, AUD_STR, aname, AUD_LONG, oid, AUD_END);
177 afs_int32 iNewEntry (call,aname,aid,oid)
178 struct rx_call *call;
179 char aname[PR_MAXNAMELEN];
183 /* used primarily for conversion - not intended to be used as usual means
184 of entering people into the database. */
185 struct ubik_trans *tt;
186 register afs_int32 code;
193 if (code != PRSUCCESS) return code;
194 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
195 if (code) return code;
196 code = ubik_SetLock(tt, 1,1,LOCKWRITE);
197 if (code) ABORT_WITH(tt,code);
198 code = read_DbHeader(tt);
199 if (code) ABORT_WITH(tt,code);
201 code = WhoIsThis(call,tt,&cid);
202 if (code) ABORT_WITH(tt,PRPERM);
203 admin = IsAMemberOf(tt,cid,SYSADMINID);
205 /* first verify the id is good */
206 if (aid == 0) ABORT_WITH(tt,PRPERM);
209 /* only sysadmin can reuse a group id */
210 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup)-1))
211 ABORT_WITH(tt,PRPERM);
213 if (FindByID (tt, aid)) ABORT_WITH(tt,PRIDEXIST);
215 /* check a few other things */
216 if (!CreateOK (tt, cid, oid, gflag, admin)) ABORT_WITH(tt,PRPERM);
218 code = CreateEntry (tt,aname,&aid,1,gflag,oid,cid);
219 if (code != PRSUCCESS) ABORT_WITH(tt,code);
221 /* finally, commit transaction */
222 code = ubik_EndTrans(tt);
223 if (code) return code;
228 afs_int32 PR_NewEntry (call, aname, flag, oid, aid)
229 struct rx_call *call;
230 char aname[PR_MAXNAMELEN];
237 code = newEntry (call, aname, flag, oid, aid);
238 osi_auditU (call, PTS_NewEntEvent, code, AUD_LONG, *aid, AUD_STR, aname, AUD_LONG, oid, AUD_END);
242 afs_int32 newEntry (call, aname, flag, oid, aid)
243 struct rx_call *call;
244 char aname[PR_MAXNAMELEN];
249 register afs_int32 code;
250 struct ubik_trans *tt;
253 extern afs_int32 WhoIsThisWithName();
254 char cname[PR_MAXNAMELEN];
257 if (code) return code;
258 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
259 if (code) return code;
260 code = ubik_SetLock(tt,1,1,LOCKWRITE);
261 if (code) ABORT_WITH(tt,code);
262 code = read_DbHeader(tt);
263 if (code) ABORT_WITH(tt,code);
265 /* this is for cross-cell self registration. It is not added in the
266 * PR_INewEntry because we want self-registration to only do
267 * automatic id assignment.
269 code = WhoIsThisWithName(call,tt,&cid,cname);
270 if (code != 2) {/* 2 specifies that this is a foreign cell request */
271 if (code) ABORT_WITH(tt,PRPERM);
272 admin = IsAMemberOf(tt,cid,SYSADMINID);
274 admin = (!strcmp(aname,cname)) || IsAMemberOf(tt,cid,SYSADMINID);
275 oid = cid = SYSADMINID;
277 if (!CreateOK (tt, cid, oid, flag, admin)) ABORT_WITH(tt,PRPERM);
279 code = CreateEntry (tt,aname,aid,0,flag,oid,cid);
280 if (code != PRSUCCESS) ABORT_WITH(tt,code);
282 code = ubik_EndTrans(tt);
283 if (code) return code;
289 afs_int32 PR_WhereIsIt (call,aid,apos)
290 struct rx_call *call;
296 code = whereIsIt(call,aid,apos);
297 osi_auditU (call, PTS_WheIsItEvent, code, AUD_LONG, aid, AUD_LONG, *apos, AUD_END);
301 afs_int32 whereIsIt (call,aid,apos)
302 struct rx_call *call;
306 register afs_int32 code;
307 struct ubik_trans *tt;
311 if (code != PRSUCCESS) return code;
312 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
313 if (code) return code;
314 code = ubik_SetLock(tt,1,1,LOCKREAD);
315 if (code) ABORT_WITH(tt,code);
316 code = read_DbHeader(tt);
317 if (code) ABORT_WITH(tt,code);
319 temp = FindByID(tt,aid);
320 if (!temp) ABORT_WITH(tt,PRNOENT);
322 code = ubik_EndTrans(tt);
323 if (code) return code;
328 afs_int32 PR_DumpEntry (call,apos, aentry)
329 struct rx_call *call;
331 struct prdebugentry *aentry;
335 code = dumpEntry(call,apos, aentry);
336 osi_auditU (call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
340 afs_int32 dumpEntry (call,apos, aentry)
341 struct rx_call *call;
343 struct prdebugentry *aentry;
345 register afs_int32 code;
347 struct ubik_trans *tt;
350 if (code != PRSUCCESS) return code;
351 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
352 if (code) return code;
353 code = ubik_SetLock(tt,1,1,LOCKREAD);
354 if (code) ABORT_WITH(tt,code);
355 code = read_DbHeader(tt);
356 if (code) ABORT_WITH(tt,code);
358 code = WhoIsThis(call,tt,&cid);
359 if (code) ABORT_WITH(tt,PRPERM);
360 code = pr_ReadEntry(tt, 0, apos, aentry);
361 if (code) ABORT_WITH(tt,code);
363 if (!AccessOK (tt, cid, aentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
364 ABORT_WITH(tt,PRPERM);
366 /* Since prdebugentry is in the form of a prentry not a coentry, we will
367 * return the coentry slots in network order where the string is. */
369 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
370 code = pr_ReadCoEntry(tt, 0, apos, aentry);
371 if (code) ABORT_WITH(tt,code);
374 code = ubik_EndTrans(tt);
375 if (code) return code;
379 afs_int32 PR_AddToGroup (call,aid,gid)
380 struct rx_call *call;
386 code = addToGroup (call,aid,gid);
387 osi_auditU (call, PTS_AdToGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid, AUD_END);
391 afs_int32 addToGroup (call,aid,gid)
392 struct rx_call *call;
396 register afs_int32 code;
397 struct ubik_trans *tt;
400 struct prentry tentry;
401 struct prentry uentry;
405 if (code != PRSUCCESS) return code;
406 if (gid == ANYUSERID || gid == AUTHUSERID) return PRPERM;
407 if (aid == ANONYMOUSID) return PRPERM;
408 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
409 if (code) return code;
410 code = ubik_SetLock(tt,1,1,LOCKWRITE);
411 if (code) ABORT_WITH(tt,code);
412 code = read_DbHeader(tt);
413 if (code) ABORT_WITH(tt,code);
415 code = WhoIsThis(call, tt, &cid);
416 if (code) ABORT_WITH(tt,PRPERM);
417 tempu = FindByID(tt,aid);
418 if (!tempu) ABORT_WITH(tt,PRNOENT);
419 memset(&uentry, 0, sizeof(uentry));
420 code = pr_ReadEntry(tt,0,tempu,&uentry);
421 if (code != 0) ABORT_WITH(tt,code);
422 /* we don't allow groups as members of groups at present */
423 if (uentry.flags & PRGRP) ABORT_WITH(tt,PRNOTUSER);
424 tempg = FindByID(tt,gid);
425 if (!tempg) ABORT_WITH(tt,PRNOENT);
426 code = pr_ReadEntry(tt,0,tempg,&tentry);
427 if (code != 0) ABORT_WITH(tt,code);
428 /* make sure that this is a group */
429 if (!(tentry.flags & PRGRP)) ABORT_WITH(tt,PRNOTGROUP);
430 if (!AccessOK (tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY)) ABORT_WITH(tt,PRPERM);
432 code = AddToEntry (tt, &tentry, tempg, aid);
433 if (code != PRSUCCESS) ABORT_WITH(tt,code);
434 /* now, modify the user's entry as well */
435 code = AddToEntry (tt, &uentry, tempu, gid);
436 if (code != PRSUCCESS) ABORT_WITH(tt,code);
437 code = ubik_EndTrans(tt);
438 if (code) return code;
442 afs_int32 PR_NameToID (call, aname, aid)
443 struct rx_call *call;
449 code = nameToID (call, aname, aid);
450 osi_auditU (call, PTS_NmToIdEvent, code, AUD_END);
454 afs_int32 nameToID (call, aname, aid)
455 struct rx_call *call;
459 register afs_int32 code;
460 struct ubik_trans *tt;
465 /* Initialize return struct */
467 aid->idlist_val = (afs_int32 *)0;
469 size = aname->namelist_len;
470 if (size == 0) return 0;
471 if (size < 0) return PRTOOMANY;
473 aid->idlist_val = (afs_int32 *)malloc(size*sizeof(afs_int32));
474 if (!aid->idlist_val) return PRNOMEM;
477 if (code != PRSUCCESS) return code;
478 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
479 if (code) return code;
480 code = ubik_SetLock(tt,1,1,LOCKREAD);
481 if (code) ABORT_WITH(tt,code);
482 code = read_DbHeader(tt);
483 if (code) ABORT_WITH(tt,code);
485 for (i=0;i<aname->namelist_len;i++) {
486 code = NameToID(tt,aname->namelist_val[i],&aid->idlist_val[i]);
487 if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID;
488 if (count++ > 50) IOMGR_Poll(), count = 0;
490 aid->idlist_len = aname->namelist_len;
492 code = ubik_EndTrans(tt);
493 if (code) return code;
499 * Given an array of ids, find the name for each of them.
500 * The array of ids and names is unlimited.
502 afs_int32 PR_IDToName (call, aid, aname)
503 struct rx_call *call;
509 code = idToName (call, aid, aname);
510 osi_auditU (call, PTS_IdToNmEvent, code, AUD_LONG, aid, AUD_END);
514 afs_int32 idToName (call, aid, aname)
515 struct rx_call *call;
519 register afs_int32 code;
520 struct ubik_trans *tt;
525 /* leave this first for rpc stub */
526 size = aid->idlist_len;
527 if (size <= 0) size = 0;
528 aname->namelist_val = (prname *)malloc(size*PR_MAXNAMELEN);
529 aname->namelist_len = 0;
530 if (aid->idlist_len == 0) return 0;
531 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
534 if (code != PRSUCCESS) return code;
535 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
536 if (code) return code;
537 code = ubik_SetLock(tt,1,1,LOCKREAD);
538 if (code) ABORT_WITH(tt,code);
539 code = read_DbHeader(tt);
540 if (code) ABORT_WITH(tt,code);
542 for (i=0;i<aid->idlist_len;i++) {
543 code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
544 if (code != PRSUCCESS)
545 sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
546 if (count++ > 50) IOMGR_Poll(), count = 0;
548 aname->namelist_len = aid->idlist_len;
550 code = ubik_EndTrans(tt);
551 if (code) return code;
555 afs_int32 PR_Delete (call, aid)
556 struct rx_call *call;
561 code = Delete (call, aid);
562 osi_auditU (call, PTS_DelEvent, code, AUD_LONG, aid, AUD_END);
566 afs_int32 Delete (call, aid)
567 struct rx_call *call;
570 register afs_int32 code;
571 struct ubik_trans *tt;
573 struct prentry tentry;
578 if (code) return code;
579 if (code != PRSUCCESS) return code;
580 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
581 aid == ANONYMOUSID) return PRPERM;
582 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
583 if (code) return code;
584 code = ubik_SetLock(tt,1,1,LOCKWRITE);
585 if (code) ABORT_WITH(tt,code);
586 code = read_DbHeader(tt);
587 if (code) ABORT_WITH(tt,code);
589 code = WhoIsThis(call,tt,&cid);
590 if (code) ABORT_WITH(tt,PRPERM);
592 /* Read in entry to be deleted */
593 loc = FindByID (tt, aid);
594 if (loc == 0) ABORT_WITH(tt,PRNOENT);
595 code = pr_ReadEntry (tt, 0, loc, &tentry);
596 if (code) ABORT_WITH(tt,PRDBFAIL);
598 /* Do some access checking */
599 if (tentry.owner != cid &&
600 !IsAMemberOf (tt, cid, SYSADMINID) &&
601 !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
602 ABORT_WITH(tt,PRPERM);
604 /* Delete each continuation block as a separate transaction so that no one
605 * transaction become to large to complete. */
607 while (nptr != (afs_int32)NULL) {
608 struct contentry centry;
611 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
612 if (code != 0) ABORT_WITH(tt,PRDBFAIL);
613 for (i=0;i<COSIZE;i++) {
614 if (centry.entries[i] == PRBADID) continue;
615 if (centry.entries[i] == 0) break;
616 code = RemoveFromEntry (tt, aid, centry.entries[i]);
617 if (code) ABORT_WITH(tt,code);
618 tentry.count--; /* maintain count */
619 if ((i&3) == 0) IOMGR_Poll();
621 tentry.next = centry.next; /* thread out this block */
622 code = FreeBlock (tt, nptr); /* free continuation block */
623 if (code) ABORT_WITH(tt,code);
624 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
625 if (code) ABORT_WITH(tt,code);
627 /* end this trans and start a new one */
628 code = ubik_EndTrans(tt);
629 if (code) return code;
630 IOMGR_Poll(); /* just to keep the connection alive */
631 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
632 if (code) return code;
633 code = ubik_SetLock(tt,1,1,LOCKWRITE);
634 if (code) ABORT_WITH(tt,code);
636 /* re-read entry to get consistent uptodate info */
637 loc = FindByID (tt, aid);
638 if (loc == 0) ABORT_WITH(tt,PRNOENT);
639 code = pr_ReadEntry (tt, 0, loc, &tentry);
640 if (code) ABORT_WITH(tt,PRDBFAIL);
645 /* Then move the owned chain, except possibly ourself to the orphan list.
646 * Because this list can be very long and so exceed the size of a ubik
647 * transaction, we start a new transaction every 50 entries. */
650 while (nptr != (afs_int32)NULL) {
651 struct prentry nentry;
653 code = pr_ReadEntry (tt, 0, nptr, &nentry);
654 if (code) ABORT_WITH(tt,PRDBFAIL);
655 nptr = tentry.owned = nentry.nextOwned; /* thread out */
657 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
658 code = AddToOrphan (tt, nentry.id);
659 if (code) ABORT_WITH(tt,code);
661 if ((count & 3) == 0) IOMGR_Poll();
663 if (count < 50) continue;
664 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
665 if (code) ABORT_WITH(tt,code);
667 /* end this trans and start a new one */
668 code = ubik_EndTrans(tt);
669 if (code) return code;
670 IOMGR_Poll(); /* just to keep the connection alive */
671 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
672 if (code) return code;
673 code = ubik_SetLock(tt,1,1,LOCKWRITE);
674 if (code) ABORT_WITH(tt,code);
676 /* re-read entry to get consistent uptodate info */
677 loc = FindByID (tt, aid);
678 if (loc == 0) ABORT_WITH(tt,PRNOENT);
679 code = pr_ReadEntry (tt, 0, loc, &tentry);
680 if (code) ABORT_WITH(tt,PRDBFAIL);
685 /* now do what's left of the deletion stuff */
686 code = DeleteEntry (tt, &tentry, loc);
687 if (code != PRSUCCESS) ABORT_WITH(tt,code);
689 code = ubik_EndTrans(tt);
690 if (code) return code;
694 afs_int32 PR_UpdateEntry (call, aid, name, uentry)
695 struct rx_call *call;
698 struct PrUpdateEntry *uentry;
700 register afs_int32 code;
701 struct ubik_trans *tt;
703 struct prentry tentry;
708 if (code) return code;
709 if (code != PRSUCCESS) return code;
712 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
713 aid == ANONYMOUSID) return PRPERM;
715 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
716 if (code) return code;
717 code = ubik_SetLock(tt,1,1,LOCKWRITE);
718 if (code) ABORT_WITH(tt,code);
719 code = read_DbHeader(tt);
720 if (code) ABORT_WITH(tt,code);
722 code = WhoIsThis(call,tt,&cid);
723 if (code) ABORT_WITH(tt,PRPERM);
724 code = IsAMemberOf (tt, cid, SYSADMINID);
725 if (!code && !pr_noAuth) ABORT_WITH(tt,PRPERM);
727 /* Read in entry to be deleted */
729 loc = FindByID (tt, aid);
731 loc = FindByName(tt, name, &tentry);
733 if (loc == 0) ABORT_WITH(tt,PRNOENT);
734 code = pr_ReadEntry (tt, 0, loc, &tentry);
735 if (code) ABORT_WITH(tt,PRDBFAIL);
737 if (uentry->Mask & PRUPDATE_NAMEHASH) {
739 code = RemoveFromNameHash(tt, tentry.name, &tloc);
740 if (code != PRSUCCESS) ABORT_WITH(tt,PRDBFAIL);
741 code = AddToNameHash(tt, tentry.name, loc);
742 if (code) ABORT_WITH(tt,code);
745 if (uentry->Mask & PRUPDATE_IDHASH) {
747 if (!id) id = tentry.id;
748 code = RemoveFromIDHash(tt, id, &tloc);
749 if (code != PRSUCCESS) ABORT_WITH(tt,PRDBFAIL);
750 code = AddToIDHash(tt, id, loc);
751 if (code) ABORT_WITH(tt,code);
754 code = ubik_EndTrans(tt);
755 if (code) return code;
759 afs_int32 PR_RemoveFromGroup (call,aid,gid)
760 struct rx_call *call;
766 code = removeFromGroup (call,aid,gid);
767 osi_auditU (call, PTS_RmFmGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid, AUD_END);
771 afs_int32 removeFromGroup (call,aid,gid)
772 struct rx_call *call;
776 register afs_int32 code;
777 struct ubik_trans *tt;
780 struct prentry uentry;
781 struct prentry gentry;
785 if (code != PRSUCCESS) return code;
786 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
787 if (code) return code;
788 code = ubik_SetLock(tt,1,1,LOCKWRITE);
789 if (code) ABORT_WITH(tt,code);
790 code = read_DbHeader(tt);
791 if (code) ABORT_WITH(tt,code);
793 code = WhoIsThis(call,tt,&cid);
794 if (code) ABORT_WITH(tt,PRPERM);
795 tempu = FindByID(tt,aid);
796 if (!tempu) ABORT_WITH(tt,PRNOENT);
797 tempg = FindByID(tt,gid);
798 if (!tempg) ABORT_WITH(tt,PRNOENT);
799 memset(&uentry, 0, sizeof(uentry));
800 memset(&gentry, 0, sizeof(gentry));
801 code = pr_ReadEntry(tt,0,tempu,&uentry);
802 if (code != 0) ABORT_WITH(tt,code);
803 code = pr_ReadEntry(tt,0,tempg,&gentry);
804 if (code != 0) ABORT_WITH(tt,code);
805 if (!(gentry.flags & PRGRP)) ABORT_WITH(tt,PRNOTGROUP);
806 if (uentry.flags & PRGRP) ABORT_WITH(tt,PRNOTUSER);
807 if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) ABORT_WITH(tt,PRPERM);
808 code = RemoveFromEntry(tt,aid,gid);
809 if (code != PRSUCCESS) ABORT_WITH(tt,code);
810 code = RemoveFromEntry(tt,gid,aid);
811 if (code != PRSUCCESS) ABORT_WITH(tt,code);
813 code = ubik_EndTrans(tt);
814 if (code) return code;
819 afs_int32 PR_GetCPS (call, aid, alist, over)
820 struct rx_call *call;
827 code = getCPS (call, aid, alist, over);
828 osi_auditU (call, PTS_GetCPSEvent, code, AUD_LONG, aid, AUD_END);
832 afs_int32 getCPS (call, aid, alist, over)
833 struct rx_call *call;
838 register afs_int32 code;
839 struct ubik_trans *tt;
842 struct prentry tentry;
845 alist->prlist_len = 0;
846 alist->prlist_val = (afs_int32 *) 0;
848 if (code != PRSUCCESS) return code;
849 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
850 if (code) return code;
851 code = ubik_SetLock(tt,1,1,LOCKREAD);
852 if (code) ABORT_WITH(tt,code);
853 code = read_DbHeader(tt);
854 if (code) ABORT_WITH(tt,code);
856 temp = FindByID (tt, aid);
857 if (!temp) ABORT_WITH(tt,PRNOENT);
858 code = pr_ReadEntry (tt, 0, temp, &tentry);
859 if (code) ABORT_WITH(tt,code);
861 /* afs does authenticate now */
862 code = WhoIsThis (call, tt, &cid);
863 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
864 ABORT_WITH(tt,PRPERM);
866 code = GetList(tt, &tentry, alist, 1);
867 if (code != PRSUCCESS) ABORT_WITH(tt,code);
869 code = ubik_EndTrans(tt);
881 for (i = (CPS.prlist_len-1) ; i >= 0; i--) {
882 if (CPS.prlist_val[i] == id)
887 #endif /* IP_WILDCARDS */
890 afs_int32 PR_GetCPS2 (call, aid, ahost, alist, over)
891 struct rx_call *call;
899 code = getCPS2 (call, aid, ahost, alist, over);
900 osi_auditU (call, PTS_GetCPS2Event, code, AUD_LONG, aid, AUD_HOST, ahost, AUD_END);
904 afs_int32 getCPS2 (call, aid, ahost, alist, over)
905 struct rx_call *call;
911 register afs_int32 code;
912 struct ubik_trans *tt;
915 struct prentry tentry;
916 struct prentry host_tentry;
919 struct in_addr iaddr;
921 extern afs_int32 addWildCards();
922 #endif /* IP_WILDCARDS */
925 iaddr.s_addr = ntohl(ahost);
926 alist->prlist_len = 0;
927 alist->prlist_val = (afs_int32 *) 0;
929 if (code != PRSUCCESS) return code;
930 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
931 if (code) return code;
932 code = ubik_SetLock(tt,1,1,LOCKREAD);
933 if (code) ABORT_WITH(tt,code);
934 code = read_DbHeader(tt);
935 if (code) ABORT_WITH(tt,code);
937 if (aid != PRBADID) {
938 temp = FindByID(tt,aid);
939 if (!temp) ABORT_WITH(tt,PRNOENT);
940 code = pr_ReadEntry (tt, 0, temp, &tentry);
941 if (code) ABORT_WITH(tt,code);
943 /* afs does authenticate now */
944 code = WhoIsThis (call, tt, &cid);
945 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
946 ABORT_WITH(tt,PRPERM);
948 code = NameToID(tt, inet_ntoa(iaddr),&hostid);
949 if (code == PRSUCCESS && hostid != 0) {
950 temp = FindByID(tt,hostid);
952 code = pr_ReadEntry (tt, 0, temp, &host_tentry);
953 if (code == PRSUCCESS)
956 fprintf(stderr,"pr_ReadEntry returned %d\n",code);
958 fprintf(stderr,"FindByID Failed -- Not found\n");
961 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
963 code = GetList(tt, &tentry, alist, 1);
966 code = addWildCards(tt,alist,ntohl(ahost));
967 #endif /* IP_WILDCARDS */
968 if (code != PRSUCCESS) ABORT_WITH(tt,code);
970 code = ubik_EndTrans(tt);
975 afs_int32 PR_GetHostCPS (call, ahost, alist, over)
976 struct rx_call *call;
983 code = getHostCPS (call, ahost, alist, over);
984 osi_auditU (call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
988 afs_int32 getHostCPS (call, ahost, alist, over)
989 struct rx_call *call;
994 register afs_int32 code, temp;
995 struct ubik_trans *tt;
996 struct prentry host_tentry;
998 struct in_addr iaddr;
1000 extern afs_int32 addWildCards();
1001 #endif /* IP_WILDCARDS */
1004 iaddr.s_addr = ntohl(ahost);
1005 alist->prlist_len = 0;
1006 alist->prlist_val = (afs_int32 *) 0;
1008 if (code != PRSUCCESS) return code;
1009 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1010 if (code) return code;
1011 code = ubik_SetLock(tt,1,1,LOCKREAD);
1012 if (code) ABORT_WITH(tt,code);
1013 code = read_DbHeader(tt);
1014 if (code) ABORT_WITH(tt,code);
1016 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1017 if (code == PRSUCCESS && hostid != 0) {
1018 temp = FindByID(tt,hostid);
1020 code = pr_ReadEntry (tt, 0, temp, &host_tentry);
1021 if (code == PRSUCCESS) {
1022 code = GetList(tt, &host_tentry, alist, 0);
1025 fprintf(stderr,"pr_ReadEntry returned %d\n",code);
1027 fprintf(stderr,"FindByID Failed -- Not found\n");
1030 code = addWildCards(tt,alist,ntohl(ahost));
1031 #endif /* IP_WILDCARDS */
1033 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1035 code = ubik_EndTrans(tt);
1040 afs_int32 PR_ListMax (call,uid,gid)
1041 struct rx_call *call;
1047 code = listMax(call,uid,gid);
1048 osi_auditU (call, PTS_LstMaxEvent, code, AUD_END);
1052 afs_int32 listMax (call,uid,gid)
1053 struct rx_call *call;
1057 register afs_int32 code;
1058 struct ubik_trans *tt;
1061 if (code != PRSUCCESS) return code;
1062 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1063 if (code) return code;
1064 code = ubik_SetLock(tt,1,1,LOCKREAD);
1065 if (code) ABORT_WITH(tt,code);
1066 code = read_DbHeader(tt);
1067 if (code) ABORT_WITH(tt,code);
1069 code = GetMax(tt,uid,gid);
1070 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1072 code = ubik_EndTrans(tt);
1073 if (code) return code;
1077 afs_int32 PR_SetMax (call,aid,gflag)
1078 struct rx_call *call;
1084 code = setMax (call,aid,gflag);
1085 osi_auditU (call, PTS_SetMaxEvent, code, AUD_LONG, aid, AUD_LONG, gflag, AUD_END);
1089 afs_int32 setMax (call,aid,gflag)
1090 struct rx_call *call;
1094 register afs_int32 code;
1095 struct ubik_trans *tt;
1099 if (code != PRSUCCESS) return code;
1100 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1101 if (code) return code;
1102 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1103 if (code) ABORT_WITH(tt,code);
1104 code = read_DbHeader(tt);
1105 if (code) ABORT_WITH(tt,code);
1107 code = WhoIsThis(call,tt,&cid);
1108 if (code) ABORT_WITH(tt,PRPERM);
1109 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1110 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0))) ABORT_WITH(tt,PRBADARG);
1112 code = SetMax(tt,aid,gflag);
1113 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1115 code = ubik_EndTrans(tt);
1116 if (code) return code;
1120 afs_int32 PR_ListEntry (call,aid,aentry)
1121 struct rx_call *call;
1123 struct prcheckentry *aentry;
1127 code = listEntry (call,aid,aentry);
1128 osi_auditU (call, PTS_LstEntEvent, code, AUD_LONG, aid, AUD_END);
1132 afs_int32 listEntry (call,aid,aentry)
1133 struct rx_call *call;
1135 struct prcheckentry *aentry;
1137 register afs_int32 code;
1138 struct ubik_trans *tt;
1141 struct prentry tentry;
1144 if (code != PRSUCCESS) return code;
1145 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1146 if (code) return code;
1147 code = ubik_SetLock(tt,1,1,LOCKREAD);
1148 if (code) ABORT_WITH(tt,code);
1149 code = read_DbHeader(tt);
1150 if (code) ABORT_WITH(tt,code);
1152 code = WhoIsThis(call,tt,&cid);
1153 if (code) ABORT_WITH(tt,PRPERM);
1154 temp = FindByID(tt,aid);
1155 if (!temp) ABORT_WITH(tt,PRNOENT);
1156 code = pr_ReadEntry(tt, 0, temp, &tentry);
1157 if (code != 0) ABORT_WITH(tt,code);
1158 if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1159 ABORT_WITH(tt,PRPERM);
1161 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1162 if (aentry->flags == 0) {
1163 if (tentry.flags & PRGRP)
1164 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
1165 else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
1167 aentry->owner = tentry.owner;
1168 aentry->id = tentry.id;
1169 strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
1170 aentry->creator = tentry.creator;
1171 aentry->ngroups = tentry.ngroups;
1172 aentry->nusers = tentry.nusers;
1173 aentry->count = tentry.count;
1174 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1175 code = ubik_EndTrans(tt);
1176 if (code) return code;
1180 afs_int32 PR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1181 struct rx_call *call;
1183 afs_int32 startindex;
1184 prentries *bulkentries;
1185 afs_int32 *nextstartindex;
1189 code = listEntries(call, flag, startindex, bulkentries, nextstartindex);
1190 osi_auditU (call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1194 afs_int32 listEntries(call, flag, startindex, bulkentries, nextstartindex)
1195 struct rx_call *call;
1197 afs_int32 startindex;
1198 prentries *bulkentries;
1199 afs_int32 *nextstartindex;
1202 struct ubik_trans *tt;
1204 afs_int32 i, eof, pos, maxentries, f;
1205 struct prentry tentry;
1206 afs_int32 pollcount=0;
1208 *nextstartindex = -1;
1209 bulkentries->prentries_val = 0;
1210 bulkentries->prentries_len = 0;
1213 if (code != PRSUCCESS) return code;
1214 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1215 if (code) return code;
1216 code = ubik_SetLock(tt,1,1,LOCKREAD);
1217 if (code) ABORT_WITH(tt,code);
1218 code = read_DbHeader(tt);
1219 if (code) ABORT_WITH(tt,code);
1221 /* Make sure we are an authenticated caller and that we are on the
1224 code = WhoIsThis(call,tt,&cid);
1225 if (code) ABORT_WITH(tt,PRPERM);
1226 code = IsAMemberOf (tt, cid, SYSADMINID);
1227 if (!code && !pr_noAuth) ABORT_WITH(tt,PRPERM);
1229 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1230 maxentries = eof / sizeof(struct prentry);
1231 for (i=startindex; i<maxentries; i++) {
1232 pos = i * sizeof(struct prentry) + sizeof(cheader);
1233 code = pr_ReadEntry (tt, 0, pos, &tentry);
1234 if (code) goto done;
1236 if (++pollcount > 50) {
1241 f = (tentry.flags & PRTYPE);
1242 if ( ((flag & PRUSERS ) && (f == 0) ) || /* User entry */
1243 ((flag & PRGROUPS) && (f & PRGRP)) ) { /* Group entry */
1244 code = put_prentries(&tentry, bulkentries);
1245 if (code == -1) break; /* Filled return array */
1246 if (code) goto done;
1251 *nextstartindex = i;
1255 if (bulkentries->prentries_val)
1256 free(bulkentries->prentries_val);
1257 bulkentries->prentries_val = 0;
1258 bulkentries->prentries_len = 0;
1259 ABORT_WITH(tt, code);
1262 code = ubik_EndTrans(tt);
1264 if (code) return code;
1268 #define PR_MAXENTRIES 500
1269 afs_int32 put_prentries(tentry, bulkentries)
1270 struct prentry *tentry;
1271 prentries *bulkentries;
1273 struct prlistentries *entry;
1275 if (bulkentries->prentries_val == 0) {
1276 bulkentries->prentries_len = 0;
1277 bulkentries->prentries_val = (struct prlistentries *)malloc(PR_MAXENTRIES * sizeof(struct prentry));
1278 if (!bulkentries->prentries_val) {
1283 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1287 entry = (struct prlistentries *)bulkentries->prentries_val;
1288 entry += bulkentries->prentries_len;
1290 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1291 if (entry->flags == 0) {
1292 entry->flags = ( (tentry->flags & PRGRP)?PRP_GROUP_DEFAULT
1293 :PRP_USER_DEFAULT ) >> PRIVATE_SHIFT;
1295 entry->owner = tentry->owner;
1296 entry->id = tentry->id;
1297 entry->creator = tentry->creator;
1298 entry->ngroups = tentry->ngroups;
1299 entry->nusers = tentry->nusers;
1300 entry->count = tentry->count;
1301 strncpy(entry->name,tentry->name,PR_MAXNAMELEN);
1302 memset(entry->reserved, 0, sizeof(entry->reserved));
1303 bulkentries->prentries_len++;
1307 afs_int32 PR_ChangeEntry (call,aid,name,oid,newid)
1308 struct rx_call *call;
1316 code = changeEntry (call,aid,name,oid,newid);
1317 osi_auditU (call, PTS_ChgEntEvent, code, AUD_LONG, aid, AUD_STR, name,
1319 AUD_LONG, newid, AUD_END);
1323 afs_int32 changeEntry (call,aid,name,oid,newid)
1324 struct rx_call *call;
1330 register afs_int32 code;
1331 struct ubik_trans *tt;
1335 if (!name) return PRPERM;
1339 if (code) return code;
1340 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID ||
1341 aid == SYSADMINID) return PRPERM;
1342 if (code != PRSUCCESS) return code;
1343 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1344 if (code) return code;
1345 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1346 if (code) ABORT_WITH(tt,code);
1347 code = read_DbHeader(tt);
1348 if (code) ABORT_WITH(tt,code);
1350 code = WhoIsThis(call,tt,&cid);
1351 if (code) ABORT_WITH(tt,PRPERM);
1352 pos = FindByID(tt,aid);
1353 if (!pos) ABORT_WITH(tt,PRNOENT);
1354 /* protection check in changeentry */
1355 code = ChangeEntry(tt,aid,cid,name,oid,newid);
1356 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1358 code = ubik_EndTrans(tt);
1362 afs_int32 PR_SetFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2)
1363 struct rx_call *call;
1365 afs_int32 mask; /* specify which fields to update */
1366 afs_int32 flags, ngroups, nusers;
1367 afs_int32 spare1, spare2;
1371 code = setFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2);
1372 osi_auditU (call, PTS_SetFldEntEvent, code, AUD_LONG, id, AUD_END);
1376 afs_int32 setFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2)
1377 struct rx_call *call;
1379 afs_int32 mask; /* specify which fields to update */
1380 afs_int32 flags, ngroups, nusers;
1381 afs_int32 spare1, spare2;
1383 register afs_int32 code;
1384 struct ubik_trans *tt;
1387 struct prentry tentry;
1390 if (mask == 0) return 0; /* no-op */
1392 if (code) return code;
1393 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1395 if (code != PRSUCCESS) return code;
1396 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1397 if (code) return code;
1398 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1399 if (code) ABORT_WITH(tt,code);
1400 code = read_DbHeader(tt);
1401 if (code) ABORT_WITH(tt,code);
1403 code = WhoIsThis(call,tt,&cid);
1404 if (code) ABORT_WITH(tt,PRPERM);
1405 pos = FindByID(tt,id);
1406 if (!pos) ABORT_WITH(tt,PRNOENT);
1407 code = pr_ReadEntry (tt, 0, pos, &tentry);
1408 if (code) ABORT_WITH(tt,code);
1409 tflags = tentry.flags;
1411 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1412 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1413 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1414 tentry.ngroups = tentry.nusers = 20;
1417 if (!AccessOK (tt, cid, &tentry, 0, 0)) ABORT_WITH(tt,PRPERM);
1420 if (mask & 0xffff) { /* if setting flag bits */
1421 afs_int32 flagsMask = mask & 0xffff;
1422 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1423 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1427 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1428 if (ngroups < 0) ABORT_WITH(tt,PRBADARG);
1429 tentry.ngroups = ngroups;
1433 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1434 if (nusers < 0) ABORT_WITH(tt,PRBADARG);
1435 tentry.nusers = nusers;
1438 tentry.flags = tflags;
1440 code = pr_WriteEntry (tt, 0, pos, &tentry);
1441 if (code) ABORT_WITH(tt,code);
1443 code = ubik_EndTrans(tt);
1447 afs_int32 PR_ListElements (call, aid, alist, over)
1448 struct rx_call *call;
1455 code = listElements (call, aid, alist, over);
1456 osi_auditU (call, PTS_LstEleEvent, code, AUD_LONG, aid, AUD_END);
1460 afs_int32 listElements (call, aid, alist, over)
1461 struct rx_call *call;
1466 register afs_int32 code;
1467 struct ubik_trans *tt;
1470 struct prentry tentry;
1473 alist->prlist_len = 0;
1474 alist->prlist_val = (afs_int32 *) 0;
1477 if (code != PRSUCCESS) return code;
1478 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1479 if (code) return code;
1480 code = ubik_SetLock(tt,1,1,LOCKREAD);
1481 if (code) ABORT_WITH(tt,code);
1482 code = read_DbHeader(tt);
1483 if (code) ABORT_WITH(tt,code);
1485 code = WhoIsThis(call,tt,&cid);
1486 if (code) ABORT_WITH(tt,PRPERM);
1488 temp = FindByID(tt,aid);
1489 if (!temp) ABORT_WITH(tt,PRNOENT);
1490 code = pr_ReadEntry (tt, 0, temp, &tentry);
1491 if (code) ABORT_WITH(tt,code);
1492 if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1493 ABORT_WITH(tt,PRPERM);
1495 code = GetList (tt, &tentry, alist, 0);
1496 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1498 code = ubik_EndTrans(tt);
1504 * List the entries owned by this id. If the id is zero,
1505 * return the orphans list. This will return up to PR_MAXGROUPS
1506 * at a time with the lastP available to get the rest. The
1507 * maximum value is enforced in GetOwnedChain().
1509 afs_int32 PR_ListOwned (call, aid, alist, lastP)
1510 struct rx_call *call;
1517 code = listOwned (call, aid, alist, lastP);
1518 osi_auditU (call, PTS_LstOwnEvent, code, AUD_LONG, aid, AUD_END);
1522 afs_int32 listOwned (call, aid, alist, lastP)
1523 struct rx_call *call;
1528 register afs_int32 code;
1529 struct ubik_trans *tt;
1531 struct prentry tentry;
1535 alist->prlist_len = 0;
1536 alist->prlist_val = (afs_int32 *) 0;
1538 if (!lastP) return PRBADARG;
1543 if (code != PRSUCCESS) return code;
1544 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1545 if (code) return code;
1546 code = ubik_SetLock(tt,1,1,LOCKREAD);
1547 if (code) ABORT_WITH(tt,code);
1548 code = read_DbHeader(tt);
1549 if (code) ABORT_WITH(tt,code);
1551 code = WhoIsThis(call,tt,&cid);
1552 if (code) ABORT_WITH(tt,PRPERM);
1555 code = pr_ReadEntry (tt, 0, start, &tentry);
1556 if (!code && (tentry.owner == aid))
1557 head = start; /* pick up where we left off */
1562 afs_int32 loc = FindByID (tt, aid);
1563 if (loc == 0) ABORT_WITH(tt,PRNOENT);
1564 code = pr_ReadEntry (tt, 0, loc, &tentry);
1565 if (code) ABORT_WITH(tt,code);
1567 if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY))
1568 ABORT_WITH(tt,PRPERM);
1569 head = tentry.owned;
1571 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1572 head = ntohl(cheader.orphan);
1576 code = GetOwnedChain (tt, &head, alist);
1578 if (code == PRTOOMANY) *lastP = head;
1579 else ABORT_WITH(tt,code);
1582 code = ubik_EndTrans(tt);
1586 afs_int32 PR_IsAMemberOf (call,uid,gid,flag)
1587 struct rx_call *call;
1594 code = isAMemberOf (call,uid,gid,flag);
1595 osi_auditU (call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid, AUD_END);
1599 afs_int32 isAMemberOf (call,uid,gid,flag)
1600 struct rx_call *call;
1605 register afs_int32 code;
1606 struct ubik_trans *tt;
1609 if (code != PRSUCCESS) return code;
1610 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1611 if (code) return code;
1612 code = ubik_SetLock(tt,1,1,LOCKREAD);
1613 if (code) ABORT_WITH(tt,code);
1614 code = read_DbHeader(tt);
1615 if (code) ABORT_WITH(tt,code);
1618 afs_int32 uloc = FindByID (tt, uid);
1619 afs_int32 gloc = FindByID (tt, gid);
1620 struct prentry uentry, gentry;
1622 if (!uloc || !gloc) ABORT_WITH(tt,PRNOENT);
1623 code = WhoIsThis(call, tt, &cid);
1624 if (code) ABORT_WITH(tt,PRPERM);
1625 code = pr_ReadEntry (tt, 0, uloc, &uentry);
1626 if (code) ABORT_WITH(tt,code);
1627 code = pr_ReadEntry (tt, 0, gloc, &gentry);
1628 if (code) ABORT_WITH(tt,code);
1629 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) ABORT_WITH(tt,PRBADARG);
1630 if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1631 !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1632 ABORT_WITH(tt,PRPERM);
1635 *flag = IsAMemberOf(tt,uid,gid);
1636 code = ubik_EndTrans(tt);
1646 if (isupper(tc)) *s = tolower(tc);
1652 afs_int32 addWildCards(tt,alist,host)
1653 struct ubik_trans *tt;
1658 struct prentry tentry;
1660 unsigned wild = htonl(0xffffff00);
1661 struct in_addr iaddr;
1663 int size = 0, i, code;
1666 while ((host = (host & wild))) {
1667 wild = htonl ( ntohl(wild) << 8) ;
1668 iaddr.s_addr = host;
1669 code = NameToID(tt, inet_ntoa(iaddr),&hostid);
1670 if (code == PRSUCCESS && hostid != 0) {
1671 temp = FindByID(tt,hostid);
1673 code = pr_ReadEntry (tt, 0, temp, &tentry);
1674 if (code != PRSUCCESS)
1680 wlist.prlist_len = 0;
1681 wlist.prlist_val = (afs_int32 *) 0;
1683 code = GetList (tt, &tentry, &wlist, 0);
1684 if (code) return code;
1685 added += wlist.prlist_len;
1686 for (i=0; i< wlist.prlist_len; i++) {
1687 if (!inCPS(*alist,wlist.prlist_val[i]))
1688 if ((code = AddToPRList (alist, &size, wlist.prlist_val[i] ))) {
1689 free(wlist.prlist_val);
1693 if (wlist.prlist_val) free(wlist.prlist_val);
1696 qsort(alist->prlist_val,alist->prlist_len,sizeof(afs_int32),IDCmp);
1699 #endif /* IP_WILDCARDS */
1702 afs_int32 WhoIsThisWithName(acall, at, aid, aname)
1703 struct rx_call *acall;
1704 struct ubik_trans *at;
1708 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
1709 /* returns -1 and sets aid to ANONYMOUSID on any failure */
1710 register struct rx_connection *tconn;
1711 register afs_int32 code;
1712 char tcell[MAXKTCREALMLEN];
1713 char name[MAXKTCNAMELEN];
1714 char inst[MAXKTCNAMELEN];
1719 tconn = rx_ConnectionOf(acall);
1720 code = rx_SecurityClassOf(tconn);
1721 if (code == 0) return 0;
1722 else if (code == 1) { /* vab class */
1723 goto done; /* no longer supported */
1725 else if (code == 2) { /* kad class */
1728 extern char *pr_realmName;
1730 if ((code = rxkad_GetServerInfo
1731 (acall->conn, (afs_int32 *) 0, 0/*was &exp*/,
1732 name, inst, tcell, (afs_int32 *) 0)))
1734 strncpy (vname, name, sizeof(vname));
1735 if ((ilen = strlen(inst))) {
1736 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
1737 strcat (vname, ".");
1738 strcat (vname, inst);
1740 if ( (clen = strlen(tcell))) {
1742 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
1743 static char local_realm[AFS_REALM_SZ] = "";
1744 if (!local_realm[0]) {
1745 if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
1746 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
1750 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
1751 strcasecmp (local_realm, tcell) &&
1753 strcasecmp (pr_realmName, tcell))
1755 if (strlen(vname) + 1 + clen >= sizeof(vname)) goto done;
1757 strcat(vname,tcell);
1758 lcstring(vname, vname, sizeof(vname));
1759 code = NameToID(at,vname,aid);
1760 strcpy(aname,vname);
1765 if (strcmp (AUTH_SUPERUSER, vname) == 0)
1766 *aid = SYSADMINID; /* special case for the fileserver */
1768 lcstring(vname, vname, sizeof(vname));
1769 code = NameToID(at,vname,aid);
1773 if (code && !pr_noAuth) return -1;