Resolve missing printf args
[openafs.git] / src / ptserver / ptutils.c
index ed4262a..dfa54ee 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"
@@ -163,7 +156,7 @@ pt_mywrite(struct ubik_dbase *tdb, afs_int32 fno, void *bp, afs_int32 pos, afs_i
  *  just after ubik_ServerInit.
  */
 
-void 
+void
 pt_hook_write(void)
 {
     extern struct ubik_dbase *ubik_dbase;
@@ -201,10 +194,10 @@ static afs_int32
 CorrectGroupName(struct ubik_trans *ut, char aname[PR_MAXNAMELEN],     /* name for group */
                 afs_int32 cid,         /* caller id */
                 afs_int32 oid,         /* owner of group */
+                afs_int32 admin,       /* non-zero if admin */
                 char cname[PR_MAXNAMELEN])     /* correct name for group */
 {
     afs_int32 code;
-    int admin;
     char *prefix;              /* ptr to group owner part */
     char *suffix;              /* ptr to group name part */
     char name[PR_MAXNAMELEN];  /* correct name for group */
@@ -212,10 +205,6 @@ CorrectGroupName(struct ubik_trans *ut, char aname[PR_MAXNAMELEN], /* name for g
 
     if (strlen(aname) >= PR_MAXNAMELEN)
        return PRBADNAM;
-    admin = pr_noAuth || IsAMemberOf(ut, cid, SYSADMINID);
-
-    if (oid == 0)
-       oid = cid;
 
     /* Determine the correct prefix for the name. */
     if (oid == SYSADMINID)
@@ -250,6 +239,13 @@ CorrectGroupName(struct ubik_trans *ut, char aname[PR_MAXNAMELEN], /* name for g
 
     strcpy(name, aname);       /* in case aname & cname are same */
     suffix = strchr(name, ':');
+    /* let e.g. pt_util create groups with "wrong" names (like
+     * an orphan whose parent ID was reused).  Check that they look like
+     * groups (with a colon) or otherwise are good user names. */
+    if (pr_noAuth) {
+       strcpy(cname, aname);
+       goto done;
+    }
     if (suffix == 0) {
        /* sysadmin can make groups w/o ':', but they must still look like
         * legal user names. */
@@ -290,8 +286,17 @@ AccessOK(struct ubik_trans *ut, afs_int32 cid,             /* caller id */
        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 (restricted && !IsAMemberOf(ut, cid, SYSADMINID)) {
+        if (mem == PRP_ADD_MEM || mem == PRP_REMOVE_MEM) {
+            /* operation is for adding/removing members from a group */
+            return 0;
+        }
+        if (mem == 0 && any == 0) {
+            /* operation is for modifying an entry (or some administrative
+             * global operations) */
+            return 0;
+        }
+    }
     if (tentry) {
        flags = tentry->flags;
        oid = tentry->owner;
@@ -334,16 +339,22 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
     /* get and init a new entry */
     afs_int32 code;
     afs_int32 newEntry;
+    afs_int32 admin;
     struct prentry tentry, tent;
     char *atsign;
 
     memset(&tentry, 0, sizeof(tentry));
 
-    if ((oid == 0) || (oid == ANONYMOUSID))
+    admin = pr_noAuth || IsAMemberOf(at, creator, SYSADMINID);
+
+    if (oid == 0 || oid == ANONYMOUSID) {
+       if (!admin && creator == 0)
+           return PRBADARG;
        oid = creator;
+    }
 
     if (flag & PRGRP) {
-       code = CorrectGroupName(at, aname, creator, oid, tentry.name);
+       code = CorrectGroupName(at, aname, creator, oid, admin, tentry.name);
        if (code)
            return code;
        if (strcmp(aname, tentry.name) != 0)
@@ -360,9 +371,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;
@@ -405,7 +414,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;
@@ -414,10 +423,8 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
        /* To create the user <name>@<cell> the group AUTHUSER_GROUP@<cell>
         * must exist.
         */
-       cellGroup =
-           (char *)malloc(strlen(AUTHUSER_GROUP) + strlen(atsign) + 1);
-       strcpy(cellGroup, AUTHUSER_GROUP);
-       strcat(cellGroup, atsign);
+       if (asprintf(&cellGroup, "%s%s", AUTHUSER_GROUP, atsign) < 0)
+           return PRNOMEM;
        pos = FindByName(at, cellGroup, &centry);
        free(cellGroup);
        if (!pos)
@@ -435,7 +442,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);
@@ -457,9 +464,14 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
 
        /* write updated entry for group */
        code = pr_Write(at, 0, pos, &centry, sizeof(centry));
+       if (code)
+           return PRDBFAIL;
 
        /* Now add the new user entry to the database */
-       tentry.creator = creator;
+       if (creator == 0)
+           tentry.creator = tentry.id;
+       else
+           tentry.creator = creator;
        *aid = tentry.id;
        code = pr_WriteEntry(at, 0, newEntry, &tentry);
        if (code)
@@ -535,7 +547,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)
@@ -561,7 +573,10 @@ CreateEntry(struct ubik_trans *at, char aname[PR_MAXNAMELEN], afs_int32 *aid, af
        tentry.ngroups = tentry.nusers = 20;
     }
 
-    tentry.creator = creator;
+    if (creator == 0)
+       tentry.creator = tentry.id;
+    else
+       tentry.creator = creator;
     *aid = tentry.id;
     code = pr_WriteEntry(at, 0, newEntry, &tentry);
     if (code)
@@ -615,9 +630,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;
@@ -773,9 +786,7 @@ RemoveFromSGEntry(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(NULL);
-#endif
     tentryg = (struct prentryg *)&tentry;
     for (i = 0; i < SGSIZE; i++) {
        if (tentryg->supergroup[i] == aid) {
@@ -838,7 +849,7 @@ RemoveFromSGEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 bid)
        }                       /* for all coentry slots */
        hloc = nptr;
        nptr = centry.next;
-       memcpy((char *)&centry, (char *)&hentry, sizeof(centry));
+       memcpy(&hentry, &centry, sizeof(centry));
     }                          /* while there are coentries */
     return PRNOENT;
 }
@@ -1014,9 +1025,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;
@@ -1128,9 +1137,7 @@ AddToSGEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_in
 
     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)
@@ -1224,20 +1231,19 @@ AddToSGEntry(struct ubik_trans *tt, struct prentry *entry, afs_int32 loc, afs_in
 afs_int32
 AddToPRList(prlist *alist, int *sizeP, afs_int32 id)
 {
-    char *tmp;
+    afs_int32 *tmp;
     int count;
 
     if (alist->prlist_len >= *sizeP) {
        count = alist->prlist_len + 100;
        if (alist->prlist_val) {
-           tmp =
-               (char *)realloc(alist->prlist_val, count * sizeof(afs_int32));
+           tmp = realloc(alist->prlist_val, count * sizeof(afs_int32));
        } else {
-           tmp = (char *)malloc(count * sizeof(afs_int32));
+           tmp = malloc(count * sizeof(afs_int32));
        }
        if (!tmp)
            return (PRNOMEM);
-       alist->prlist_val = (afs_int32 *) tmp;
+       alist->prlist_val = tmp;
        *sizeP = count;
     }
     alist->prlist_val[alist->prlist_len++] = id;
@@ -1553,7 +1559,7 @@ GetListSG2(struct ubik_trans *at, afs_int32 gid, prlist *alist, afs_int32 *sizeP
            didsomething ? "TRUE" : "FALSE");
     if (predictflagged && didsomething != predictfound)
        fprintf(stderr, "**** for gid=%d, didsomething=%d predictfound=%d\n",
-               didsomething, predictfound);
+               gid, didsomething, predictfound);
 #endif
     if (didsomething)
        sg_found = add_map(sg_found, -gid);
@@ -1775,8 +1781,7 @@ Initdb(void)
     }
 
     if (build) {
-       /* Only rebuild database if the db was deleted (the header is zero) and we
-        * are running noAuth. */
+       /* 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++) {
@@ -1787,11 +1792,6 @@ Initdb(void)
                break;
            }
        }
-       if (!pr_noAuth) {
-           code = PRDBBAD;
-           afs_com_err(whoami, code,
-                       "Can't rebuild database because not running NoAuth");
-       }
     }
 
     if (code) {
@@ -1893,6 +1893,7 @@ ChangeEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 cid, char *name, afs
     struct prentry tentry, tent;
     afs_int32 loc;
     afs_int32 oldowner;
+    afs_int32 admin;
     char holder[PR_MAXNAMELEN];
     char temp[PR_MAXNAMELEN];
     char oldname[PR_MAXNAMELEN];
@@ -1906,18 +1907,17 @@ 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
+    admin = pr_noAuth || IsAMemberOf(at, cid, SYSADMINID);
 
     /* we're actually trying to change the id */
     if (newid && (newid != aid)) {
-       if (!IsAMemberOf(at, cid, SYSADMINID) && !pr_noAuth)
+       if (!admin)
            return PRPERM;
 
        pos = FindByID(at, newid);
@@ -2034,7 +2034,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) {
@@ -2108,7 +2108,11 @@ ChangeEntry(struct ubik_trans *at, afs_int32 aid, afs_int32 cid, char *name, afs
            /* don't let foreign cell groups change name */
            if (atsign != NULL)
                return PRPERM;
-           code = CorrectGroupName(at, name, cid, tentry.owner, tentry.name);
+
+           if (tentry.owner == 0 || tentry.owner == ANONYMOUSID)
+               tentry.owner = cid;
+
+           code = CorrectGroupName(at, name, cid, tentry.owner, admin, tentry.name);
            if (code)
                return code;
 
@@ -2173,13 +2177,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;
@@ -2195,7 +2199,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.
      */
 
@@ -2204,9 +2208,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
      */