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
13 Information Technology Center
16 Modified May, 1989 by Jeff Schiller to keep disk file in
22 #include <sys/types.h>
26 #include <netinet/in.h>
30 #include <rx/rx_vab.h>
36 extern struct prheader cheader;
37 extern struct ubik_dbase *dbase;
42 /* returns hash bucket for x */
43 return ((abs(x)) % HASHSIZE);
47 register unsigned char *aname;
49 /* returns hash bucket for aname */
50 register unsigned int hash=0;
52 /* stolen directly from the HashString function in the vol package */
53 for (i=strlen(aname),aname += i-1;i--;aname--)
54 hash = (hash*31) + (*aname-31);
55 return(hash % HASHSIZE);
59 long pr_Write(tt,afd,pos,buff,len)
60 struct ubik_trans *tt;
66 /* package up seek and write into one procedure for ease of use */
68 code = ubik_Seek(tt,afd,pos);
69 if (code) return code;
70 code = ubik_Write(tt,buff,len);
74 long pr_Read(tt,afd,pos,buff,len)
75 struct ubik_trans *tt;
81 /* same thing for read */
83 code = ubik_Seek(tt,afd,pos);
84 if (code) return code;
85 code = ubik_Read(tt,buff,len);
89 pr_WriteEntry(tt, afd, pos, tentry)
90 struct ubik_trans *tt;
93 struct prentry *tentry;
97 struct prentry nentry;
98 if (ntohl(1) != 1) { /* Need to swap bytes. */
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 for (i = 0; i < PRSIZE; i++)
118 nentry.entries[i] = htonl(tentry->entries[i]);
119 code = ubik_Seek(tt, afd, pos);
120 if (code) return (code);
121 code = ubik_Write(tt, (char *) &nentry, sizeof(struct prentry));
124 code = ubik_Seek(tt, afd, pos);
125 if (code) return (code);
126 code = ubik_Write(tt, (char *) tentry, sizeof(struct prentry));
131 pr_ReadEntry(tt, afd, pos, tentry)
132 struct ubik_trans *tt;
135 struct prentry *tentry;
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));
146 code = ubik_Read(tt, (char *) &nentry, sizeof(struct prentry));
147 if (code) return (code);
148 tentry->flags = ntohl(nentry.flags);
149 tentry->id = ntohl(nentry.id);
150 tentry->cellid = ntohl(nentry.cellid);
151 tentry->next = ntohl(nentry.next);
152 tentry->nextID = ntohl(nentry.nextID);
153 tentry->nextName = ntohl(nentry.nextName);
154 tentry->owner = ntohl(nentry.owner);
155 tentry->creator = ntohl(nentry.creator);
156 tentry->ngroups = ntohl(nentry.ngroups);
157 tentry->nusers = ntohl(nentry.nusers);
158 tentry->count = ntohl(nentry.count);
159 tentry->instance = ntohl(nentry.instance);
160 tentry->owned = ntohl(nentry.owned);
161 tentry->nextOwned = ntohl(nentry.nextOwned);
162 tentry->parent = ntohl(nentry.parent);
163 tentry->sibling = ntohl(nentry.sibling);
164 tentry->child = ntohl(nentry.child);
165 strncpy(tentry->name, nentry.name, PR_MAXNAMELEN);
166 for (i = 0; i < PRSIZE; i++)
167 tentry->entries[i] = ntohl(nentry.entries[i]);
171 pr_WriteCoEntry(tt, afd, pos, tentry)
172 struct ubik_trans *tt;
175 struct contentry *tentry;
179 struct contentry nentry;
180 if (ntohl(1) == 1) { /* No need to swap */
181 code = ubik_Seek(tt, afd, pos);
182 if (code) return(code);
183 code = ubik_Write(tt, (char *) tentry, sizeof(struct contentry));
186 nentry.flags = htonl(tentry->flags);
187 nentry.id = htonl(tentry->id);
188 nentry.cellid = htonl(tentry->cellid);
189 nentry.next = htonl(tentry->next);
190 for (i = 0; i < COSIZE; i++)
191 nentry.entries[i] = htonl(tentry->entries[i]);
192 code = ubik_Seek(tt, afd, pos);
193 if (code) return (code);
194 code = ubik_Write(tt, (char *) &nentry, sizeof(struct contentry));
198 pr_ReadCoEntry(tt, afd, pos, tentry)
199 struct ubik_trans *tt;
202 struct contentry *tentry;
206 struct contentry nentry;
207 code = ubik_Seek(tt, afd, pos);
208 if (code) return (code);
209 if (ntohl(1) == 1) { /* No swapping needed. */
210 code = ubik_Read(tt, (char *) tentry, sizeof(struct contentry));
213 code = ubik_Read(tt, (char *) &nentry, sizeof(struct contentry));
214 if (code) return (code);
215 tentry->flags = ntohl(nentry.flags);
216 tentry->id = ntohl(nentry.id);
217 tentry->cellid = ntohl(nentry.cellid);
218 tentry->next = ntohl(nentry.next);
219 for (i = 0; i < COSIZE; i++)
220 tentry->entries[i] = ntohl(nentry.entries[i]);
225 register struct ubik_trans *at;
227 /* allocate a free block of storage for entry, returning address of new entry */
230 struct prentry tentry;
232 if (cheader.freePtr) {
233 /* allocate this dude */
234 temp = ntohl(cheader.freePtr);
235 code = pr_ReadEntry(at, 0, temp, &tentry);
237 cheader.freePtr = htonl(tentry.next);
238 code = pr_Write(at, 0, 8, (char *)&cheader.freePtr, sizeof(cheader.freePtr));
239 if (code != 0) return 0;
243 /* hosed, nothing on free list, grow file */
244 temp = ntohl(cheader.eofPtr); /* remember this guy */
245 cheader.eofPtr = htonl(temp + ENTRYSIZE);
246 code = pr_Write(at, 0, 12,(char *) &cheader.eofPtr, sizeof(cheader.eofPtr));
247 if (code != 0) return 0;
252 long FreeBlock(at, pos)
253 register struct ubik_trans *at;
256 /* add a block of storage to the free list */
258 struct prentry tentry;
260 bzero(&tentry,sizeof(tentry));
261 tentry.next = ntohl(cheader.freePtr);
262 tentry.flags |= PRFREE;
263 cheader.freePtr = htonl(pos);
264 code = pr_Write(at,0,8, (char *) &cheader.freePtr,sizeof(cheader.freePtr));
265 if (code != 0) return code;
266 code = pr_WriteEntry(at,0,pos,&tentry);
267 if (code != 0) return code;
271 long FindByID(at,aid)
272 register struct ubik_trans *at;
275 /* returns address of entry if found, 0 otherwise */
278 struct prentry tentry;
282 entry = ntohl(cheader.idHash[i]);
283 if (entry == 0) return entry;
284 bzero(&tentry,sizeof(tentry));
285 code = pr_ReadEntry(at, 0, entry, &tentry);
286 if (code != 0) return 0;
287 if (aid == tentry.id) return entry;
288 entry = tentry.nextID;
289 while (entry != NULL) {
290 bzero(&tentry,sizeof(tentry));
291 code = pr_ReadEntry(at,0,entry,&tentry);
292 if (code != 0) return 0;
293 if (aid == tentry.id) return entry;
294 entry = tentry.nextID;
301 long FindByName(at,aname)
302 register struct ubik_trans *at;
303 char aname[PR_MAXNAMELEN];
308 struct prentry tentry;
312 entry = ntohl(cheader.nameHash[i]);
313 if (entry == 0) return entry;
314 bzero(&tentry,sizeof(tentry));
315 code = pr_ReadEntry(at, 0, entry,&tentry);
316 if (code != 0) return 0;
317 if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry;
318 entry = tentry.nextName;
319 while (entry != NULL) {
320 bzero(&tentry,sizeof(tentry));
321 code = pr_ReadEntry(at,0,entry,&tentry);
322 if (code != 0) return 0;
323 if ((strncmp(aname,tentry.name,PR_MAXNAMELEN)) == 0) return entry;
324 entry = tentry.nextName;
329 long AllocID(at,flag,aid)
330 register struct ubik_trans *at;
334 /* allocs an id from the proper area of address space, based on flag */
335 register long code = 1;
337 register maxcount = 50; /* to prevent infinite loops */
340 *aid = ntohl(cheader.maxGroup);
341 while (code && i<maxcount) {
343 code = FindByID(at,*aid);
346 if (code) return PRNOIDS;
347 cheader.maxGroup = htonl(*aid);
348 code = pr_Write(at,0,16,(char *)&cheader.maxGroup,sizeof(cheader.maxGroup));
349 if (code) return PRDBFAIL;
352 else if (flag & PRFOREIGN) {
353 *aid = ntohl(cheader.maxForeign);
354 while (code && i<maxcount) {
356 code = FindByID(at,*aid);
359 if (code) return PRNOIDS;
360 cheader.maxForeign = htonl(*aid);
361 code = pr_Write(at,0,24,(char *)&cheader.maxForeign,sizeof(cheader.maxForeign));
362 if (code) return PRDBFAIL;
366 *aid = ntohl(cheader.maxID);
367 while (code && i<maxcount) {
369 code = FindByID(at,*aid);
372 if (code) return PRNOIDS;
373 cheader.maxID = htonl(*aid);
374 code = pr_Write(at,0,20,(char *)&cheader.maxID,sizeof(cheader.maxID));
375 if (code) return PRDBFAIL;
384 /* used to sort CPS's so that comparison with acl's is easier */
385 if (*a > *b) return 1;
386 if (*a == *b) return 0;
387 if (*a < *b) return -1;
390 long RemoveFromIDHash(tt,aid,loc)
391 struct ubik_trans *tt;
395 /* remove entry designated by aid from id hash table */
397 long current, trail, i;
398 struct prentry tentry;
399 struct prentry bentry;
402 current = ntohl(cheader.idHash[i]);
403 bzero(&tentry,sizeof(tentry));
404 bzero(&bentry,sizeof(bentry));
406 if (current == NULL) return PRNOENT;
407 code = pr_ReadEntry(tt,0,current,&tentry);
408 if (code) return PRDBFAIL;
409 while (aid != tentry.id) {
411 current = tentry.nextID;
412 if (current == NULL) break;
413 code = pr_ReadEntry(tt,0,current,&tentry);
414 if (code) return PRDBFAIL;
416 if (current == NULL) return PRNOENT; /* we didn't find him */
418 /* it's the first entry! */
419 cheader.idHash[i] = htonl(tentry.nextID);
420 code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i]));
421 if (code) return PRDBFAIL;
424 code = pr_ReadEntry(tt,0,trail, &bentry);
425 if (code) return PRDBFAIL;
426 bentry.nextID = tentry.nextID;
427 code = pr_WriteEntry(tt,0,trail,&bentry);
433 long AddToIDHash(tt, aid, loc)
434 struct ubik_trans *tt;
438 /* add entry at loc designated by aid to id hash table */
441 struct prentry tentry;
444 bzero(&tentry,sizeof(tentry));
445 code = pr_ReadEntry(tt,0,loc,&tentry);
446 if (code) return PRDBFAIL;
447 tentry.nextID = ntohl(cheader.idHash[i]);
448 cheader.idHash[i] = htonl(loc);
449 code = pr_WriteEntry(tt,0,loc,&tentry);
450 if (code) return PRDBFAIL;
451 code = pr_Write(tt,0,72+HASHSIZE*4+i*4,(char *)&cheader.idHash[i],sizeof(cheader.idHash[i]));
452 if (code) return PRDBFAIL;
456 long RemoveFromNameHash(tt,aname,loc)
457 struct ubik_trans *tt;
461 /* remove from name hash */
463 long current, trail, i;
464 struct prentry tentry;
465 struct prentry bentry;
468 current = ntohl(cheader.nameHash[i]);
469 bzero(&tentry,sizeof(tentry));
470 bzero(&bentry,sizeof(bentry));
472 if (current == NULL) return PRNOENT;
473 code = pr_ReadEntry(tt,0,current,&tentry);
474 if (code) return PRDBFAIL;
475 while (strcmp(aname,tentry.name)) {
477 current = tentry.nextName;
478 if (current == NULL) break;
479 code = pr_ReadEntry(tt,0,current,&tentry);
480 if (code) return PRDBFAIL;
482 if (current == NULL) return PRNOENT; /* we dnamen't find him */
484 /* it's the first entry! */
485 cheader.nameHash[i] = htonl(tentry.nextName);
486 code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i]));
487 if (code) return PRDBFAIL;
490 code = pr_ReadEntry(tt,0,trail, &bentry);
491 if (code) return PRDBFAIL;
492 bentry.nextName = tentry.nextName;
493 code = pr_WriteEntry(tt,0,trail,&bentry);
499 long AddToNameHash(tt, aname, loc)
500 struct ubik_trans *tt;
504 /* add to name hash */
507 struct prentry tentry;
510 bzero(&tentry,sizeof(tentry));
511 code = pr_ReadEntry(tt,0,loc,&tentry);
512 if (code) return PRDBFAIL;
513 tentry.nextName = ntohl(cheader.nameHash[i]);
514 cheader.nameHash[i] = htonl(loc);
515 code = pr_WriteEntry(tt,0,loc,&tentry);
516 if (code) return PRDBFAIL;
517 code = pr_Write(tt,0,72+i*4,(char *)&cheader.nameHash[i],sizeof(cheader.nameHash[i]));
518 if (code) return PRDBFAIL;
522 long AddToOwnerChain(at,gid,oid)
523 struct ubik_trans *at;
527 /* add entry designated by gid to owner chain of entry designated by oid */
531 struct prentry tentry;
532 struct prentry gentry;
534 loc = FindByID(at,oid);
535 if (!loc) return PRNOENT;
536 code = pr_ReadEntry(at,0,loc,&tentry);
537 if (code != 0) return PRDBFAIL;
538 gloc = FindByID(at,gid);
539 code = pr_ReadEntry(at,0,gloc,&gentry);
540 if (code != 0) return PRDBFAIL;
541 gentry.nextOwned = tentry.owned;
543 code = pr_WriteEntry(at,0,loc,&tentry);
544 if (code != 0) return PRDBFAIL;
545 code = pr_WriteEntry(at,0,gloc,&gentry);
546 if (code != 0) return PRDBFAIL;
550 long RemoveFromOwnerChain(at,gid,oid)
551 struct ubik_trans *at;
555 /* remove gid from owner chain for oid */
558 struct prentry tentry;
559 struct prentry bentry;
562 loc = FindByID(at,oid);
563 if (!loc) return PRNOENT;
564 code = pr_ReadEntry(at,0,loc,&tentry);
565 if (code != 0) return PRDBFAIL;
566 if (!tentry.owned) return PRNOENT;
568 bcopy(&tentry,&bentry,sizeof(tentry));
569 while (nptr != NULL) {
570 code = pr_ReadEntry(at,0,nptr,&tentry);
571 if (code != 0) return PRDBFAIL;
572 if (tentry.id == gid) {
574 if (nptr == bentry.owned) /* modifying first of chain */
575 bentry.owned = tentry.nextOwned;
576 else bentry.nextOwned = tentry.nextOwned;
577 tentry.nextOwned = 0;
578 code = pr_WriteEntry(at,0,loc,&bentry);
579 if (code != 0) return PRDBFAIL;
580 code = pr_WriteEntry(at,0,nptr,&tentry);
581 if (code != 0) return PRDBFAIL;
585 nptr = tentry.nextOwned;
586 bcopy(&tentry,&bentry,sizeof(tentry));
591 long AddToOrphan(at,gid)
592 struct ubik_trans *at;
595 /* add gid to orphan list, as it's owner has died */
598 struct prentry tentry;
600 loc = FindByID(at,gid);
601 if (!loc) return PRNOENT;
602 code = pr_ReadEntry(at,0,loc,&tentry);
603 if (code != 0) return PRDBFAIL;
604 tentry.nextOwned = ntohl(cheader.orphan);
605 cheader.orphan = htonl(loc);
606 code = pr_WriteEntry(at,0,loc,&tentry);
607 if (code != 0) return PRDBFAIL;
608 code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan));
609 if (code != 0) return PRDBFAIL;
613 long RemoveFromOrphan(at,gid)
614 struct ubik_trans *at;
617 /* remove gid from the orphan list */
621 struct prentry tentry;
622 struct prentry bentry;
624 loc = FindByID(at,gid);
625 if (!loc) return PRNOENT;
626 code = pr_ReadEntry(at,0,loc,&tentry);
627 if (code != 0) return PRDBFAIL;
628 if (cheader.orphan == htonl(loc)) {
629 cheader.orphan = htonl(tentry.nextOwned);
630 tentry.nextOwned = 0;
631 code = pr_Write(at,0,32,(char *)&cheader.orphan,sizeof(cheader.orphan));
632 if (code != 0) return PRDBFAIL;
633 code = pr_WriteEntry(at,0,loc,&tentry);
634 if (code != 0) return PRDBFAIL;
637 nptr = ntohl(cheader.orphan);
638 bzero(&bentry,sizeof(bentry));
640 while (nptr != NULL) {
641 code = pr_ReadEntry(at,0,nptr,&tentry);
642 if (code != 0) return PRDBFAIL;
643 if (gid == tentry.id) {
645 bentry.nextOwned = tentry.nextOwned;
646 tentry.nextOwned = 0;
647 code = pr_WriteEntry(at,0,loc,&bentry);
648 if (code != 0) return PRDBFAIL;
649 code = pr_WriteEntry(at,0,nptr,&tentry);
650 if (code != 0) return PRDBFAIL;
654 nptr = tentry.nextOwned;
655 bcopy(&tentry,&bentry,sizeof(tentry));
660 long IsOwnerOf(at,aid,gid)
661 struct ubik_trans *at;
665 /* returns 1 if aid is the owner of gid, 0 otherwise */
667 struct prentry tentry;
670 loc = FindByID(at,gid);
672 code = pr_ReadEntry(at,0,loc,&tentry);
673 if (code != 0) return 0;
674 if (tentry.owner == aid) return 1;
679 struct ubik_trans *at;
682 /* returns the owner of gid */
685 struct prentry tentry;
687 loc = FindByID(at,gid);
689 code = pr_ReadEntry(at,0,loc,&tentry);
690 if (code != 0) return 0;
695 long WhoIsThis(acall, at, aid)
696 struct rx_call *acall;
697 struct ubik_trans *at;
700 /* aid is set to the identity of the caller, if known, ANONYMOUSID otherwise */
701 /* returns -1 and sets aid to ANONYMOUSID on any failure */
702 register struct rx_connection *tconn;
703 struct rxvab_conn *tc;
709 tconn = rx_ConnectionOf(acall);
710 code = rx_SecurityClassOf(tconn);
713 else if (code == 1) {
715 tc = (struct rxvab_conn *) tconn->securityData;
717 *aid = ANONYMOUSID; /* set it to something harmless */
720 *aid = ntohl(tc->viceID);
722 else if (code == 2) {
724 code = rxkad_GetServerInfo(acall->conn,(long *) 0, &exp, vname, (char *) 0, tcell, (long *) 0);
729 if (exp < FT_ApproxTime()) return -1;
730 code = NameToID(at,vname,aid);
744 long IsAMemberOf(at,aid,gid)
745 struct ubik_trans *at;
749 /* returns true if aid is a member of gid */
750 struct prentry tentry;
751 struct contentry centry;
756 loc = FindByID(at,gid);
758 bzero(&tentry,sizeof(tentry));
759 code = pr_ReadEntry(at, 0, loc,&tentry);
761 if (!(tentry.flags & PRGRP)) return 0;
762 for (i= 0;i<PRSIZE;i++) {
763 if (tentry.entries[i] == aid) return 1;
764 if (tentry.entries[i] == 0) return 0;
769 bzero(¢ry,sizeof(centry));
770 code = pr_ReadCoEntry(at,0,loc,¢ry);
772 for (i=0;i<COSIZE;i++) {
773 if (centry.entries[i] == aid) return 1;
774 if (centry.entries[i] == 0) return 0;
779 return 0; /* actually, should never get here */