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