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 <afs/param.h>
15 #include <afs/afsutil.h>
25 #include <netinet/in.h>
29 #include "afs/audit.h"
31 #ifdef AFS_ATHENA_STDENV
36 #define IP_WILDCARDS 1 /* XXX Should be defined outside of here XXX */
38 extern struct ubik_dbase *dbase;
39 extern afs_int32 Initdb();
41 extern afs_int32 initd;
42 afs_int32 iNewEntry(), newEntry(), whereIsIt(), dumpEntry(), addToGroup(), nameToID(), Delete(), removeFromGroup();
43 afs_int32 getCPS(), getCPS2(), getHostCPS(), listMax(), setMax(), listEntry();
44 afs_int32 listEntries(), changeEntry(), setFieldsEntry(), put_prentries();
45 afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
49 /* When abort, reset initd so that the header is read in on next call.
50 * Abort the transarction and return the code.
52 #define ABORT_WITH(tt,code) return(initd=0,ubik_AbortTrans(tt),code)
54 static int CreateOK (ut, cid, oid, flag, admin)
55 struct ubik_trans *ut;
56 afs_int32 cid; /* id of caller */
57 afs_int32 oid; /* id of owner */
58 afs_int32 flag; /* indicates type of entry */
59 int admin; /* sysadmin membership */
61 if (flag & PRFOREIGN) {
62 /* Foreign users are recognized by the '@' sign and
63 * not by the PRFOREIGN flag.
67 else if (flag & PRGRP) {
68 /* Allow anonymous group creation only if owner specified
71 if (cid == ANONYMOUSID) {
72 if ((oid == 0) || !pr_noAuth) return 0;
75 else { /* creating a user */
76 if (!admin && !pr_noAuth) return 0;
81 afs_int32 WhoIsThis (acall, at, aid)
82 struct rx_call *acall;
83 struct ubik_trans *at;
87 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
88 /* returns -1 and sets aid to ANONYMOUSID on any failure */
89 register struct rx_connection *tconn;
90 register afs_int32 code;
91 char tcell[MAXKTCREALMLEN];
92 char name[MAXKTCNAMELEN];
93 char inst[MAXKTCNAMELEN];
98 tconn = rx_ConnectionOf(acall);
99 code = rx_SecurityClassOf(tconn);
100 if (code == 0) return 0;
101 else if (code == 1) { /* vab class */
102 goto done; /* no longer supported */
104 else if (code == 2) { /* kad class */
105 if (code = rxkad_GetServerInfo
106 (acall->conn, (afs_int32 *) 0, 0/*was &exp*/,
107 name, inst, tcell, (afs_int32 *) 0))
110 /* This test is unnecessary, since rxkad_GetServerInfo already check.
111 * In addition, this is wrong since exp must be unsigned. */
112 if (exp < FT_ApproxTime()) goto done;
114 if (strlen (tcell)) {
115 extern char *pr_realmName;
116 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
117 static char local_realm[AFS_REALM_SZ] = "";
118 if (!local_realm[0]) {
119 if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
120 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
124 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
125 strcasecmp (local_realm, tcell) &&
127 strcasecmp (pr_realmName, tcell))
130 strncpy (vname, name, sizeof(vname));
131 if (ilen = strlen (inst)) {
132 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
134 strcat (vname, inst);
137 if (strlen(vname) + strlen(tcell) + 1 >= sizeof(vname)) goto done;
139 strcat (vname, tcell);
141 if (strcmp (AUTH_SUPERUSER, vname) == 0)
142 *aid = SYSADMINID; /* special case for the fileserver */
144 lcstring(vname, vname, sizeof(vname));
145 code = NameToID(at,vname,aid);
149 if (code && !pr_noAuth) return -1;
153 afs_int32 PR_INewEntry (call,aname,aid,oid)
154 struct rx_call *call;
155 char aname[PR_MAXNAMELEN];
161 code = iNewEntry (call,aname,aid,oid);
162 osi_auditU (call, PTS_INewEntEvent, code, AUD_LONG, aid, AUD_STR, aname, AUD_LONG, oid, AUD_END);
166 afs_int32 iNewEntry (call,aname,aid,oid)
167 struct rx_call *call;
168 char aname[PR_MAXNAMELEN];
172 /* used primarily for conversion - not intended to be used as usual means
173 of entering people into the database. */
174 struct ubik_trans *tt;
175 register afs_int32 code;
182 if (code != PRSUCCESS) return code;
183 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
184 if (code) return code;
185 code = ubik_SetLock(tt, 1,1,LOCKWRITE);
186 if (code) ABORT_WITH(tt,code);
187 code = read_DbHeader(tt);
188 if (code) ABORT_WITH(tt,code);
190 code = WhoIsThis(call,tt,&cid);
191 if (code) ABORT_WITH(tt,PRPERM);
192 admin = IsAMemberOf(tt,cid,SYSADMINID);
194 /* first verify the id is good */
195 if (aid == 0) ABORT_WITH(tt,PRPERM);
198 /* only sysadmin can reuse a group id */
199 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup)-1))
200 ABORT_WITH(tt,PRPERM);
202 if (FindByID (tt, aid)) ABORT_WITH(tt,PRIDEXIST);
204 /* check a few other things */
205 if (!CreateOK (tt, cid, oid, gflag, admin)) ABORT_WITH(tt,PRPERM);
207 code = CreateEntry (tt,aname,&aid,1,gflag,oid,cid);
208 if (code != PRSUCCESS) ABORT_WITH(tt,code);
210 /* finally, commit transaction */
211 code = ubik_EndTrans(tt);
212 if (code) return code;
217 afs_int32 PR_NewEntry (call, aname, flag, oid, aid)
218 struct rx_call *call;
219 char aname[PR_MAXNAMELEN];
226 code = newEntry (call, aname, flag, oid, aid);
227 osi_auditU (call, PTS_NewEntEvent, code, AUD_LONG, *aid, AUD_STR, aname, AUD_LONG, oid, AUD_END);
231 afs_int32 newEntry (call, aname, flag, oid, aid)
232 struct rx_call *call;
233 char aname[PR_MAXNAMELEN];
238 register afs_int32 code;
239 struct ubik_trans *tt;
242 extern afs_int32 WhoIsThisWithName();
243 char cname[PR_MAXNAMELEN];
246 if (code) return code;
247 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
248 if (code) return code;
249 code = ubik_SetLock(tt,1,1,LOCKWRITE);
250 if (code) ABORT_WITH(tt,code);
251 code = read_DbHeader(tt);
252 if (code) ABORT_WITH(tt,code);
254 /* this is for cross-cell self registration. It is not added in the
255 * PR_INewEntry because we want self-registration to only do
256 * automatic id assignment.
258 code = WhoIsThisWithName(call,tt,&cid,cname);
259 if (code != 2) {/* 2 specifies that this is a foreign cell request */
260 if (code) ABORT_WITH(tt,PRPERM);
261 admin = IsAMemberOf(tt,cid,SYSADMINID);
263 admin = (!strcmp(aname,cname)) || IsAMemberOf(tt,cid,SYSADMINID);
264 oid = cid = SYSADMINID;
266 if (!CreateOK (tt, cid, oid, flag, admin)) ABORT_WITH(tt,PRPERM);
268 code = CreateEntry (tt,aname,aid,0,flag,oid,cid);
269 if (code != PRSUCCESS) ABORT_WITH(tt,code);
271 code = ubik_EndTrans(tt);
272 if (code) return code;
278 afs_int32 PR_WhereIsIt (call,aid,apos)
279 struct rx_call *call;
285 code = whereIsIt(call,aid,apos);
286 osi_auditU (call, PTS_WheIsItEvent, code, AUD_LONG, aid, AUD_LONG, *apos, AUD_END);
290 afs_int32 whereIsIt (call,aid,apos)
291 struct rx_call *call;
295 register afs_int32 code;
296 struct ubik_trans *tt;
300 if (code != PRSUCCESS) return code;
301 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
302 if (code) return code;
303 code = ubik_SetLock(tt,1,1,LOCKREAD);
304 if (code) ABORT_WITH(tt,code);
305 code = read_DbHeader(tt);
306 if (code) ABORT_WITH(tt,code);
308 temp = FindByID(tt,aid);
309 if (!temp) ABORT_WITH(tt,PRNOENT);
311 code = ubik_EndTrans(tt);
312 if (code) return code;
317 afs_int32 PR_DumpEntry (call,apos, aentry)
318 struct rx_call *call;
320 struct prdebugentry *aentry;
324 code = dumpEntry(call,apos, aentry);
325 osi_auditU (call, PTS_DmpEntEvent, code, AUD_LONG, apos, AUD_END);
329 afs_int32 dumpEntry (call,apos, aentry)
330 struct rx_call *call;
332 struct prdebugentry *aentry;
334 register afs_int32 code;
336 struct ubik_trans *tt;
339 if (code != PRSUCCESS) return code;
340 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
341 if (code) return code;
342 code = ubik_SetLock(tt,1,1,LOCKREAD);
343 if (code) ABORT_WITH(tt,code);
344 code = read_DbHeader(tt);
345 if (code) ABORT_WITH(tt,code);
347 code = WhoIsThis(call,tt,&cid);
348 if (code) ABORT_WITH(tt,PRPERM);
349 code = pr_ReadEntry(tt, 0, apos, aentry);
350 if (code) ABORT_WITH(tt,code);
352 if (!AccessOK (tt, cid, aentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
353 ABORT_WITH(tt,PRPERM);
355 /* Since prdebugentry is in the form of a prentry not a coentry, we will
356 * return the coentry slots in network order where the string is. */
358 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
359 code = pr_ReadCoEntry(tt, 0, apos, aentry);
360 if (code) ABORT_WITH(tt,code);
363 code = ubik_EndTrans(tt);
364 if (code) return code;
368 afs_int32 PR_AddToGroup (call,aid,gid)
369 struct rx_call *call;
375 code = addToGroup (call,aid,gid);
376 osi_auditU (call, PTS_AdToGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid, AUD_END);
380 afs_int32 addToGroup (call,aid,gid)
381 struct rx_call *call;
385 register afs_int32 code;
386 struct ubik_trans *tt;
389 struct prentry tentry;
390 struct prentry uentry;
394 if (code != PRSUCCESS) return code;
395 if (gid == ANYUSERID || gid == AUTHUSERID) return PRPERM;
396 if (aid == ANONYMOUSID) return PRPERM;
397 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
398 if (code) return code;
399 code = ubik_SetLock(tt,1,1,LOCKWRITE);
400 if (code) ABORT_WITH(tt,code);
401 code = read_DbHeader(tt);
402 if (code) ABORT_WITH(tt,code);
404 code = WhoIsThis(call, tt, &cid);
405 if (code) ABORT_WITH(tt,PRPERM);
406 tempu = FindByID(tt,aid);
407 if (!tempu) ABORT_WITH(tt,PRNOENT);
408 bzero(&uentry,sizeof(uentry));
409 code = pr_ReadEntry(tt,0,tempu,&uentry);
410 if (code != 0) ABORT_WITH(tt,code);
411 /* we don't allow groups as members of groups at present */
412 if (uentry.flags & PRGRP) ABORT_WITH(tt,PRNOTUSER);
413 tempg = FindByID(tt,gid);
414 if (!tempg) ABORT_WITH(tt,PRNOENT);
415 code = pr_ReadEntry(tt,0,tempg,&tentry);
416 if (code != 0) ABORT_WITH(tt,code);
417 /* make sure that this is a group */
418 if (!(tentry.flags & PRGRP)) ABORT_WITH(tt,PRNOTGROUP);
419 if (!AccessOK (tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY)) ABORT_WITH(tt,PRPERM);
421 code = AddToEntry (tt, &tentry, tempg, aid);
422 if (code != PRSUCCESS) ABORT_WITH(tt,code);
423 /* now, modify the user's entry as well */
424 code = AddToEntry (tt, &uentry, tempu, gid);
425 if (code != PRSUCCESS) ABORT_WITH(tt,code);
426 code = ubik_EndTrans(tt);
427 if (code) return code;
431 afs_int32 PR_NameToID (call, aname, aid)
432 struct rx_call *call;
438 code = nameToID (call, aname, aid);
439 osi_auditU (call, PTS_NmToIdEvent, code, AUD_END);
443 afs_int32 nameToID (call, aname, aid)
444 struct rx_call *call;
448 register afs_int32 code;
449 struct ubik_trans *tt;
454 /* Initialize return struct */
456 aid->idlist_val = (afs_int32 *)0;
458 size = aname->namelist_len;
459 if (size == 0) return 0;
460 if (size < 0) return PRTOOMANY;
462 aid->idlist_val = (afs_int32 *)malloc(size*sizeof(afs_int32));
463 if (!aid->idlist_val) return PRNOMEM;
466 if (code != PRSUCCESS) return code;
467 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
468 if (code) return code;
469 code = ubik_SetLock(tt,1,1,LOCKREAD);
470 if (code) ABORT_WITH(tt,code);
471 code = read_DbHeader(tt);
472 if (code) ABORT_WITH(tt,code);
474 for (i=0;i<aname->namelist_len;i++) {
475 code = NameToID(tt,aname->namelist_val[i],&aid->idlist_val[i]);
476 if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID;
477 if (count++ > 50) IOMGR_Poll(), count = 0;
479 aid->idlist_len = aname->namelist_len;
481 code = ubik_EndTrans(tt);
482 if (code) return code;
488 * Given an array of ids, find the name for each of them.
489 * The array of ids and names is unlimited.
491 afs_int32 PR_IDToName (call, aid, aname)
492 struct rx_call *call;
498 code = idToName (call, aid, aname);
499 osi_auditU (call, PTS_IdToNmEvent, code, AUD_LONG, aid, AUD_END);
503 afs_int32 idToName (call, aid, aname)
504 struct rx_call *call;
508 register afs_int32 code;
509 struct ubik_trans *tt;
514 /* leave this first for rpc stub */
515 size = aid->idlist_len;
516 if (size <= 0) size = 0;
517 aname->namelist_val = (prname *)malloc(size*PR_MAXNAMELEN);
518 aname->namelist_len = 0;
519 if (aid->idlist_len == 0) return 0;
520 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
523 if (code != PRSUCCESS) return code;
524 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
525 if (code) return code;
526 code = ubik_SetLock(tt,1,1,LOCKREAD);
527 if (code) ABORT_WITH(tt,code);
528 code = read_DbHeader(tt);
529 if (code) ABORT_WITH(tt,code);
531 for (i=0;i<aid->idlist_len;i++) {
532 code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
533 if (code != PRSUCCESS)
534 sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
535 if (count++ > 50) IOMGR_Poll(), count = 0;
537 aname->namelist_len = aid->idlist_len;
539 code = ubik_EndTrans(tt);
540 if (code) return code;
544 afs_int32 PR_Delete (call, aid)
545 struct rx_call *call;
550 code = Delete (call, aid);
551 osi_auditU (call, PTS_DelEvent, code, AUD_LONG, aid, AUD_END);
555 afs_int32 Delete (call, aid)
556 struct rx_call *call;
559 register afs_int32 code;
560 struct ubik_trans *tt;
562 struct prentry tentry;
567 if (code) return code;
568 if (code != PRSUCCESS) return code;
569 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
570 aid == ANONYMOUSID) return PRPERM;
571 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
572 if (code) return code;
573 code = ubik_SetLock(tt,1,1,LOCKWRITE);
574 if (code) ABORT_WITH(tt,code);
575 code = read_DbHeader(tt);
576 if (code) ABORT_WITH(tt,code);
578 code = WhoIsThis(call,tt,&cid);
579 if (code) ABORT_WITH(tt,PRPERM);
581 /* Read in entry to be deleted */
582 loc = FindByID (tt, aid);
583 if (loc == 0) ABORT_WITH(tt,PRNOENT);
584 code = pr_ReadEntry (tt, 0, loc, &tentry);
585 if (code) ABORT_WITH(tt,PRDBFAIL);
587 /* Do some access checking */
588 if (tentry.owner != cid &&
589 !IsAMemberOf (tt, cid, SYSADMINID) &&
590 !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
591 ABORT_WITH(tt,PRPERM);
593 /* Delete each continuation block as a separate transaction so that no one
594 * transaction become to large to complete. */
596 while (nptr != NULL) {
597 struct contentry centry;
600 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
601 if (code != 0) ABORT_WITH(tt,PRDBFAIL);
602 for (i=0;i<COSIZE;i++) {
603 if (centry.entries[i] == PRBADID) continue;
604 if (centry.entries[i] == 0) break;
605 code = RemoveFromEntry (tt, aid, centry.entries[i]);
606 if (code) ABORT_WITH(tt,code);
607 tentry.count--; /* maintain count */
608 if ((i&3) == 0) IOMGR_Poll();
610 tentry.next = centry.next; /* thread out this block */
611 code = FreeBlock (tt, nptr); /* free continuation block */
612 if (code) ABORT_WITH(tt,code);
613 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
614 if (code) ABORT_WITH(tt,code);
616 /* end this trans and start a new one */
617 code = ubik_EndTrans(tt);
618 if (code) return code;
619 IOMGR_Poll(); /* just to keep the connection alive */
620 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
621 if (code) return code;
622 code = ubik_SetLock(tt,1,1,LOCKWRITE);
623 if (code) ABORT_WITH(tt,code);
625 /* re-read entry to get consistent uptodate info */
626 loc = FindByID (tt, aid);
627 if (loc == 0) ABORT_WITH(tt,PRNOENT);
628 code = pr_ReadEntry (tt, 0, loc, &tentry);
629 if (code) ABORT_WITH(tt,PRDBFAIL);
634 /* Then move the owned chain, except possibly ourself to the orphan list.
635 * Because this list can be very long and so exceed the size of a ubik
636 * transaction, we start a new transaction every 50 entries. */
639 while (nptr != NULL) {
640 struct prentry nentry;
642 code = pr_ReadEntry (tt, 0, nptr, &nentry);
643 if (code) ABORT_WITH(tt,PRDBFAIL);
644 nptr = tentry.owned = nentry.nextOwned; /* thread out */
646 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
647 code = AddToOrphan (tt, nentry.id);
648 if (code) ABORT_WITH(tt,code);
650 if ((count & 3) == 0) IOMGR_Poll();
652 if (count < 50) continue;
653 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
654 if (code) ABORT_WITH(tt,code);
656 /* end this trans and start a new one */
657 code = ubik_EndTrans(tt);
658 if (code) return code;
659 IOMGR_Poll(); /* just to keep the connection alive */
660 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
661 if (code) return code;
662 code = ubik_SetLock(tt,1,1,LOCKWRITE);
663 if (code) ABORT_WITH(tt,code);
665 /* re-read entry to get consistent uptodate info */
666 loc = FindByID (tt, aid);
667 if (loc == 0) ABORT_WITH(tt,PRNOENT);
668 code = pr_ReadEntry (tt, 0, loc, &tentry);
669 if (code) ABORT_WITH(tt,PRDBFAIL);
674 /* now do what's left of the deletion stuff */
675 code = DeleteEntry (tt, &tentry, loc);
676 if (code != PRSUCCESS) ABORT_WITH(tt,code);
678 code = ubik_EndTrans(tt);
679 if (code) return code;
683 afs_int32 PR_UpdateEntry (call, aid, name, uentry)
684 struct rx_call *call;
687 struct PrUpdateEntry *uentry;
689 register afs_int32 code;
690 struct ubik_trans *tt;
692 struct prentry tentry;
697 if (code) return code;
698 if (code != PRSUCCESS) return code;
701 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
702 aid == ANONYMOUSID) return PRPERM;
704 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
705 if (code) return code;
706 code = ubik_SetLock(tt,1,1,LOCKWRITE);
707 if (code) ABORT_WITH(tt,code);
708 code = read_DbHeader(tt);
709 if (code) ABORT_WITH(tt,code);
711 code = WhoIsThis(call,tt,&cid);
712 if (code) ABORT_WITH(tt,PRPERM);
713 code = IsAMemberOf (tt, cid, SYSADMINID);
714 if (!code && !pr_noAuth) ABORT_WITH(tt,PRPERM);
716 /* Read in entry to be deleted */
718 loc = FindByID (tt, aid);
720 loc = FindByName(tt, name, &tentry);
722 if (loc == 0) ABORT_WITH(tt,PRNOENT);
723 code = pr_ReadEntry (tt, 0, loc, &tentry);
724 if (code) ABORT_WITH(tt,PRDBFAIL);
726 if (uentry->Mask & PRUPDATE_NAMEHASH) {
728 code = RemoveFromNameHash(tt, tentry.name, &tloc);
729 if (code != PRSUCCESS) ABORT_WITH(tt,PRDBFAIL);
730 code = AddToNameHash(tt, tentry.name, loc);
731 if (code) ABORT_WITH(tt,code);
734 if (uentry->Mask & PRUPDATE_IDHASH) {
736 if (!id) id = tentry.id;
737 code = RemoveFromIDHash(tt, id, &tloc);
738 if (code != PRSUCCESS) ABORT_WITH(tt,PRDBFAIL);
739 code = AddToIDHash(tt, id, loc);
740 if (code) ABORT_WITH(tt,code);
743 code = ubik_EndTrans(tt);
744 if (code) return code;
748 afs_int32 PR_RemoveFromGroup (call,aid,gid)
749 struct rx_call *call;
755 code = removeFromGroup (call,aid,gid);
756 osi_auditU (call, PTS_RmFmGrpEvent, code, AUD_LONG, gid, AUD_LONG, aid, AUD_END);
760 afs_int32 removeFromGroup (call,aid,gid)
761 struct rx_call *call;
765 register afs_int32 code;
766 struct ubik_trans *tt;
769 struct prentry uentry;
770 struct prentry gentry;
774 if (code != PRSUCCESS) return code;
775 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
776 if (code) return code;
777 code = ubik_SetLock(tt,1,1,LOCKWRITE);
778 if (code) ABORT_WITH(tt,code);
779 code = read_DbHeader(tt);
780 if (code) ABORT_WITH(tt,code);
782 code = WhoIsThis(call,tt,&cid);
783 if (code) ABORT_WITH(tt,PRPERM);
784 tempu = FindByID(tt,aid);
785 if (!tempu) ABORT_WITH(tt,PRNOENT);
786 tempg = FindByID(tt,gid);
787 if (!tempg) ABORT_WITH(tt,PRNOENT);
788 bzero(&uentry,sizeof(uentry));
789 bzero(&gentry,sizeof(gentry));
790 code = pr_ReadEntry(tt,0,tempu,&uentry);
791 if (code != 0) ABORT_WITH(tt,code);
792 code = pr_ReadEntry(tt,0,tempg,&gentry);
793 if (code != 0) ABORT_WITH(tt,code);
794 if (!(gentry.flags & PRGRP)) ABORT_WITH(tt,PRNOTGROUP);
795 if (uentry.flags & PRGRP) ABORT_WITH(tt,PRNOTUSER);
796 if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) ABORT_WITH(tt,PRPERM);
797 code = RemoveFromEntry(tt,aid,gid);
798 if (code != PRSUCCESS) ABORT_WITH(tt,code);
799 code = RemoveFromEntry(tt,gid,aid);
800 if (code != PRSUCCESS) ABORT_WITH(tt,code);
802 code = ubik_EndTrans(tt);
803 if (code) return code;
808 afs_int32 PR_GetCPS (call, aid, alist, over)
809 struct rx_call *call;
816 code = getCPS (call, aid, alist, over);
817 osi_auditU (call, PTS_GetCPSEvent, code, AUD_LONG, aid, AUD_END);
821 afs_int32 getCPS (call, aid, alist, over)
822 struct rx_call *call;
827 register afs_int32 code;
828 struct ubik_trans *tt;
831 struct prentry tentry;
834 alist->prlist_len = 0;
835 alist->prlist_val = (afs_int32 *) 0;
837 if (code != PRSUCCESS) return code;
838 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
839 if (code) return code;
840 code = ubik_SetLock(tt,1,1,LOCKREAD);
841 if (code) ABORT_WITH(tt,code);
842 code = read_DbHeader(tt);
843 if (code) ABORT_WITH(tt,code);
845 temp = FindByID (tt, aid);
846 if (!temp) ABORT_WITH(tt,PRNOENT);
847 code = pr_ReadEntry (tt, 0, temp, &tentry);
848 if (code) ABORT_WITH(tt,code);
850 /* afs does authenticate now */
851 code = WhoIsThis (call, tt, &cid);
852 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
853 ABORT_WITH(tt,PRPERM);
855 code = GetList(tt, &tentry, alist, 1);
856 if (code != PRSUCCESS) ABORT_WITH(tt,code);
858 code = ubik_EndTrans(tt);
870 for (i = (CPS.prlist_len-1) ; i >= 0; i--) {
871 if (CPS.prlist_val[i] == id)
876 #endif /* IP_WILDCARDS */
879 afs_int32 PR_GetCPS2 (call, aid, ahost, alist, over)
880 struct rx_call *call;
888 code = getCPS2 (call, aid, ahost, alist, over);
889 osi_auditU (call, PTS_GetCPS2Event, code, AUD_LONG, aid, AUD_HOST, ahost, AUD_END);
893 afs_int32 getCPS2 (call, aid, ahost, alist, over)
894 struct rx_call *call;
900 register afs_int32 code;
901 struct ubik_trans *tt;
904 struct prentry tentry;
905 struct prentry host_tentry;
908 struct in_addr iaddr;
910 extern afs_int32 addWildCards();
911 #endif /* IP_WILDCARDS */
914 iaddr.s_addr = ntohl(ahost);
915 alist->prlist_len = 0;
916 alist->prlist_val = (afs_int32 *) 0;
918 if (code != PRSUCCESS) return code;
919 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
920 if (code) return code;
921 code = ubik_SetLock(tt,1,1,LOCKREAD);
922 if (code) ABORT_WITH(tt,code);
923 code = read_DbHeader(tt);
924 if (code) ABORT_WITH(tt,code);
926 if (aid != PRBADID) {
927 temp = FindByID(tt,aid);
928 if (!temp) ABORT_WITH(tt,PRNOENT);
929 code = pr_ReadEntry (tt, 0, temp, &tentry);
930 if (code) ABORT_WITH(tt,code);
932 /* afs does authenticate now */
933 code = WhoIsThis (call, tt, &cid);
934 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
935 ABORT_WITH(tt,PRPERM);
937 code = NameToID(tt, inet_ntoa(iaddr),&hostid);
938 if (code == PRSUCCESS && hostid != 0) {
939 temp = FindByID(tt,hostid);
941 code = pr_ReadEntry (tt, 0, temp, &host_tentry);
942 if (code == PRSUCCESS)
945 fprintf(stderr,"pr_ReadEntry returned %d\n",code);
947 fprintf(stderr,"FindByID Failed -- Not found\n");
950 code = GetList2(tt, &tentry, &host_tentry, alist, 1);
952 code = GetList(tt, &tentry, alist, 1);
955 code = addWildCards(tt,alist,ntohl(ahost));
956 #endif /* IP_WILDCARDS */
957 if (code != PRSUCCESS) ABORT_WITH(tt,code);
959 code = ubik_EndTrans(tt);
964 afs_int32 PR_GetHostCPS (call, ahost, alist, over)
965 struct rx_call *call;
972 code = getHostCPS (call, ahost, alist, over);
973 osi_auditU (call, PTS_GetHCPSEvent, code, AUD_HOST, ahost, AUD_END);
977 afs_int32 getHostCPS (call, ahost, alist, over)
978 struct rx_call *call;
983 register afs_int32 code, temp;
984 struct ubik_trans *tt;
985 struct prentry host_tentry;
987 struct in_addr iaddr;
989 extern afs_int32 addWildCards();
990 #endif /* IP_WILDCARDS */
993 iaddr.s_addr = ntohl(ahost);
994 alist->prlist_len = 0;
995 alist->prlist_val = (afs_int32 *) 0;
997 if (code != PRSUCCESS) return code;
998 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
999 if (code) return code;
1000 code = ubik_SetLock(tt,1,1,LOCKREAD);
1001 if (code) ABORT_WITH(tt,code);
1002 code = read_DbHeader(tt);
1003 if (code) ABORT_WITH(tt,code);
1005 code = NameToID(tt, inet_ntoa(iaddr), &hostid);
1006 if (code == PRSUCCESS && hostid != 0) {
1007 temp = FindByID(tt,hostid);
1009 code = pr_ReadEntry (tt, 0, temp, &host_tentry);
1010 if (code == PRSUCCESS) {
1011 code = GetList(tt, &host_tentry, alist, 0);
1014 fprintf(stderr,"pr_ReadEntry returned %d\n",code);
1016 fprintf(stderr,"FindByID Failed -- Not found\n");
1019 code = addWildCards(tt,alist,ntohl(ahost));
1020 #endif /* IP_WILDCARDS */
1022 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1024 code = ubik_EndTrans(tt);
1029 afs_int32 PR_ListMax (call,uid,gid)
1030 struct rx_call *call;
1036 code = listMax(call,uid,gid);
1037 osi_auditU (call, PTS_LstMaxEvent, code, AUD_END);
1041 afs_int32 listMax (call,uid,gid)
1042 struct rx_call *call;
1046 register afs_int32 code;
1047 struct ubik_trans *tt;
1050 if (code != PRSUCCESS) return code;
1051 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1052 if (code) return code;
1053 code = ubik_SetLock(tt,1,1,LOCKREAD);
1054 if (code) ABORT_WITH(tt,code);
1055 code = read_DbHeader(tt);
1056 if (code) ABORT_WITH(tt,code);
1058 code = GetMax(tt,uid,gid);
1059 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1061 code = ubik_EndTrans(tt);
1062 if (code) return code;
1066 afs_int32 PR_SetMax (call,aid,gflag)
1067 struct rx_call *call;
1073 code = setMax (call,aid,gflag);
1074 osi_auditU (call, PTS_SetMaxEvent, code, AUD_LONG, aid, AUD_LONG, gflag, AUD_END);
1078 afs_int32 setMax (call,aid,gflag)
1079 struct rx_call *call;
1083 register afs_int32 code;
1084 struct ubik_trans *tt;
1088 if (code != PRSUCCESS) return code;
1089 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1090 if (code) return code;
1091 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1092 if (code) ABORT_WITH(tt,code);
1093 code = read_DbHeader(tt);
1094 if (code) ABORT_WITH(tt,code);
1096 code = WhoIsThis(call,tt,&cid);
1097 if (code) ABORT_WITH(tt,PRPERM);
1098 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1099 if (((gflag & PRGRP) && (aid > 0)) || (!(gflag & PRGRP) && (aid < 0))) ABORT_WITH(tt,PRBADARG);
1101 code = SetMax(tt,aid,gflag);
1102 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1104 code = ubik_EndTrans(tt);
1105 if (code) return code;
1109 afs_int32 PR_ListEntry (call,aid,aentry)
1110 struct rx_call *call;
1112 struct prcheckentry *aentry;
1116 code = listEntry (call,aid,aentry);
1117 osi_auditU (call, PTS_LstEntEvent, code, AUD_LONG, aid, AUD_END);
1121 afs_int32 listEntry (call,aid,aentry)
1122 struct rx_call *call;
1124 struct prcheckentry *aentry;
1126 register afs_int32 code;
1127 struct ubik_trans *tt;
1130 struct prentry tentry;
1133 if (code != PRSUCCESS) return code;
1134 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1135 if (code) return code;
1136 code = ubik_SetLock(tt,1,1,LOCKREAD);
1137 if (code) ABORT_WITH(tt,code);
1138 code = read_DbHeader(tt);
1139 if (code) ABORT_WITH(tt,code);
1141 code = WhoIsThis(call,tt,&cid);
1142 if (code) ABORT_WITH(tt,PRPERM);
1143 temp = FindByID(tt,aid);
1144 if (!temp) ABORT_WITH(tt,PRNOENT);
1145 code = pr_ReadEntry(tt, 0, temp, &tentry);
1146 if (code != 0) ABORT_WITH(tt,code);
1147 if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
1148 ABORT_WITH(tt,PRPERM);
1150 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
1151 if (aentry->flags == 0)
1152 if (tentry.flags & PRGRP)
1153 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
1154 else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
1155 aentry->owner = tentry.owner;
1156 aentry->id = tentry.id;
1157 strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
1158 aentry->creator = tentry.creator;
1159 aentry->ngroups = tentry.ngroups;
1160 aentry->nusers = tentry.nusers;
1161 aentry->count = tentry.count;
1162 bzero (aentry->reserved, sizeof(aentry->reserved));
1163 code = ubik_EndTrans(tt);
1164 if (code) return code;
1168 afs_int32 PR_ListEntries(call, flag, startindex, bulkentries, nextstartindex)
1169 struct rx_call *call;
1171 afs_int32 startindex;
1172 prentries *bulkentries;
1173 afs_int32 *nextstartindex;
1177 code = listEntries(call, flag, startindex, bulkentries, nextstartindex);
1178 osi_auditU (call, PTS_LstEntsEvent, code, AUD_LONG, flag, AUD_END);
1182 afs_int32 listEntries(call, flag, startindex, bulkentries, nextstartindex)
1183 struct rx_call *call;
1185 afs_int32 startindex;
1186 prentries *bulkentries;
1187 afs_int32 *nextstartindex;
1190 struct ubik_trans *tt;
1192 afs_int32 temp, i, eof, pos, maxentries, f;
1193 struct prentry tentry;
1194 afs_int32 pollcount=0;
1196 *nextstartindex = -1;
1197 bulkentries->prentries_val = 0;
1198 bulkentries->prentries_len = 0;
1201 if (code != PRSUCCESS) return code;
1202 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1203 if (code) return code;
1204 code = ubik_SetLock(tt,1,1,LOCKREAD);
1205 if (code) ABORT_WITH(tt,code);
1206 code = read_DbHeader(tt);
1207 if (code) ABORT_WITH(tt,code);
1209 /* Make sure we are an authenticated caller and that we are on the
1212 code = WhoIsThis(call,tt,&cid);
1213 if (code) ABORT_WITH(tt,PRPERM);
1214 code = IsAMemberOf (tt, cid, SYSADMINID);
1215 if (!code && !pr_noAuth) ABORT_WITH(tt,PRPERM);
1217 eof = ntohl(cheader.eofPtr) - sizeof(cheader);
1218 maxentries = eof / sizeof(struct prentry);
1219 for (i=startindex; i<maxentries; i++) {
1220 pos = i * sizeof(struct prentry) + sizeof(cheader);
1221 code = pr_ReadEntry (tt, 0, pos, &tentry);
1222 if (code) goto done;
1224 if (++pollcount > 50) {
1229 f = (tentry.flags & PRTYPE);
1230 if ( ((flag & PRUSERS ) && (f == 0) ) || /* User entry */
1231 ((flag & PRGROUPS) && (f & PRGRP)) ) { /* Group entry */
1232 code = put_prentries(&tentry, bulkentries);
1233 if (code == -1) break; /* Filled return array */
1234 if (code) goto done;
1239 *nextstartindex = i;
1243 if (bulkentries->prentries_val)
1244 free(bulkentries->prentries_val);
1245 bulkentries->prentries_val = 0;
1246 bulkentries->prentries_len = 0;
1247 ABORT_WITH(tt, code);
1250 code = ubik_EndTrans(tt);
1252 if (code) return code;
1256 #define PR_MAXENTRIES 500
1257 afs_int32 put_prentries(tentry, bulkentries)
1258 struct prentry *tentry;
1259 prentries *bulkentries;
1261 struct prlistentries *entry;
1263 if (bulkentries->prentries_val == 0) {
1264 bulkentries->prentries_len = 0;
1265 bulkentries->prentries_val = (struct prlistentries *)malloc(PR_MAXENTRIES * sizeof(struct prentry));
1266 if (!bulkentries->prentries_val) {
1271 if (bulkentries->prentries_len >= PR_MAXENTRIES) {
1275 entry = (struct prlistentries *)bulkentries->prentries_val;
1276 entry += bulkentries->prentries_len;
1278 entry->flags = tentry->flags >> PRIVATE_SHIFT;
1279 if (entry->flags == 0) {
1280 entry->flags = ( (tentry->flags & PRGRP)?PRP_GROUP_DEFAULT
1281 :PRP_USER_DEFAULT ) >> PRIVATE_SHIFT;
1283 entry->owner = tentry->owner;
1284 entry->id = tentry->id;
1285 entry->creator = tentry->creator;
1286 entry->ngroups = tentry->ngroups;
1287 entry->nusers = tentry->nusers;
1288 entry->count = tentry->count;
1289 strncpy(entry->name,tentry->name,PR_MAXNAMELEN);
1290 bzero(entry->reserved, sizeof(entry->reserved));
1291 bulkentries->prentries_len++;
1295 afs_int32 PR_ChangeEntry (call,aid,name,oid,newid)
1296 struct rx_call *call;
1304 code = changeEntry (call,aid,name,oid,newid);
1305 osi_auditU (call, PTS_ChgEntEvent, code, AUD_LONG, aid, AUD_STR, name,
1307 AUD_LONG, newid, AUD_END);
1311 afs_int32 changeEntry (call,aid,name,oid,newid)
1312 struct rx_call *call;
1318 register afs_int32 code;
1319 struct ubik_trans *tt;
1323 if (!name) return PRPERM;
1327 if (code) return code;
1328 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID ||
1329 aid == SYSADMINID) return PRPERM;
1330 if (code != PRSUCCESS) return code;
1331 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1332 if (code) return code;
1333 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1334 if (code) ABORT_WITH(tt,code);
1335 code = read_DbHeader(tt);
1336 if (code) ABORT_WITH(tt,code);
1338 code = WhoIsThis(call,tt,&cid);
1339 if (code) ABORT_WITH(tt,PRPERM);
1340 pos = FindByID(tt,aid);
1341 if (!pos) ABORT_WITH(tt,PRNOENT);
1342 /* protection check in changeentry */
1343 code = ChangeEntry(tt,aid,cid,name,oid,newid);
1344 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1346 code = ubik_EndTrans(tt);
1350 afs_int32 PR_SetFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2)
1351 struct rx_call *call;
1353 afs_int32 mask; /* specify which fields to update */
1354 afs_int32 flags, ngroups, nusers;
1355 afs_int32 spare1, spare2;
1359 code = setFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2);
1360 osi_auditU (call, PTS_SetFldEntEvent, code, AUD_LONG, id, AUD_END);
1364 afs_int32 setFieldsEntry (call, id, mask, flags, ngroups, nusers, spare1, spare2)
1365 struct rx_call *call;
1367 afs_int32 mask; /* specify which fields to update */
1368 afs_int32 flags, ngroups, nusers;
1369 afs_int32 spare1, spare2;
1371 register afs_int32 code;
1372 struct ubik_trans *tt;
1375 struct prentry tentry;
1378 if (mask == 0) return 0; /* no-op */
1380 if (code) return code;
1381 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
1383 if (code != PRSUCCESS) return code;
1384 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
1385 if (code) return code;
1386 code = ubik_SetLock(tt,1,1,LOCKWRITE);
1387 if (code) ABORT_WITH(tt,code);
1388 code = read_DbHeader(tt);
1389 if (code) ABORT_WITH(tt,code);
1391 code = WhoIsThis(call,tt,&cid);
1392 if (code) ABORT_WITH(tt,PRPERM);
1393 pos = FindByID(tt,id);
1394 if (!pos) ABORT_WITH(tt,PRNOENT);
1395 code = pr_ReadEntry (tt, 0, pos, &tentry);
1396 if (code) ABORT_WITH(tt,code);
1397 tflags = tentry.flags;
1399 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
1400 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1401 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
1402 tentry.ngroups = tentry.nusers = 20;
1405 if (!AccessOK (tt, cid, &tentry, 0, 0)) ABORT_WITH(tt,PRPERM);
1408 if (mask & 0xffff) { /* if setting flag bits */
1409 afs_int32 flagsMask = mask & 0xffff;
1410 tflags &= ~(flagsMask << PRIVATE_SHIFT);
1411 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
1415 if (mask & PR_SF_NGROUPS) { /* setting group limit */
1416 if (ngroups < 0) ABORT_WITH(tt,PRBADARG);
1417 tentry.ngroups = ngroups;
1421 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
1422 if (nusers < 0) ABORT_WITH(tt,PRBADARG);
1423 tentry.nusers = nusers;
1426 tentry.flags = tflags;
1428 code = pr_WriteEntry (tt, 0, pos, &tentry);
1429 if (code) ABORT_WITH(tt,code);
1431 code = ubik_EndTrans(tt);
1435 afs_int32 PR_ListElements (call, aid, alist, over)
1436 struct rx_call *call;
1443 code = listElements (call, aid, alist, over);
1444 osi_auditU (call, PTS_LstEleEvent, code, AUD_LONG, aid, AUD_END);
1448 afs_int32 listElements (call, aid, alist, over)
1449 struct rx_call *call;
1454 register afs_int32 code;
1455 struct ubik_trans *tt;
1458 struct prentry tentry;
1461 alist->prlist_len = 0;
1462 alist->prlist_val = (afs_int32 *) 0;
1465 if (code != PRSUCCESS) return code;
1466 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1467 if (code) return code;
1468 code = ubik_SetLock(tt,1,1,LOCKREAD);
1469 if (code) ABORT_WITH(tt,code);
1470 code = read_DbHeader(tt);
1471 if (code) ABORT_WITH(tt,code);
1473 code = WhoIsThis(call,tt,&cid);
1474 if (code) ABORT_WITH(tt,PRPERM);
1476 temp = FindByID(tt,aid);
1477 if (!temp) ABORT_WITH(tt,PRNOENT);
1478 code = pr_ReadEntry (tt, 0, temp, &tentry);
1479 if (code) ABORT_WITH(tt,code);
1480 if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1481 ABORT_WITH(tt,PRPERM);
1483 code = GetList (tt, &tentry, alist, 0);
1484 if (code != PRSUCCESS) ABORT_WITH(tt,code);
1486 code = ubik_EndTrans(tt);
1492 * List the entries owned by this id. If the id is zero,
1493 * return the orphans list. This will return up to PR_MAXGROUPS
1494 * at a time with the lastP available to get the rest. The
1495 * maximum value is enforced in GetOwnedChain().
1497 afs_int32 PR_ListOwned (call, aid, alist, lastP)
1498 struct rx_call *call;
1505 code = listOwned (call, aid, alist, lastP);
1506 osi_auditU (call, PTS_LstOwnEvent, code, AUD_LONG, aid, AUD_END);
1510 afs_int32 listOwned (call, aid, alist, lastP)
1511 struct rx_call *call;
1516 register afs_int32 code;
1517 struct ubik_trans *tt;
1519 struct prentry tentry;
1523 alist->prlist_len = 0;
1524 alist->prlist_val = (afs_int32 *) 0;
1526 if (!lastP) return PRBADARG;
1531 if (code != PRSUCCESS) return code;
1532 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1533 if (code) return code;
1534 code = ubik_SetLock(tt,1,1,LOCKREAD);
1535 if (code) ABORT_WITH(tt,code);
1536 code = read_DbHeader(tt);
1537 if (code) ABORT_WITH(tt,code);
1539 code = WhoIsThis(call,tt,&cid);
1540 if (code) ABORT_WITH(tt,PRPERM);
1543 code = pr_ReadEntry (tt, 0, start, &tentry);
1544 if (!code && (tentry.owner == aid))
1545 head = start; /* pick up where we left off */
1550 afs_int32 loc = FindByID (tt, aid);
1551 if (loc == 0) ABORT_WITH(tt,PRNOENT);
1552 code = pr_ReadEntry (tt, 0, loc, &tentry);
1553 if (code) ABORT_WITH(tt,code);
1555 if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY))
1556 ABORT_WITH(tt,PRPERM);
1557 head = tentry.owned;
1559 if (!AccessOK (tt, cid, 0, 0, 0)) ABORT_WITH(tt,PRPERM);
1560 head = ntohl(cheader.orphan);
1564 code = GetOwnedChain (tt, &head, alist);
1566 if (code == PRTOOMANY) *lastP = head;
1567 else ABORT_WITH(tt,code);
1570 code = ubik_EndTrans(tt);
1574 afs_int32 PR_IsAMemberOf (call,uid,gid,flag)
1575 struct rx_call *call;
1582 code = isAMemberOf (call,uid,gid,flag);
1583 osi_auditU (call, PTS_IsMemOfEvent, code, AUD_LONG, uid, AUD_LONG, gid, AUD_END);
1587 afs_int32 isAMemberOf (call,uid,gid,flag)
1588 struct rx_call *call;
1593 register afs_int32 code;
1594 struct ubik_trans *tt;
1597 if (code != PRSUCCESS) return code;
1598 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1599 if (code) return code;
1600 code = ubik_SetLock(tt,1,1,LOCKREAD);
1601 if (code) ABORT_WITH(tt,code);
1602 code = read_DbHeader(tt);
1603 if (code) ABORT_WITH(tt,code);
1606 afs_int32 uloc = FindByID (tt, uid);
1607 afs_int32 gloc = FindByID (tt, gid);
1608 struct prentry uentry, gentry;
1610 if (!uloc || !gloc) ABORT_WITH(tt,PRNOENT);
1611 code = WhoIsThis(call, tt, &cid);
1612 if (code) ABORT_WITH(tt,PRPERM);
1613 code = pr_ReadEntry (tt, 0, uloc, &uentry);
1614 if (code) ABORT_WITH(tt,code);
1615 code = pr_ReadEntry (tt, 0, gloc, &gentry);
1616 if (code) ABORT_WITH(tt,code);
1617 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) ABORT_WITH(tt,PRBADARG);
1618 if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1619 !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1620 ABORT_WITH(tt,PRPERM);
1623 *flag = IsAMemberOf(tt,uid,gid);
1624 code = ubik_EndTrans(tt);
1634 if (isupper(tc)) *s = tolower(tc);
1640 afs_int32 addWildCards(tt,alist,host)
1641 struct ubik_trans *tt;
1646 struct prentry tentry;
1648 unsigned wild = htonl(0xffffff00);
1649 struct in_addr iaddr;
1651 int size = 0, i, code;
1653 extern afs_int32 IDCmp();
1655 while (host = (host & wild)) {
1656 wild = htonl ( ntohl(wild) << 8) ;
1657 iaddr.s_addr = host;
1658 code = NameToID(tt, inet_ntoa(iaddr),&hostid);
1659 if (code == PRSUCCESS && hostid != 0) {
1660 temp = FindByID(tt,hostid);
1662 code = pr_ReadEntry (tt, 0, temp, &tentry);
1663 if (code != PRSUCCESS)
1669 wlist.prlist_len = 0;
1670 wlist.prlist_val = (afs_int32 *) 0;
1672 code = GetList (tt, &tentry, &wlist, 0);
1673 if (code) return code;
1674 added += wlist.prlist_len;
1675 for (i=0; i< wlist.prlist_len; i++) {
1676 if (!inCPS(*alist,wlist.prlist_val[i]))
1677 if (code = AddToPRList (alist, &size, wlist.prlist_val[i] )) {
1678 free(wlist.prlist_val);
1682 if (wlist.prlist_val) free(wlist.prlist_val);
1685 qsort(alist->prlist_val,alist->prlist_len,sizeof(afs_int32),IDCmp);
1688 #endif /* IP_WILDCARDS */
1691 afs_int32 WhoIsThisWithName(acall, at, aid, aname)
1692 struct rx_call *acall;
1693 struct ubik_trans *at;
1697 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
1698 /* returns -1 and sets aid to ANONYMOUSID on any failure */
1699 register struct rx_connection *tconn;
1700 register afs_int32 code;
1701 char tcell[MAXKTCREALMLEN];
1702 char name[MAXKTCNAMELEN];
1703 char inst[MAXKTCNAMELEN];
1708 tconn = rx_ConnectionOf(acall);
1709 code = rx_SecurityClassOf(tconn);
1710 if (code == 0) return 0;
1711 else if (code == 1) { /* vab class */
1712 goto done; /* no longer supported */
1714 else if (code == 2) { /* kad class */
1717 extern char *pr_realmName;
1719 if (code = rxkad_GetServerInfo
1720 (acall->conn, (afs_int32 *) 0, 0/*was &exp*/,
1721 name, inst, tcell, (afs_int32 *) 0))
1723 strncpy (vname, name, sizeof(vname));
1724 if (ilen = strlen (inst)) {
1725 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
1726 strcat (vname, ".");
1727 strcat (vname, inst);
1729 if (clen = strlen (tcell)){
1731 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
1732 static char local_realm[AFS_REALM_SZ] = "";
1733 if (!local_realm[0]) {
1734 if (afs_krb_get_lrealm(local_realm, 0) != 0/*KSUCCESS*/)
1735 strncpy(local_realm, pr_realmName, AFS_REALM_SZ);
1739 #if defined(AFS_ATHENA_STDENV) || defined(AFS_KERBREALM_ENV)
1740 strcasecmp (local_realm, tcell) &&
1742 strcasecmp (pr_realmName, tcell))
1744 if (strlen(vname) + 1 + clen >= sizeof(vname)) goto done;
1746 strcat(vname,tcell);
1747 lcstring(vname, vname, sizeof(vname));
1748 code = NameToID(at,vname,aid);
1749 strcpy(aname,vname);
1754 if (strcmp (AUTH_SUPERUSER, vname) == 0)
1755 *aid = SYSADMINID; /* special case for the fileserver */
1757 lcstring(vname, vname, sizeof(vname));
1758 code = NameToID(at,vname,aid);
1762 if (code && !pr_noAuth) return -1;