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>
33 #if defined(CROSS_CELL) && !defined(WhoIsThisWithName)
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 #if !defined(WhoIsThis)
66 long WhoIsThis (acall, at, aid)
67 struct rx_call *acall;
68 struct ubik_trans *at;
71 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
72 /* returns -1 and sets aid to ANONYMOUSID on any failure */
73 register struct rx_connection *tconn;
75 char tcell[MAXKTCREALMLEN];
76 char name[MAXKTCNAMELEN];
77 char inst[MAXKTCNAMELEN];
88 tconn = rx_ConnectionOf(acall);
89 code = rx_SecurityClassOf(tconn);
90 if (code == 0) return 0;
91 else if (code == 1) { /* vab class */
92 goto done; /* no longer supported */
94 else if (code == 2) { /* kad class */
95 if (code = rxkad_GetServerInfo
96 (acall->conn, (long *) 0, 0/*was &exp*/,
97 name, inst, tcell, (long *) 0))
100 /* This test is unnecessary, since rxkad_GetServerInfo already check.
101 * In addition, this is wrong since exp must be unsigned. */
102 if (exp < FT_ApproxTime()) goto done;
104 if (strlen (tcell)) {
105 if (!afsconf_LocalRealm(prdir, tcell)) {
113 strncpy (vname, name, sizeof(vname));
114 if (ilen = strlen (inst)) {
115 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
117 strcat (vname, inst);
121 if ((strlen(name)+strlen(tcell)+1) >= sizeof(vname)) {
125 strcat (vname, tcell);
128 if (strcmp (AUTH_SUPERUSER, vname) == 0)
129 *aid = SYSADMINID; /* special case for the fileserver */
131 lcstring(vname, vname, sizeof(vname));
132 code = NameToID(at,vname,aid);
136 if (code && !pr_noAuth) return -1;
141 long PR_INewEntry(call,aname,aid,oid)
142 struct rx_call *call;
143 char aname[PR_MAXNAMELEN];
147 /* used primarily for conversion - not intended to be used as usual means
148 of entering people into the database. */
149 struct ubik_trans *tt;
155 #define abort_with(code) return (ubik_AbortTrans(tt),code)
159 if (code != PRSUCCESS) return code;
160 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
161 if (code) return code;
162 code = ubik_SetLock(tt, 1,1,LOCKWRITE);
163 if (code) abort_with (code);
165 code = WhoIsThis(call,tt,&cid);
166 if (code) abort_with (PRPERM);
167 admin = IsAMemberOf(tt,cid,SYSADMINID);
169 /* first verify the id is good */
170 if (aid == 0) abort_with (PRPERM);
173 /* only sysadmin can reuse a group id */
174 if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup)-1))
177 if (FindByID (tt, aid)) abort_with (PRIDEXIST);
179 /* check a few other things */
180 if (!CreateOK (tt, cid, oid, gflag, admin)) abort_with (PRPERM);
182 code = CreateEntry (tt,aname,&aid,1,gflag,oid,cid);
183 if (code != PRSUCCESS) {
187 /* finally, commit transaction */
188 code = ubik_EndTrans(tt);
189 if (code) return code;
194 long PR_NewEntry (call, aname, flag, oid, aid)
195 struct rx_call *call;
196 char aname[PR_MAXNAMELEN];
202 struct ubik_trans *tt;
206 char cname[PR_MAXNAMELEN];
211 if (code) return code;
212 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
213 if (code) return code;
214 code = ubik_SetLock(tt,1,1,LOCKWRITE);
222 /* this is for cross-cell self registration */
223 code = WhoIsThisWithName(call,tt,&cid,cname);
224 if (code != 2) { /* 2 specifies that this is a foreign cell request */
230 admin = IsAMemberOf(tt,cid,SYSADMINID);
232 admin = (!strcmp(aname,cname)) || IsAMemberOf(tt,cid,SYSADMINID);
233 oid = cid = SYSADMINID;
236 code = WhoIsThis(call,tt,&cid);
242 admin = IsAMemberOf(tt,cid,SYSADMINID);
245 if (!CreateOK (tt, cid, oid, flag, admin)) goto perm;
247 code = CreateEntry (tt,aname,aid,0,flag,oid,cid);
248 if (code != PRSUCCESS) goto abort;
250 code = ubik_EndTrans(tt);
251 if (code) return code;
257 PR_WhereIsIt(call,aid,apos)
258 struct rx_call *call;
263 struct ubik_trans *tt;
267 if (code != PRSUCCESS) return code;
268 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
269 if (code) return code;
270 code = ubik_SetLock(tt,1,1,LOCKREAD);
275 temp = FindByID(tt,aid);
281 code = ubik_EndTrans(tt);
282 if (code) return code;
287 PR_DumpEntry(call,apos, aentry)
288 struct rx_call *call;
290 struct prdebugentry *aentry;
293 struct ubik_trans *tt;
296 if (code != PRSUCCESS) return code;
297 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
298 if (code) return code;
299 code = ubik_SetLock(tt,1,1,LOCKREAD);
305 code = pr_ReadEntry(tt, 0, apos, aentry);
306 if (code) goto abort;
308 /* Since prdebugentry is in the form of a prentry not a coentry, we will
309 * return the coentry slots in network order where the string is. */
311 if (aentry->flags & PRCONT) { /* wrong type, get coentry instead */
312 code = pr_ReadCoEntry(tt, 0, apos, aentry);
313 if (code) goto abort;
316 code = ubik_EndTrans(tt);
317 if (code) return code;
321 PR_AddToGroup(call,aid,gid)
322 struct rx_call *call;
327 struct ubik_trans *tt;
330 struct prentry tentry;
331 struct prentry uentry;
335 if (code != PRSUCCESS) return code;
336 if (gid == ANYUSERID || gid == AUTHUSERID) return PRPERM;
337 if (aid == ANONYMOUSID) return PRPERM;
338 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
339 if (code) return code;
340 code = ubik_SetLock(tt,1,1,LOCKWRITE);
345 code = WhoIsThis(call, tt, &cid);
350 tempu = FindByID(tt,aid);
355 bzero(&uentry,sizeof(uentry));
356 code = pr_ReadEntry(tt,0,tempu,&uentry);
361 /* we don't allow groups as members of groups at present */
362 if (uentry.flags & PRGRP) {
366 tempg = FindByID(tt,gid);
371 code = pr_ReadEntry(tt,0,tempg,&tentry);
376 /* make sure that this is a group */
377 if (!(tentry.flags & PRGRP)) {
381 if (!AccessOK (tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY)) {
386 code = AddToEntry (tt, &tentry, tempg, aid);
387 if (code != PRSUCCESS) {
391 /* now, modify the user's entry as well */
392 code = AddToEntry (tt, &uentry, tempu, gid);
393 if (code != PRSUCCESS) {
397 code = ubik_EndTrans(tt);
398 if (code) return code;
402 long PR_NameToID (call, aname, aid)
403 struct rx_call *call;
408 struct ubik_trans *tt;
413 /* must do this first for RPC stub to work */
414 size = aname->namelist_len;
415 if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
416 aid->idlist_val = (long *)malloc(size*sizeof(long));
418 if (aname->namelist_len == 0) return 0;
419 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
422 if (code != PRSUCCESS) return code;
423 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
424 if (code) return code;
425 code = ubik_SetLock(tt,1,1,LOCKREAD);
430 for (i=0;i<aname->namelist_len;i++) {
431 code = NameToID(tt,aname->namelist_val[i],&aid->idlist_val[i]);
432 if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID;
433 if (count++ > 50) IOMGR_Poll(), count = 0;
435 aid->idlist_len = aname->namelist_len;
437 code = ubik_EndTrans(tt);
438 if (code) return code;
442 long PR_IDToName (call, aid, aname)
443 struct rx_call *call;
448 struct ubik_trans *tt;
453 /* leave this first for rpc stub */
454 size = aid->idlist_len;
455 if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
456 aname->namelist_val = (prname *)malloc(size*PR_MAXNAMELEN);
457 aname->namelist_len = 0;
458 if (aid->idlist_len == 0) return 0;
459 if (size == 0) return PRTOOMANY; /* rxgen will probably handle this */
462 if (code != PRSUCCESS) return code;
463 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
464 if (code) return code;
465 code = ubik_SetLock(tt,1,1,LOCKREAD);
470 for (i=0;i<aid->idlist_len;i++) {
471 /* interface won't allow more than PR_MAXLIST to be sent in */
472 code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
473 if (code != PRSUCCESS)
474 sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
475 if (count++ > 50) IOMGR_Poll(), count = 0;
477 aname->namelist_len = aid->idlist_len;
479 code = ubik_EndTrans(tt);
480 if (code) return code;
484 long PR_Delete (call, aid)
485 struct rx_call *call;
489 struct ubik_trans *tt;
491 struct prentry tentry;
496 if (code) return code;
497 if (code != PRSUCCESS) return code;
498 if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID ||
499 aid == ANONYMOUSID) return PRPERM;
500 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
501 if (code) return code;
502 code = ubik_SetLock(tt,1,1,LOCKWRITE);
508 code = WhoIsThis(call,tt,&cid);
514 /* Read in entry to be deleted */
515 loc = FindByID (tt, aid);
516 if (loc == 0) {code = PRNOENT; goto abort;}
517 code = pr_ReadEntry (tt, 0, loc, &tentry);
518 if (code) {code = PRDBFAIL; goto abort;}
520 /* Do some access checking */
521 if (tentry.owner != cid &&
522 !IsAMemberOf (tt, cid, SYSADMINID) &&
523 !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
524 {code = PRPERM; goto abort;}
526 /* Delete each continuation block as a separate transaction so that no one
527 * transaction become to large to complete. */
529 while (nptr != NULL) {
530 struct contentry centry;
533 code = pr_ReadCoEntry(tt, 0, nptr, ¢ry);
534 if (code != 0) {code = PRDBFAIL; goto abort;}
535 for (i=0;i<COSIZE;i++) {
536 if (centry.entries[i] == PRBADID) continue;
537 if (centry.entries[i] == 0) break;
538 code = RemoveFromEntry (tt, aid, centry.entries[i]);
539 if (code) goto abort;
540 tentry.count--; /* maintain count */
541 if ((i&3) == 0) IOMGR_Poll();
543 tentry.next = centry.next; /* thread out this block */
544 code = FreeBlock (tt, nptr); /* free continuation block */
545 if (code) goto abort;
546 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
547 if (code) goto abort;
549 /* end this trans and start a new one */
550 code = ubik_EndTrans(tt);
551 if (code) return code;
552 IOMGR_Poll(); /* just to keep the connection alive */
553 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
554 if (code) return code;
555 code = ubik_SetLock(tt,1,1,LOCKWRITE);
556 if (code) goto abort;
558 /* re-read entry to get consistent uptodate info */
559 loc = FindByID (tt, aid);
560 if (loc == 0) {code = PRNOENT; goto abort;}
561 code = pr_ReadEntry (tt, 0, loc, &tentry);
562 if (code) {code = PRDBFAIL; goto abort;}
567 /* Then move the owned chain, except possibly ourself to the orphan list.
568 * Because this list can be very long and so exceed the size of a ubik
569 * transaction, we start a new transaction every 50 entries. */
572 while (nptr != NULL) {
573 struct prentry nentry;
575 code = pr_ReadEntry (tt, 0, nptr, &nentry);
576 if (code) {code = PRDBFAIL; goto abort;}
577 nptr = tentry.owned = nentry.nextOwned; /* thread out */
579 if (nentry.id != tentry.id) { /* don't add us to orphan chain! */
580 code = AddToOrphan (tt, nentry.id);
581 if (code) goto abort;
583 if ((count & 3) == 0) IOMGR_Poll();
585 if (count < 50) continue;
586 code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
587 if (code) goto abort;
589 /* end this trans and start a new one */
590 code = ubik_EndTrans(tt);
591 if (code) return code;
592 IOMGR_Poll(); /* just to keep the connection alive */
593 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
594 if (code) return code;
595 code = ubik_SetLock(tt,1,1,LOCKWRITE);
596 if (code) goto abort;
598 /* re-read entry to get consistent uptodate info */
599 loc = FindByID (tt, aid);
600 if (loc == 0) {code = PRNOENT; goto abort;}
601 code = pr_ReadEntry (tt, 0, loc, &tentry);
602 if (code) {code = PRDBFAIL; goto abort;}
607 /* now do what's left of the deletion stuff */
608 code = DeleteEntry (tt, &tentry, loc);
609 if (code != PRSUCCESS) {
613 code = ubik_EndTrans(tt);
614 if (code) return code;
618 PR_RemoveFromGroup(call,aid,gid)
619 struct rx_call *call;
624 struct ubik_trans *tt;
627 struct prentry uentry;
628 struct prentry gentry;
632 if (code != PRSUCCESS) return code;
633 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
634 if (code) return code;
635 code = ubik_SetLock(tt,1,1,LOCKWRITE);
640 code = WhoIsThis(call,tt,&cid);
645 tempu = FindByID(tt,aid);
650 tempg = FindByID(tt,gid);
655 bzero(&uentry,sizeof(uentry));
656 bzero(&gentry,sizeof(gentry));
657 code = pr_ReadEntry(tt,0,tempu,&uentry);
662 code = pr_ReadEntry(tt,0,tempg,&gentry);
667 if (!(gentry.flags & PRGRP)) {
671 if (uentry.flags & PRGRP) {
675 if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) {
679 code = RemoveFromEntry(tt,aid,gid);
680 if (code != PRSUCCESS) {
684 code = RemoveFromEntry(tt,gid,aid);
685 if (code != PRSUCCESS) {
689 code = ubik_EndTrans(tt);
690 if (code) return code;
694 long PR_GetCPS (call, aid, alist, over)
695 struct rx_call *call;
701 struct ubik_trans *tt;
704 struct prentry tentry;
706 alist->prlist_len = 0;
707 alist->prlist_val = (long *) 0;
709 if (code != PRSUCCESS) goto done;
710 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
712 code = ubik_SetLock(tt,1,1,LOCKREAD);
719 temp = FindByID (tt, aid);
720 if (!temp) {code = PRNOENT; goto abort;}
721 code = pr_ReadEntry (tt, 0, temp, &tentry);
722 if (code) goto abort;
724 /* afs does authenticate now */
725 code = WhoIsThis (call, tt, &cid);
726 if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) {
731 code = GetList(tt, &tentry, alist, 1);
733 if (code == PRTOOMANY) *over = 1;
734 else if (code != PRSUCCESS) {
739 code = ubik_EndTrans(tt);
742 /* return code, making sure that prlist_val points to malloc'd memory */
743 if (!alist->prlist_val)
744 alist->prlist_val = (long *) malloc(0); /* make xdr stub happy */
748 PR_ListMax(call,uid,gid)
749 struct rx_call *call;
754 struct ubik_trans *tt;
757 if (code != PRSUCCESS) return code;
758 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
759 if (code) return code;
760 code = ubik_SetLock(tt,1,1,LOCKREAD);
765 code = GetMax(tt,uid,gid);
766 if (code != PRSUCCESS) {
770 code = ubik_EndTrans(tt);
771 if (code) return code;
775 PR_SetMax(call,aid,gflag)
776 struct rx_call *call;
781 struct ubik_trans *tt;
785 if (code != PRSUCCESS) return code;
786 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
787 if (code) return code;
788 code = ubik_SetLock(tt,1,1,LOCKWRITE);
793 code = WhoIsThis(call,tt,&cid);
798 if (!AccessOK (tt, cid, 0, 0, 0)) {
802 if (((gflag & PRGRP) && (aid > 0)) ||
803 (!(gflag & PRGRP) && (aid < 0))) {
808 code = SetMax(tt,aid,gflag);
809 if (code != PRSUCCESS) {
814 code = ubik_EndTrans(tt);
815 if (code) return code;
819 PR_ListEntry(call,aid,aentry)
820 struct rx_call *call;
822 struct prcheckentry *aentry;
825 struct ubik_trans *tt;
828 struct prentry tentry;
831 if (code != PRSUCCESS) return code;
832 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
833 if (code) return code;
834 code = ubik_SetLock(tt,1,1,LOCKREAD);
839 code = WhoIsThis(call,tt,&cid);
845 temp = FindByID(tt,aid);
850 code = pr_ReadEntry(tt, 0, temp, &tentry);
855 if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY))
858 aentry->flags = tentry.flags >> PRIVATE_SHIFT;
859 if (aentry->flags == 0)
860 if (tentry.flags & PRGRP)
861 aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
862 else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
863 aentry->owner = tentry.owner;
864 aentry->id = tentry.id;
865 strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
866 aentry->creator = tentry.creator;
867 aentry->ngroups = tentry.ngroups;
868 aentry->nusers = tentry.nusers;
869 aentry->count = tentry.count;
870 bzero (aentry->reserved, sizeof(aentry->reserved));
871 code = ubik_EndTrans(tt);
872 if (code) return code;
876 PR_ChangeEntry(call,aid,name,oid,newid)
877 struct rx_call *call;
884 struct ubik_trans *tt;
890 if (code) return code;
891 if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID ||
892 aid == SYSADMINID) return PRPERM;
893 if (code != PRSUCCESS) return code;
894 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
895 if (code) return code;
896 code = ubik_SetLock(tt,1,1,LOCKWRITE);
901 code = WhoIsThis(call,tt,&cid);
906 pos = FindByID(tt,aid);
911 /* protection check in changeentry */
912 code = ChangeEntry(tt,aid,cid,name,oid,newid);
913 if (code != PRSUCCESS) {
917 code = ubik_EndTrans(tt);
921 PR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
922 struct rx_call *call;
924 long mask; /* specify which fields to update */
925 long flags, ngroups, nusers;
929 struct ubik_trans *tt;
932 struct prentry tentry;
935 if (mask == 0) return 0; /* no-op */
937 if (code) return code;
938 if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
940 if (code != PRSUCCESS) return code;
941 code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
942 if (code) return code;
943 code = ubik_SetLock(tt,1,1,LOCKWRITE);
949 code = WhoIsThis(call,tt,&cid);
955 pos = FindByID(tt,id);
960 code = pr_ReadEntry (tt, 0, pos, &tentry);
961 if (code) goto abort;
962 tflags = tentry.flags;
964 if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
965 if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
966 if ((tflags & PRQUOTA) == 0) { /* default if only setting one */
967 tentry.ngroups = tentry.nusers = 20;
970 if (!AccessOK (tt, cid, &tentry, 0, 0)) goto perm;
973 if (mask & 0xffff) { /* if setting flag bits */
974 long flagsMask = mask & 0xffff;
975 tflags &= ~(flagsMask << PRIVATE_SHIFT);
976 tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
980 if (mask & PR_SF_NGROUPS) { /* setting group limit */
981 if (ngroups < 0) {code = PRBADARG; goto abort;}
982 tentry.ngroups = ngroups;
986 if (mask & PR_SF_NUSERS) { /* setting foreign user limit */
987 if (nusers < 0) {code = PRBADARG; goto abort;}
988 tentry.nusers = nusers;
991 tentry.flags = tflags;
993 code = pr_WriteEntry (tt, 0, pos, &tentry);
994 if (code) goto abort;
996 code = ubik_EndTrans(tt);
1000 long PR_ListElements (call, aid, alist, over)
1001 struct rx_call *call;
1007 struct ubik_trans *tt;
1010 struct prentry tentry;
1012 alist->prlist_len = 0;
1013 alist->prlist_val = (long *) 0;
1016 if (code != PRSUCCESS) goto done;
1017 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1018 if (code) goto done;
1019 code = ubik_SetLock(tt,1,1,LOCKREAD);
1022 ubik_AbortTrans(tt);
1025 code = WhoIsThis(call,tt,&cid);
1029 ubik_AbortTrans(tt);
1033 temp = FindByID(tt,aid);
1034 if (!temp) {code = PRNOENT; goto abort;}
1035 code = pr_ReadEntry (tt, 0, temp, &tentry);
1036 if (code) goto abort;
1037 if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1040 code = GetList (tt, &tentry, alist, 0);
1042 if (code == PRTOOMANY) *over = 1;
1043 else if (code != PRSUCCESS) goto abort;
1045 code = ubik_EndTrans(tt);
1048 if (!alist->prlist_val)
1049 alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1053 /* List the entries owned by this id. If the id is zero return the orphans
1056 PR_ListOwned (call, aid, alist, over)
1057 struct rx_call *call;
1063 struct ubik_trans *tt;
1065 struct prentry tentry;
1068 alist->prlist_len = 0;
1069 alist->prlist_val = (long *) 0;
1072 if (code != PRSUCCESS) goto done;
1073 code = ubik_BeginTransReadAny(dbase,UBIK_READTRANS,&tt);
1074 if (code) goto done;
1075 code = ubik_SetLock(tt,1,1,LOCKREAD);
1078 ubik_AbortTrans(tt);
1081 code = WhoIsThis(call,tt,&cid);
1085 ubik_AbortTrans(tt);
1090 long loc = FindByID (tt, aid);
1091 if (loc == 0) { code = PRNOENT; goto abort; }
1092 code = pr_ReadEntry (tt, 0, loc, &tentry);
1093 if (code) goto abort;
1095 if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY)) goto perm;
1096 head = tentry.owned;
1098 if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
1099 head = ntohl(cheader.orphan);
1102 code = GetOwnedChain (tt, head, alist);
1104 if (code == PRTOOMANY) *over = 1;
1105 else if (code) goto abort;
1107 code = ubik_EndTrans(tt);
1110 if (!alist->prlist_val)
1111 alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1115 PR_IsAMemberOf(call,uid,gid,flag)
1116 struct rx_call *call;
1122 struct ubik_trans *tt;
1125 if (code != PRSUCCESS) return code;
1126 code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
1127 if (code) return code;
1128 code = ubik_SetLock(tt,1,1,LOCKREAD);
1131 ubik_AbortTrans(tt);
1135 long uloc = FindByID (tt, uid);
1136 long gloc = FindByID (tt, gid);
1137 struct prentry uentry, gentry;
1139 if (!uloc || !gloc) {
1143 code = WhoIsThis(call, tt, &cid);
1149 code = pr_ReadEntry (tt, 0, uloc, &uentry);
1150 if (code) goto abort;
1151 code = pr_ReadEntry (tt, 0, gloc, &gentry);
1152 if (code) goto abort;
1153 if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) {
1157 if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1158 !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1162 *flag = IsAMemberOf(tt,uid,gid);
1163 code = ubik_EndTrans(tt);
1173 if (isupper(tc)) *s = tolower(tc);
1178 #if defined(CROSS_CELL) && !defined(WhoIsThisWithName)
1179 static long WhoIsThisWithName(acall, at, aid, aname)
1180 struct rx_call *acall;
1181 struct ubik_trans *at;
1185 /* aid is set to the identity of the caller, if known, else ANONYMOUSID */
1186 /* returns -1 and sets aid to ANONYMOUSID on any failure */
1188 register struct rx_connection *tconn;
1190 char tcell[MAXKTCREALMLEN];
1191 char name[MAXKTCNAMELEN];
1192 char inst[MAXKTCNAMELEN];
1200 tconn = rx_ConnectionOf(acall);
1201 code = rx_SecurityClassOf(tconn);
1202 if (code == 0) return 0;
1203 else if (code == 1) { /* vab class */
1204 goto done; /* no longer supported */
1206 else if (code == 2) { /* kad class */
1209 extern char *pr_realmName;
1211 if (code = rxkad_GetServerInfo
1212 (acall->conn, (long *)0, 0 /*was &exp*/,
1213 name, inst, tcell, (long *)0))
1215 strncpy (vname, name, sizeof(vname));
1216 if (ilen = strlen (inst)) {
1217 if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
1218 strcat (vname, ".");
1219 strcat (vname, inst);
1221 if (clen = strlen (tcell)) {
1222 if (!afsconf_LocalRealm(prdir, tcell)) {
1223 if (strlen(vname) + 1 + clen >= sizeof(vname)) goto done;
1225 strcat(vname,tcell);
1226 lcstring(vname, vname, sizeof(vname));
1227 code = NameToID(at,vname,aid);
1228 strcpy(aname,vname);
1233 if (strcmp (AUTH_SUPERUSER, vname) == 0)
1234 /* special case for the fileserver */
1237 lcstring(vname, vname, sizeof(vname));
1238 code = NameToID(at,vname,aid);
1242 if (code && !pr_noAuth) return -1;