]> andersk Git - moira.git/blame - afssync/utils.c
Update illegal characters and log something when one is found.
[moira.git] / afssync / utils.c
CommitLineData
dba0cf81 1/* Copyright (C) 1989 Transarc Corporation - All rights reserved */
e1f001e5 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
dba0cf81 8#ifndef lint
9static char rcsid[] = "$Header$";
10#endif
11
e1f001e5 12/*
13 Sherri Nichols
14 Information Technology Center
15 November, 1988
16
dba0cf81 17
e1f001e5 18 Modified May, 1989 by Jeff Schiller to keep disk file in
19 network byte order
20
21*/
22
d81c5086 23#include <afs/param.h>
e1f001e5 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>
dba0cf81 30#include "ptserver.h"
31#include "pterror.h"
e1f001e5 32
33long IDHash(x)
34long x;
35{
36 /* returns hash bucket for x */
37 return ((abs(x)) % HASHSIZE);
38}
39
40long NameHash(aname)
41register 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
53long pr_Write(tt,afd,pos,buff,len)
54struct ubik_trans *tt;
55long afd;
56long pos;
57char *buff;
58long len;
59{
60 /* package up seek and write into one procedure for ease of use */
61 long code;
dba0cf81 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 }
e1f001e5 66 code = ubik_Seek(tt,afd,pos);
67 if (code) return code;
68 code = ubik_Write(tt,buff,len);
69 return code;
70}
71
72long pr_Read(tt,afd,pos,buff,len)
73struct ubik_trans *tt;
74long afd;
75long pos;
76char *buff;
77long 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
87pr_WriteEntry(tt, afd, pos, tentry)
88struct ubik_trans *tt;
89long afd;
90long pos;
91struct prentry *tentry;
92{
93 long code;
94 register long i;
95 struct prentry nentry;
dba0cf81 96
e1f001e5 97 if (ntohl(1) != 1) { /* Need to swap bytes. */
dba0cf81 98 bzero (&nentry, sizeof(nentry)); /* make sure reseved fields are zero */
e1f001e5 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);
dba0cf81 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
e1f001e5 123 for (i = 0; i < PRSIZE; i++)
124 nentry.entries[i] = htonl(tentry->entries[i]);
dba0cf81 125 tentry = &nentry;
e1f001e5 126 }
dba0cf81 127 code = pr_Write (tt, afd, pos, (char *)tentry, sizeof(struct prentry));
128 return(code);
e1f001e5 129}
dba0cf81 130
e1f001e5 131pr_ReadEntry(tt, afd, pos, tentry)
132struct ubik_trans *tt;
133long afd;
134long pos;
135struct 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);
dba0cf81 148 bzero (tentry, sizeof(*tentry)); /* make sure reseved fields are zero */
e1f001e5 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);
dba0cf81 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
e1f001e5 173 for (i = 0; i < PRSIZE; i++)
174 tentry->entries[i] = ntohl(nentry.entries[i]);
175 return(code);
176}
177
178pr_WriteCoEntry(tt, afd, pos, tentry)
dba0cf81 179 struct ubik_trans *tt;
180 long afd;
181 long pos;
182 struct contentry *tentry;
e1f001e5 183{
184 long code;
185 register long i;
186 struct contentry nentry;
dba0cf81 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;
e1f001e5 197 }
dba0cf81 198 code = pr_Write (tt, afd, pos, (char *)tentry, sizeof(struct contentry));
e1f001e5 199 return(code);
200}
201
202pr_ReadCoEntry(tt, afd, pos, tentry)
203struct ubik_trans *tt;
204long afd;
205long pos;
206struct 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);
dba0cf81 219 bzero (tentry, sizeof(*tentry)); /* make reseved fields zero */
e1f001e5 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
dba0cf81 229/* AllocBloc - allocate a free block of storage for entry, returning address of
230 * new entry */
231
e1f001e5 232long AllocBlock(at)
dba0cf81 233 register struct ubik_trans *at;
e1f001e5 234{
e1f001e5 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
259long FreeBlock(at, pos)
260register struct ubik_trans *at;
261long 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
278long FindByID(at,aid)
279register struct ubik_trans *at;
280long 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
dba0cf81 288 if ((aid == PRBADID) || (aid == 0)) return 0;
e1f001e5 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
309long FindByName(at,aname)
310register struct ubik_trans *at;
311char 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
337long AllocID(at,flag,aid)
338register struct ubik_trans *at;
339long flag;
340long *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
dba0cf81 388long 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
405long NameToID(at, aname, aid)
406register struct ubik_trans *at;
407char aname[PR_MAXNAMELEN];
408long *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
e1f001e5 422long IDCmp(a,b)
423long *a;
424long *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
432long RemoveFromIDHash(tt,aid,loc)
433struct ubik_trans *tt;
434long aid;
dba0cf81 435long *loc; /* ??? in case ID hashed twice ??? */
e1f001e5 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
dba0cf81 443 if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT;
e1f001e5 444 i = IDHash(aid);
445 current = ntohl(cheader.idHash[i]);
446 bzero(&tentry,sizeof(tentry));
447 bzero(&bentry,sizeof(bentry));
448 trail = 0;
dba0cf81 449 if (current == NULL) return PRSUCCESS; /* already gone */
e1f001e5 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 }
dba0cf81 459 if (current == NULL) return PRSUCCESS; /* we didn't find him, so he's already gone */
e1f001e5 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
476long AddToIDHash(tt, aid, loc)
477struct ubik_trans *tt;
478long aid;
dba0cf81 479long loc; /* ??? */
e1f001e5 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
dba0cf81 486 if ((aid == PRBADID) || (aid == 0)) return PRINCONSISTENT;
e1f001e5 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
500long RemoveFromNameHash(tt,aname,loc)
501struct ubik_trans *tt;
502char *aname;
503long *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;
dba0cf81 516 if (current == NULL) return PRSUCCESS; /* already gone */
e1f001e5 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 }
dba0cf81 526 if (current == NULL) return PRSUCCESS; /* we didn't find him, already gone */
e1f001e5 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
543long AddToNameHash(tt, aname, loc)
544struct ubik_trans *tt;
545char *aname;
546long 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
566long AddToOwnerChain(at,gid,oid)
dba0cf81 567 struct ubik_trans *at;
568 long gid;
569 long oid;
e1f001e5 570{
571 /* add entry designated by gid to owner chain of entry designated by oid */
572 register long code;
573 long loc;
e1f001e5 574 struct prentry tentry;
575 struct prentry gentry;
dba0cf81 576 long gloc;
e1f001e5 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;
dba0cf81 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 }
e1f001e5 594 code = pr_WriteEntry(at,0,loc,&tentry);
595 if (code != 0) return PRDBFAIL;
e1f001e5 596 return PRSUCCESS;
597}
598
dba0cf81 599/* RemoveFromOwnerChain - remove gid from owner chain for oid */
600
e1f001e5 601long RemoveFromOwnerChain(at,gid,oid)
dba0cf81 602 struct ubik_trans *at;
603 long gid;
604 long oid;
e1f001e5 605{
e1f001e5 606 register long code;
607 long nptr;
dba0cf81 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;
e1f001e5 613
614 loc = FindByID(at,oid);
615 if (!loc) return PRNOENT;
dba0cf81 616 code = pr_ReadEntry (at, 0, loc, &thisEntry);
e1f001e5 617 if (code != 0) return PRDBFAIL;
dba0cf81 618 le = &thisEntry;
619 lastLoc = 0;
620 nptr = thisEntry.owned;
e1f001e5 621 while (nptr != NULL) {
dba0cf81 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);
e1f001e5 627 if (code != 0) return PRDBFAIL;
dba0cf81 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);
e1f001e5 642 if (code != 0) return PRDBFAIL;
643 return PRSUCCESS;
644 }
dba0cf81 645 lastLoc = nptr;
646 le = te;
647 nptr = te->nextOwned;
e1f001e5 648 }
dba0cf81 649 return PRSUCCESS; /* already removed? */
e1f001e5 650}
651
dba0cf81 652/* AddToOrphan - add gid to orphan list, as it's owner has died */
653
e1f001e5 654long AddToOrphan(at,gid)
dba0cf81 655 struct ubik_trans *at;
656 long gid;
e1f001e5 657{
e1f001e5 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);
dba0cf81 667 code = set_header_word (at, orphan, htonl(loc));
e1f001e5 668 if (code != 0) return PRDBFAIL;
dba0cf81 669 tentry.owner = 0; /* so there's no confusion later */
670 code = pr_WriteEntry(at,0,loc,&tentry);
e1f001e5 671 if (code != 0) return PRDBFAIL;
672 return PRSUCCESS;
673}
674
675long RemoveFromOrphan(at,gid)
676struct ubik_trans *at;
677long 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;
dba0cf81 717 bcopy(&tentry,&bentry, sizeof(tentry));
e1f001e5 718 }
dba0cf81 719 return PRSUCCESS;
e1f001e5 720}
721
722long IsOwnerOf(at,aid,gid)
723struct ubik_trans *at;
724long aid;
725long 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
740long OwnerOf(at,gid)
741struct ubik_trans *at;
742long 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
e1f001e5 757long IsAMemberOf(at,aid,gid)
758struct ubik_trans *at;
759long aid;
760long 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
dba0cf81 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;
e1f001e5 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++) {
e1f001e5 780 if (tentry.entries[i] == 0) return 0;
dba0cf81 781 if (tentry.entries[i] == aid) return 1;
e1f001e5 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.217013 seconds and 5 git commands to generate.