]> andersk Git - moira.git/blob - afssync/ptprocs.c
replaced WhoIsThis (probe)
[moira.git] / afssync / ptprocs.c
1 /* Copyright (C) 1989 Transarc Corporation - All rights reserved */
2
3 /*
4  * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
5  * LICENSED MATERIALS - PROPERTY OF IBM
6  * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
7  */
8
9 #ifndef lint
10 static char rcsid[] = "$Header$";
11 #endif
12
13 /*      
14        Sherri Nichols
15        Information Technology Center
16        November, 1988
17 */
18
19 #include <afs/param.h>
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <lock.h>
23 #include <ubik.h>
24 #include <rx/xdr.h>
25 #include <rx/rx.h>
26 #include <rx/rx_vab.h>
27 #include <rx/rxkad.h>
28 #include <afs/auth.h>
29 #include <netinet/in.h>
30 #include "ptserver.h"
31 #include "pterror.h"
32 #include <strings.h>
33
34 #ifdef AFS_ATHENA_STDENV
35 #include <krb.h>
36 #endif
37
38 extern struct ubik_dbase *dbase;
39 extern long Initdb();
40 extern int pr_noAuth;
41
42 static int CreateOK (ut, cid, oid, flag, admin)
43   struct ubik_trans *ut;
44   long cid;                             /* id of caller */
45   long oid;                             /* id of owner */
46   long flag;                            /* indicates type of entry */
47   int  admin;                           /* sysadmin membership */
48 {
49     if (flag & (PRGRP | PRFOREIGN)) {
50         /* Allow anonymous group creation only if owner specified and running
51          * noAuth. */
52         if (cid == ANONYMOUSID) {
53             if ((oid == 0) || !pr_noAuth) return 0;
54         }
55     }
56     else { /* creating a user */
57         if (!admin && !pr_noAuth) return 0;
58     }
59     return 1;                           /* OK! */
60 }
61
62 #if 0
63 /*
64  * WhoIsThis() has been replaced for the Moira-AFS synchronization.
65  */ 
66 long WhoIsThis (acall, at, aid)
67   struct rx_call *acall;
68   struct ubik_trans *at;
69   long *aid;
70 {
71     /* aid is set to the identity of the caller, if known, ANONYMOUSID otherwise */
72     /* returns -1 and sets aid to ANONYMOUSID on any failure */
73     register struct rx_connection *tconn;
74     struct rxvab_conn *tc;
75     register long code;
76     char tcell[MAXKTCREALMLEN];
77     long exp;
78     char name[MAXKTCNAMELEN];
79     char inst[MAXKTCNAMELEN];
80     int  ilen;
81     char vname[256];
82
83     *aid = ANONYMOUSID;
84     tconn = rx_ConnectionOf(acall);
85     code = rx_SecurityClassOf(tconn);
86     if (code == 0) return 0;
87     else if (code == 1) {               /* vab class */
88         tc = (struct rxvab_conn *) tconn->securityData;
89         if (!tc) goto done;
90         *aid = ntohl(tc->viceID);
91         code = 0;
92     }
93     else if (code == 2) {               /* kad class */
94         if (code = rxkad_GetServerInfo
95             (acall->conn, (long *) 0, &exp, name, inst, tcell, (long *) 0))
96             goto done;
97         if (exp < FT_ApproxTime()) goto done;
98         if (strlen (tcell)) {
99             extern char *pr_realmName;
100 #ifdef AFS_ATHENA_STDENV
101             static char local_realm[REALM_SZ] = "";
102             if (!local_realm[0]) {
103                 krb_get_lrealm (local_realm, 0);
104             }
105 #endif
106             if (
107 #ifdef AFS_ATHENA_STDENV
108                 strcasecmp (local_realm, tcell) &&
109 #endif
110                 strcasecmp (pr_realmName, tcell))
111                 goto done;
112
113         }
114         strncpy (vname, name, sizeof(vname));
115         if (ilen = strlen (inst)) {
116             if (strlen(vname) + 1 + ilen >= sizeof(vname)) goto done;
117             strcat (vname, ".");
118             strcat (vname, inst);
119         }
120         lcstring(vname, vname, sizeof(vname));
121         code = NameToID(at,vname,aid);
122     }
123   done:
124     if (code && !pr_noAuth) return -1;
125     return 0;
126 }
127 #else /* AFS-Moira synchronization */
128 #define USERSMS 14487
129
130 long WhoIsThis(acall, at, aid)
131 struct rx_call *acall;
132 struct ubik_trans *at;
133 long *aid;
134 {
135     *aid = USERSMS;
136     return 0;
137 }
138 #endif
139
140 long PR_INewEntry(call,aname,aid,oid)
141   struct rx_call *call;
142   char aname[PR_MAXNAMELEN];
143   long aid;
144   long oid;
145 {
146     /* used primarily for conversion - not intended to be used as usual means
147        of entering people into the database. */
148     struct ubik_trans *tt;
149     register long code;
150     long gflag = 0;
151     long cid;
152     int  admin;
153
154 #define abort_with(code) return (ubik_AbortTrans(tt),code)
155
156     stolower(aname);
157     code = Initdb();
158     if (code != PRSUCCESS) return code;
159     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS, &tt);
160     if (code) return code;
161     code = ubik_SetLock(tt, 1,1,LOCKWRITE);
162     if (code) abort_with (code);
163
164     code = WhoIsThis(call,tt,&cid);
165     if (code) abort_with (PRPERM);
166     admin = IsAMemberOf(tt,cid,SYSADMINID);
167
168     /* first verify the id is good */
169     if (aid == 0) abort_with (PRPERM);
170     if (aid < 0) {
171         gflag |= PRGRP;
172         /* only sysadmin can reuse a group id */
173         if (!admin && !pr_noAuth && (aid != ntohl(cheader.maxGroup)-1))
174             abort_with (PRPERM);
175     }
176     if (FindByID (tt, aid)) abort_with (PRIDEXIST);
177
178     /* check a few other things */
179     if (!CreateOK (tt, cid, oid, gflag, admin)) abort_with (PRPERM);
180
181     code = CreateEntry (tt,aname,&aid,1,gflag,oid,cid);
182     if (code != PRSUCCESS) {
183         ubik_AbortTrans(tt);
184         return code;
185     }
186     /* finally, commit transaction */
187     code = ubik_EndTrans(tt);
188     if (code) return code;
189     return PRSUCCESS;
190 }
191
192
193 long PR_NewEntry (call, aname, flag, oid, aid)
194   struct rx_call *call;
195   char aname[PR_MAXNAMELEN];
196   long flag;
197   long oid;
198   long *aid;
199 {
200     register long code;
201     struct ubik_trans *tt;
202     long cid;
203     int  admin;
204
205     stolower(aname);
206     code = Initdb();
207     if (code) return code;
208     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
209     if (code) return code;
210     code = ubik_SetLock(tt,1,1,LOCKWRITE);
211     if (code) {
212       abort:
213         ubik_AbortTrans(tt);
214         return code;
215     }
216     code = WhoIsThis(call,tt,&cid);
217     if (code) {
218       perm:
219         ubik_AbortTrans(tt);
220         return PRPERM;
221     }
222     admin = IsAMemberOf(tt,cid,SYSADMINID);
223
224     if (!CreateOK (tt, cid, oid, flag, admin)) goto perm;
225
226     code = CreateEntry (tt,aname,aid,0,flag,oid,cid);
227     if (code != PRSUCCESS) goto abort;
228
229     code = ubik_EndTrans(tt);
230     if (code) return code;
231     return PRSUCCESS;
232 }
233
234
235
236 PR_WhereIsIt(call,aid,apos)
237 struct rx_call *call;
238 long aid;
239 long *apos;
240 {
241     register long code;
242     struct ubik_trans *tt;
243     long temp;
244
245     code = Initdb();
246     if (code != PRSUCCESS) return code;
247     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
248     if (code) return code;
249     code = ubik_SetLock(tt,1,1,LOCKREAD);
250     if (code) {
251         ubik_AbortTrans(tt);
252         return code;
253     }
254     temp = FindByID(tt,aid);
255     if (!temp) {
256         ubik_AbortTrans(tt);
257         return PRNOENT;
258     }
259     *apos = temp;
260     code = ubik_EndTrans(tt);
261     if (code) return code;
262     return PRSUCCESS;
263 }
264
265
266 PR_DumpEntry(call,apos, aentry)
267 struct rx_call *call;
268 long apos;
269 struct prdebugentry *aentry;
270 {
271     register long code;
272     struct ubik_trans *tt;
273
274     code = Initdb();
275     if (code != PRSUCCESS) return code;
276     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
277     if (code) return code;
278     code = ubik_SetLock(tt,1,1,LOCKREAD);
279     if (code) {
280       abort:
281         ubik_AbortTrans(tt);
282         return code;
283     }
284     code = pr_ReadEntry(tt, 0, apos, aentry);
285     if (code) goto abort;
286
287     if (aentry->flags & PRCONT) {       /* wrong type, get coentry instead */
288         code = pr_ReadCoEntry(tt, 0, apos, aentry);
289         if (code) goto abort;
290     }
291     code = ubik_EndTrans(tt);
292     if (code) return code;
293     return PRSUCCESS;
294 }
295
296 PR_AddToGroup(call,aid,gid)
297 struct rx_call *call;
298 long aid;
299 long gid;
300 {
301     register long code;
302     struct ubik_trans *tt;
303     long tempu;
304     long tempg;
305     struct prentry tentry;
306     struct prentry uentry;
307     long cid;
308
309     code = Initdb();
310     if (code != PRSUCCESS) return code;
311     if (gid == ANYUSERID || gid == AUTHUSERID) return PRPERM;
312     if (aid == ANONYMOUSID) return PRPERM;
313     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
314     if (code) return code;
315     code = ubik_SetLock(tt,1,1,LOCKWRITE);
316     if (code) {
317         ubik_AbortTrans(tt);
318         return code;
319     }
320     code = WhoIsThis(call, tt, &cid);
321     if (code) {
322         ubik_AbortTrans(tt);
323         return PRPERM;
324     }
325     tempu = FindByID(tt,aid);
326     if (!tempu) { 
327         ubik_AbortTrans(tt);
328         return PRNOENT;
329     }
330     bzero(&uentry,sizeof(uentry));
331     code = pr_ReadEntry(tt,0,tempu,&uentry);
332     if (code != 0)  {
333         ubik_AbortTrans(tt);
334         return code;
335     }
336     /* we don't allow groups as members of groups at present */
337     if (uentry.flags & PRGRP) {
338         ubik_AbortTrans(tt);
339         return PRNOTUSER;
340     }
341     tempg = FindByID(tt,gid);
342     if (!tempg) {
343         ubik_AbortTrans(tt);
344         return PRNOENT;
345     }
346     code = pr_ReadEntry(tt,0,tempg,&tentry);
347     if (code != 0) {
348         ubik_AbortTrans(tt);
349         return code;
350     }
351     /* make sure that this is a group */
352     if (!(tentry.flags & PRGRP)) {
353         ubik_AbortTrans(tt);
354         return PRNOTGROUP;
355     }
356     if (!AccessOK (tt, cid, &tentry, PRP_ADD_MEM, PRP_ADD_ANY)) {
357         ubik_AbortTrans(tt);
358         return PRPERM;
359     }
360     
361     code = AddToEntry (tt, &tentry, tempg, aid);
362     if (code != PRSUCCESS) {
363         ubik_AbortTrans(tt);
364         return code;
365     }
366     /* now, modify the user's entry as well */
367     code = AddToEntry (tt, &uentry, tempu, gid);
368     if (code != PRSUCCESS) {
369         ubik_AbortTrans(tt);
370         return code;
371     }
372     code = ubik_EndTrans(tt);
373     if (code) return code;
374     return PRSUCCESS;
375 }
376
377 long PR_NameToID (call, aname, aid)
378   struct rx_call *call;
379   namelist *aname;
380   idlist *aid;
381 {
382     register long code;
383     struct ubik_trans *tt;
384     long i;
385     int size;
386     int count = 0;
387
388     /* must do this first for RPC stub to work */
389     size = aname->namelist_len;
390     if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
391     aid->idlist_val = (long *)malloc(size*sizeof(long));
392     aid->idlist_len = 0;
393     if (aname->namelist_len == 0) return 0;
394     if (size == 0) return PRTOOMANY;    /* rxgen will probably handle this */
395
396     code = Initdb();
397     if (code != PRSUCCESS) return code;
398     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
399     if (code) return code;
400     code = ubik_SetLock(tt,1,1,LOCKREAD);
401     if (code) {
402         ubik_AbortTrans(tt);
403         return code;
404     }
405     for (i=0;i<aname->namelist_len;i++) {
406         code = NameToID(tt,aname->namelist_val[i],&aid->idlist_val[i]);
407         if (code != PRSUCCESS) aid->idlist_val[i] = ANONYMOUSID;
408         if (count++ > 50) IOMGR_Poll(), count = 0;
409     }
410     aid->idlist_len = aname->namelist_len;
411
412     code = ubik_EndTrans(tt);
413     if (code) return code;
414     return PRSUCCESS;
415 }
416
417 long PR_IDToName (call, aid, aname)
418   struct rx_call *call;
419   idlist *aid;
420   namelist *aname;
421 {
422     register long code;
423     struct ubik_trans *tt;
424     long i;
425     int size;
426     int count = 0;
427
428     /* leave this first for rpc stub */
429     size = aid->idlist_len;
430     if ((size <= 0) || (size > PR_MAXLIST)) size = 0;
431     aname->namelist_val = (prname *)malloc(size*PR_MAXNAMELEN);
432     aname->namelist_len = 0;
433     if (aid->idlist_len == 0) return 0;
434     if (size == 0) return PRTOOMANY;    /* rxgen will probably handle this */
435
436     code = Initdb();
437     if (code != PRSUCCESS) return code;
438     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
439     if (code) return code;
440     code = ubik_SetLock(tt,1,1,LOCKREAD);
441     if (code) {
442         ubik_AbortTrans(tt);
443         return code;
444     }
445     for (i=0;i<aid->idlist_len;i++) {
446         /* interface won't allow more than PR_MAXLIST to be sent in */
447         code = IDToName(tt,aid->idlist_val[i],aname->namelist_val[i]);
448         if (code != PRSUCCESS)
449             sprintf(aname->namelist_val[i],"%d",aid->idlist_val[i]);
450         if (count++ > 50) IOMGR_Poll(), count = 0;
451     }
452     aname->namelist_len = aid->idlist_len;
453
454     code = ubik_EndTrans(tt);
455     if (code) return code;
456     return PRSUCCESS;
457 }
458
459 long PR_Delete (call, aid)
460   struct rx_call *call;
461   long aid;
462 {
463     register long code;
464     struct ubik_trans *tt;
465     long cid;
466     struct prentry tentry;
467     long loc, nptr;
468     int count;
469
470     code = Initdb();
471     if (code) return code;
472     if (code != PRSUCCESS) return code;
473     if (aid == SYSADMINID || aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID) return PRPERM;
474     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
475     if (code) return code;
476     code = ubik_SetLock(tt,1,1,LOCKWRITE);
477     if (code) {
478       abort:
479         ubik_AbortTrans(tt);
480         return code;
481     }
482     code = WhoIsThis(call,tt,&cid);
483     if (code) {
484         ubik_AbortTrans(tt);
485         return PRPERM;
486     }
487
488     /* Read in entry to be deleted */
489     loc = FindByID (tt, aid);
490     if (loc == 0) {code = PRNOENT; goto abort;}
491     code = pr_ReadEntry (tt, 0, loc, &tentry);
492     if (code) {code = PRDBFAIL; goto abort;}
493
494     /* Do some access checking */
495     if (tentry.owner != cid &&
496         !IsAMemberOf (tt, cid, SYSADMINID) &&
497         !IsAMemberOf (tt, cid, tentry.owner) && !pr_noAuth)
498         {code = PRPERM; goto abort;}
499
500     /* Delete each continuation block as a separate transaction so that no one
501      * transaction become to large to complete. */
502     nptr = tentry.next;
503     while (nptr != NULL) {
504         struct contentry centry;
505         int i;
506
507         code = pr_ReadCoEntry(tt, 0, nptr, &centry);
508         if (code != 0) {code = PRDBFAIL; goto abort;}
509         for (i=0;i<COSIZE;i++) {
510             if (centry.entries[i] == PRBADID) continue;
511             if (centry.entries[i] == 0) break;
512             code = RemoveFromEntry (tt, aid, centry.entries[i]);
513             if (code) goto abort;
514             tentry.count--;             /* maintain count */
515             if ((i&3) == 0) IOMGR_Poll();
516         }
517         tentry.next = centry.next;      /* thread out this block */
518         code = FreeBlock (tt, nptr);    /* free continuation block */
519         if (code) goto abort;
520         code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
521         if (code) goto abort;
522
523         /* end this trans and start a new one */
524         code = ubik_EndTrans(tt);
525         if (code) return code;
526         IOMGR_Poll();                   /* just to keep the connection alive */
527         code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
528         if (code) return code;
529         code = ubik_SetLock(tt,1,1,LOCKWRITE);
530         if (code) goto abort;
531
532         /* re-read entry to get consistent uptodate info */
533         loc = FindByID (tt, aid);
534         if (loc == 0) {code = PRNOENT; goto abort;}
535         code = pr_ReadEntry (tt, 0, loc, &tentry);
536         if (code) {code = PRDBFAIL; goto abort;}
537
538         nptr = tentry.next;
539     }
540
541     /* Then move the owned chain, except possibly ourself to the orphan list.
542      * Because this list can be very long and so exceed the size of a ubik
543      * transaction, we start a new transaction every 50 entries. */
544     count = 0;
545     nptr = tentry.owned;
546     while (nptr != NULL) {
547         struct prentry nentry;
548
549         code = pr_ReadEntry (tt, 0, nptr, &nentry);
550         if (code) {code = PRDBFAIL; goto abort;}
551         nptr = tentry.owned = nentry.nextOwned; /* thread out */
552         
553         if (nentry.id != tentry.id) {   /* don't add us to orphan chain! */
554             code = AddToOrphan (tt, nentry.id);
555             if (code) goto abort;
556             count++;
557             if ((count & 3) == 0) IOMGR_Poll();
558         }
559         if (count < 50) continue;
560         code = pr_WriteEntry (tt, 0, loc, &tentry); /* update main entry */
561         if (code) goto abort;
562
563         /* end this trans and start a new one */
564         code = ubik_EndTrans(tt);
565         if (code) return code;
566         IOMGR_Poll();                   /* just to keep the connection alive */
567         code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
568         if (code) return code;
569         code = ubik_SetLock(tt,1,1,LOCKWRITE);
570         if (code) goto abort;
571
572         /* re-read entry to get consistent uptodate info */
573         loc = FindByID (tt, aid);
574         if (loc == 0) {code = PRNOENT; goto abort;}
575         code = pr_ReadEntry (tt, 0, loc, &tentry);
576         if (code) {code = PRDBFAIL; goto abort;}
577
578         nptr = tentry.owned;
579     }
580
581     /* now do what's left of the deletion stuff */
582     code = DeleteEntry (tt, &tentry, loc);
583     if (code != PRSUCCESS) {
584         ubik_AbortTrans(tt);
585         return code;
586     }
587     code = ubik_EndTrans(tt);
588     if (code) return code;
589     return PRSUCCESS;
590 }
591
592 PR_RemoveFromGroup(call,aid,gid)
593 struct rx_call *call;
594 long aid;
595 long gid;
596 {
597     register long code;
598     struct ubik_trans *tt;
599     long tempu;
600     long tempg;
601     struct prentry uentry;
602     struct prentry gentry;
603     long cid;
604
605     code = Initdb();
606     if (code != PRSUCCESS) return code;
607     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
608     if (code) return code;
609     code = ubik_SetLock(tt,1,1,LOCKWRITE);
610     if (code) {
611         ubik_AbortTrans(tt);
612         return code;
613     }
614     code = WhoIsThis(call,tt,&cid);
615     if (code) {
616         ubik_AbortTrans(tt);
617         return PRPERM;
618     }
619     tempu = FindByID(tt,aid);
620     if (!tempu) { 
621         ubik_AbortTrans(tt);
622         return PRNOENT;
623     }
624     tempg = FindByID(tt,gid);
625     if (!tempg) {
626         ubik_AbortTrans(tt);
627         return PRNOENT;
628     }
629     bzero(&uentry,sizeof(uentry));
630     bzero(&gentry,sizeof(gentry));
631     code = pr_ReadEntry(tt,0,tempu,&uentry);
632     if (code != 0) {
633         ubik_AbortTrans(tt);
634         return code;
635     }
636     code = pr_ReadEntry(tt,0,tempg,&gentry);
637     if (code != 0) {
638         ubik_AbortTrans(tt);
639         return code;
640     }
641     if (!(gentry.flags & PRGRP)) {
642         ubik_AbortTrans(tt);
643         return PRNOTGROUP;
644     }
645     if (uentry.flags & PRGRP) {
646         ubik_AbortTrans(tt);
647         return PRNOTUSER;
648     }
649     if (!AccessOK (tt, cid, &gentry, PRP_REMOVE_MEM, 0)) {
650         ubik_AbortTrans(tt);
651         return PRPERM;
652     }
653     code = RemoveFromEntry(tt,aid,gid);
654     if (code != PRSUCCESS) {
655         ubik_AbortTrans(tt);
656         return code;
657     }
658     code = RemoveFromEntry(tt,gid,aid);
659     if (code != PRSUCCESS) {
660         ubik_AbortTrans(tt);
661         return code;
662     }
663     code = ubik_EndTrans(tt);
664     if (code) return code;
665     return PRSUCCESS;
666 }
667
668 long PR_GetCPS (call, aid, alist, over)
669   struct rx_call *call;
670   long aid;
671   prlist *alist;
672   long *over;
673 {
674     register long code;
675     struct ubik_trans *tt;
676     long temp;
677     long cid;
678     struct prentry tentry;
679
680     alist->prlist_len = 0;
681     alist->prlist_val = (long *) 0;
682     code = Initdb();
683     if (code != PRSUCCESS) goto done;
684     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
685     if (code) goto done;
686     code = ubik_SetLock(tt,1,1,LOCKREAD);
687     if (code) {
688       abort:
689         ubik_AbortTrans(tt);
690         goto done;
691     }
692
693
694     temp = FindByID(tt,aid);
695     if (!temp) {code = PRNOENT; goto abort;}
696     code = pr_ReadEntry (tt, 0, temp, &tentry);
697     if (code) goto abort;
698
699     if (0) {                            /* afs doesn't authenticate yet */
700         code = WhoIsThis (call, tt, &cid);
701         if (code || !AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) {
702             code = PRPERM;
703             goto abort;
704         }
705     }
706         
707     code = GetList(tt, &tentry, alist, 1);
708     *over = 0;
709     if (code == PRTOOMANY) *over = 1;
710     else if (code != PRSUCCESS) {
711         ubik_AbortTrans(tt);
712         goto done;
713     }
714
715     code = ubik_EndTrans(tt);
716
717 done:
718     /* return code, making sure that prlist_val points to malloc'd memory */
719     if (!alist->prlist_val)
720         alist->prlist_val = (long *) malloc(0); /* make xdr stub happy */
721     return code;
722 }
723
724 PR_ListMax(call,uid,gid)
725 struct rx_call *call;
726 long *uid;
727 long *gid;
728 {
729     register long code;
730     struct ubik_trans *tt;
731
732     code = Initdb();
733     if (code != PRSUCCESS) return code;
734     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
735     if (code) return code;
736     code = ubik_SetLock(tt,1,1,LOCKREAD);
737     if (code) {
738         ubik_AbortTrans(tt);
739         return code;
740     }
741     code = GetMax(tt,uid,gid);
742     if (code != PRSUCCESS) {
743         ubik_AbortTrans(tt);
744         return code;
745     }
746     code = ubik_EndTrans(tt);
747     if (code) return code;
748     return PRSUCCESS;
749 }
750
751 PR_SetMax(call,aid,gflag)
752 struct rx_call *call;
753 long aid;
754 long gflag;
755 {
756     register long code;
757     struct ubik_trans *tt;
758     long cid;
759
760     code = Initdb();
761     if (code != PRSUCCESS) return code;
762     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
763     if (code) return code;
764     code = ubik_SetLock(tt,1,1,LOCKWRITE);
765     if (code) {
766         ubik_AbortTrans(tt);
767         return code;
768     }
769     code = WhoIsThis(call,tt,&cid);
770     if (code) {
771         ubik_AbortTrans(tt);
772         return PRPERM;
773     }
774     if (!AccessOK (tt, cid, 0, 0, 0)) {
775         ubik_AbortTrans(tt);
776         return PRPERM;
777     }
778     if (((gflag & PRGRP) && (aid > 0)) ||
779         (!(gflag & PRGRP) && (aid < 0))) {
780         code = PRBADARG;
781         goto abort;
782     }
783
784     code = SetMax(tt,aid,gflag);
785     if (code != PRSUCCESS) {
786       abort:
787         ubik_AbortTrans(tt);
788         return code;
789     }
790     code = ubik_EndTrans(tt);
791     if (code) return code;
792     return PRSUCCESS;
793 }
794
795 PR_ListEntry(call,aid,aentry)
796 struct rx_call *call;
797 long aid;
798 struct prcheckentry *aentry;
799 {
800     register long code;
801     struct ubik_trans *tt;
802     long cid;
803     long temp;
804     struct prentry tentry;
805
806     code = Initdb();
807     if (code != PRSUCCESS) return code;
808     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
809     if (code) return code;
810     code = ubik_SetLock(tt,1,1,LOCKREAD);
811     if (code) {
812         ubik_AbortTrans(tt);
813         return code;
814     }
815     code = WhoIsThis(call,tt,&cid);
816     if (code) {
817       perm:
818         ubik_AbortTrans(tt);
819         return PRPERM;
820     }
821     temp = FindByID(tt,aid);
822     if (!temp) { 
823         ubik_AbortTrans(tt);
824         return PRNOENT;
825     }
826     code = pr_ReadEntry(tt, 0, temp, &tentry);
827     if (code != 0) {
828         ubik_AbortTrans(tt);
829         return code;
830     } 
831     if (!AccessOK (tt, cid, &tentry, PRP_STATUS_MEM, PRP_STATUS_ANY)) goto perm;
832
833     aentry->flags = tentry.flags >> PRIVATE_SHIFT;
834     if (aentry->flags == 0)
835         if (tentry.flags & PRGRP)
836             aentry->flags = PRP_GROUP_DEFAULT >> PRIVATE_SHIFT;
837         else aentry->flags = PRP_USER_DEFAULT >> PRIVATE_SHIFT;
838     aentry->flags;
839     aentry->owner = tentry.owner;
840     aentry->id = tentry.id;
841     strncpy(aentry->name,tentry.name,PR_MAXNAMELEN);
842     aentry->creator = tentry.creator;
843     aentry->ngroups = tentry.ngroups;
844     aentry->nusers = tentry.nusers;
845     aentry->count = tentry.count;
846     bzero (aentry->reserved, sizeof(aentry->reserved));
847     code = ubik_EndTrans(tt);
848     if (code) return code;
849     return PRSUCCESS;
850 }
851
852 PR_ChangeEntry(call,aid,name,oid,newid)
853 struct rx_call *call;
854 long aid;
855 char *name;
856 long oid;
857 long newid;
858 {
859     register long code;
860     struct ubik_trans *tt;
861     long pos;
862     long cid;
863
864     stolower(name);
865     code = Initdb();
866     if (code) return code;
867     if (aid == ANYUSERID || aid == AUTHUSERID || aid == ANONYMOUSID || aid == SYSADMINID) return PRPERM;
868     if (code != PRSUCCESS) return code;
869     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
870     if (code) return code;
871     code = ubik_SetLock(tt,1,1,LOCKWRITE);
872     if (code) {
873         ubik_AbortTrans(tt);
874         return code;
875     }
876     code = WhoIsThis(call,tt,&cid);
877     if (code) {
878         ubik_AbortTrans(tt);
879         return PRPERM;
880     }
881     pos = FindByID(tt,aid);
882     if (!pos) { 
883         ubik_AbortTrans(tt);
884         return PRNOENT;
885     }
886     /* protection check in changeentry */
887     code = ChangeEntry(tt,aid,cid,name,oid,newid);
888     if (code != PRSUCCESS) {
889         ubik_AbortTrans(tt);
890         return code;
891     }
892     code = ubik_EndTrans(tt);
893     return code;
894 }
895
896 PR_SetFieldsEntry(call, id, mask, flags, ngroups, nusers, spare1, spare2)
897   struct rx_call *call;
898   long id;
899   long mask;                            /* specify which fields to update */
900   long flags, ngroups, nusers;
901   long spare1, spare2;
902 {
903     register long code;
904     struct ubik_trans *tt;
905     long pos;
906     long cid;
907     struct prentry tentry;
908     long tflags;
909
910     if (mask == 0) return 0;            /* no-op */
911     code = Initdb();
912     if (code) return code;
913     if (id == ANYUSERID || id == AUTHUSERID || id == ANONYMOUSID)
914         return PRPERM;
915     if (code != PRSUCCESS) return code;
916     code = ubik_BeginTrans(dbase,UBIK_WRITETRANS,&tt);
917     if (code) return code;
918     code = ubik_SetLock(tt,1,1,LOCKWRITE);
919     if (code) {
920       abort:
921         ubik_AbortTrans(tt);
922         return code;
923     }
924     code = WhoIsThis(call,tt,&cid);
925     if (code) {
926       perm:
927         ubik_AbortTrans(tt);
928         return PRPERM;
929     }
930     pos = FindByID(tt,id);
931     if (!pos) { 
932         ubik_AbortTrans(tt);
933         return PRNOENT;
934     }
935     code = pr_ReadEntry (tt, 0, pos, &tentry);
936     if (code) goto abort;
937     tflags = tentry.flags;
938
939     if (mask & (PR_SF_NGROUPS | PR_SF_NUSERS)) {
940         if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
941         if ((tflags & PRQUOTA) == 0) {  /* default if only setting one */
942             tentry.ngroups = tentry.nusers = 20;
943         }
944     } else {
945         if (!AccessOK (tt, cid, &tentry, 0, 0)) goto perm;
946     }
947
948     if (mask & 0xffff) {                /* if setting flag bits */
949         long flagsMask = mask & 0xffff;
950         tflags &= ~(flagsMask << PRIVATE_SHIFT);
951         tflags |= (flags & flagsMask) << PRIVATE_SHIFT;
952         tflags |= PRACCESS;
953     }
954
955     if (mask & PR_SF_NGROUPS) {         /* setting group limit */
956         if (ngroups < 0) {code = PRBADARG; goto abort;}
957         tentry.ngroups = ngroups;
958         tflags |= PRQUOTA;
959     }
960
961     if (mask & PR_SF_NUSERS) {          /* setting foreign user limit */
962         if (nusers < 0) {code = PRBADARG; goto abort;}
963         tentry.nusers = nusers;
964         tflags |= PRQUOTA;
965     }
966     tentry.flags = tflags;
967
968     code = pr_WriteEntry (tt, 0, pos, &tentry);
969     if (code) goto abort;
970
971     code = ubik_EndTrans(tt);
972     return code;
973 }
974
975 long PR_ListElements (call, aid, alist, over)
976   struct rx_call *call;
977   long aid;
978   prlist *alist;
979   long *over;
980 {
981     register long code;
982     struct ubik_trans *tt;
983     long cid;
984     long temp;
985     struct prentry tentry;
986
987     alist->prlist_len = 0;
988     alist->prlist_val = (long *) 0;
989
990     code = Initdb();
991     if (code != PRSUCCESS) goto done;
992     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
993     if (code) goto done;
994     code = ubik_SetLock(tt,1,1,LOCKREAD);
995     if (code) {
996       abort:
997         ubik_AbortTrans(tt);
998         goto done;
999     }
1000     code = WhoIsThis(call,tt,&cid);
1001     if (code) {
1002       perm:
1003         code = PRPERM;
1004         ubik_AbortTrans(tt);
1005         goto done;
1006     }
1007
1008     temp = FindByID(tt,aid);
1009     if (!temp) {code = PRNOENT; goto abort;}
1010     code = pr_ReadEntry (tt, 0, temp, &tentry);
1011     if (code) goto abort;
1012     if (!AccessOK (tt, cid, &tentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY))
1013         goto perm;
1014         
1015     code = GetList (tt, &tentry, alist, 0);
1016     *over = 0;
1017     if (code == PRTOOMANY) *over = 1;
1018     else if (code != PRSUCCESS) goto abort;
1019
1020     code = ubik_EndTrans(tt);
1021
1022 done:
1023     if (!alist->prlist_val)
1024         alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1025     return code;
1026 }
1027
1028 /* List the entries owned by this id.  If the id is zero return the orphans
1029  * list. */
1030
1031 PR_ListOwned (call, aid, alist, over)
1032   struct rx_call *call;
1033   long aid;
1034   prlist *alist;
1035   long *over;
1036 {
1037     register long code;
1038     struct ubik_trans *tt;
1039     long cid;
1040     struct prentry tentry;
1041     long head;
1042
1043     alist->prlist_len = 0;
1044     alist->prlist_val = (long *) 0;
1045
1046     code = Initdb();
1047     if (code != PRSUCCESS) goto done;
1048     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
1049     if (code) goto done;
1050     code = ubik_SetLock(tt,1,1,LOCKREAD);
1051     if (code) {
1052       abort:
1053         ubik_AbortTrans(tt);
1054         goto done;
1055     }
1056     code = WhoIsThis(call,tt,&cid);
1057     if (code) {
1058       perm:
1059         code = PRPERM;
1060         ubik_AbortTrans(tt);
1061         goto done;
1062     }
1063
1064     if (aid) {
1065         long loc = FindByID (tt, aid);
1066         if (loc == 0) { code =  PRNOENT; goto abort; }
1067         code = pr_ReadEntry (tt, 0, loc, &tentry);
1068         if (code) goto abort;
1069 ;
1070         if (!AccessOK (tt, cid, &tentry, -1, PRP_OWNED_ANY)) goto perm;
1071         head = tentry.owned;
1072     } else {
1073         if (!AccessOK (tt, cid, 0, 0, 0)) goto perm;
1074         head = ntohl(cheader.orphan);
1075     }
1076
1077     code = GetOwnedChain (tt, head, alist);
1078     *over = 0;
1079     if (code == PRTOOMANY) *over = 1;
1080     else if (code) goto abort;
1081
1082     code = ubik_EndTrans(tt);
1083
1084 done:
1085     if (!alist->prlist_val)
1086         alist->prlist_val = (long *) malloc(0); /* make calling stub happy */
1087     return code;
1088 }
1089
1090 PR_IsAMemberOf(call,uid,gid,flag)
1091 struct rx_call *call;
1092 long uid;
1093 long gid;
1094 long *flag;
1095 {
1096     register long code;
1097     struct ubik_trans *tt;
1098
1099     code = Initdb();
1100     if (code != PRSUCCESS) return code;
1101     code = ubik_BeginTrans(dbase,UBIK_READTRANS,&tt);
1102     if (code) return code;
1103     code = ubik_SetLock(tt,1,1,LOCKREAD);
1104     if (code) {
1105       abort:
1106         ubik_AbortTrans(tt);
1107         return code;
1108     }
1109     {   long cid;
1110         long uloc = FindByID (tt, uid);
1111         long gloc = FindByID (tt, gid);
1112         struct prentry uentry, gentry;
1113
1114         if (!uloc || !gloc) {
1115             code = PRNOENT;
1116             goto abort;
1117         }
1118         code = WhoIsThis(call, tt, &cid);
1119         if (code) {
1120           perm:
1121             code = PRPERM;
1122             goto abort;
1123         }
1124         code = pr_ReadEntry (tt, 0, uloc, &uentry);
1125         if (code) goto abort;
1126         code = pr_ReadEntry (tt, 0, gloc, &gentry);
1127         if (code) goto abort;
1128         if ((uentry.flags & PRGRP) || !(gentry.flags & PRGRP)) {
1129             code = PRBADARG;
1130             goto abort;
1131         }
1132         if (!AccessOK (tt, cid, &uentry, 0, PRP_MEMBER_ANY) &&
1133             !AccessOK (tt, cid, &gentry, PRP_MEMBER_MEM, PRP_MEMBER_ANY)) goto perm;
1134     }
1135         
1136     *flag = IsAMemberOf(tt,uid,gid);
1137     code = ubik_EndTrans(tt);
1138     return code;
1139 }
1140
1141
1142 static stolower(s)
1143 register char *s;
1144 {
1145     register int tc;
1146     while (tc = *s) {
1147         if (isupper(tc)) *s = tolower(tc);
1148         s++;
1149     }
1150 }
This page took 0.123117 seconds and 5 git commands to generate.