]> andersk Git - moira.git/blob - afssync/utils.c
have WhoIsThis always return system:administrators
[moira.git] / afssync / utils.c
1 /* $Header$ */
2 /* $Source$ */
3
4
5 /*
6  * P_R_P_Q_# (C) COPYRIGHT IBM CORPORATION 1988
7  * LICENSED MATERIALS - PROPERTY OF IBM
8  * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
9  */
10
11 /*      
12        Sherri Nichols
13        Information Technology Center
14        November, 1988
15
16        Modified May, 1989 by Jeff Schiller to keep disk file in
17        network byte order
18
19 */
20
21
22 #include <sys/types.h>
23 #include <lock.h>
24 #include <ubik.h>
25 #include <stdio.h>
26 #include <netinet/in.h>
27 #include <netdb.h>
28 #include <rx/xdr.h>
29 #include <rx/rx.h>
30 #include <rx/rx_vab.h>
31 #include "print.h"
32 #include "prserver.h"
33 #include "prerror.h"
34
35 extern struct prheader cheader;
36 extern struct ubik_dbase *dbase;
37
38 long IDHash(x)
39 long x;
40 {
41     /* returns hash bucket for x */
42     return ((abs(x)) % HASHSIZE);
43 }
44
45 long NameHash(aname)
46 register unsigned char *aname;
47 {
48     /* returns hash bucket for aname */
49     register unsigned int hash=0;
50     register int i;
51 /* stolen directly from the HashString function in the vol package */
52     for (i=strlen(aname),aname += i-1;i--;aname--)
53         hash = (hash*31) + (*aname-31);
54     return(hash % HASHSIZE);
55 }
56
57
58 long pr_Write(tt,afd,pos,buff,len)
59 struct ubik_trans *tt;
60 long afd;
61 long pos;
62 char *buff;
63 long len;
64 {
65     /* package up seek and write into one procedure for ease of use */
66     long code;
67     code = ubik_Seek(tt,afd,pos);
68     if (code) return code;
69     code = ubik_Write(tt,buff,len);
70     return code;
71 }
72
73 long pr_Read(tt,afd,pos,buff,len)
74 struct ubik_trans *tt;
75 long afd;
76 long pos;
77 char *buff;
78 long len;
79 {
80     /* same thing for read */
81     long code;
82     code = ubik_Seek(tt,afd,pos);
83     if (code) return code;
84     code = ubik_Read(tt,buff,len);
85     return code;
86 }
87
88 pr_WriteEntry(tt, afd, pos, tentry)
89 struct ubik_trans *tt;
90 long afd;
91 long pos;
92 struct prentry *tentry;
93 {
94     long code;
95     register long i;
96     struct prentry nentry;
97     if (ntohl(1) != 1) {        /* Need to swap bytes. */
98       nentry.flags = htonl(tentry->flags);
99       nentry.id = htonl(tentry->id);
100       nentry.cellid = htonl(tentry->cellid);
101       nentry.next = htonl(tentry->next);
102       nentry.nextID = htonl(tentry->nextID);
103       nentry.nextName = htonl(tentry->nextName);
104       nentry.owner = htonl(tentry->owner);
105       nentry.creator = htonl(tentry->creator);
106       nentry.ngroups = htonl(tentry->ngroups);
107       nentry.nusers = htonl(tentry->nusers);
108       nentry.count = htonl(tentry->count);
109       nentry.instance = htonl(tentry->instance);
110       nentry.owned = htonl(tentry->owned);
111       nentry.nextOwned = htonl(tentry->nextOwned);
112       nentry.parent = htonl(tentry->parent);
113       nentry.sibling = htonl(tentry->sibling);
114       nentry.child = htonl(tentry->child);
115       strncpy(nentry.name, tentry->name, PR_MAXNAMELEN);
116       for (i = 0; i < PRSIZE; i++)
117         nentry.entries[i] = htonl(tentry->entries[i]);
118       code = ubik_Seek(tt, afd, pos);
119       if (code) return (code);
120       code = ubik_Write(tt, (char *) &nentry, sizeof(struct prentry));
121       return(code);
122     } else {
123       code = ubik_Seek(tt, afd, pos);
124       if (code) return (code);
125       code = ubik_Write(tt, (char *) tentry, sizeof(struct prentry));
126       return(code);
127     }
128 }
129
130 pr_ReadEntry(tt, afd, pos, tentry)
131 struct ubik_trans *tt;
132 long afd;
133 long pos;
134 struct prentry *tentry;
135 {
136     long code;
137     register long i;
138     struct prentry nentry;
139     code = ubik_Seek(tt, afd, pos);
140     if (code) return (code);
141     if (ntohl(1) == 1) {        /* no swapping needed */
142       code = ubik_Read(tt, (char *) tentry, sizeof(struct prentry));
143       return(code);
144     }
145     code = ubik_Read(tt, (char *) &nentry, sizeof(struct prentry));
146     if (code) return (code);
147     tentry->flags = ntohl(nentry.flags);
148     tentry->id = ntohl(nentry.id);
149     tentry->cellid = ntohl(nentry.cellid);
150     tentry->next = ntohl(nentry.next);
151     tentry->nextID = ntohl(nentry.nextID);
152     tentry->nextName = ntohl(nentry.nextName);
153     tentry->owner = ntohl(nentry.owner);
154     tentry->creator = ntohl(nentry.creator);
155     tentry->ngroups = ntohl(nentry.ngroups);
156     tentry->nusers = ntohl(nentry.nusers);
157     tentry->count = ntohl(nentry.count);
158     tentry->instance = ntohl(nentry.instance);
159     tentry->owned = ntohl(nentry.owned);
160     tentry->nextOwned = ntohl(nentry.nextOwned);
161     tentry->parent = ntohl(nentry.parent);
162     tentry->sibling = ntohl(nentry.sibling);
163     tentry->child = ntohl(nentry.child);
164     strncpy(tentry->name, nentry.name, PR_MAXNAMELEN);
165     for (i = 0; i < PRSIZE; i++)
166       tentry->entries[i] = ntohl(nentry.entries[i]);
167     return(code);
168 }
169
170 pr_WriteCoEntry(tt, afd, pos, tentry)
171 struct ubik_trans *tt;
172 long afd;
173 long pos;
174 struct contentry *tentry;
175 {
176     long code;
177     register long i;
178     struct contentry nentry;
179     if (ntohl(1) == 1) {        /* No need to swap */
180       code = ubik_Seek(tt, afd, pos);
181       if (code) return(code);
182       code = ubik_Write(tt, (char *) tentry, sizeof(struct contentry));
183       return(code);
184     }
185     nentry.flags = htonl(tentry->flags);
186     nentry.id = htonl(tentry->id);
187     nentry.cellid = htonl(tentry->cellid);
188     nentry.next = htonl(tentry->next);
189     for (i = 0; i < COSIZE; i++)
190       nentry.entries[i] = htonl(tentry->entries[i]);
191     code = ubik_Seek(tt, afd, pos);
192     if (code) return (code);
193     code = ubik_Write(tt, (char *) &nentry, sizeof(struct contentry));
194     return(code);
195 }
196
197 pr_ReadCoEntry(tt, afd, pos, tentry)
198 struct ubik_trans *tt;
199 long afd;
200 long pos;
201 struct contentry *tentry;
202 {
203     long code;
204     register long i;
205     struct contentry nentry;
206     code = ubik_Seek(tt, afd, pos);
207     if (code) return (code);
208     if (ntohl(1) == 1) {        /* No swapping needed. */
209       code = ubik_Read(tt, (char *) tentry, sizeof(struct contentry));
210       return(code);
211     }
212     code = ubik_Read(tt, (char *) &nentry, sizeof(struct contentry));
213     if (code) return (code);
214     tentry->flags = ntohl(nentry.flags);
215     tentry->id = ntohl(nentry.id);
216     tentry->cellid = ntohl(nentry.cellid);
217     tentry->next = ntohl(nentry.next);
218     for (i = 0; i < COSIZE; i++)
219       tentry->entries[i] = ntohl(nentry.entries[i]);
220     return(code);
221 }
222
223 long AllocBlock(at)
224 register struct ubik_trans *at;
225 {
226     /* allocate a free block of storage for entry, returning address of new entry  */
227     register long code;
228     long temp;
229     struct prentry tentry;
230
231     if (cheader.freePtr) {
232         /* allocate this dude */
233         temp = ntohl(cheader.freePtr);      
234         code = pr_ReadEntry(at, 0, temp, &tentry);
235         if (code) return 0;
236         cheader.freePtr = htonl(tentry.next);
237         code = pr_Write(at, 0, 8, (char *)&cheader.freePtr, sizeof(cheader.freePtr));
238         if (code != 0) return 0;
239         return temp;
240     }
241     else {
242         /* hosed, nothing on free list, grow file */
243         temp = ntohl(cheader.eofPtr);   /* remember this guy */
244         cheader.eofPtr = htonl(temp + ENTRYSIZE);
245         code = pr_Write(at, 0, 12,(char *) &cheader.eofPtr, sizeof(cheader.eofPtr));
246         if (code != 0) return 0;
247         return temp;
248     }
249 }
250
251 long FreeBlock(at, pos)
252 register struct ubik_trans *at;
253 long pos;
254 {
255     /* add a block of storage to the free list */
256     register long code;
257     struct prentry tentry;
258
259     bzero(&tentry,sizeof(tentry));
260     tentry.next = ntohl(cheader.freePtr);
261     tentry.flags |= PRFREE;
262     cheader.freePtr = htonl(pos);
263     code = pr_Write(at,0,8, (char *) &cheader.freePtr,sizeof(cheader.freePtr));
264     if (code != 0) return code;
265     code = pr_WriteEntry(at,0,pos,&tentry);
266     if (code != 0) return code;
267     return PRSUCCESS;
268 }
269
270 long FindByID(at,aid)
271 register struct ubik_trans *at;
272 long aid;
273 {
274     /* returns address of entry if found, 0 otherwise */
275     register long code;
276     long i;
277     struct prentry tentry;
278     long entry;
279
280     i = IDHash(aid);
281     entry = ntohl(cheader.idHash[i]);
282     if (entry == 0) return entry;
283     bzero(&tentry,sizeof(tentry));
284     code = pr_ReadEntry(at, 0, entry, &tentry);
285     if (code != 0) return 0;
286     if (aid == tentry.id) return entry;
287     entry = tentry.nextID;
288     while (entry != NULL) {
289         bzero(&tentry,sizeof(tentry));
290         code = pr_ReadEntry(at,0,entry,&tentry);
291         if (code != 0) return 0;
292         if (aid == tentry.id) return entry;
293         entry = tentry.nextID;
294     }
295     return 0;
296 }
297  
298
299
300 long FindByName(at,aname)    
301 register struct ubik_trans *at;
302 char aname[PR_MAXNAMELEN];
303 {
304     /* ditto */
305     register long code;
306     long i;
307     struct prentry tentry;
308     long entry;
309
310     i = NameHash(aname);
311     entry = ntohl(cheader.nameHash[i]);
312     if (entry == 0) return entry;
313     bzero(&tentry,sizeof(tentry));
314     code = pr_ReadEntry(at, 0, entry,&tentry);
315     if (code != 0) return 0;
316     if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry;
317     entry = tentry.nextName;
318     while (entry != NULL) {
319         bzero(&tentry,sizeof(tentry));
320         code = pr_ReadEntry(at,0,entry,&tentry);
321         if (code != 0) return 0;
322         if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry;
323         entry = tentry.nextName;
324     }
325     return 0;
326 }
327
328 long AllocID(at,flag,aid)
329 register struct ubik_trans *at;
330 long flag;
331 long *aid;
332 {
333     /* allocs an id from the proper area of address space, based on flag */
334     register long code = 1;
335     register long i = 0;
336     register maxcount = 50;  /* to prevent infinite loops */
337     
338     if (flag & PRGRP) {
339         *aid = ntohl(cheader.maxGroup);
340         while (code && i<maxcount) {
341             --(*aid);
342             code = FindByID(at,*aid);
343             i++;
344         }
345         if (code) return PRNOIDS;
346         cheader.maxGroup = htonl(*aid);
347         code = pr_Write(at,0,16,(char *)&cheader.maxGroup,sizeof(cheader.maxGroup));
348         if (code) return PRDBFAIL;
349         return PRSUCCESS;
350     }
351     else if (flag & PRFOREIGN) {
352         *aid = ntohl(cheader.maxForeign);
353         while (code && i<maxcount) {
354             ++(*aid);
355             code = FindByID(at,*aid);
356             i++;
357         }
358         if (code) return PRNOIDS;
359         cheader.maxForeign = htonl(*aid);
360         code = pr_Write(at,0,24,(char *)&cheader.maxForeign,sizeof(cheader.maxForeign));
361         if (code) return PRDBFAIL;
362         return PRSUCCESS;
363     }
364     else {
365         *aid = ntohl(cheader.maxID);
366         while (code && i<maxcount) {
367             ++(*aid);
368             code = FindByID(at,*aid);
369             i++;
370         }
371         if (code) return PRNOIDS;
372         cheader.maxID = htonl(*aid);
373         code = pr_Write(at,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
374         if (code) return PRDBFAIL;
375         return PRSUCCESS;
376     }
377 }
378
379 long IDCmp(a,b)
380 long *a;
381 long *b;
382 {
383     /* used to sort CPS's so that comparison with acl's is easier */
384     if (*a > *b) return 1;
385     if (*a == *b) return 0;
386     if (*a < *b) return -1;
387 }
388
389 long RemoveFromIDHash(tt,aid,loc)
390 struct ubik_trans *tt;
391 long aid;
392 long *loc;
393 {
394     /* remove entry designated by aid from id hash table */
395     register long code;
396     long current, trail, i;
397     struct prentry tentry;
398     struct prentry bentry;
399
400     i = IDHash(aid);
401     current = ntohl(cheader.idHash[i]);
402     bzero(&tentry,sizeof(tentry));
403     bzero(&bentry,sizeof(bentry));
404     trail = 0;
405     if (current == NULL) return PRNOENT;
406     code = pr_ReadEntry(tt,0,current,&tentry);
407     if (code) return PRDBFAIL;
408     while (aid != tentry.id) {
409         trail = current;
410         current = tentry.nextID;
411         if (current == NULL) break;
412         code = pr_ReadEntry(tt,0,current,&tentry);
413         if (code) return PRDBFAIL;
414     }
415     if (current == NULL) return PRNOENT;  /* we didn't find him */
416     if (trail == NULL) {
417         /* it's the first entry! */
418         cheader.idHash[i] = htonl(tentry.nextID);
419         code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i]));
420         if (code) return PRDBFAIL;
421     }
422     else {
423         code = pr_ReadEntry(tt,0,trail, &bentry);
424         if (code) return PRDBFAIL;
425         bentry.nextID = tentry.nextID;
426         code = pr_WriteEntry(tt,0,trail,&bentry);
427     }
428     *loc = current;
429     return PRSUCCESS;
430 }
431
432 long AddToIDHash(tt, aid, loc)
433 struct ubik_trans *tt;
434 long aid;
435 long loc;
436 {
437     /* add entry at loc designated by aid to id hash table */
438     register long code;
439     long i;
440     struct prentry tentry;
441
442     i = IDHash(aid);
443     bzero(&tentry,sizeof(tentry));
444     code = pr_ReadEntry(tt,0,loc,&tentry);
445     if (code) return PRDBFAIL;
446     tentry.nextID = ntohl(cheader.idHash[i]);
447     cheader.idHash[i] = htonl(loc);
448     code = pr_WriteEntry(tt,0,loc,&tentry);
449     if (code) return PRDBFAIL;
450     code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i]));
451     if (code) return PRDBFAIL;
452     return PRSUCCESS;
453 }
454
455 long RemoveFromNameHash(tt,aname,loc)
456 struct ubik_trans *tt;
457 char *aname;
458 long *loc;
459 {
460     /* remove from name hash */
461     register long code;
462     long current, trail, i;
463     struct prentry tentry;
464     struct prentry bentry;
465
466     i = NameHash(aname);
467     current = ntohl(cheader.nameHash[i]);
468     bzero(&tentry,sizeof(tentry));
469     bzero(&bentry,sizeof(bentry));
470     trail = 0;
471     if (current == NULL) return PRNOENT;
472     code = pr_ReadEntry(tt,0,current,&tentry);
473     if (code) return PRDBFAIL;
474     while (strcmp(aname,tentry.name)) {
475         trail = current;
476         current = tentry.nextName;
477         if (current == NULL) break;
478         code = pr_ReadEntry(tt,0,current,&tentry);
479         if (code) return PRDBFAIL;
480     }
481     if (current == NULL) return PRNOENT;  /* we dnamen't find him */
482     if (trail == NULL) {
483         /* it's the first entry! */
484         cheader.nameHash[i] = htonl(tentry.nextName);
485         code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i]));
486         if (code) return PRDBFAIL;
487     }
488     else {
489         code = pr_ReadEntry(tt,0,trail, &bentry);
490         if (code) return PRDBFAIL;
491         bentry.nextName = tentry.nextName;
492         code = pr_WriteEntry(tt,0,trail,&bentry);
493     }
494     *loc = current;
495     return PRSUCCESS;
496 }
497
498 long AddToNameHash(tt, aname, loc)
499 struct ubik_trans *tt;
500 char *aname;
501 long loc;
502 {
503     /* add to name hash */
504     register long code;
505     long i;
506     struct prentry tentry;
507
508     i = NameHash(aname);
509     bzero(&tentry,sizeof(tentry));
510     code = pr_ReadEntry(tt,0,loc,&tentry);
511     if (code) return PRDBFAIL;
512     tentry.nextName = ntohl(cheader.nameHash[i]);
513     cheader.nameHash[i] = htonl(loc);
514     code = pr_WriteEntry(tt,0,loc,&tentry);
515     if (code) return PRDBFAIL;
516     code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i]));
517     if (code) return PRDBFAIL;
518     return PRSUCCESS;
519 }
520
521 long AddToOwnerChain(at,gid,oid)
522 struct ubik_trans *at;
523 long gid;
524 long oid;
525 {
526     /* add entry designated by gid to owner chain of entry designated by oid */
527     register long code;
528     long loc;
529     long gloc;
530     struct prentry tentry;
531     struct prentry gentry;
532
533     loc = FindByID(at,oid);
534     if (!loc) return PRNOENT;
535     code = pr_ReadEntry(at,0,loc,&tentry);
536     if (code != 0) return PRDBFAIL;
537     gloc = FindByID(at,gid);
538     code = pr_ReadEntry(at,0,gloc,&gentry);
539     if (code != 0) return PRDBFAIL;
540     gentry.nextOwned = tentry.owned;
541     tentry.owned = gloc;
542     code = pr_WriteEntry(at,0,loc,&tentry);
543     if (code != 0) return PRDBFAIL;
544     code = pr_WriteEntry(at,0,gloc,&gentry);
545     if (code != 0) return PRDBFAIL;
546     return PRSUCCESS;
547 }
548
549 long RemoveFromOwnerChain(at,gid,oid)
550 struct ubik_trans *at;
551 long gid;
552 long oid;
553 {
554     /* remove gid from owner chain for oid */
555     register long code;
556     long nptr;
557     struct prentry tentry;
558     struct prentry bentry;
559     long loc;
560
561     loc = FindByID(at,oid);
562     if (!loc) return PRNOENT;
563     code = pr_ReadEntry(at,0,loc,&tentry);
564     if (code != 0) return PRDBFAIL;
565     if (!tentry.owned) return PRNOENT;
566     nptr = tentry.owned;
567     bcopy(&tentry,&bentry,sizeof(tentry));
568     while (nptr != NULL) {
569         code = pr_ReadEntry(at,0,nptr,&tentry);
570         if (code != 0) return PRDBFAIL;
571         if (tentry.id == gid) {
572             /* found it */
573             if (nptr == bentry.owned) /* modifying first of chain */
574                 bentry.owned = tentry.nextOwned;
575             else bentry.nextOwned = tentry.nextOwned;
576             tentry.nextOwned = 0;
577             code = pr_WriteEntry(at,0,loc,&bentry);
578             if (code != 0) return PRDBFAIL;
579             code = pr_WriteEntry(at,0,nptr,&tentry);
580             if (code != 0) return PRDBFAIL;
581             return PRSUCCESS;
582         }
583         loc = nptr;
584         nptr = tentry.nextOwned;
585         bcopy(&tentry,&bentry,sizeof(tentry));
586     }
587     return PRNOENT;
588 }
589
590 long AddToOrphan(at,gid)
591 struct ubik_trans *at;
592 long gid;
593 {
594     /* add gid to orphan list, as it's owner has died */
595     register long code;
596     long loc;
597     struct prentry tentry;
598
599     loc = FindByID(at,gid);
600     if (!loc) return PRNOENT;
601     code = pr_ReadEntry(at,0,loc,&tentry);
602     if (code != 0) return PRDBFAIL;
603     tentry.nextOwned = ntohl(cheader.orphan);
604     cheader.orphan = htonl(loc);
605     code = pr_WriteEntry(at,0,loc,&tentry);
606     if (code != 0) return PRDBFAIL;
607     code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan));
608     if (code != 0) return PRDBFAIL;
609     return PRSUCCESS;
610 }
611
612 long RemoveFromOrphan(at,gid)
613 struct ubik_trans *at;
614 long gid;
615 {
616     /* remove gid from the orphan list */
617     register long code;
618     long loc;
619     long nptr;
620     struct prentry tentry;
621     struct prentry bentry;
622
623     loc = FindByID(at,gid);
624     if (!loc) return PRNOENT;
625     code = pr_ReadEntry(at,0,loc,&tentry);
626     if (code != 0) return PRDBFAIL;
627     if (cheader.orphan == htonl(loc)) {
628         cheader.orphan = htonl(tentry.nextOwned);
629         tentry.nextOwned = 0;
630         code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan));
631         if (code != 0) return PRDBFAIL;
632         code = pr_WriteEntry(at,0,loc,&tentry);
633         if (code != 0) return PRDBFAIL;
634         return PRSUCCESS;
635     }
636     nptr = ntohl(cheader.orphan);
637     bzero(&bentry,sizeof(bentry));
638     loc = 0;
639     while (nptr != NULL) {
640         code = pr_ReadEntry(at,0,nptr,&tentry);
641         if (code != 0) return PRDBFAIL;
642         if (gid == tentry.id) {
643             /* found it */
644             bentry.nextOwned = tentry.nextOwned;
645             tentry.nextOwned = 0;
646             code = pr_WriteEntry(at,0,loc,&bentry);
647             if (code != 0) return PRDBFAIL;
648             code = pr_WriteEntry(at,0,nptr,&tentry);
649             if (code != 0) return PRDBFAIL;
650             return PRSUCCESS;
651         }
652         loc = nptr;
653         nptr = tentry.nextOwned;
654         bcopy(&tentry,&bentry,sizeof(tentry));
655     }
656     return PRNOENT;
657 }
658
659 long IsOwnerOf(at,aid,gid)
660 struct ubik_trans *at;
661 long aid;
662 long gid;
663 {
664     /* returns 1 if aid is the owner of gid, 0 otherwise */
665     register long code;
666     struct prentry tentry;
667     long loc;
668
669     loc = FindByID(at,gid);
670     if (!loc) return 0;
671     code = pr_ReadEntry(at,0,loc,&tentry);
672     if (code != 0) return 0;
673     if (tentry.owner == aid) return 1;
674     return 0;
675 }
676
677 long OwnerOf(at,gid)
678 struct ubik_trans *at;
679 long gid;
680 {
681     /* returns the owner of gid */
682     register long code;
683     long loc;
684     struct prentry tentry;
685
686     loc = FindByID(at,gid);
687     if (!loc) return 0;
688     code = pr_ReadEntry(at,0,loc,&tentry);
689     if (code != 0) return 0;
690     return tentry.owner;
691 }
692     
693
694 long WhoIsThis(acall, at, aid)
695 struct rx_call *acall;
696 struct ubik_trans *at;
697 long *aid;
698 {
699     *aid = SYSADMINID;
700     return 0;
701 }
702
703 long IsAMemberOf(at,aid,gid)
704 struct ubik_trans *at;
705 long aid;
706 long gid;
707 {
708     /* returns true if aid is a member of gid */
709     struct prentry tentry;
710     struct contentry centry;
711     register long code;
712     long i;
713     long loc;
714
715     loc = FindByID(at,gid);
716     if (!loc) return 0;
717     bzero(&tentry,sizeof(tentry));
718     code = pr_ReadEntry(at, 0, loc,&tentry);
719     if (code) return 0;
720     if (!(tentry.flags & PRGRP)) return 0;
721     for (i= 0;i<PRSIZE;i++) {
722         if (tentry.entries[i] == aid) return 1;
723         if (tentry.entries[i] == 0) return 0;
724     }
725     if (tentry.next) {
726         loc = tentry.next;
727         while (loc) {
728             bzero(&centry,sizeof(centry));
729             code = pr_ReadCoEntry(at,0,loc,&centry);
730             if (code) return 0;
731             for (i=0;i<COSIZE;i++) {
732                 if (centry.entries[i] == aid) return 1;
733                 if (centry.entries[i] == 0) return 0;
734             }
735             loc = centry.next;
736         }
737     }
738     return 0;  /* actually, should never get here */
739 }
This page took 0.091814 seconds and 5 git commands to generate.