ptserver: Remove PR_REMEMBER_TIMES
[openafs.git] / src / ptserver / ptutils.c
index 87d24a7..a597121 100644 (file)
@@ -1,13 +1,13 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
-/* 
+/*
  *                      (5) Add functions to process supergroups:
  *                          ChangeIDEntry(), RemoveFromSGEntry(),
  *                          AddToSGEntry(), GetListSG2().
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
+#include <roken.h>
 
-#include <afs/stds.h>
-#include <sys/types.h>
-#include <stdio.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-#include <string.h>
 #include <lock.h>
 #include <ubik.h>
 #include <rx/xdr.h>
 #include <afs/com_err.h>
 #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"
@@ -84,10 +77,11 @@ struct map *sg_found;
  *  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(struct ubik_dbase *tdb, afs_int32 fno, char *bp, afs_int32 pos, afs_int32 count)
+pt_mywrite(struct ubik_dbase *tdb, afs_int32 fno, void *bp, afs_int32 pos, afs_int32 count)
 {
     afs_uint32 headersize = ntohl(cheader.headerSize);
 
@@ -162,8 +156,8 @@ pt_mywrite(struct ubik_dbase *tdb, afs_int32 fno, char *bp, afs_int32 pos, afs_i
  *  just after ubik_ServerInit.
  */
 
-void 
-pt_hook_write()
+void
+pt_hook_write(void)
 {
     extern struct ubik_dbase *ubik_dbase;
     if (ubik_dbase->write != pt_mywrite) {
@@ -175,22 +169,18 @@ pt_hook_write()
 #endif /* SUPERGROUPS */
 
 /* CorrectUserName - Check to make sure a user name is OK.  It must not include
- *   either a colon (or it would look like a group) or an atsign (or it would
- *   look like a foreign user).  The length is checked as well to make sure
- *   that the user name, an atsign, and the local cell name will fit in
- *   PR_MAXNAMELEN.  This is so this user can fit in another cells database as
- *   a foreign user with our cell name tacked on.  This is a predicate, so it
- *   return one if name is OK and zero if name is bogus. */
+ *   either a colon (or it would look like a group) or a newline (which can
+ *   confuse some ptdb code, depending on the format we're reading from).
+ *   This is a predicate, so it return one if name is OK and zero if name is
+ *   bogus. */
 
 static int
 CorrectUserName(char *name)
 {
-    extern int pr_realmNameLen;
-
     /* We accept foreign names, so we will deal with '@' later */
     if (strchr(name, ':') || strchr(name, '\n'))
        return 0;
-    if (strlen(name) >= PR_MAXNAMELEN - pr_realmNameLen - 1)
+    if (strlen(name) >= PR_MAXNAMELEN)
        return 0;
     return 1;
 }
@@ -363,9 +353,7 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
     newEntry = AllocBlock(at);
     if (!newEntry)
        return PRDBFAIL;
-#ifdef PR_REMEMBER_TIMES
     tentry.createTime = time(0);
-#endif
 
     if (flag & PRGRP) {
        tentry.flags = PRGRP;
@@ -408,7 +396,7 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
        }
     } else {
        /* A foreign user: <name>@<cell>. The foreign user is added to
-        * its representing group. It is 
+        * its representing group. It is
         */
        char *cellGroup;
        afs_int32 pos, n;
@@ -438,7 +426,7 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
                return PRBADARG;
            tentry.id = *aid;
        } else {
-           /* Allocate an ID special for this foreign user. It is based 
+           /* Allocate an ID special for this foreign user. It is based
             * on the representing group's id and nusers count.
             */
            tentry.id = allocNextId(at, &centry);
@@ -538,7 +526,7 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
            }
 
            /* Admins don't get charged for creating a group.
-            * If in noAuth mode, you get changed for it but you 
+            * If in noAuth mode, you get changed for it but you
             * are still allowed to create as many groups as you want.
             */
            admin = ((creator == SYSADMINID)
@@ -618,9 +606,7 @@ RemoveFromEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 bid)
     code = pr_ReadEntry(at, 0, temp, &tentry);
     if (code != 0)
        return code;
-#ifdef PR_REMEMBER_TIMES
     tentry.removeTime = time(0);
-#endif
     for (i = 0; i < PRSIZE; i++) {
        if (tentry.entries[i] == aid) {
            tentry.entries[i] = PRBADID;
@@ -686,9 +672,9 @@ RemoveFromEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 bid)
  * entry if appropriate */
 
 afs_int32
-ChangeIDEntry(register struct ubik_trans *at, register afs_int32 aid, afs_int32 newid, register afs_int32 bid)
+ChangeIDEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 newid, afs_int32 bid)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct prentry tentry;
     struct contentry centry;
     afs_int32 temp;
@@ -754,9 +740,9 @@ ChangeIDEntry(register struct ubik_trans *at, register afs_int32 aid, afs_int32
  * continuation entry if appropriate */
 
 afs_int32
-RemoveFromSGEntry(register struct ubik_trans *at, register afs_int32 aid, register afs_int32 bid)
+RemoveFromSGEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 bid)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct prentry tentry;
     struct prentryg *tentryg;
     struct contentry centry;
@@ -776,9 +762,7 @@ RemoveFromSGEntry(register struct ubik_trans *at, register afs_int32 aid, regist
     code = pr_ReadEntry(at, 0, temp, &tentry);
     if (code != 0)
        return code;
-#ifdef PR_REMEMBER_TIMES
     tentry.removeTime = time(NULL);
-#endif
     tentryg = (struct prentryg *)&tentry;
     for (i = 0; i < SGSIZE; i++) {
        if (tentryg->supergroup[i] == aid) {
@@ -1017,9 +1001,7 @@ AddToEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_int3
 
     if (entry->id == aid)
        return PRINCONSISTENT;
-#ifdef PR_REMEMBER_TIMES
     entry->addTime = time(0);
-#endif
     for (i = 0; i < PRSIZE; i++) {
        if (entry->entries[i] == aid)
            return PRIDEXIST;
@@ -1118,7 +1100,7 @@ AddToEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_int3
 afs_int32
 AddToSGEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_int32 aid)
 {
-    register afs_int32 code;
+    afs_int32 code;
     afs_int32 i;
     struct contentry nentry;
     struct contentry aentry;
@@ -1126,14 +1108,12 @@ AddToSGEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_in
     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(NULL);
-#endif
     entryg = (struct prentryg *)entry;
     for (i = 0; i < SGSIZE; i++) {
        if (entryg->supergroup[i] == aid)
@@ -1449,7 +1429,7 @@ GetList2(struct ubik_trans *at, struct prentry *tentry, struct prentry *tentry2,
 afs_int32
 GetListSG2(struct ubik_trans *at, afs_int32 gid, prlist *alist, afs_int32 *sizeP, afs_int32 depth)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct prentry tentry;
     struct prentryg *tentryg = (struct prentryg *)&tentry;
     afs_int32 i;
@@ -1569,7 +1549,7 @@ GetListSG2(struct ubik_trans *at, afs_int32 gid, prlist *alist, afs_int32 *sizeP
 afs_int32
 GetSGList(struct ubik_trans *at, struct prentry *tentry, prlist *alist)
 {
-    register afs_int32 code;
+    afs_int32 code;
     afs_int32 i;
     struct contentry centry;
     struct prentryg *tentryg;
@@ -1693,14 +1673,11 @@ SetMax(struct ubik_trans *at, afs_int32 id, afs_int32 flag)
     return PRSUCCESS;
 }
 
-afs_int32
-read_DbHeader(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) {
        afs_com_err(whoami, code, "Couldn't read header");
@@ -1708,15 +1685,57 @@ read_DbHeader(struct ubik_trans *tt)
     return code;
 }
 
+afs_int32
+read_DbHeader(struct ubik_trans *tt)
+{
+    return ubik_CheckCache(tt, UpdateCache, NULL);
+}
+
 int pr_noAuth;
-afs_int32 initd = 0;
+
+/**
+ * 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;
+    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)
 {
-    afs_int32 code;
     struct ubik_trans *tt;
-    afs_int32 len;
+    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. */
@@ -1731,52 +1750,34 @@ Initdb(void)
        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) {
-       afs_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) != 0
-       && 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) */
        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;
                afs_com_err(whoami, code,
                        "Can't rebuild database because it is not empty");
-               return code;
+               break;
            }
+       }
+    }
+
+    if (code) {
+       ubik_EndTrans(tt);
+    } else {
+       code = ubik_EndTrans(tt);
     }
-    if (!pr_noAuth) {
-       code = PRDBBAD;
-       afs_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;
     }
 
@@ -1795,6 +1796,12 @@ Initdb(void)
      * 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) != 0
@@ -1853,11 +1860,13 @@ afs_int32
 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;
@@ -1874,14 +1883,12 @@ ChangeEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 cid, char *name, afs
     code = pr_ReadEntry(at, 0, loc, &tentry);
     if (code)
        return PRDBFAIL;
-    if (restricted && !IsAMemberOf(at, cid, SYSADMINID)) 
+    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;
-#ifdef PR_REMEMBER_TIMES
     tentry.changeTime = time(0);
-#endif
 
     /* we're actually trying to change the id */
     if (newid && (newid != aid)) {
@@ -2002,7 +2009,7 @@ ChangeEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 cid, char *name, afs
                return code;
        }
        /* Look through cont entries too. This needs to be broken into
-        * seperate transaction so that no one transaction becomes too 
+        * seperate transaction so that no one transaction becomes too
         * large to complete.
         */
        for (nptr = tentry.next; nptr; nptr = centry.next) {
@@ -2141,13 +2148,13 @@ allocNextId(struct ubik_trans * at, struct prentry * cellEntry)
     }
 
     cellEntry->nusers = htonl(id);
-    /* use the field nusers to keep 
+    /* use the field nusers to keep
      * the next available id in that
      * foreign cell's group. Note :
      * It would seem more appropriate
      * to use ngroup for that and nusers
      * to enforce the quota, however pts
-     * does not have an option to change 
+     * does not have an option to change
      * foreign users quota yet  */
 
     id = (id << 16) | cellid;
@@ -2163,7 +2170,7 @@ inRange(struct prentry *cellEntry, afs_int32 aid)
     /*
      * The only thing that we want to make sure here is that
      * the id is in the legal range of this group. If it is
-     * a duplicate we don't care since it will get caught 
+     * a duplicate we don't care since it will get caught
      * in a different check.
      */
 
@@ -2172,9 +2179,9 @@ inRange(struct prentry *cellEntry, afs_int32 aid)
     if (cellid != groupid)
        return 0;               /* not in range */
 
-    /* 
+    /*
      * if we got here we're ok but we need to update the nusers
-     * field in order to get the id correct the next time that 
+     * field in order to get the id correct the next time that
      * we try to allocate it automatically
      */