2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include <afs/param.h>
22 #if defined(SUPERGROUPS)
23 extern afs_int32 depthsg
;
24 afs_int32
IsAMemberOfSG(struct ubik_trans
*at
, afs_int32 aid
, afs_int32 gid
,
31 /* returns hash bucket for x */
32 return ((abs(x
)) % HASHSIZE
);
38 /* returns hash bucket for aname */
39 unsigned int hash
= 0;
41 /* stolen directly from the HashString function in the vol package */
42 for (i
= strlen(aname
), aname
+= i
- 1; i
--; aname
--)
43 hash
= (hash
* 31) + (*(unsigned char *)aname
- 31);
44 return (hash
% HASHSIZE
);
49 pr_Write(struct ubik_trans
*tt
, afs_int32 afd
, afs_int32 pos
, void *buff
, afs_int32 len
)
51 /* package up seek and write into one procedure for ease of use */
53 if ((pos
< sizeof(cheader
)) && (buff
!= (char *)&cheader
+ pos
)) {
55 "ptserver: dbwrite: Illegal attempt to write a location 0\n");
58 code
= ubik_Seek(tt
, afd
, pos
);
61 code
= ubik_Write(tt
, buff
, len
);
66 pr_Read(struct ubik_trans
*tt
, afs_int32 afd
, afs_int32 pos
, void *buff
, afs_int32 len
)
68 /* same thing for read */
70 code
= ubik_Seek(tt
, afd
, pos
);
73 code
= ubik_Read(tt
, buff
, len
);
78 pr_WriteEntry(struct ubik_trans
*tt
, afs_int32 afd
, afs_int32 pos
, struct prentry
*tentry
)
82 struct prentry nentry
;
84 if (ntohl(1) != 1) { /* Need to swap bytes. */
85 memset(&nentry
, 0, sizeof(nentry
)); /* make sure reseved fields are zero */
86 nentry
.flags
= htonl(tentry
->flags
);
87 nentry
.id
= htonl(tentry
->id
);
88 nentry
.cellid
= htonl(tentry
->cellid
);
89 nentry
.next
= htonl(tentry
->next
);
90 nentry
.nextID
= htonl(tentry
->nextID
);
91 nentry
.nextName
= htonl(tentry
->nextName
);
92 nentry
.owner
= htonl(tentry
->owner
);
93 nentry
.creator
= htonl(tentry
->creator
);
94 nentry
.ngroups
= htonl(tentry
->ngroups
);
95 nentry
.nusers
= htonl(tentry
->nusers
);
96 nentry
.count
= htonl(tentry
->count
);
97 nentry
.instance
= htonl(tentry
->instance
);
98 nentry
.owned
= htonl(tentry
->owned
);
99 nentry
.nextOwned
= htonl(tentry
->nextOwned
);
100 nentry
.parent
= htonl(tentry
->parent
);
101 nentry
.sibling
= htonl(tentry
->sibling
);
102 nentry
.child
= htonl(tentry
->child
);
103 strncpy(nentry
.name
, tentry
->name
, PR_MAXNAMELEN
);
104 nentry
.createTime
= htonl(tentry
->createTime
);
105 nentry
.addTime
= htonl(tentry
->addTime
);
106 nentry
.removeTime
= htonl(tentry
->removeTime
);
107 nentry
.changeTime
= htonl(tentry
->changeTime
);
108 for (i
= 0; i
< PRSIZE
; i
++)
109 nentry
.entries
[i
] = htonl(tentry
->entries
[i
]);
112 code
= pr_Write(tt
, afd
, pos
, (char *)tentry
, sizeof(struct prentry
));
117 pr_ReadEntry(struct ubik_trans
*tt
, afs_int32 afd
, afs_int32 pos
, struct prentry
*tentry
)
121 struct prentry nentry
;
122 code
= ubik_Seek(tt
, afd
, pos
);
125 if (ntohl(1) == 1) { /* no swapping needed */
126 code
= ubik_Read(tt
, (char *)tentry
, sizeof(struct prentry
));
129 code
= ubik_Read(tt
, (char *)&nentry
, sizeof(struct prentry
));
132 memset(tentry
, 0, sizeof(*tentry
)); /* make sure reseved fields are zero */
133 tentry
->flags
= ntohl(nentry
.flags
);
134 tentry
->id
= ntohl(nentry
.id
);
135 tentry
->cellid
= ntohl(nentry
.cellid
);
136 tentry
->next
= ntohl(nentry
.next
);
137 tentry
->nextID
= ntohl(nentry
.nextID
);
138 tentry
->nextName
= ntohl(nentry
.nextName
);
139 tentry
->owner
= ntohl(nentry
.owner
);
140 tentry
->creator
= ntohl(nentry
.creator
);
141 tentry
->ngroups
= ntohl(nentry
.ngroups
);
142 tentry
->nusers
= ntohl(nentry
.nusers
);
143 tentry
->count
= ntohl(nentry
.count
);
144 tentry
->instance
= ntohl(nentry
.instance
);
145 tentry
->owned
= ntohl(nentry
.owned
);
146 tentry
->nextOwned
= ntohl(nentry
.nextOwned
);
147 tentry
->parent
= ntohl(nentry
.parent
);
148 tentry
->sibling
= ntohl(nentry
.sibling
);
149 tentry
->child
= ntohl(nentry
.child
);
150 strncpy(tentry
->name
, nentry
.name
, PR_MAXNAMELEN
);
151 tentry
->createTime
= ntohl(nentry
.createTime
);
152 tentry
->addTime
= ntohl(nentry
.addTime
);
153 tentry
->removeTime
= ntohl(nentry
.removeTime
);
154 tentry
->changeTime
= ntohl(nentry
.changeTime
);
155 for (i
= 0; i
< PRSIZE
; i
++)
156 tentry
->entries
[i
] = ntohl(nentry
.entries
[i
]);
161 pr_WriteCoEntry(struct ubik_trans
*tt
, afs_int32 afd
, afs_int32 pos
, struct contentry
*tentry
)
165 struct contentry nentry
;
167 if (ntohl(1) != 1) { /* No need to swap */
168 memset(&nentry
, 0, sizeof(nentry
)); /* make reseved fields zero */
169 nentry
.flags
= htonl(tentry
->flags
);
170 nentry
.id
= htonl(tentry
->id
);
171 nentry
.cellid
= htonl(tentry
->cellid
);
172 nentry
.next
= htonl(tentry
->next
);
173 for (i
= 0; i
< COSIZE
; i
++)
174 nentry
.entries
[i
] = htonl(tentry
->entries
[i
]);
177 code
= pr_Write(tt
, afd
, pos
, (char *)tentry
, sizeof(struct contentry
));
182 pr_ReadCoEntry(struct ubik_trans
*tt
, afs_int32 afd
, afs_int32 pos
, struct contentry
*tentry
)
186 struct contentry nentry
;
187 code
= ubik_Seek(tt
, afd
, pos
);
190 if (ntohl(1) == 1) { /* No swapping needed. */
191 code
= ubik_Read(tt
, (char *)tentry
, sizeof(struct contentry
));
194 code
= ubik_Read(tt
, (char *)&nentry
, sizeof(struct contentry
));
197 memset(tentry
, 0, sizeof(*tentry
)); /* make reseved fields zero */
198 tentry
->flags
= ntohl(nentry
.flags
);
199 tentry
->id
= ntohl(nentry
.id
);
200 tentry
->cellid
= ntohl(nentry
.cellid
);
201 tentry
->next
= ntohl(nentry
.next
);
202 for (i
= 0; i
< COSIZE
; i
++)
203 tentry
->entries
[i
] = ntohl(nentry
.entries
[i
]);
207 /* AllocBloc - allocate a free block of storage for entry, returning address of
211 AllocBlock(struct ubik_trans
*at
)
215 struct prentry tentry
;
217 if (cheader
.freePtr
) {
218 /* allocate this dude */
219 temp
= ntohl(cheader
.freePtr
);
220 code
= pr_ReadEntry(at
, 0, temp
, &tentry
);
223 cheader
.freePtr
= htonl(tentry
.next
);
225 pr_Write(at
, 0, 8, (char *)&cheader
.freePtr
,
226 sizeof(cheader
.freePtr
));
231 /* hosed, nothing on free list, grow file */
232 temp
= ntohl(cheader
.eofPtr
); /* remember this guy */
233 cheader
.eofPtr
= htonl(temp
+ ENTRYSIZE
);
235 pr_Write(at
, 0, 12, (char *)&cheader
.eofPtr
,
236 sizeof(cheader
.eofPtr
));
244 FreeBlock(struct ubik_trans
*at
, afs_int32 pos
)
246 /* add a block of storage to the free list */
248 struct prentry tentry
;
250 memset(&tentry
, 0, sizeof(tentry
));
251 tentry
.next
= ntohl(cheader
.freePtr
);
252 tentry
.flags
|= PRFREE
;
253 cheader
.freePtr
= htonl(pos
);
255 pr_Write(at
, 0, 8, (char *)&cheader
.freePtr
, sizeof(cheader
.freePtr
));
258 code
= pr_WriteEntry(at
, 0, pos
, &tentry
);
265 FindByID(struct ubik_trans
*at
, afs_int32 aid
)
267 /* returns address of entry if found, 0 otherwise */
270 struct prentry tentry
;
273 if ((aid
== PRBADID
) || (aid
== 0))
276 entry
= ntohl(cheader
.idHash
[i
]);
279 memset(&tentry
, 0, sizeof(tentry
));
280 code
= pr_ReadEntry(at
, 0, entry
, &tentry
);
283 if (aid
== tentry
.id
)
285 opr_Assert(entry
!= tentry
.nextID
);
286 entry
= tentry
.nextID
;
288 memset(&tentry
, 0, sizeof(tentry
));
289 code
= pr_ReadEntry(at
, 0, entry
, &tentry
);
292 if (aid
== tentry
.id
)
294 opr_Assert(entry
!= tentry
.nextID
);
295 entry
= tentry
.nextID
;
301 FindByName(struct ubik_trans
*at
, char aname
[PR_MAXNAMELEN
], struct prentry
*tentryp
)
309 entry
= ntohl(cheader
.nameHash
[i
]);
312 memset(tentryp
, 0, sizeof(struct prentry
));
313 code
= pr_ReadEntry(at
, 0, entry
, tentryp
);
316 if ((strncmp(aname
, tentryp
->name
, PR_MAXNAMELEN
)) == 0)
318 opr_Assert(entry
!= tentryp
->nextName
);
319 entry
= tentryp
->nextName
;
321 memset(tentryp
, 0, sizeof(struct prentry
));
322 code
= pr_ReadEntry(at
, 0, entry
, tentryp
);
325 if ((strncmp(aname
, tentryp
->name
, PR_MAXNAMELEN
)) == 0)
327 opr_Assert(entry
!= tentryp
->nextName
);
328 entry
= tentryp
->nextName
;
334 AllocID(struct ubik_trans
*at
, afs_int32 flag
, afs_int32
*aid
)
336 /* allocs an id from the proper area of address space, based on flag */
339 int maxcount
= 50; /* to prevent infinite loops */
342 *aid
= ntohl(cheader
.maxGroup
);
343 /* Check for PRBADID to avoid wrap-around. */
344 while (code
&& i
< maxcount
&& *aid
!= PRBADID
) {
346 code
= FindByID(at
, *aid
);
351 cheader
.maxGroup
= htonl(*aid
);
353 pr_Write(at
, 0, 16, (char *)&cheader
.maxGroup
,
354 sizeof(cheader
.maxGroup
));
358 } else if (flag
& PRFOREIGN
) {
359 *aid
= ntohl(cheader
.maxForeign
);
360 while (code
&& i
< maxcount
) {
362 code
= FindByID(at
, *aid
);
367 cheader
.maxForeign
= htonl(*aid
);
369 pr_Write(at
, 0, 24, (char *)&cheader
.maxForeign
,
370 sizeof(cheader
.maxForeign
));
375 *aid
= ntohl(cheader
.maxID
);
376 while (code
&& i
< maxcount
&& *aid
!= 0x7fffffff) {
378 code
= FindByID(at
, *aid
);
383 cheader
.maxID
= htonl(*aid
);
385 pr_Write(at
, 0, 20, (char *)&cheader
.maxID
,
386 sizeof(cheader
.maxID
));
394 IDToName(struct ubik_trans
*at
, afs_int32 aid
, char aname
[PR_MAXNAMELEN
])
397 struct prentry tentry
;
400 temp
= FindByID(at
, aid
);
403 code
= pr_Read(at
, 0, temp
, (char *)&tentry
, sizeof(tentry
));
406 strncpy(aname
, tentry
.name
, PR_MAXNAMELEN
);
411 NameToID(struct ubik_trans
*at
, char aname
[PR_MAXNAMELEN
], afs_int32
*aid
)
414 struct prentry tentry
;
416 temp
= FindByName(at
, aname
, &tentry
);
424 IDCmp(const void *a
, const void *b
)
426 /* used to sort CPS's so that comparison with acl's is easier */
427 if (*(afs_int32
*)a
> *(afs_int32
*)b
) {
429 } else if (*(afs_int32
*)a
== *(afs_int32
*)b
) {
431 } else /* (*a < *b) */ {
437 RemoveFromIDHash(struct ubik_trans
*tt
, afs_int32 aid
, afs_int32
*loc
) /* ??? in case ID hashed twice ??? */
439 /* remove entry designated by aid from id hash table */
441 afs_int32 current
, trail
, i
;
442 struct prentry tentry
;
443 struct prentry bentry
;
445 if ((aid
== PRBADID
) || (aid
== 0))
446 return PRINCONSISTENT
;
448 current
= ntohl(cheader
.idHash
[i
]);
449 memset(&tentry
, 0, sizeof(tentry
));
450 memset(&bentry
, 0, sizeof(bentry
));
453 return PRSUCCESS
; /* already gone */
454 code
= pr_ReadEntry(tt
, 0, current
, &tentry
);
457 while (aid
!= tentry
.id
) {
458 opr_Assert(trail
!= current
);
460 current
= tentry
.nextID
;
463 code
= pr_ReadEntry(tt
, 0, current
, &tentry
);
468 return PRSUCCESS
; /* we didn't find him, so he's already gone */
470 /* it's the first entry! */
471 cheader
.idHash
[i
] = htonl(tentry
.nextID
);
473 pr_Write(tt
, 0, 72 + HASHSIZE
* 4 + i
* 4,
474 (char *)&cheader
.idHash
[i
], sizeof(cheader
.idHash
[i
]));
478 code
= pr_ReadEntry(tt
, 0, trail
, &bentry
);
481 bentry
.nextID
= tentry
.nextID
;
482 code
= pr_WriteEntry(tt
, 0, trail
, &bentry
);
491 AddToIDHash(struct ubik_trans
*tt
, afs_int32 aid
, afs_int32 loc
)
493 /* add entry at loc designated by aid to id hash table */
496 struct prentry tentry
;
498 if ((aid
== PRBADID
) || (aid
== 0))
499 return PRINCONSISTENT
;
501 memset(&tentry
, 0, sizeof(tentry
));
502 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
505 tentry
.nextID
= ntohl(cheader
.idHash
[i
]);
506 cheader
.idHash
[i
] = htonl(loc
);
507 code
= pr_WriteEntry(tt
, 0, loc
, &tentry
);
511 pr_Write(tt
, 0, 72 + HASHSIZE
* 4 + i
* 4, (char *)&cheader
.idHash
[i
],
512 sizeof(cheader
.idHash
[i
]));
519 RemoveFromNameHash(struct ubik_trans
*tt
, char *aname
, afs_int32
*loc
)
521 /* remove from name hash */
523 afs_int32 current
, trail
, i
;
524 struct prentry tentry
;
525 struct prentry bentry
;
528 current
= ntohl(cheader
.nameHash
[i
]);
529 memset(&tentry
, 0, sizeof(tentry
));
530 memset(&bentry
, 0, sizeof(bentry
));
533 return PRSUCCESS
; /* already gone */
534 code
= pr_ReadEntry(tt
, 0, current
, &tentry
);
537 while (strcmp(aname
, tentry
.name
)) {
538 opr_Assert(trail
!= current
);
540 current
= tentry
.nextName
;
543 code
= pr_ReadEntry(tt
, 0, current
, &tentry
);
548 return PRSUCCESS
; /* we didn't find him, already gone */
550 /* it's the first entry! */
551 cheader
.nameHash
[i
] = htonl(tentry
.nextName
);
553 pr_Write(tt
, 0, 72 + i
* 4, (char *)&cheader
.nameHash
[i
],
554 sizeof(cheader
.nameHash
[i
]));
558 code
= pr_ReadEntry(tt
, 0, trail
, &bentry
);
561 bentry
.nextName
= tentry
.nextName
;
562 code
= pr_WriteEntry(tt
, 0, trail
, &bentry
);
571 AddToNameHash(struct ubik_trans
*tt
, char *aname
, afs_int32 loc
)
573 /* add to name hash */
576 struct prentry tentry
;
579 memset(&tentry
, 0, sizeof(tentry
));
580 code
= pr_ReadEntry(tt
, 0, loc
, &tentry
);
583 tentry
.nextName
= ntohl(cheader
.nameHash
[i
]);
584 cheader
.nameHash
[i
] = htonl(loc
);
585 code
= pr_WriteEntry(tt
, 0, loc
, &tentry
);
589 pr_Write(tt
, 0, 72 + i
* 4, (char *)&cheader
.nameHash
[i
],
590 sizeof(cheader
.nameHash
[i
]));
597 AddToOwnerChain(struct ubik_trans
*at
, afs_int32 gid
, afs_int32 oid
)
599 /* add entry designated by gid to owner chain of entry designated by oid */
602 struct prentry tentry
;
603 struct prentry gentry
;
606 loc
= FindByID(at
, oid
);
609 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
612 if (oid
== gid
) { /* added it to its own chain */
613 tentry
.nextOwned
= tentry
.owned
;
616 gloc
= FindByID(at
, gid
);
617 code
= pr_ReadEntry(at
, 0, gloc
, &gentry
);
620 gentry
.nextOwned
= tentry
.owned
;
622 code
= pr_WriteEntry(at
, 0, gloc
, &gentry
);
626 code
= pr_WriteEntry(at
, 0, loc
, &tentry
);
632 /* RemoveFromOwnerChain - remove gid from owner chain for oid */
635 RemoveFromOwnerChain(struct ubik_trans
*at
, afs_int32 gid
, afs_int32 oid
)
639 struct prentry thisEntry
;
640 struct prentry thatEntry
;
641 struct prentry
*te
; /* pointer to current (this) entry */
642 struct prentry
*le
; /* pointer to previous (last) entry */
643 afs_int32 loc
, lastLoc
;
645 loc
= FindByID(at
, oid
);
648 code
= pr_ReadEntry(at
, 0, loc
, &thisEntry
);
653 nptr
= thisEntry
.owned
;
658 if (&thisEntry
== le
)
662 code
= pr_ReadEntry(at
, 0, nptr
, te
);
668 if (lastLoc
== 0) { /* modifying first of chain */
669 le
->owned
= te
->nextOwned
;
670 lastLoc
= loc
; /* so we write to correct location */
672 le
->nextOwned
= te
->nextOwned
;
675 code
= pr_WriteEntry(at
, 0, nptr
, te
);
679 code
= pr_WriteEntry(at
, 0, lastLoc
, le
);
686 nptr
= te
->nextOwned
;
688 return PRSUCCESS
; /* already removed? */
691 /* AddToOrphan - add gid to orphan list, as it's owner has died */
694 AddToOrphan(struct ubik_trans
*at
, afs_int32 gid
)
698 struct prentry tentry
;
700 loc
= FindByID(at
, gid
);
703 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
706 tentry
.nextOwned
= ntohl(cheader
.orphan
);
707 code
= set_header_word(at
, orphan
, htonl(loc
));
710 tentry
.owner
= 0; /* so there's no confusion later */
711 code
= pr_WriteEntry(at
, 0, loc
, &tentry
);
718 RemoveFromOrphan(struct ubik_trans
*at
, afs_int32 gid
)
720 /* remove gid from the orphan list */
724 struct prentry tentry
;
725 struct prentry bentry
;
727 loc
= FindByID(at
, gid
);
730 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
733 if (cheader
.orphan
== htonl(loc
)) {
734 cheader
.orphan
= htonl(tentry
.nextOwned
);
735 tentry
.nextOwned
= 0;
737 pr_Write(at
, 0, 32, (char *)&cheader
.orphan
,
738 sizeof(cheader
.orphan
));
741 code
= pr_WriteEntry(at
, 0, loc
, &tentry
);
746 nptr
= ntohl(cheader
.orphan
);
747 memset(&bentry
, 0, sizeof(bentry
));
750 code
= pr_ReadEntry(at
, 0, nptr
, &tentry
);
753 if (gid
== tentry
.id
) {
755 bentry
.nextOwned
= tentry
.nextOwned
;
756 tentry
.nextOwned
= 0;
757 code
= pr_WriteEntry(at
, 0, loc
, &bentry
);
760 code
= pr_WriteEntry(at
, 0, nptr
, &tentry
);
766 nptr
= tentry
.nextOwned
;
767 memcpy(&bentry
, &tentry
, sizeof(tentry
));
773 IsOwnerOf(struct ubik_trans
*at
, afs_int32 aid
, afs_int32 gid
)
775 /* returns 1 if aid is the owner of gid, 0 otherwise */
777 struct prentry tentry
;
780 loc
= FindByID(at
, gid
);
783 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
786 if (tentry
.owner
== aid
)
792 OwnerOf(struct ubik_trans
*at
, afs_int32 gid
)
794 /* returns the owner of gid */
797 struct prentry tentry
;
799 loc
= FindByID(at
, gid
);
802 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
810 IsAMemberOf(struct ubik_trans
*at
, afs_int32 aid
, afs_int32 gid
)
812 /* returns true if aid is a member of gid */
813 #if !defined(SUPERGROUPS)
814 struct prentry tentry
;
815 struct contentry centry
;
821 /* special case anyuser and authuser */
822 if (gid
== ANYUSERID
)
824 if (gid
== AUTHUSERID
&& aid
!= ANONYMOUSID
)
826 /* check -localauth case */
827 if (gid
== SYSADMINID
&& aid
== SYSADMINID
)
829 if ((gid
== 0) || (aid
== 0))
831 #if defined(SUPERGROUPS)
832 return IsAMemberOfSG(at
, aid
, gid
, depthsg
);
834 loc
= FindByID(at
, gid
);
837 memset(&tentry
, 0, sizeof(tentry
));
838 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
841 if (!(tentry
.flags
& PRGRP
))
843 for (i
= 0; i
< PRSIZE
; i
++) {
844 if (tentry
.entries
[i
] == 0)
846 if (tentry
.entries
[i
] == aid
)
852 memset(¢ry
, 0, sizeof(centry
));
853 code
= pr_ReadCoEntry(at
, 0, loc
, ¢ry
);
856 for (i
= 0; i
< COSIZE
; i
++) {
857 if (centry
.entries
[i
] == aid
)
859 if (centry
.entries
[i
] == 0)
865 return 0; /* actually, should never get here */
870 #if defined(SUPERGROUPS)
872 IsAMemberOfSG(struct ubik_trans
*at
, afs_int32 aid
, afs_int32 gid
, afs_int32 depth
)
874 /* returns true if aid is a member of gid */
875 struct prentry tentry
;
876 struct contentry centry
;
883 loc
= FindByID(at
, gid
);
886 memset(&tentry
, 0, sizeof(tentry
));
887 code
= pr_ReadEntry(at
, 0, loc
, &tentry
);
890 if (!(tentry
.flags
& PRGRP
))
892 for (i
= 0; i
< PRSIZE
; i
++) {
893 gid
= tentry
.entries
[i
];
898 if (gid
== ANYUSERID
)
900 if (gid
== AUTHUSERID
&& aid
!= ANONYMOUSID
)
903 #ifndef AFS_PTHREAD_ENV
906 if (IsAMemberOfSG(at
, aid
, gid
, depth
- 1))
913 memset(¢ry
, 0, sizeof(centry
));
914 code
= pr_ReadCoEntry(at
, 0, loc
, ¢ry
);
917 for (i
= 0; i
< COSIZE
; i
++) {
918 gid
= centry
.entries
[i
];
923 if (gid
== ANYUSERID
)
925 if (gid
== AUTHUSERID
&& aid
!= ANONYMOUSID
)
928 #ifndef AFS_PTHREAD_ENV
931 if (IsAMemberOfSG(at
, aid
, gid
, depth
- 1))
938 return 0; /* actually, should never get here */
940 #endif /* SUPERGROUPS */