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 (aname->namelist_val == 0) return PRNOMEM;
531 if (aid->idlist_len == 0) return 0;
532 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
535 if (code != PRSUCCESS) return code;
536 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
537 if (code) return code;
538 code = ubik_SetLock(tt,1,1,LOCKREAD);
539 if (code) ABORT_WITH(tt,code);
540 code = read_DbHeader(tt);
541 if (code) ABORT_WITH(tt,code);
543 for (i=0;i<aid->idlist_len;i++) {
544 code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
545 if (code != PRSUCCESS)
546 sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
547 if (count++ > 50) IOMGR_Poll(), count = 0;
549 aname->namelist_len = aid->idlist_len;
551 code = ubik_EndTrans(tt);
552 if (code) return code;
556 afs_int32 PR_Delete (call, aid)
557 struct rx_call *call;
562 code = Delete (call, aid);
563 osi_auditU (call, PTS_DelEvent, code, AUD_LONG, aid, AUD_END);
567 afs_int32 Delete (call, aid)
568 struct rx_call *call;
571 register afs_int32 code;
572 struct ubik_trans *tt;
574 struct prentry tentry;
579 if (code) return code;
580 if (code != PRSUCCESS) return code;
581 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
582 aid == ANONYMOUSID) return PRPERM;
583 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
584 if (code) return code;
585 code = ubik_SetLock(tt,1,1,LOCKWRITE);
586 if (code) ABORT_WITH(tt,code);
587 code = read_DbHeader(tt);
588 if (code) ABORT_WITH(tt,code);
590 code = WhoIsThis(call,tt,&cid);
591 if (code) ABORT_WITH(tt,PRPERM);
593 /* Read in entry to be deleted */
594 loc = FindByID (tt, aid);
595 if (loc == 0) ABORT_WITH(tt,PRNOENT);
596 code = pr_ReadEntry (tt, 0, loc, &tentry);
597 if (code) ABORT_WITH(tt,PRDBFAIL);
599 /* Do some access checking */
600 if (tentry.owner != cid &&
601 !IsAMemberOf (tt, cid, SYSADMINID) &&
602 !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
603 ABORT_WITH(tt,PRPERM);
605 /* Delete each continuation block as a separate transaction so that no one
606 * transaction become to large to complete. */
608 while (nptr != (afs_int32)NULL) {
609 struct contentry centry;
612 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
613 if (code != 0) ABORT_WITH(tt,PRDBFAIL);
614 for (i=0;i<COSIZE;i++) {
615 if (centry.entries[i] == PRBADID) continue;
616 if (centry.entries[i] == 0) break;
617 code = RemoveFromEntry (tt, aid, centry.entries[i]);
618 if (code) ABORT_WITH(tt,code);
619 tentry.count--; /* maintain count */
620 if ((i&3) == 0) IOMGR_Poll();
622 tentry.next = centry.next; /* thread out this block */
623 code = FreeBlock (tt, nptr); /* free continuation block */
624 if (code) ABORT_WITH(tt,code);
625 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
626 if (code) ABORT_WITH(tt,code);
628 /* end this trans and start a new one */
629 code = ubik_EndTrans(tt);
630 if (code) return code;
631 IOMGR_Poll(); /* just to keep the connection alive */
632 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
633 if (code) return code;
634 code = ubik_SetLock(tt,1,1,LOCKWRITE);
635 if (code) ABORT_WITH(tt,code);
637 /* re-read entry to get consistent uptodate info */
638 loc = FindByID (tt, aid);
639 if (loc == 0) ABORT_WITH(tt,PRNOENT);
640 code = pr_ReadEntry (tt, 0, loc, &tentry);
641 if (code) ABORT_WITH(tt,PRDBFAIL);
646 /* Then move the owned chain, except possibly ourself to the orphan list.
647 * Because this list can be very long and so exceed the size of a ubik
648 * transaction, we start a new transaction every 50 entries. */
651 while (nptr != (afs_int32)NULL) {
652 struct prentry nentry;
654 code = pr_ReadEntry (tt, 0, nptr, &nentry);
655 if (code) ABORT_WITH(tt,PRDBFAIL);
656 nptr = tentry.owned = nentry.nextOwned; /* thread out */
658 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
659 code = AddToOrphan (tt, nentry.id);
660 if (code) ABORT_WITH(tt,code);
662 if ((count & 3) == 0) IOMGR_Poll();
664 if (count < 50) continue;
665 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
666 if (code) ABORT_WITH(tt,code);
668 /* end this trans and start a new one */
669 code = ubik_EndTrans(tt);
670 if (code) return code;
671 IOMGR_Poll(); /* just to keep the connection alive */
672 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
673 if (code) return code;
674 code = ubik_SetLock(tt,1,1,LOCKWRITE);
675 if (code) ABORT_WITH(tt,code);
677 /* re-read entry to get consistent uptodate info */
678 loc = FindByID (tt, aid);
679 if (loc == 0) ABORT_WITH(tt,PRNOENT);
680 code = pr_ReadEntry (tt, 0, loc, &tentry);
681 if (code) ABORT_WITH(tt,PRDBFAIL);
686 /* now do what's left of the deletion stuff */
687 code = DeleteEntry (tt, &tentry, loc);
688 if (code != PRSUCCESS) ABORT_WITH(tt,code);
690 code = ubik_EndTrans(tt);
691 if (code) return code;
695 afs_int32 PR_UpdateEntry (call, aid, name, uentry)
696 struct rx_call *call;
699 struct PrUpdateEntry *uentry;
701 register afs_int32 code;
702 struct ubik_trans *tt;
704 struct prentry tentry;
709 if (code) return code;
710 if (code != PRSUCCESS) return code;
713 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
714 aid == ANONYMOUSID) return PRPERM;
716 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
717 if (code) return code;
718 code = ubik_SetLock(tt,1,1,LOCKWRITE);
719 if (code) ABORT_WITH(tt,code);
720 code = read_DbHeader(tt);
721 if (code) ABORT_WITH(tt,code);
723 code = WhoIsThis(call,tt,&cid);
724 if (code) ABORT_WITH(tt,PRPERM);
725 code = IsAMemberOf (tt, cid, SYSADMINID);
726 if (!code && !pr_noAuth) ABORT_WITH(tt,PRPERM);
728 /* Read in entry to be deleted */
730 loc = FindByID (tt, aid);
732 loc = FindByName(tt, name, &tentry);
734 if (loc == 0) ABORT_WITH(tt,PRNOENT);
735 code = pr_ReadEntry (tt, 0, loc, &tentry);
736 if (code) ABORT_WITH(tt,PRDBFAIL);
738 if (uentry->Mask & PRUPDATE_NAMEHASH) {
740 code = RemoveFromNameHash(tt, tentry.name, &tloc);
741 if (code != PRSUCCESS) ABORT_WITH(tt,PRDBFAIL);
742 code = AddToNameHash(tt, tentry.name, loc);
743 if (code) ABORT_WITH(tt,code);
746 if (uentry->Mask & PRUPDATE_IDHASH) {
748 if (!id) id = tentry.id;
749 code = RemoveFromIDHash(tt, id, &tloc);
750 if (code != PRSUCCESS) ABORT_WITH(tt,PRDBFAIL);
751 code = AddToIDHash(tt, id, loc);
752 if (code) ABORT_WITH(tt,code);
755 code = ubik_EndTrans(tt);
756 if (code) return code;
760 afs_int32 PR_RemoveFromGroup (call,aid,gid)
761 struct rx_call *call;
767 code = removeFromGroup (call,aid,gid);
768 osi_auditU (call, PTS_RmFmGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid, AUD_END);
772 afs_int32 removeFromGroup (call,aid,gid)
773 struct rx_call *call;
777 register afs_int32 code;
778 struct ubik_trans *tt;
781 struct prentry uentry;
782 struct prentry gentry;
786 if (code != PRSUCCESS) return code;
787 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
788 if (code) return code;
789 code = ubik_SetLock(tt,1,1,LOCKWRITE);
790 if (code) ABORT_WITH(tt,code);
791 code = read_DbHeader(tt);
792 if (code) ABORT_WITH(tt,code);
794 code = WhoIsThis(call,tt,&cid);
795 if (code) ABORT_WITH(tt,PRPERM);
796 tempu = FindByID(tt,aid);
797 if (!tempu) ABORT_WITH(tt,PRNOENT);
798 tempg = FindByID(tt,gid);
799 if (!tempg) ABORT_WITH(tt,PRNOENT);
800 memset(&uentry, 0, sizeof(uentry));
801 memset(&gentry, 0, sizeof(gentry));
802 code = pr_ReadEntry(tt,0,tempu,&uentry);
803 if (code != 0) ABORT_WITH(tt,code);
804 code = pr_ReadEntry(tt,0,tempg,&gentry);
805 if (code != 0) ABORT_WITH(tt,code);
806 if (!(gentry.flags & PRGRP)) ABORT_WITH(tt,PRNOTGROUP);
807 if (uentry.flags & PRGRP) ABORT_WITH(tt,PRNOTUSER);
808 if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) ABORT_WITH(tt,PRPERM);
809 code = RemoveFromEntry(tt,aid,gid);
810 if (code != PRSUCCESS) ABORT_WITH(tt,code);
811 code = RemoveFromEntry(tt,gid,aid);
812 if (code != PRSUCCESS) ABORT_WITH(tt,code);
814 code = ubik_EndTrans(tt);
815 if (code) return code;
820 afs_int32 PR_GetCPS (call, aid, alist, over)
821 struct rx_call *call;
828 code = getCPS (call, aid, alist, over);
829 osi_auditU (call, PTS_GetCPSEvent, code, AUD_LONG, aid, AUD_END);
833 afs_int32 getCPS (call, aid, alist, over)
834 struct rx_call *call;
839 register afs_int32 code;
840 struct ubik_trans *tt;
843 struct prentry tentry;
846 alist->prlist_len = 0;
847 alist->prlist_val = (afs_int32 *) 0;
849 if (code != PRSUCCESS) return code;
850 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
851 if (code) return code;
852 code = ubik_SetLock(tt,1,1,LOCKREAD);
853 if (code) ABORT_WITH(tt,code);
854 code = read_DbHeader(tt);
855 if (code) ABORT_WITH(tt,code);
857 temp = FindByID (tt, aid);
858 if (!temp) ABORT_WITH(tt,PRNOENT);
859 code = pr_ReadEntry (tt, 0, temp, &tentry);
860 if (code) ABORT_WITH(tt,code);
862 /* afs does authenticate now */
863 code = WhoIsThis (call, tt, &cid);
864 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
865 ABORT_WITH(tt,PRPERM);
867 code = GetList(tt, &tentry, alist, 1);
868 if (code != PRSUCCESS) ABORT_WITH(tt,code);
870 code = ubik_EndTrans(tt);
882 for (i = (CPS.prlist_len-1) ; i >= 0; i--) {
883 if (CPS.prlist_val[i] == id)
888 #endif /* IP_WILDCARDS */
891 afs_int32 PR_GetCPS2 (call, aid, ahost, alist, over)
892 struct rx_call *call;
900 code = getCPS2 (call, aid, ahost, alist, over);
901 osi_auditU (call, PTS_GetCPS2Event, code, AUD_LONG, aid, AUD_HOST, ahost, AUD_END);
905 afs_int32 getCPS2 (call, aid, ahost, alist, over)
906 struct rx_call *call;
912 register afs_int32 code;
913 struct ubik_trans *tt;
916 struct prentry tentry;
917 struct prentry host_tentry;
920 struct in_addr iaddr;
922 extern afs_int32 addWildCards();
923 #endif /* IP_WILDCARDS */
926 iaddr.s_addr = ntohl(ahost);
927 alist->prlist_len = 0;
928 alist->prlist_val = (afs_int32 *) 0;
930 if (code != PRSUCCESS) return code;
931 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
932 if (code) return code;
933 code = ubik_SetLock(tt,1,1,LOCKREAD);
934 if (code) ABORT_WITH(tt,code);
935 code = read_DbHeader(tt);
936 if (code) ABORT_WITH(tt,code);
938 if (aid != PRBADID) {
939 temp = FindByID(tt,aid);
940 if (!temp) ABORT_WITH(tt,PRNOENT);
941 code = pr_ReadEntry (tt, 0, temp, &tentry);
942 if (code) ABORT_WITH(tt,code);
944 /* afs does authenticate now */
945 code = WhoIsThis (call, tt, &cid);
946 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
947 ABORT_WITH(tt,PRPERM);
949 code = NameToID(tt, inet_ntoa(iaddr),&hostid);
950 if (code == PRSUCCESS && hostid != 0) {
951 temp = FindByID(tt,hostid);
953 code = pr_ReadEntry (tt, 0, temp, &host_tentry);
954 if (code == PRSUCCESS)
957 fprintf(stderr,"pr_ReadEntry returned %d\n",code);
959 fprintf(stderr,"FindByID Failed -- Not found\n");
962 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
964 code = GetList(tt, &tentry, alist, 1);
967 code = addWildCards(tt,alist,ntohl(ahost));
968 #endif /* IP_WILDCARDS */
969 if (code != PRSUCCESS) ABORT_WITH(tt,code);
971 code = ubik_EndTrans(tt);
976 afs_int32 PR_GetHostCPS (call, ahost, alist, over)
977 struct rx_call *call;
984 code = getHostCPS (call, ahost, alist, over);
985 osi_auditU (call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
989 afs_int32 getHostCPS (call, ahost, alist, over)
990 struct rx_call *call;
995 register afs_int32 code, temp;
996 struct ubik_trans *tt;
997 struct prentry host_tentry;
999 struct in_addr iaddr;
1001 extern afs_int32 addWildCards();
1002 #endif /* IP_WILDCARDS */
1005 iaddr.s_addr = ntohl(ahost);
1006 alist->prlist_len = 0;
1007 alist->prlist_val = (afs_int32 *) 0;
1009 if (code != PRSUCCESS) return code;
1010 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1011 if (code) return code;
1012 code = ubik_SetLock(tt,1,1,LOCKREAD);
1013 if (code) ABORT_WITH(tt,code);
1014 code = read_DbHeader(tt);
1015 if (code) ABORT_WITH(tt,code);
1017 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1018 if (code == PRSUCCESS && hostid != 0) {
1019 temp = FindByID(tt,hostid);
1021 code = pr_ReadEntry (tt, 0, temp, &host_tentry);
1022 if (code == PRSUCCESS) {
1023 code = GetList(tt, &host_tentry, alist, 0);
1026 fprintf(stderr,"pr_ReadEntry returned %d\n",code);
1028 fprintf(stderr,"FindByID Failed -- Not found\n");
1031 code = addWildCards(tt,alist,ntohl(ahost));
1032 #endif /* IP_WILDCARDS */
1034 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1036 code = ubik_EndTrans(tt);
1041 afs_int32 PR_ListMax (call,uid,gid)
1042 struct rx_call *call;
1048 code = listMax(call,uid,gid);
1049 osi_auditU (call, PTS_LstMaxEvent, code, AUD_END);
1053 afs_int32 listMax (call,uid,gid)
1054 struct rx_call *call;
1058 register afs_int32 code;
1059 struct ubik_trans *tt;
1062 if (code != PRSUCCESS) return code;
1063 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1064 if (code) return code;
1065 code = ubik_SetLock(tt,1,1,LOCKREAD);
1066 if (code) ABORT_WITH(tt,code);
1067 code = read_DbHeader(tt);
1068 if (code) ABORT_WITH(tt,code);
1070 code = GetMax(tt,uid,gid);
1071 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1073 code = ubik_EndTrans(tt);
1074 if (code) return code;
1078 afs_int32 PR_SetMax (call,aid,gflag)
1079 struct rx_call *call;
1085 code = setMax (call,aid,gflag);
1086 osi_auditU (call, PTS_SetMaxEvent, code, AUD_LONG, aid, AUD_LONG, gflag, AUD_END);
1090 afs_int32 setMax (call,aid,gflag)
1091 struct rx_call *call;
1095 register afs_int32 code;
1096 struct ubik_trans *tt;
1100 if (code != PRSUCCESS) return code;
1101 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1102 if (code) return code;
1103 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1104 if (code) ABORT_WITH(tt,code);
1105 code = read_DbHeader(tt);
1106 if (code) ABORT_WITH(tt,code);
1108 code = WhoIsThis(call,tt,&cid);
1109 if (code) ABORT_WITH(tt,PRPERM);
1110 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1111 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0))) ABORT_WITH(tt,PRBADARG);
1113 code = SetMax(tt,aid,gflag);
1114 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1116 code = ubik_EndTrans(tt);
1117 if (code) return code;
1121 afs_int32 PR_ListEntry (call,aid,aentry)
1122 struct rx_call *call;
1124 struct prcheckentry *aentry;
1128 code = listEntry (call,aid,aentry);
1129 osi_auditU (call, PTS_LstEntEvent, code, AUD_LONG, aid, AUD_END);
1133 afs_int32 listEntry (call,aid,aentry)
1134 struct rx_call *call;
1136 struct prcheckentry *aentry;
1138 register afs_int32 code;
1139 struct ubik_trans *tt;
1142 struct prentry tentry;
1145 if (code != PRSUCCESS) return code;
1146 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1147 if (code) return code;
1148 code = ubik_SetLock(tt,1,1,LOCKREAD);
1149 if (code) ABORT_WITH(tt,code);
1150 code = read_DbHeader(tt);
1151 if (code) ABORT_WITH(tt,code);
1153 code = WhoIsThis(call,tt,&cid);
1154 if (code) ABORT_WITH(tt,PRPERM);
1155 temp = FindByID(tt,aid);
1156 if (!temp) ABORT_WITH(tt,PRNOENT);
1157 code = pr_ReadEntry(tt, 0, temp, &tentry);
1158 if (code != 0) ABORT_WITH(tt,code);
1159 if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1160 ABORT_WITH(tt,PRPERM);
1162 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1163 if (aentry->flags == 0) {
1164 if (tentry.flags & PRGRP)
1165 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
1166 else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
1168 aentry->owner = tentry.owner;
1169 aentry->id = tentry.id;
1170 strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
1171 aentry->creator = tentry.creator;
1172 aentry->ngroups = tentry.ngroups;
1173 aentry->nusers = tentry.nusers;
1174 aentry->count = tentry.count;
1175 memset(aentry->reserved, 0, sizeof(aentry->reserved));
1176 code = ubik_EndTrans(tt);
1177 if (code) return code;
1181 afs_int32 PR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1182 struct rx_call *call;
1184 afs_int32 startindex;
1185 prentries *bulkentries;
1186 afs_int32 *nextstartindex;
1190 code = listEntries(call, flag, startindex, bulkentries, nextstartindex);
1191 osi_auditU (call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1195 afs_int32 listEntries(call, flag, startindex, bulkentries, nextstartindex)
1196 struct rx_call *call;
1198 afs_int32 startindex;
1199 prentries *bulkentries;
1200 afs_int32 *nextstartindex;
1203 struct ubik_trans *tt;
1205 afs_int32 i, eof, pos, maxentries, f;
1206 struct prentry tentry;
1207 afs_int32 pollcount=0;
1209 *nextstartindex = -1;
1210 bulkentries->prentries_val = 0;
1211 bulkentries->prentries_len = 0;
1214 if (code != PRSUCCESS) return code;
1215 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1216 if (code) return code;
1217 code = ubik_SetLock(tt,1,1,LOCKREAD);
1218 if (code) ABORT_WITH(tt,code);
1219 code = read_DbHeader(tt);
1220 if (code) ABORT_WITH(tt,code);
1222 /* Make sure we are an authenticated caller and that we are on the
1225 code = WhoIsThis(call,tt,&cid);
1226 if (code) ABORT_WITH(tt,PRPERM);
1227 code = IsAMemberOf (tt, cid, SYSADMINID);
1228 if (!code && !pr_noAuth) ABORT_WITH(tt,PRPERM);
1230 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1231 maxentries = eof / sizeof(struct prentry);
1232 for (i=startindex; i<maxentries; i++) {
1233 pos = i * sizeof(struct prentry) + sizeof(cheader);
1234 code = pr_ReadEntry (tt, 0, pos, &tentry);
1235 if (code) goto done;
1237 if (++pollcount > 50) {
1242 f = (tentry.flags & PRTYPE);
1243 if ( ((flag & PRUSERS ) && (f == 0) ) || /* User entry */
1244 ((flag & PRGROUPS) && (f & PRGRP)) ) { /* Group entry */
1245 code = put_prentries(&tentry, bulkentries);
1246 if (code == -1) break; /* Filled return array */
1247 if (code) goto done;
1252 *nextstartindex = i;
1256 if (bulkentries->prentries_val)
1257 free(bulkentries->prentries_val);
1258 bulkentries->prentries_val = 0;
1259 bulkentries->prentries_len = 0;
1260 ABORT_WITH(tt, code);
1263 code = ubik_EndTrans(tt);
1265 if (code) return code;
1269 #define PR_MAXENTRIES 500
1270 afs_int32 put_prentries(tentry, bulkentries)
1271 struct prentry *tentry;
1272 prentries *bulkentries;
1274 struct prlistentries *entry;
1276 if (bulkentries->prentries_val == 0) {
1277 bulkentries->prentries_len = 0;
1278 bulkentries->prentries_val = (struct prlistentries *)malloc(PR_MAXENTRIES * sizeof(struct prentry));
1279 if (!bulkentries->prentries_val) {
1284 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1288 entry = (struct prlistentries *)bulkentries->prentries_val;
1289 entry += bulkentries->prentries_len;
1291 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1292 if (entry->flags == 0) {
1293 entry->flags = ( (tentry->flags & PRGRP)?PRP_GROUP_DEFAULT
1294 :PRP_USER_DEFAULT ) >> PRIVATE_SHIFT;
1296 entry->owner = tentry->owner;
1297 entry->id = tentry->id;
1298 entry->creator = tentry->creator;
1299 entry->ngroups = tentry->ngroups;
1300 entry->nusers = tentry->nusers;
1301 entry->count = tentry->count;
1302 strncpy(entry->name,tentry->name,PR_MAXNAMELEN);
1303 memset(entry->reserved, 0, sizeof(entry->reserved));
1304 bulkentries->prentries_len++;
1308 afs_int32 PR_ChangeEntry (call,aid,name,oid,newid)
1309 struct rx_call *call;
1317 code = changeEntry (call,aid,name,oid,newid);
1318 osi_auditU (call, PTS_ChgEntEvent, code, AUD_LONG, aid, AUD_STR, name,
1320 AUD_LONG, newid, AUD_END);
1324 afs_int32 changeEntry (call,aid,name,oid,newid)
1325 struct rx_call *call;
1331 register afs_int32 code;
1332 struct ubik_trans *tt;
1336 if (!name) return PRPERM;
1340 if (code) return code;
1341 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID ||
1342 aid == SYSADMINID) return PRPERM;
1343 if (code != PRSUCCESS) return code;
1344 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1345 if (code) return code;
1346 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1347 if (code) ABORT_WITH(tt,code);
1348 code = read_DbHeader(tt);
1349 if (code) ABORT_WITH(tt,code);
1351 code = WhoIsThis(call,tt,&cid);
1352 if (code) ABORT_WITH(tt,PRPERM);
1353 pos = FindByID(tt,aid);
1354 if (!pos) ABORT_WITH(tt,PRNOENT);
1355 /* protection check in changeentry */
1356 code = ChangeEntry(tt,aid,cid,name,oid,newid);
1357 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1359 code = ubik_EndTrans(tt);
1363 afs_int32 PR_SetFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2)
1364 struct rx_call *call;
1366 afs_int32 mask; /* specify which fields to update */
1367 afs_int32 flags, ngroups, nusers;
1368 afs_int32 spare1, spare2;
1372 code = setFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2);
1373 osi_auditU (call, PTS_SetFldEntEvent, code, AUD_LONG, id, AUD_END);
1377 afs_int32 setFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2)
1378 struct rx_call *call;
1380 afs_int32 mask; /* specify which fields to update */
1381 afs_int32 flags, ngroups, nusers;
1382 afs_int32 spare1, spare2;
1384 register afs_int32 code;
1385 struct ubik_trans *tt;
1388 struct prentry tentry;
1391 if (mask == 0) return 0; /* no-op */
1393 if (code) return code;
1394 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1396 if (code != PRSUCCESS) return code;
1397 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1398 if (code) return code;
1399 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1400 if (code) ABORT_WITH(tt,code);
1401 code = read_DbHeader(tt);
1402 if (code) ABORT_WITH(tt,code);
1404 code = WhoIsThis(call,tt,&cid);
1405 if (code) ABORT_WITH(tt,PRPERM);
1406 pos = FindByID(tt,id);
1407 if (!pos) ABORT_WITH(tt,PRNOENT);
1408 code = pr_ReadEntry (tt, 0, pos, &tentry);
1409 if (code) ABORT_WITH(tt,code);
1410 tflags = tentry.flags;
1412 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1413 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1414 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1415 tentry.ngroups = tentry.nusers = 20;
1418 if (!AccessOK (tt, cid, &tentry, 0, 0)) ABORT_WITH(tt,PRPERM);
1421 if (mask & 0xffff) { /* if setting flag bits */
1422 afs_int32 flagsMask = mask & 0xffff;
1423 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1424 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1428 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1429 if (ngroups < 0) ABORT_WITH(tt,PRBADARG);
1430 tentry.ngroups = ngroups;
1434 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1435 if (nusers < 0) ABORT_WITH(tt,PRBADARG);
1436 tentry.nusers = nusers;
1439 tentry.flags = tflags;
1441 code = pr_WriteEntry (tt, 0, pos, &tentry);
1442 if (code) ABORT_WITH(tt,code);
1444 code = ubik_EndTrans(tt);
1448 afs_int32 PR_ListElements (call, aid, alist, over)
1449 struct rx_call *call;
1456 code = listElements (call, aid, alist, over);
1457 osi_auditU (call, PTS_LstEleEvent, code, AUD_LONG, aid, AUD_END);
1461 afs_int32 listElements (call, aid, alist, over)
1462 struct rx_call *call;
1467 register afs_int32 code;
1468 struct ubik_trans *tt;
1471 struct prentry tentry;
1474 alist->prlist_len = 0;
1475 alist->prlist_val = (afs_int32 *) 0;
1478 if (code != PRSUCCESS) return code;
1479 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1480 if (code) return code;
1481 code = ubik_SetLock(tt,1,1,LOCKREAD);
1482 if (code) ABORT_WITH(tt,code);
1483 code = read_DbHeader(tt);
1484 if (code) ABORT_WITH(tt,code);
1486 code = WhoIsThis(call,tt,&cid);
1487 if (code) ABORT_WITH(tt,PRPERM);
1489 temp = FindByID(tt,aid);
1490 if (!temp) ABORT_WITH(tt,PRNOENT);
1491 code = pr_ReadEntry (tt, 0, temp, &tentry);
1492 if (code) ABORT_WITH(tt,code);
1493 if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1494 ABORT_WITH(tt,PRPERM);
1496 code = GetList (tt, &tentry, alist, 0);
1497 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1499 code = ubik_EndTrans(tt);
1505 * List the entries owned by this id. If the id is zero,
1506 * return the orphans list. This will return up to PR_MAXGROUPS
1507 * at a time with the lastP available to get the rest. The
1508 * maximum value is enforced in GetOwnedChain().
1510 afs_int32 PR_ListOwned (call, aid, alist, lastP)
1511 struct rx_call *call;
1518 code = listOwned (call, aid, alist, lastP);
1519 osi_auditU (call, PTS_LstOwnEvent, code, AUD_LONG, aid, AUD_END);
1523 afs_int32 listOwned (call, aid, alist, lastP)
1524 struct rx_call *call;
1529 register afs_int32 code;
1530 struct ubik_trans *tt;
1532 struct prentry tentry;
1536 alist->prlist_len = 0;
1537 alist->prlist_val = (afs_int32 *) 0;
1539 if (!lastP) return PRBADARG;
1544 if (code != PRSUCCESS) return code;
1545 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1546 if (code) return code;
1547 code = ubik_SetLock(tt,1,1,LOCKREAD);
1548 if (code) ABORT_WITH(tt,code);
1549 code = read_DbHeader(tt);
1550 if (code) ABORT_WITH(tt,code);
1552 code = WhoIsThis(call,tt,&cid);
1553 if (code) ABORT_WITH(tt,PRPERM);
1556 code = pr_ReadEntry (tt, 0, start, &tentry);
1557 if (!code && (tentry.owner == aid))
1558 head = start; /* pick up where we left off */
1563 afs_int32 loc = FindByID (tt, aid);
1564 if (loc == 0) ABORT_WITH(tt,PRNOENT);
1565 code = pr_ReadEntry (tt, 0, loc, &tentry);
1566 if (code) ABORT_WITH(tt,code);
1568 if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY))
1569 ABORT_WITH(tt,PRPERM);
1570 head = tentry.owned;
1572 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1573 head = ntohl(cheader.orphan);
1577 code = GetOwnedChain (tt, &head, alist);
1579 if (code == PRTOOMANY) *lastP = head;
1580 else ABORT_WITH(tt,code);
1583 code = ubik_EndTrans(tt);
1587 afs_int32 PR_IsAMemberOf (call,uid,gid,flag)
1588 struct rx_call *call;
1595 code = isAMemberOf (call,uid,gid,flag);
1596 osi_auditU (call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid, AUD_END);
1600 afs_int32 isAMemberOf (call,uid,gid,flag)
1601 struct rx_call *call;
1606 register afs_int32 code;
1607 struct ubik_trans *tt;
1610 if (code != PRSUCCESS) return code;
1611 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1612 if (code) return code;
1613 code = ubik_SetLock(tt,1,1,LOCKREAD);
1614 if (code) ABORT_WITH(tt,code);
1615 code = read_DbHeader(tt);
1616 if (code) ABORT_WITH(tt,code);
1619 afs_int32 uloc = FindByID (tt, uid);
1620 afs_int32 gloc = FindByID (tt, gid);
1621 struct prentry uentry, gentry;
1623 if (!uloc || !gloc) ABORT_WITH(tt,PRNOENT);
1624 code = WhoIsThis(call, tt, &cid);
1625 if (code) ABORT_WITH(tt,PRPERM);
1626 code = pr_ReadEntry (tt, 0, uloc, &uentry);
1627 if (code) ABORT_WITH(tt,code);
1628 code = pr_ReadEntry (tt, 0, gloc, &gentry);
1629 if (code) ABORT_WITH(tt,code);
1630 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) ABORT_WITH(tt,PRBADARG);
1631 if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1632 !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1633 ABORT_WITH(tt,PRPERM);
1636 *flag = IsAMemberOf(tt,uid,gid);
1637 code = ubik_EndTrans(tt);
1647 if (isupper(tc)) *s = tolower(tc);
1653 afs_int32 addWildCards(tt,alist,host)
1654 struct ubik_trans *tt;
1659 struct prentry tentry;
1661 unsigned wild = htonl(0xffffff00);
1662 struct in_addr iaddr;
1664 int size = 0, i, code;
1667 while ((host = (host & wild))) {
1668 wild = htonl ( ntohl(wild) << 8) ;
1669 iaddr.s_addr = host;
1670 code = NameToID(tt, inet_ntoa(iaddr),&hostid);
1671 if (code == PRSUCCESS && hostid != 0) {
1672 temp = FindByID(tt,hostid);
1674 code = pr_ReadEntry (tt, 0, temp, &tentry);
1675 if (code != PRSUCCESS)
1681 wlist.prlist_len = 0;
1682 wlist.prlist_val = (afs_int32 *) 0;
1684 code = GetList (tt, &tentry, &wlist, 0);
1685 if (code) return code;
1686 added += wlist.prlist_len;
1687 for (i=0; i< wlist.prlist_len; i++) {
1688 if (!inCPS(*alist,wlist.prlist_val[i]))
1689 if ((code = AddToPRList (alist, &size, wlist.prlist_val[i] ))) {
1690 free(wlist.prlist_val);
1694 if (wlist.prlist_val) free(wlist.prlist_val);
1697 qsort(alist->prlist_val,alist->prlist_len,sizeof(afs_int32),IDCmp);
1700 #endif /* IP_WILDCARDS */
1703 afs_int32 WhoIsThisWithName(acall, at, aid, aname)
1704 struct rx_call *acall;
1705 struct ubik_trans *at;
1709 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
1710 /* returns -1 and sets aid to ANONYMOUSID on any failure */
1711 register struct rx_connection *tconn;
1712 register afs_int32 code;
1713 char tcell[MAXKTCREALMLEN];
1714 char name[MAXKTCNAMELEN];
1715 char inst[MAXKTCNAMELEN];
1720 tconn = rx_ConnectionOf(acall);
1721 code = rx_SecurityClassOf(tconn);
1722 if (code == 0) return 0;
1723 else if (code == 1) { /* vab class */
1724 goto done; /* no longer supported */
1726 else if (code == 2) { /* kad class */
1729 extern char *pr_realmName;
1731 if ((code = rxkad_GetServerInfo
1732 (acall->conn, (afs_int32 *) 0, 0/*was &exp*/,
1733 name, inst, tcell, (afs_int32 *) 0)))
1735 strncpy (vname, name, sizeof(vname));
1736 if ((ilen = strlen(inst))) {
1737 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
1738 strcat (vname, ".");
1739 strcat (vname, inst);
1741 if ( (clen = strlen(tcell))) {
1743 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
1744 static char local_realm[AFS_REALM_SZ] = "";
1745 if (!local_realm[0]) {
1746 if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
1747 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
1751 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
1752 strcasecmp (local_realm, tcell) &&
1754 strcasecmp (pr_realmName, tcell))
1756 if (strlen(vname) + 1 + clen >= sizeof(vname)) goto done;
1758 strcat(vname,tcell);
1759 lcstring(vname, vname, sizeof(vname));
1760 code = NameToID(at,vname,aid);
1761 strcpy(aname,vname);
1766 if (strcmp (AUTH_SUPERUSER, vname) == 0)
1767 *aid = SYSADMINID; /* special case for the fileserver */
1769 lcstring(vname, vname, sizeof(vname));
1770 code = NameToID(at,vname,aid);
1774 if (code && !pr_noAuth) return -1;