1 /* Copyright (C) 1990, 1989 Transarc Corporation - All rights reserved */
3 * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
4 * LICENSED MATERIALS - PROPERTY OF IBM
5 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
10 Information Technology Center
14 #include <afs/param.h>
29 #include <netinet/in.h>
34 static long WhoIsThisWithName();
40 extern struct ubik_dbase *dbase;
45 static int CreateOK (ut, cid, oid, flag, admin)
46 struct ubik_trans *ut;
47 long cid; /* id of caller */
48 long oid; /* id of owner */
49 long flag; /* indicates type of entry */
50 int admin; /* sysadmin membership */
52 if (flag & (PRGRP | PRFOREIGN)) {
53 /* Allow anonymous group creation only if owner specified and running
55 if (cid == ANONYMOUSID) {
56 if ((oid == 0) || !pr_noAuth) return 0;
59 else { /* creating a user */
60 if (!admin && !pr_noAuth) return 0;
65 long WhoIsThis (acall, at, aid)
66 struct rx_call *acall;
67 struct ubik_trans *at;
70 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
71 /* returns -1 and sets aid to ANONYMOUSID on any failure */
72 register struct rx_connection *tconn;
74 char tcell[MAXKTCREALMLEN];
75 char name[MAXKTCNAMELEN];
76 char inst[MAXKTCNAMELEN];
87 tconn = rx_ConnectionOf(acall);
88 code = rx_SecurityClassOf(tconn);
89 if (code == 0) return 0;
90 else if (code == 1) { /* vab class */
91 goto done; /* no longer supported */
93 else if (code == 2) { /* kad class */
94 if (code = rxkad_GetServerInfo
95 (acall->conn, (long *) 0, 0/*was &exp*/,
96 name, inst, tcell, (long *) 0))
99 /* This test is unnecessary, since rxkad_GetServerInfo already check.
100 * In addition, this is wrong since exp must be unsigned. */
101 if (exp < FT_ApproxTime()) goto done;
103 if (strlen (tcell)) {
104 if (!afsconf_LocalRealm(prdir, tcell)) {
112 strncpy (vname, name, sizeof(vname));
113 if (ilen = strlen (inst)) {
114 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
116 strcat (vname, inst);
120 if ((strlen(name)+strlen(tcell)+1) >= sizeof(vname)) {
124 strcat (vname, tcell);
127 if (strcmp (AUTH_SUPERUSER, vname) == 0)
128 *aid = SYSADMINID; /* special case for the fileserver */
130 lcstring(vname, vname, sizeof(vname));
131 code = NameToID(at,vname,aid);
135 if (code && !pr_noAuth) return -1;
139 long PR_INewEntry(call,aname,aid,oid)
140 struct rx_call *call;
141 char aname[PR_MAXNAMELEN];
145 /* used primarily for conversion - not intended to be used as usual means
146 of entering people into the database. */
147 struct ubik_trans *tt;
153 #define abort_with(code) return (ubik_AbortTrans(tt),code)
157 if (code != PRSUCCESS) return code;
158 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
159 if (code) return code;
160 code = ubik_SetLock(tt, 1,1,LOCKWRITE);
161 if (code) abort_with (code);
163 code = WhoIsThis(call,tt,&cid);
164 if (code) abort_with (PRPERM);
165 admin = IsAMemberOf(tt,cid,SYSADMINID);
167 /* first verify the id is good */
168 if (aid == 0) abort_with (PRPERM);
171 /* only sysadmin can reuse a group id */
172 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup)-1))
175 if (FindByID (tt, aid)) abort_with (PRIDEXIST);
177 /* check a few other things */
178 if (!CreateOK (tt, cid, oid, gflag, admin)) abort_with (PRPERM);
180 code = CreateEntry (tt,aname,&aid,1,gflag,oid,cid);
181 if (code != PRSUCCESS) {
185 /* finally, commit transaction */
186 code = ubik_EndTrans(tt);
187 if (code) return code;
192 long PR_NewEntry (call, aname, flag, oid, aid)
193 struct rx_call *call;
194 char aname[PR_MAXNAMELEN];
200 struct ubik_trans *tt;
204 char cname[PR_MAXNAMELEN];
209 if (code) return code;
210 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
211 if (code) return code;
212 code = ubik_SetLock(tt,1,1,LOCKWRITE);
220 /* this is for cross-cell self registration */
221 code = WhoIsThisWithName(call,tt,&cid,cname);
222 if (code != 2) { /* 2 specifies that this is a foreign cell request */
228 admin = IsAMemberOf(tt,cid,SYSADMINID);
230 admin = (!strcmp(aname,cname)) || IsAMemberOf(tt,cid,SYSADMINID);
231 oid = cid = SYSADMINID;
234 code = WhoIsThis(call,tt,&cid);
240 admin = IsAMemberOf(tt,cid,SYSADMINID);
243 if (!CreateOK (tt, cid, oid, flag, admin)) goto perm;
245 code = CreateEntry (tt,aname,aid,0,flag,oid,cid);
246 if (code != PRSUCCESS) goto abort;
248 code = ubik_EndTrans(tt);
249 if (code) return code;
255 PR_WhereIsIt(call,aid,apos)
256 struct rx_call *call;
261 struct ubik_trans *tt;
265 if (code != PRSUCCESS) return code;
266 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
267 if (code) return code;
268 code = ubik_SetLock(tt,1,1,LOCKREAD);
273 temp = FindByID(tt,aid);
279 code = ubik_EndTrans(tt);
280 if (code) return code;
285 PR_DumpEntry(call,apos, aentry)
286 struct rx_call *call;
288 struct prdebugentry *aentry;
291 struct ubik_trans *tt;
294 if (code != PRSUCCESS) return code;
295 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
296 if (code) return code;
297 code = ubik_SetLock(tt,1,1,LOCKREAD);
303 code = pr_ReadEntry(tt, 0, apos, aentry);
304 if (code) goto abort;
306 /* Since prdebugentry is in the form of a prentry not a coentry, we will
307 * return the coentry slots in network order where the string is. */
309 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
310 code = pr_ReadCoEntry(tt, 0, apos, aentry);
311 if (code) goto abort;
314 code = ubik_EndTrans(tt);
315 if (code) return code;
319 PR_AddToGroup(call,aid,gid)
320 struct rx_call *call;
325 struct ubik_trans *tt;
328 struct prentry tentry;
329 struct prentry uentry;
333 if (code != PRSUCCESS) return code;
334 if (gid == ANYUSERID || gid == AUTHUSERID) return PRPERM;
335 if (aid == ANONYMOUSID) return PRPERM;
336 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
337 if (code) return code;
338 code = ubik_SetLock(tt,1,1,LOCKWRITE);
343 code = WhoIsThis(call, tt, &cid);
348 tempu = FindByID(tt,aid);
353 bzero(&uentry,sizeof(uentry));
354 code = pr_ReadEntry(tt,0,tempu,&uentry);
359 /* we don't allow groups as members of groups at present */
360 if (uentry.flags & PRGRP) {
364 tempg = FindByID(tt,gid);
369 code = pr_ReadEntry(tt,0,tempg,&tentry);
374 /* make sure that this is a group */
375 if (!(tentry.flags & PRGRP)) {
379 if (!AccessOK (tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY)) {
384 code = AddToEntry (tt, &tentry, tempg, aid);
385 if (code != PRSUCCESS) {
389 /* now, modify the user's entry as well */
390 code = AddToEntry (tt, &uentry, tempu, gid);
391 if (code != PRSUCCESS) {
395 code = ubik_EndTrans(tt);
396 if (code) return code;
400 long PR_NameToID (call, aname, aid)
401 struct rx_call *call;
406 struct ubik_trans *tt;
411 /* must do this first for RPC stub to work */
412 size = aname->namelist_len;
413 if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
414 aid->idlist_val = (long *)malloc(size*sizeof(long));
416 if (aname->namelist_len == 0) return 0;
417 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
420 if (code != PRSUCCESS) return code;
421 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
422 if (code) return code;
423 code = ubik_SetLock(tt,1,1,LOCKREAD);
428 for (i=0;i<aname->namelist_len;i++) {
429 code = NameToID(tt,aname->namelist_val[i],&aid->idlist_val[i]);
430 if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID;
431 if (count++ > 50) IOMGR_Poll(), count = 0;
433 aid->idlist_len = aname->namelist_len;
435 code = ubik_EndTrans(tt);
436 if (code) return code;
440 long PR_IDToName (call, aid, aname)
441 struct rx_call *call;
446 struct ubik_trans *tt;
451 /* leave this first for rpc stub */
452 size = aid->idlist_len;
453 if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
454 aname->namelist_val = (prname *)malloc(size*PR_MAXNAMELEN);
455 aname->namelist_len = 0;
456 if (aid->idlist_len == 0) return 0;
457 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
460 if (code != PRSUCCESS) return code;
461 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
462 if (code) return code;
463 code = ubik_SetLock(tt,1,1,LOCKREAD);
468 for (i=0;i<aid->idlist_len;i++) {
469 /* interface won't allow more than PR_MAXLIST to be sent in */
470 code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
471 if (code != PRSUCCESS)
472 sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
473 if (count++ > 50) IOMGR_Poll(), count = 0;
475 aname->namelist_len = aid->idlist_len;
477 code = ubik_EndTrans(tt);
478 if (code) return code;
482 long PR_Delete (call, aid)
483 struct rx_call *call;
487 struct ubik_trans *tt;
489 struct prentry tentry;
494 if (code) return code;
495 if (code != PRSUCCESS) return code;
496 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
497 aid == ANONYMOUSID) return PRPERM;
498 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
499 if (code) return code;
500 code = ubik_SetLock(tt,1,1,LOCKWRITE);
506 code = WhoIsThis(call,tt,&cid);
512 /* Read in entry to be deleted */
513 loc = FindByID (tt, aid);
514 if (loc == 0) {code = PRNOENT; goto abort;}
515 code = pr_ReadEntry (tt, 0, loc, &tentry);
516 if (code) {code = PRDBFAIL; goto abort;}
518 /* Do some access checking */
519 if (tentry.owner != cid &&
520 !IsAMemberOf (tt, cid, SYSADMINID) &&
521 !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
522 {code = PRPERM; goto abort;}
524 /* Delete each continuation block as a separate transaction so that no one
525 * transaction become to large to complete. */
527 while (nptr != NULL) {
528 struct contentry centry;
531 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
532 if (code != 0) {code = PRDBFAIL; goto abort;}
533 for (i=0;i<COSIZE;i++) {
534 if (centry.entries[i] == PRBADID) continue;
535 if (centry.entries[i] == 0) break;
536 code = RemoveFromEntry (tt, aid, centry.entries[i]);
537 if (code) goto abort;
538 tentry.count--; /* maintain count */
539 if ((i&3) == 0) IOMGR_Poll();
541 tentry.next = centry.next; /* thread out this block */
542 code = FreeBlock (tt, nptr); /* free continuation block */
543 if (code) goto abort;
544 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
545 if (code) goto abort;
547 /* end this trans and start a new one */
548 code = ubik_EndTrans(tt);
549 if (code) return code;
550 IOMGR_Poll(); /* just to keep the connection alive */
551 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
552 if (code) return code;
553 code = ubik_SetLock(tt,1,1,LOCKWRITE);
554 if (code) goto abort;
556 /* re-read entry to get consistent uptodate info */
557 loc = FindByID (tt, aid);
558 if (loc == 0) {code = PRNOENT; goto abort;}
559 code = pr_ReadEntry (tt, 0, loc, &tentry);
560 if (code) {code = PRDBFAIL; goto abort;}
565 /* Then move the owned chain, except possibly ourself to the orphan list.
566 * Because this list can be very long and so exceed the size of a ubik
567 * transaction, we start a new transaction every 50 entries. */
570 while (nptr != NULL) {
571 struct prentry nentry;
573 code = pr_ReadEntry (tt, 0, nptr, &nentry);
574 if (code) {code = PRDBFAIL; goto abort;}
575 nptr = tentry.owned = nentry.nextOwned; /* thread out */
577 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
578 code = AddToOrphan (tt, nentry.id);
579 if (code) goto abort;
581 if ((count & 3) == 0) IOMGR_Poll();
583 if (count < 50) continue;
584 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
585 if (code) goto abort;
587 /* end this trans and start a new one */
588 code = ubik_EndTrans(tt);
589 if (code) return code;
590 IOMGR_Poll(); /* just to keep the connection alive */
591 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
592 if (code) return code;
593 code = ubik_SetLock(tt,1,1,LOCKWRITE);
594 if (code) goto abort;
596 /* re-read entry to get consistent uptodate info */
597 loc = FindByID (tt, aid);
598 if (loc == 0) {code = PRNOENT; goto abort;}
599 code = pr_ReadEntry (tt, 0, loc, &tentry);
600 if (code) {code = PRDBFAIL; goto abort;}
605 /* now do what's left of the deletion stuff */
606 code = DeleteEntry (tt, &tentry, loc);
607 if (code != PRSUCCESS) {
611 code = ubik_EndTrans(tt);
612 if (code) return code;
616 PR_RemoveFromGroup(call,aid,gid)
617 struct rx_call *call;
622 struct ubik_trans *tt;
625 struct prentry uentry;
626 struct prentry gentry;
630 if (code != PRSUCCESS) return code;
631 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
632 if (code) return code;
633 code = ubik_SetLock(tt,1,1,LOCKWRITE);
638 code = WhoIsThis(call,tt,&cid);
643 tempu = FindByID(tt,aid);
648 tempg = FindByID(tt,gid);
653 bzero(&uentry,sizeof(uentry));
654 bzero(&gentry,sizeof(gentry));
655 code = pr_ReadEntry(tt,0,tempu,&uentry);
660 code = pr_ReadEntry(tt,0,tempg,&gentry);
665 if (!(gentry.flags & PRGRP)) {
669 if (uentry.flags & PRGRP) {
673 if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) {
677 code = RemoveFromEntry(tt,aid,gid);
678 if (code != PRSUCCESS) {
682 code = RemoveFromEntry(tt,gid,aid);
683 if (code != PRSUCCESS) {
687 code = ubik_EndTrans(tt);
688 if (code) return code;
692 long PR_GetCPS (call, aid, alist, over)
693 struct rx_call *call;
699 struct ubik_trans *tt;
702 struct prentry tentry;
704 alist->prlist_len = 0;
705 alist->prlist_val = (long *) 0;
707 if (code != PRSUCCESS) goto done;
708 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
710 code = ubik_SetLock(tt,1,1,LOCKREAD);
717 temp = FindByID (tt, aid);
718 if (!temp) {code = PRNOENT; goto abort;}
719 code = pr_ReadEntry (tt, 0, temp, &tentry);
720 if (code) goto abort;
722 /* afs does authenticate now */
723 code = WhoIsThis (call, tt, &cid);
724 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) {
729 code = GetList(tt, &tentry, alist, 1);
731 if (code == PRTOOMANY) *over = 1;
732 else if (code != PRSUCCESS) {
737 code = ubik_EndTrans(tt);
740 /* return code, making sure that prlist_val points to malloc'd memory */
741 if (!alist->prlist_val)
742 alist->prlist_val = (long *) malloc(0); /* make xdr stub happy */
746 PR_ListMax(call,uid,gid)
747 struct rx_call *call;
752 struct ubik_trans *tt;
755 if (code != PRSUCCESS) return code;
756 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
757 if (code) return code;
758 code = ubik_SetLock(tt,1,1,LOCKREAD);
763 code = GetMax(tt,uid,gid);
764 if (code != PRSUCCESS) {
768 code = ubik_EndTrans(tt);
769 if (code) return code;
773 PR_SetMax(call,aid,gflag)
774 struct rx_call *call;
779 struct ubik_trans *tt;
783 if (code != PRSUCCESS) return code;
784 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
785 if (code) return code;
786 code = ubik_SetLock(tt,1,1,LOCKWRITE);
791 code = WhoIsThis(call,tt,&cid);
796 if (!AccessOK (tt, cid, 0, 0, 0)) {
800 if (((gflag & PRGRP) && (aid > 0)) ||
801 (!(gflag & PRGRP) && (aid < 0))) {
806 code = SetMax(tt,aid,gflag);
807 if (code != PRSUCCESS) {
812 code = ubik_EndTrans(tt);
813 if (code) return code;
817 PR_ListEntry(call,aid,aentry)
818 struct rx_call *call;
820 struct prcheckentry *aentry;
823 struct ubik_trans *tt;
826 struct prentry tentry;
829 if (code != PRSUCCESS) return code;
830 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
831 if (code) return code;
832 code = ubik_SetLock(tt,1,1,LOCKREAD);
837 code = WhoIsThis(call,tt,&cid);
843 temp = FindByID(tt,aid);
848 code = pr_ReadEntry(tt, 0, temp, &tentry);
853 if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
856 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
857 if (aentry->flags == 0)
858 if (tentry.flags & PRGRP)
859 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
860 else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
861 aentry->owner = tentry.owner;
862 aentry->id = tentry.id;
863 strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
864 aentry->creator = tentry.creator;
865 aentry->ngroups = tentry.ngroups;
866 aentry->nusers = tentry.nusers;
867 aentry->count = tentry.count;
868 bzero (aentry->reserved, sizeof(aentry->reserved));
869 code = ubik_EndTrans(tt);
870 if (code) return code;
874 PR_ChangeEntry(call,aid,name,oid,newid)
875 struct rx_call *call;
882 struct ubik_trans *tt;
888 if (code) return code;
889 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID ||
890 aid == SYSADMINID) return PRPERM;
891 if (code != PRSUCCESS) return code;
892 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
893 if (code) return code;
894 code = ubik_SetLock(tt,1,1,LOCKWRITE);
899 code = WhoIsThis(call,tt,&cid);
904 pos = FindByID(tt,aid);
909 /* protection check in changeentry */
910 code = ChangeEntry(tt,aid,cid,name,oid,newid);
911 if (code != PRSUCCESS) {
915 code = ubik_EndTrans(tt);
919 PR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
920 struct rx_call *call;
922 long mask; /* specify which fields to update */
923 long flags, ngroups, nusers;
927 struct ubik_trans *tt;
930 struct prentry tentry;
933 if (mask == 0) return 0; /* no-op */
935 if (code) return code;
936 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
938 if (code != PRSUCCESS) return code;
939 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
940 if (code) return code;
941 code = ubik_SetLock(tt,1,1,LOCKWRITE);
947 code = WhoIsThis(call,tt,&cid);
953 pos = FindByID(tt,id);
958 code = pr_ReadEntry (tt, 0, pos, &tentry);
959 if (code) goto abort;
960 tflags = tentry.flags;
962 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
963 if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
964 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
965 tentry.ngroups = tentry.nusers = 20;
968 if (!AccessOK (tt, cid, &tentry, 0, 0)) goto perm;
971 if (mask & 0xffff) { /* if setting flag bits */
972 long flagsMask = mask & 0xffff;
973 tflags &= ~(flagsMask << PRIVATE_SHIFT);
974 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
978 if (mask & PR_SF_NGROUPS) { /* setting group limit */
979 if (ngroups < 0) {code = PRBADARG; goto abort;}
980 tentry.ngroups = ngroups;
984 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
985 if (nusers < 0) {code = PRBADARG; goto abort;}
986 tentry.nusers = nusers;
989 tentry.flags = tflags;
991 code = pr_WriteEntry (tt, 0, pos, &tentry);
992 if (code) goto abort;
994 code = ubik_EndTrans(tt);
998 long PR_ListElements (call, aid, alist, over)
999 struct rx_call *call;
1005 struct ubik_trans *tt;
1008 struct prentry tentry;
1010 alist->prlist_len = 0;
1011 alist->prlist_val = (long *) 0;
1014 if (code != PRSUCCESS) goto done;
1015 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1016 if (code) goto done;
1017 code = ubik_SetLock(tt,1,1,LOCKREAD);
1020 ubik_AbortTrans(tt);
1023 code = WhoIsThis(call,tt,&cid);
1027 ubik_AbortTrans(tt);
1031 temp = FindByID(tt,aid);
1032 if (!temp) {code = PRNOENT; goto abort;}
1033 code = pr_ReadEntry (tt, 0, temp, &tentry);
1034 if (code) goto abort;
1035 if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1038 code = GetList (tt, &tentry, alist, 0);
1040 if (code == PRTOOMANY) *over = 1;
1041 else if (code != PRSUCCESS) goto abort;
1043 code = ubik_EndTrans(tt);
1046 if (!alist->prlist_val)
1047 alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1051 /* List the entries owned by this id. If the id is zero return the orphans
1054 PR_ListOwned (call, aid, alist, over)
1055 struct rx_call *call;
1061 struct ubik_trans *tt;
1063 struct prentry tentry;
1066 alist->prlist_len = 0;
1067 alist->prlist_val = (long *) 0;
1070 if (code != PRSUCCESS) goto done;
1071 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1072 if (code) goto done;
1073 code = ubik_SetLock(tt,1,1,LOCKREAD);
1076 ubik_AbortTrans(tt);
1079 code = WhoIsThis(call,tt,&cid);
1083 ubik_AbortTrans(tt);
1088 long loc = FindByID (tt, aid);
1089 if (loc == 0) { code = PRNOENT; goto abort; }
1090 code = pr_ReadEntry (tt, 0, loc, &tentry);
1091 if (code) goto abort;
1093 if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY)) goto perm;
1094 head = tentry.owned;
1096 if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
1097 head = ntohl(cheader.orphan);
1100 code = GetOwnedChain (tt, head, alist);
1102 if (code == PRTOOMANY) *over = 1;
1103 else if (code) goto abort;
1105 code = ubik_EndTrans(tt);
1108 if (!alist->prlist_val)
1109 alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1113 PR_IsAMemberOf(call,uid,gid,flag)
1114 struct rx_call *call;
1120 struct ubik_trans *tt;
1123 if (code != PRSUCCESS) return code;
1124 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
1125 if (code) return code;
1126 code = ubik_SetLock(tt,1,1,LOCKREAD);
1129 ubik_AbortTrans(tt);
1133 long uloc = FindByID (tt, uid);
1134 long gloc = FindByID (tt, gid);
1135 struct prentry uentry, gentry;
1137 if (!uloc || !gloc) {
1141 code = WhoIsThis(call, tt, &cid);
1147 code = pr_ReadEntry (tt, 0, uloc, &uentry);
1148 if (code) goto abort;
1149 code = pr_ReadEntry (tt, 0, gloc, &gentry);
1150 if (code) goto abort;
1151 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) {
1155 if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1156 !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1160 *flag = IsAMemberOf(tt,uid,gid);
1161 code = ubik_EndTrans(tt);
1171 if (isupper(tc)) *s = tolower(tc);
1177 static long WhoIsThisWithName(acall, at, aid, aname)
1178 struct rx_call *acall;
1179 struct ubik_trans *at;
1183 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
1184 /* returns -1 and sets aid to ANONYMOUSID on any failure */
1186 register struct rx_connection *tconn;
1188 char tcell[MAXKTCREALMLEN];
1189 char name[MAXKTCNAMELEN];
1190 char inst[MAXKTCNAMELEN];
1198 tconn = rx_ConnectionOf(acall);
1199 code = rx_SecurityClassOf(tconn);
1200 if (code == 0) return 0;
1201 else if (code == 1) { /* vab class */
1202 goto done; /* no longer supported */
1204 else if (code == 2) { /* kad class */
1207 extern char *pr_realmName;
1209 if (code = rxkad_GetServerInfo
1210 (acall->conn, (long *)0, 0 /*was &exp*/,
1211 name, inst, tcell, (long *)0))
1213 strncpy (vname, name, sizeof(vname));
1214 if (ilen = strlen (inst)) {
1215 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
1216 strcat (vname, ".");
1217 strcat (vname, inst);
1219 if (clen = strlen (tcell)) {
1220 if (!afsconf_LocalRealm(prdir, tcell)) {
1221 if (strlen(vname) + 1 + clen >= sizeof(vname)) goto done;
1223 strcat(vname,tcell);
1224 lcstring(vname, vname, sizeof(vname));
1225 code = NameToID(at,vname,aid);
1226 strcpy(aname,vname);
1231 if (strcmp (AUTH_SUPERUSER, vname) == 0)
1232 /* special case for the fileserver */
1235 lcstring(vname, vname, sizeof(vname));
1236 code = NameToID(at,vname,aid);
1240 if (code && !pr_noAuth) return -1;