Protect ubik cache accesses
[openafs.git] / src / ptserver / ptutils.c
index acce83a..c4315c2 100644 (file)
@@ -23,8 +23,6 @@
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
 
 #include <afs/stds.h>
 #include <sys/types.h>
@@ -34,13 +32,7 @@ RCSID
 #else
 #include <netinet/in.h>
 #endif
-#ifdef HAVE_STRING_H
 #include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
 #include <lock.h>
 #include <ubik.h>
 #include <rx/xdr.h>
@@ -48,35 +40,36 @@ RCSID
 #include <afs/cellconfig.h>
 #include "ptserver.h"
 #include "pterror.h"
+#include "ptprototypes.h"
 #include <stdlib.h>
 
 /* Foreign cells are represented by the group system:authuser@cell*/
 #define AUTHUSER_GROUP "system:authuser"
 
-
+extern int restricted;
 extern struct ubik_dbase *dbase;
 extern struct afsconf_dir *prdir;
 extern int pr_noAuth;
-extern int IDCmp();
 
-extern afs_int32 AddToEntry();
+static int inRange(struct prentry *cellEntry, afs_int32 aid);
+static afs_int32 allocNextId(struct ubik_trans *, struct prentry *);
+static int AddAuthGroup(struct prentry *tentry, prlist *alist, afs_int32 *size);
+
 static char *whoami = "ptserver";
 
+int prp_user_default = PRP_USER_DEFAULT;
+int prp_group_default = PRP_GROUP_DEFAULT;
 
 #if defined(SUPERGROUPS)
 
 #include "map.h"
 
 afs_int32 depthsg = 5;         /* Maximum iterations used during IsAMemberOF */
-extern int IDCmp();
 afs_int32 GetListSG2(struct ubik_trans *at, afs_int32 gid, prlist * alist,
                     afs_int32 * sizeP, afs_int32 depth);
-afs_int32 allocNextId(struct ubik_trans *, struct prentry *);
 
 struct map *sg_flagged;
 struct map *sg_found;
-int prp_user_default = PRP_USER_DEFAULT;
-int prp_group_default = PRP_GROUP_DEFAULT;
 
 #define NIL_MAP ((struct map *) 0)
 
@@ -91,13 +84,11 @@ int prp_group_default = PRP_GROUP_DEFAULT;
  *  so we can always tell if we're writing a group record.
  */
 
-int (*pt_save_dbase_write) ();
+int (*pt_save_dbase_write)(struct ubik_dbase *, afs_int32, void *, afs_int32,
+                           afs_int32);
 
 int
-pt_mywrite(tdb, fno, bp, pos, count)
-     struct ubik_dbase *tdb;
-     afs_int32 fno, pos, count;
-     char *bp;
+pt_mywrite(struct ubik_dbase *tdb, afs_int32 fno, void *bp, afs_int32 pos, afs_int32 count)
 {
     afs_uint32 headersize = ntohl(cheader.headerSize);
 
@@ -116,71 +107,52 @@ pt_mywrite(tdb, fno, bp, pos, count)
            c = ENTRYSIZE - o;
            if (c > l)
                c = l;
+#define xPT(p,x) ((((struct prentry *)(p))->flags & htonl(PRTYPE)) == htonl(x))
 #if DEBUG_SG_MAP
            if (o)
                fprintf(stderr, "Writing %d bytes of entry @ %#lx(+%d)\n", c,
                        p - o, o);
            else if (c == ENTRYSIZE)
                fprintf(stderr,
-                       "Writing %d bytes of entry @ %#lx (%d<%s>,%d)\n", c,
-                       p, ((struct prentry *)cp)->flags,
-                       (((struct prentry *)cp)->flags & PRTYPE) ==
-                       PRUSER ? "user" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRFREE ? "free" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRGRP ? "group" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRCONT ? "cont" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRCELL ? "cell" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRFOREIGN ? "foreign" : (((struct prentry *)cp)->
-                                                flags & PRTYPE) ==
-                       PRINST ? "sub/super instance" : "?",
-                       ((struct prentry *)cp)->id);
+                       "Writing %d bytes of entry @ %#lx (%d<%s>,%d)\n",
+                       c, p, ntohl(((struct prentry *)cp)->flags),
+                       xPT(cp,PRUSER) ? "user" : xPT(cp,PRFREE) ? "free" :
+                       xPT(cp,PRGRP) ? "group" : xPT(cp,PRCONT) ? "cont" :
+                       xPT(cp,PRCELL) ? "cell" : xPT(cp,PRFOREIGN) ? "foreign" :
+                       xPT(cp,PRINST) ? "sub/super instance" : "?",
+                       ntohl(((struct prentry *)cp)->id));
            else if (c >= 8)
                fprintf(stderr,
                        "Writing first %d bytes of entry @ %#lx (%d<%s>,%d)\n",
-                       c, p, ((struct prentry *)cp)->flags,
-                       (((struct prentry *)cp)->flags & PRTYPE) ==
-                       PRUSER ? "user" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRFREE ? "free" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRGRP ? "group" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRCONT ? "cont" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRCELL ? "cell" : (((struct prentry *)cp)->
-                                          flags & PRTYPE) ==
-                       PRFOREIGN ? "foreign" : (((struct prentry *)cp)->
-                                                flags & PRTYPE) ==
-                       PRINST ? "sub/super instance" : "?",
-                       ((struct prentry *)cp)->id);
+                       c, p, ntohl(((struct prentry *)cp)->flags),
+                       xPT(cp,PRUSER) ? "user" : xPT(cp,PRFREE) ? "free" :
+                       xPT(cp,PRGRP) ? "group" : xPT(cp,PRCONT) ? "cont" :
+                       xPT(cp,PRCELL) ? "cell" : xPT(cp,PRFOREIGN) ? "foreign" :
+                       xPT(cp,PRINST) ? "sub/super instance" : "?",
+                       ntohl(((struct prentry *)cp)->id));
            else
                fprintf(stderr, "Writing %d bytes of entry @ %#lx\n", c, p);
 #endif
-           if (!o && c >= 8
-               && (((struct prentry *)cp)->flags & PRTYPE) == PRGRP) {
+           if (!o && c >= 8 && xPT(cp,PRGRP)) {
 #if DEBUG_SG_MAP
-               if (in_map(sg_found, -((struct prentry *)cp)->id))
+               if (in_map(sg_found, -ntohl(((struct prentry *)cp)->id)))
                    fprintf(stderr, "Unfound: Removing group %d\n",
-                           ((struct prentry *)cp)->id);
-               if (in_map(sg_flagged, -((struct prentry *)cp)->id))
+                           ntohl(((struct prentry *)cp)->id));
+               if (in_map(sg_flagged, -ntohl(((struct prentry *)cp)->id)))
                    fprintf(stderr, "Unflag: Removing group %d\n",
-                           ((struct prentry *)cp)->id);
+                           ntohl(((struct prentry *)cp)->id));
 #endif
                sg_found =
                    bic_map(sg_found,
-                           add_map(NIL_MAP, -((struct prentry *)cp)->id));
+                       add_map(NIL_MAP, -ntohl(((struct prentry *)cp)->id)));
                sg_flagged =
                    bic_map(sg_flagged,
-                           add_map(NIL_MAP, -((struct prentry *)cp)->id));
+                       add_map(NIL_MAP, -ntohl(((struct prentry *)cp)->id)));
            }
            cp += c;
            p += c;
            l -= c;
+#undef xPT
        }
     }
     return (*pt_save_dbase_write) (tdb, fno, bp, pos, count);
@@ -191,7 +163,8 @@ pt_mywrite(tdb, fno, bp, pos, count)
  *  just after ubik_ServerInit.
  */
 
-pt_hook_write()
+void 
+pt_hook_write(void)
 {
     extern struct ubik_dbase *ubik_dbase;
     if (ubik_dbase->write != pt_mywrite) {
@@ -211,8 +184,7 @@ pt_hook_write()
  *   return one if name is OK and zero if name is bogus. */
 
 static int
-CorrectUserName(name)
-     char *name;
+CorrectUserName(char *name)
 {
     extern int pr_realmNameLen;
 
@@ -230,12 +202,10 @@ CorrectUserName(name)
  * rename, which then compares the correct name with the requested new name. */
 
 static afs_int32
-CorrectGroupName(ut, aname, cid, oid, cname)
-     struct ubik_trans *ut;
-     char aname[PR_MAXNAMELEN];        /* name for group */
-     afs_int32 cid;            /* caller id */
-     afs_int32 oid;            /* owner of group */
-     char cname[PR_MAXNAMELEN];        /* correct name for group */
+CorrectGroupName(struct ubik_trans *ut, char aname[PR_MAXNAMELEN],     /* name for group */
+                afs_int32 cid,         /* caller id */
+                afs_int32 oid,         /* owner of group */
+                char cname[PR_MAXNAMELEN])     /* correct name for group */
 {
     afs_int32 code;
     int admin;
@@ -311,12 +281,10 @@ CorrectGroupName(ut, aname, cid, oid, cname)
 }
 
 int
-AccessOK(ut, cid, tentry, mem, any)
-     struct ubik_trans *ut;
-     afs_int32 cid;            /* caller id */
-     struct prentry *tentry;   /* object being accessed */
-     int mem;                  /* check membership in aid, if group */
-     int any;                  /* if set return true */
+AccessOK(struct ubik_trans *ut, afs_int32 cid,         /* caller id */
+        struct prentry *tentry,        /* object being accessed */
+        int mem,                       /* check membership in aid, if group */
+        int any)                       /* if set return true */
 {
     afs_int32 flags;
     afs_int32 oid;
@@ -326,6 +294,8 @@ AccessOK(ut, cid, tentry, mem, any)
        return 1;
     if (cid == SYSADMINID)
        return 1;               /* special case fileserver */
+    if (restricted && ((mem == PRP_ADD_MEM) || (mem == PRP_REMOVE_MEM)) && (any == 0))
+       return 0;
     if (tentry) {
        flags = tentry->flags;
        oid = tentry->owner;
@@ -363,14 +333,7 @@ AccessOK(ut, cid, tentry, mem, any)
 }
 
 afs_int32
-CreateEntry(at, aname, aid, idflag, flag, oid, creator)
-     struct ubik_trans *at;
-     char aname[PR_MAXNAMELEN];
-     afs_int32 *aid;
-     afs_int32 idflag;
-     afs_int32 flag;
-     afs_int32 oid;
-     afs_int32 creator;
+CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, afs_int32 idflag, afs_int32 flag, afs_int32 oid, afs_int32 creator)
 {
     /* get and init a new entry */
     afs_int32 code;
@@ -636,10 +599,7 @@ CreateEntry(at, aname, aid, idflag, flag, oid, creator)
  * entry if appropriate */
 
 afs_int32
-RemoveFromEntry(at, aid, bid)
-     struct ubik_trans *at;
-     afs_int32 aid;
-     afs_int32 bid;
+RemoveFromEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 bid)
 {
     afs_int32 code;
     struct prentry tentry;
@@ -727,11 +687,7 @@ RemoveFromEntry(at, aid, bid)
  * entry if appropriate */
 
 afs_int32
-ChangeIDEntry(at, aid, newid, bid)
-     register struct ubik_trans *at;
-     register afs_int32 aid;
-     register afs_int32 bid;
-     afs_int32 newid;
+ChangeIDEntry(register struct ubik_trans *at, register afs_int32 aid, afs_int32 newid, register afs_int32 bid)
 {
     register afs_int32 code;
     struct prentry tentry;
@@ -763,7 +719,7 @@ ChangeIDEntry(at, aid, newid, bid)
     }
 
     nptr = tentry.next;
-    while (nptr != NULL) {
+    while (nptr) {
        code = pr_ReadCoEntry(at, 0, nptr, &centry);
        if (code != 0)
            return code;
@@ -799,10 +755,7 @@ ChangeIDEntry(at, aid, newid, bid)
  * continuation entry if appropriate */
 
 afs_int32
-RemoveFromSGEntry(at, aid, bid)
-     register struct ubik_trans *at;
-     register afs_int32 aid;
-     register afs_int32 bid;
+RemoveFromSGEntry(register struct ubik_trans *at, register afs_int32 aid, register afs_int32 bid)
 {
     register afs_int32 code;
     struct prentry tentry;
@@ -825,7 +778,7 @@ RemoveFromSGEntry(at, aid, bid)
     if (code != 0)
        return code;
 #ifdef PR_REMEMBER_TIMES
-    tentry.removeTime = time((afs_int32 *) 0);
+    tentry.removeTime = time(NULL);
 #endif
     tentryg = (struct prentryg *)&tentry;
     for (i = 0; i < SGSIZE; i++) {
@@ -843,7 +796,7 @@ RemoveFromSGEntry(at, aid, bid)
     }
     hloc = 0;
     nptr = tentryg->nextsg;
-    while (nptr != NULL) {
+    while (nptr) {
        code = pr_ReadCoEntry(at, 0, nptr, &centry);
        if (code != 0)
            return code;
@@ -889,7 +842,7 @@ RemoveFromSGEntry(at, aid, bid)
        }                       /* for all coentry slots */
        hloc = nptr;
        nptr = centry.next;
-       bcopy((char *)&centry, (char *)&hentry, sizeof(centry));
+       memcpy((char *)&centry, (char *)&hentry, sizeof(centry));
     }                          /* while there are coentries */
     return PRNOENT;
 }
@@ -900,10 +853,7 @@ RemoveFromSGEntry(at, aid, bid)
  * groups, putting groups owned by it on orphan chain, and freeing the space */
 
 afs_int32
-DeleteEntry(at, tentry, loc)
-     struct ubik_trans *at;
-     struct prentry *tentry;
-     afs_int32 loc;
+DeleteEntry(struct ubik_trans *at, struct prentry *tentry, afs_int32 loc)
 {
     afs_int32 code;
     struct contentry centry;
@@ -966,7 +916,7 @@ DeleteEntry(at, tentry, loc)
     }
 #endif /* SUPERGROUPS */
     nptr = tentry->next;
-    while (nptr != (afs_int32) NULL) {
+    while (nptr != 0) {
        code = pr_ReadCoEntry(at, 0, nptr, &centry);
        if (code != 0)
            return PRDBFAIL;
@@ -1054,11 +1004,7 @@ DeleteEntry(at, tentry, loc)
  * Note the entry is written out by this routine. */
 
 afs_int32
-AddToEntry(tt, entry, loc, aid)
-     struct ubik_trans *tt;
-     struct prentry *entry;
-     afs_int32 loc;
-     afs_int32 aid;
+AddToEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_int32 aid)
 {
     afs_int32 code;
     afs_int32 i;
@@ -1091,7 +1037,7 @@ AddToEntry(tt, entry, loc, aid)
     }
     last = 0;
     nptr = entry->next;
-    while (nptr != (afs_int32) NULL) {
+    while (nptr != 0) {
        code = pr_ReadCoEntry(tt, 0, nptr, &nentry);
        if (code != 0)
            return code;
@@ -1171,11 +1117,7 @@ AddToEntry(tt, entry, loc, aid)
  * Note the entry is written out by this routine. */
 
 afs_int32
-AddToSGEntry(tt, entry, loc, aid)
-     struct ubik_trans *tt;
-     struct prentry *entry;
-     afs_int32 loc;
-     afs_int32 aid;
+AddToSGEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_int32 aid)
 {
     register afs_int32 code;
     afs_int32 i;
@@ -1185,13 +1127,13 @@ AddToSGEntry(tt, entry, loc, aid)
     afs_int32 nptr;
     afs_int32 last;            /* addr of last cont. block */
     afs_int32 first = 0;
-    afs_int32 cloc;
+    afs_int32 cloc = 0;
     afs_int32 slot = -1;
 
     if (entry->id == aid)
        return PRINCONSISTENT;
 #ifdef PR_REMEMBER_TIMES
-    entry->addTime = time((afs_int32 *) 0);
+    entry->addTime = time(NULL);
 #endif
     entryg = (struct prentryg *)entry;
     for (i = 0; i < SGSIZE; i++) {
@@ -1210,7 +1152,7 @@ AddToSGEntry(tt, entry, loc, aid)
     }
     last = 0;
     nptr = entryg->nextsg;
-    while (nptr != NULL) {
+    while (nptr) {
        code = pr_ReadCoEntry(tt, 0, nptr, &nentry);
        if (code != 0)
            return code;
@@ -1270,7 +1212,7 @@ AddToSGEntry(tt, entry, loc, aid)
     memset(&aentry, 0, sizeof(aentry));
     aentry.flags |= PRCONT;
     aentry.id = entry->id;
-    aentry.next = NULL;
+    aentry.next = 0;
     aentry.entries[0] = aid;
     code = pr_WriteCoEntry(tt, 0, nptr, &aentry);
     if (code != 0)
@@ -1284,10 +1226,7 @@ AddToSGEntry(tt, entry, loc, aid)
 #endif /* SUPERGROUPS */
 
 afs_int32
-AddToPRList(alist, sizeP, id)
-     prlist *alist;
-     int *sizeP;
-     afs_int32 id;
+AddToPRList(prlist *alist, int *sizeP, afs_int32 id)
 {
     char *tmp;
     int count;
@@ -1310,11 +1249,7 @@ AddToPRList(alist, sizeP, id)
 }
 
 afs_int32
-GetList(at, tentry, alist, add)
-     struct ubik_trans *at;
-     struct prentry *tentry;
-     prlist *alist;
-     afs_int32 add;
+GetList(struct ubik_trans *at, struct prentry *tentry, prlist *alist, afs_int32 add)
 {
     afs_int32 code;
     afs_int32 i;
@@ -1365,8 +1300,12 @@ GetList(at, tentry, alist, add)
                return code;
 #endif
        }
-       if (count++ > 50)
-           IOMGR_Poll(), count = 0;
+       if (count++ > 50) {
+#ifndef AFS_PTHREAD_ENV
+           IOMGR_Poll();
+#endif
+           count = 0;
+       }
     }
 
     if (add) {                 /* this is for a CPS, so tack on appropriate stuff */
@@ -1381,20 +1320,17 @@ GetList(at, tentry, alist, add)
                return code;
        }
     }
+#ifndef AFS_PTHREAD_ENV
     if (alist->prlist_len > 100)
        IOMGR_Poll();
+#endif
     qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
     return PRSUCCESS;
 }
 
 
 afs_int32
-GetList2(at, tentry, tentry2, alist, add)
-     struct ubik_trans *at;
-     struct prentry *tentry;
-     struct prentry *tentry2;
-     prlist *alist;
-     afs_int32 add;
+GetList2(struct ubik_trans *at, struct prentry *tentry, struct prentry *tentry2, prlist *alist, afs_int32 add)
 {
     afs_int32 code = 0;
     afs_int32 i;
@@ -1424,7 +1360,7 @@ GetList2(at, tentry, tentry2, alist, add)
     }
 
     nptr = tentry->next;
-    while (nptr != (afs_uint32) NULL) {
+    while (nptr != 0) {
        /* look through cont entries */
        code = pr_ReadCoEntry(at, 0, nptr, &centry);
        if (code != 0)
@@ -1446,8 +1382,12 @@ GetList2(at, tentry, tentry2, alist, add)
 #endif
        }
        nptr = centry.next;
-       if (count++ > 50)
-           IOMGR_Poll(), count = 0;
+       if (count++ > 50) {
+#ifndef AFS_PTHREAD_ENV
+           IOMGR_Poll();
+#endif
+           count = 0;
+       }
     }
 
     for (i = 0; i < PRSIZE; i++) {
@@ -1462,7 +1402,7 @@ GetList2(at, tentry, tentry2, alist, add)
 
     if (!code) {
        nptr = tentry2->next;
-       while (nptr != (afs_uint32) NULL) {
+       while (nptr != 0) {
            /* look through cont entries */
            code = pr_ReadCoEntry(at, 0, nptr, &centry);
            if (code != 0)
@@ -1477,8 +1417,12 @@ GetList2(at, tentry, tentry2, alist, add)
                    break;
            }
            nptr = centry.next;
-           if (count++ > 50)
-               IOMGR_Poll(), count = 0;
+           if (count++ > 50) {
+#ifndef AFS_PTHREAD_ENV
+               IOMGR_Poll();
+#endif
+               count = 0;
+           }
        }
     }
     if (add) {                 /* this is for a CPS, so tack on appropriate stuff */
@@ -1493,8 +1437,10 @@ GetList2(at, tentry, tentry2, alist, add)
                return code;
        }
     }
+#ifndef AFS_PTHREAD_ENV
     if (alist->prlist_len > 100)
        IOMGR_Poll();
+#endif
     qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
     return PRSUCCESS;
 }
@@ -1502,12 +1448,7 @@ GetList2(at, tentry, tentry2, alist, add)
 #if defined(SUPERGROUPS)
 
 afs_int32
-GetListSG2(at, gid, alist, sizeP, depth)
-     struct ubik_trans *at;
-     afs_int32 gid;
-     prlist *alist;
-     afs_int32 depth;
-     afs_int32 *sizeP;
+GetListSG2(struct ubik_trans *at, afs_int32 gid, prlist *alist, afs_int32 *sizeP, afs_int32 depth)
 {
     register afs_int32 code;
     struct prentry tentry;
@@ -1581,7 +1522,7 @@ GetListSG2(at, gid, alist, sizeP, depth)
     }
 
     nptr = tentryg->nextsg;
-    while (nptr != NULL) {
+    while (nptr) {
        didsomething = 1;
        /* look through cont entries */
        code = pr_ReadCoEntry(at, 0, nptr, &centry);
@@ -1604,8 +1545,12 @@ GetListSG2(at, gid, alist, sizeP, depth)
                return code;
        }
        nptr = centry.next;
-       if (count++ > 50)
-           IOMGR_Poll(), count = 0;
+       if (count++ > 50) {
+#ifndef AFS_PTHREAD_ENV
+           IOMGR_Poll();
+#endif
+           count = 0;
+       }
     }
 #if DEBUG_SG_MAP
     fprintf(stderr, "] for gid %d, done [flag=%s]\n", gid,
@@ -1623,10 +1568,7 @@ GetListSG2(at, gid, alist, sizeP, depth)
 }
 
 afs_int32
-GetSGList(at, tentry, alist)
-     struct ubik_trans *at;
-     struct prentry *tentry;
-     prlist *alist;
+GetSGList(struct ubik_trans *at, struct prentry *tentry, prlist *alist)
 {
     register afs_int32 code;
     afs_int32 i;
@@ -1652,7 +1594,7 @@ GetSGList(at, tentry, alist)
     }
 
     nptr = tentryg->nextsg;
-    while (nptr != NULL) {
+    while (nptr) {
        /* look through cont entries */
        code = pr_ReadCoEntry(at, 0, nptr, &centry);
        if (code != 0)
@@ -1667,12 +1609,18 @@ GetSGList(at, tentry, alist)
                return code;
        }
        nptr = centry.next;
-       if (count++ > 50)
-           IOMGR_Poll(), count = 0;
+       if (count++ > 50) {
+#ifndef AFS_PTHREAD_ENV
+           IOMGR_Poll();
+#endif
+           count = 0;
+       }
     }
 
+#ifndef AFS_PTHREAD_ENV
     if (alist->prlist_len > 100)
        IOMGR_Poll();
+#endif
     qsort((char *)alist->prlist_val, (int)alist->prlist_len,
          sizeof(afs_int32), IDCmp);
     return PRSUCCESS;
@@ -1680,10 +1628,7 @@ GetSGList(at, tentry, alist)
 #endif /* SUPERGROUPS */
 
 afs_int32
-GetOwnedChain(ut, next, alist)
-     struct ubik_trans *ut;
-     afs_int32 *next;
-     prlist *alist;
+GetOwnedChain(struct ubik_trans *ut, afs_int32 *next, prlist *alist)
 {
     afs_int32 code;
     struct prentry tentry;
@@ -1704,20 +1649,23 @@ GetOwnedChain(ut, next, alist)
        }
        if (code)
            return code;
-       if (count++ > 50)
-           IOMGR_Poll(), count = 0;
+       if (count++ > 50) {
+#ifndef AFS_PTHREAD_ENV
+           IOMGR_Poll();
+#endif
+           count = 0;
+       }
     }
+#ifndef AFS_PTHREAD_ENV
     if (alist->prlist_len > 100)
        IOMGR_Poll();
+#endif
     qsort(alist->prlist_val, alist->prlist_len, sizeof(afs_int32), IDCmp);
     return PRSUCCESS;
 }
 
 afs_int32
-GetMax(at, uid, gid)
-     struct ubik_trans *at;
-     afs_int32 *uid;
-     afs_int32 *gid;
+GetMax(struct ubik_trans *at, afs_int32 *uid, afs_int32 *gid)
 {
     *uid = ntohl(cheader.maxID);
     *gid = ntohl(cheader.maxGroup);
@@ -1725,10 +1673,7 @@ GetMax(at, uid, gid)
 }
 
 afs_int32
-SetMax(at, id, flag)
-     struct ubik_trans *at;
-     afs_int32 id;
-     afs_int32 flag;
+SetMax(struct ubik_trans *at, afs_int32 id, afs_int32 flag)
 {
     afs_int32 code;
     if (flag & PRGRP) {
@@ -1749,32 +1694,70 @@ SetMax(at, id, flag)
     return PRSUCCESS;
 }
 
-afs_int32
-read_DbHeader(tt)
-     struct ubik_trans *tt;
+static afs_int32
+UpdateCache(struct ubik_trans *tt, void *rock)
 {
     afs_int32 code;
 
-    if (!ubik_CacheUpdate(tt))
-       return 0;
-
     code = pr_Read(tt, 0, 0, (char *)&cheader, sizeof(cheader));
     if (code != 0) {
-       com_err(whoami, code, "Couldn't read header");
+       afs_com_err(whoami, code, "Couldn't read header");
     }
     return code;
 }
 
+afs_int32
+read_DbHeader(struct ubik_trans *tt)
+{
+    return ubik_CheckCache(tt, UpdateCache, NULL);
+}
+
 int pr_noAuth;
-afs_int32 initd = 0;
 
-afs_int32
-Initdb()
+/**
+ * reads in db cache from ubik.
+ *
+ * @param[in] ut ubik transaction
+ * @param[out] rock  opaque pointer to an int*, which on success will be set
+ *                   to 1 if we need to build the database, or 0 if we do not
+ *
+ * @return operation status
+ *   @retval 0 success
+ */
+static afs_int32
+Initdb_check(struct ubik_trans *tt, void *rock)
 {
+    int *build_rock = rock;
     afs_int32 code;
-    struct ubik_trans *tt;
     afs_int32 len;
 
+    len = sizeof(cheader);
+    code = pr_Read(tt, 0, 0, (char *)&cheader, len);
+    if (code != 0) {
+       afs_com_err(whoami, code, "couldn't read header");
+       return code;
+    }
+    if ((ntohl(cheader.version) == PRDBVERSION)
+       && ntohl(cheader.headerSize) == sizeof(cheader)
+       && ntohl(cheader.eofPtr) != 0
+       && FindByID(tt, ANONYMOUSID) != 0) {
+       /* database exists, so we don't have to build it */
+       *build_rock = 0;
+       return 0;
+    }
+
+    /* else we need to build a database */
+    *build_rock = 1;
+    return 0;
+}
+
+afs_int32
+Initdb(void)
+{
+    struct ubik_trans *tt;
+    int build = 0;
+    afs_int32 code;
+
     /* init the database.  We'll try reading it, but if we're starting
      * from scratch, we'll have to do a write transaction. */
 
@@ -1788,52 +1771,40 @@ Initdb()
        ubik_AbortTrans(tt);
        return code;
     }
-    if (!initd) {
-       initd = 1;
-    } else if (!ubik_CacheUpdate(tt)) {
-       code = ubik_EndTrans(tt);
-       return code;
-    }
 
-    len = sizeof(cheader);
-    code = pr_Read(tt, 0, 0, (char *)&cheader, len);
-    if (code != 0) {
-       com_err(whoami, code, "couldn't read header");
+    code = ubik_CheckCache(tt, Initdb_check, &build);
+    if (code) {
        ubik_AbortTrans(tt);
        return code;
     }
-    if ((ntohl(cheader.version) == PRDBVERSION)
-       && ntohl(cheader.headerSize) == sizeof(cheader)
-       && ntohl(cheader.eofPtr) != (afs_uint32) NULL
-       && FindByID(tt, ANONYMOUSID) != 0) {
-       /* database exists, so we don't have to build it */
-       code = ubik_EndTrans(tt);
-       if (code)
-           return code;
-       return PRSUCCESS;
-    }
-    /* else we need to build a database */
-    code = ubik_EndTrans(tt);
-    if (code)
-       return code;
 
-    /* Only rebuild database if the db was deleted (the header is zero) and we
-     * are running noAuth. */
-    {
+    if (build) {
+       /* Only rebuild database if the db was deleted (the header is zero) and we
+        * are running noAuth. */
        char *bp = (char *)&cheader;
        int i;
-       for (i = 0; i < sizeof(cheader); i++)
+       for (i = 0; i < sizeof(cheader); i++) {
            if (bp[i]) {
                code = PRDBBAD;
-               com_err(whoami, code,
+               afs_com_err(whoami, code,
                        "Can't rebuild database because it is not empty");
-               return code;
+               break;
            }
+       }
+       if (!pr_noAuth) {
+           code = PRDBBAD;
+           afs_com_err(whoami, code,
+                       "Can't rebuild database because not running NoAuth");
+       }
+    }
+
+    if (code) {
+       ubik_EndTrans(tt);
+    } else {
+       code = ubik_EndTrans(tt);
     }
-    if (!pr_noAuth) {
-       code = PRDBBAD;
-       com_err(whoami, code,
-               "Can't rebuild database because not running NoAuth");
+    if (code || !build) {
+       /* either we encountered an error, or we don't need to build the db */
        return code;
     }
 
@@ -1852,9 +1823,15 @@ Initdb()
      * actually have been a good database out there.  Now that we have a
      * real write transaction, make sure things are still bad.
      */
+    code = pr_Read(tt, 0, 0, (char *)&cheader, sizeof(cheader));
+    if (code != 0) {
+       afs_com_err(whoami, code, "couldn't read header");
+       ubik_AbortTrans(tt);
+       return code;
+    }
     if ((ntohl(cheader.version) == PRDBVERSION)
        && ntohl(cheader.headerSize) == sizeof(cheader)
-       && ntohl(cheader.eofPtr) != (afs_uint32) NULL
+       && ntohl(cheader.eofPtr) != 0
        && FindByID(tt, ANONYMOUSID) != 0) {
        /* database exists, so we don't have to build it */
        code = ubik_EndTrans(tt);
@@ -1867,7 +1844,7 @@ Initdb()
     if ((code = set_header_word(tt, version, htonl(PRDBVERSION)))
        || (code = set_header_word(tt, headerSize, htonl(sizeof(cheader))))
        || (code = set_header_word(tt, eofPtr, cheader.headerSize))) {
-       com_err(whoami, code, "couldn't write header words");
+       afs_com_err(whoami, code, "couldn't write header words");
        ubik_AbortTrans(tt);
        return code;
     }
@@ -1877,7 +1854,7 @@ Initdb()
     code = CreateEntry               \
        (tt, (name), &temp, /*idflag*/1, flag, SYSADMINID, SYSADMINID); \
     if (code) {                              \
-       com_err (whoami, code, "couldn't create %s with id %di.",       \
+       afs_com_err (whoami, code, "couldn't create %s with id %di.",   \
                 (name), (id));       \
        ubik_AbortTrans(tt);          \
        return code;                  \
@@ -1895,7 +1872,7 @@ Initdb()
      * it back to 0 */
     code = set_header_word(tt, maxID, 0);      /* correct in any byte order */
     if (code) {
-       com_err(whoami, code, "couldn't reset max id");
+       afs_com_err(whoami, code, "couldn't reset max id");
        ubik_AbortTrans(tt);
        return code;
     }
@@ -1907,20 +1884,16 @@ Initdb()
 }
 
 afs_int32
-ChangeEntry(at, aid, cid, name, oid, newid)
-     struct ubik_trans *at;
-     afs_int32 aid;
-     afs_int32 cid;
-     char *name;
-     afs_int32 oid;
-     afs_int32 newid;
+ChangeEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 cid, char *name, afs_int32 oid, afs_int32 newid)
 {
     afs_int32 code;
-    afs_int32 i, nptr, pos;
+    afs_int32 i, pos;
 #if defined(SUPERGROUPS)
     afs_int32 nextpos;
-#endif
+#else
+    afs_int32 nptr;
     struct contentry centry;
+#endif
     struct prentry tentry, tent;
     afs_int32 loc;
     afs_int32 oldowner;
@@ -1937,6 +1910,8 @@ ChangeEntry(at, aid, cid, name, oid, newid)
     code = pr_ReadEntry(at, 0, loc, &tentry);
     if (code)
        return PRDBFAIL;
+    if (restricted && !IsAMemberOf(at, cid, SYSADMINID)) 
+       return PRPERM;
     if (tentry.owner != cid && !IsAMemberOf(at, cid, SYSADMINID)
        && !IsAMemberOf(at, cid, tentry.owner) && !pr_noAuth)
        return PRPERM;
@@ -2009,7 +1984,7 @@ ChangeEntry(at, aid, cid, name, oid, newid)
                break;
        }
        pos = tentry.next;
-       while (pos != NULL) {
+       while (pos) {
 #define centry  (*(struct contentry*)&tent)
            code = pr_ReadCoEntry(at, 0, pos, &centry);
            if ((centry.id != aid)
@@ -2105,7 +2080,7 @@ ChangeEntry(at, aid, cid, name, oid, newid)
        tentry.owner = oid;
        /* The entry must be written through first so Remove and Add routines
         * can operate on disk data */
-       code = pr_WriteEntry(at, 0, loc, (char *)&tentry);
+       code = pr_WriteEntry(at, 0, loc, &tentry);
        if (code)
            return PRDBFAIL;
 
@@ -2172,7 +2147,7 @@ ChangeEntry(at, aid, cid, name, oid, newid)
        if (code != PRSUCCESS)
            return code;
        strncpy(tentry.name, name, PR_MAXNAMELEN);
-       code = pr_WriteEntry(at, 0, loc, (char *)&tentry);
+       code = pr_WriteEntry(at, 0, loc, &tentry);
        if (code)
            return PRDBFAIL;
        code = AddToNameHash(at, tentry.name, loc);
@@ -2184,7 +2159,7 @@ ChangeEntry(at, aid, cid, name, oid, newid)
 }
 
 
-afs_int32
+static afs_int32
 allocNextId(struct ubik_trans * at, struct prentry * cellEntry)
 {
     /* Id's for foreign cell entries are constructed as follows:
@@ -2215,7 +2190,7 @@ allocNextId(struct ubik_trans * at, struct prentry * cellEntry)
     return id;
 }
 
-int
+static int
 inRange(struct prentry *cellEntry, afs_int32 aid)
 {
     afs_uint32 id, cellid, groupid;
@@ -2246,10 +2221,8 @@ inRange(struct prentry *cellEntry, afs_int32 aid)
 
 }
 
-AddAuthGroup(tentry, alist, size)
-     struct prentry *tentry;
-     prlist *alist;
-     afs_int32 *size;
+static int
+AddAuthGroup(struct prentry *tentry, prlist *alist, afs_int32 *size)
 {
     if (!(strchr(tentry->name, '@')))
        return (AddToPRList(alist, size, AUTHUSERID));