pt_util: fix group line check for input files
[openafs.git] / src / ptserver / pt_util.c
index e0c01b4..138de38 100644 (file)
  *                  output of this program to be valid.
  */
 
-#include <sys/types.h>
-#include <sys/time.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/file.h>
-
 #include <afsconfig.h>
 #include <afs/param.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
 
+#ifndef _WIN32
+#include <sys/file.h>
+#else
+#define L_SET SEEK_SET
+#endif
+#include <ctype.h>
+
+#include <afs/com_err.h>
 #include <afs/cmd.h>           /*Command line parsing */
-#include <errno.h>
+#include <afs/afsutil.h>
 #include <lock.h>
-#include <netinet/in.h>
 #define UBIK_INTERNALS
 #include <ubik.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
-#include <afs/com_err.h>
+
 #include "ptint.h"
 #include "ptserver.h"
 #include "pterror.h"
+#include "ptprototypes.h"
 
 #define IDHash(x) (abs(x) % HASHSIZE)
 #define print_id(x) ( ((flags&DO_SYS)==0 && (x<-32767 || x>97536)) || \
@@ -46,15 +45,16 @@ extern char *optarg;
 extern int optind;
 
 int restricted = 0;
-int display_entry();
-void add_group();
-void display_groups();
-void display_group();
-void fix_pre();
-char *checkin();
-char *check_core();
-char *id_to_name();
-int CommandProc(struct cmd_syndesc *, void *);
+
+static int display_entry(int);
+static void add_group(long);
+static void display_groups(void);
+static void display_group(int);
+static void fix_pre(struct prentry *);
+static char *id_to_name(int);
+static char *checkin(struct prentry *);
+static char *check_core(int);
+static int CommandProc(struct cmd_syndesc *, void *);
 
 struct hash_entry {
     char h_name[PR_MAXNAMELEN];
@@ -103,8 +103,8 @@ int
 main(int argc, char **argv)
 {
 
-    register struct cmd_syndesc *cs;   /*Command line syntax descriptor */
-    register afs_int32 code;   /*Return code */
+    struct cmd_syndesc *cs;    /*Command line syntax descriptor */
+    afs_int32 code;    /*Return code */
 
     cs = cmd_CreateSyntax(NULL, CommandProc, NULL,
                          "access protection database");
@@ -128,16 +128,19 @@ main(int argc, char **argv)
 
 }
 
-int
-CommandProc(register struct cmd_syndesc *a_as, void *arock)
+static int
+CommandProc(struct cmd_syndesc *a_as, void *arock)
 {
-    register int i;
-    register long code;
-    long cc, upos, gpos;
+    int i;
+    long code = 0;
+    long upos;
+    long gpos = 0;
     struct prentry uentry, gentry;
     struct ubik_hdr *uh;
     char *dfile = 0;
-    char *pfile = "/usr/afs/db/prdb.DB0";
+    const char *pbase = AFSDIR_SERVER_PRDB_FILEPATH;
+    char *pfile = NULL;
+    char pbuffer[1028];
     struct cmd_parmdesc *tparm;
 
     tparm = a_as->parms;
@@ -170,6 +173,10 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
        dfile = tparm[8].items->data;
     }
 
+    if (pfile == NULL) {
+        snprintf(pbuffer, sizeof(pbuffer), "%s.DB0", pbase);
+        pfile = pbuffer;
+    }
     if ((dbase_fd = open(pfile, (wflag ? O_RDWR : O_RDONLY) | O_CREAT, 0600))
        < 0) {
        fprintf(stderr, "pt_util: cannot open %s: %s\n", pfile,
@@ -196,8 +203,9 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
        fprintf(stderr, "pt_util: %s: Bad UBIK_MAGIC. Is %x should be %x\n",
                pfile, ntohl(uh->magic), UBIK_MAGIC);
     memcpy(&uv, &uh->version, sizeof(struct ubik_version));
-    if (wflag && uv.epoch == 0 && uv.counter == 0) {
-       uv.epoch = 2;           /* a ubik version of 0 or 1 has special meaning */
+
+    if (wflag && ntohl(uv.epoch) == 0 && ntohl(uv.counter) == 0) {
+       uv.epoch = htonl(2); /* a ubik version of 0 or 1 has special meaning */
        memcpy(&uh->version, &uv, sizeof(struct ubik_version));
        lseek(dbase_fd, 0, SEEK_SET);
        if (write(dbase_fd, buffer, HDRSIZE) < 0) {
@@ -206,6 +214,11 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
            exit(1);
        }
     }
+
+    /* Now that any writeback is done, swap these */
+    uv.epoch = ntohl(uv.epoch);
+    uv.counter = ntohl(uv.counter);
+
     fprintf(stderr, "Ubik Version is: %d.%d\n", uv.epoch, uv.counter);
     if (read(dbase_fd, &prh, sizeof(struct prheader)) < 0) {
        fprintf(stderr, "pt_util: error reading %s: %s\n", pfile,
@@ -218,13 +231,26 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
 
     if (wflag) {
        struct usr_list *u;
+       int seenGroup = 0;
 
        while (fgets(buffer, sizeof(buffer), dfp)) {
            int id, oid, cid, flags, quota, uid;
            char name[PR_MAXNAMELEN], mem[PR_MAXNAMELEN];
 
            if (isspace(*buffer)) {
-               sscanf(buffer, "%s %d", mem, &uid);
+               code = sscanf(buffer, "%s %d", mem, &uid);
+               if (code != 2) {
+                   fprintf(stderr,
+                           "Insuffient data provided for group membership\n");
+                   exit(1);
+               }
+
+               if (!seenGroup) {
+                   fprintf(stderr,
+                           "Group member %s listed outside of group\n",
+                           mem);
+                   exit(1);
+               }
 
                for (u = usr_head; u; u = u->next)
                    if (u->uid && u->uid == uid)
@@ -274,8 +300,15 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
                    fprintf(stderr, "Error while adding %s to %s: %s\n", mem,
                            name, afs_error_message(code));
            } else {
-               sscanf(buffer, "%s %d/%d %d %d %d", name, &flags, &quota, &id,
-                      &oid, &cid);
+               code = sscanf(buffer, "%s %d/%d %d %d %d", name, &flags, &quota, &id,
+                             &oid, &cid);
+               if (code != 6) {
+                   fprintf(stderr,
+                           "Insufficient data provided for user/group\n");
+                   exit(1);
+               }
+
+               seenGroup = 1;
 
                if (FindByID(0, id))
                    code = PRIDEXIST;
@@ -283,7 +316,7 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
                    code = CreateEntry(0, name, &id, 1 /*idflag */ ,
                                       flags & PRGRP, oid, cid);
                if (code == PRBADNAM) {
-                   u = (struct usr_list *)malloc(sizeof(struct usr_list));
+                   u = malloc(sizeof(struct usr_list));
                    u->next = usr_head;
                    u->uid = id;
                    strcpy(u->name, name);
@@ -315,8 +348,16 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
     } else {
        for (i = 0; i < HASHSIZE; i++) {
            upos = nflag ? ntohl(prh.nameHash[i]) : ntohl(prh.idHash[i]);
-           while (upos)
-               upos = display_entry(upos);
+           while (upos) {
+               long newpos;
+               newpos = display_entry(upos);
+               if (newpos == upos) {
+                   fprintf(stderr, "pt_util: hash error in %s chain %d\n",
+                           nflag ? "name":"id", i);
+                   exit(1);
+               } else
+                   upos = newpos;
+           }
        }
        if (flags & DO_GRP)
            display_groups();
@@ -329,6 +370,10 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
        exit(1);
     }
     uh = (struct ubik_hdr *)buffer;
+
+    uh->version.epoch = ntohl(uh->version.epoch);
+    uh->version.counter = ntohl(uh->version.counter);
+
     if ((uh->version.epoch != uv.epoch)
        || (uh->version.counter != uv.counter)) {
        fprintf(stderr,
@@ -340,11 +385,9 @@ CommandProc(register struct cmd_syndesc *a_as, void *arock)
     exit(0);
 }
 
-int
+static int
 display_entry(int offset)
 {
-    register int i;
-
     lseek(dbase_fd, offset + HDRSIZE, L_SET);
     read(dbase_fd, &pre, sizeof(struct prentry));
 
@@ -364,15 +407,15 @@ display_entry(int offset)
     return (nflag ? pre.nextName : pre.nextID);
 }
 
-void
+static void
 add_group(long id)
 {
     struct grp_list *g;
-    register long i;
+    long i;
 
     i = grp_count++ % 1024;
     if (i == 0) {
-       g = (struct grp_list *)malloc(sizeof(struct grp_list));
+       g = malloc(sizeof(struct grp_list));
        g->next = grp_head;
        grp_head = g;
     }
@@ -380,10 +423,10 @@ add_group(long id)
     g->groups[i] = id;
 }
 
-void
-display_groups()
+static void
+display_groups(void)
 {
-    register int i, id;
+    int i, id;
     struct grp_list *g;
 
     g = grp_head;
@@ -399,10 +442,10 @@ display_groups()
     }
 }
 
-void
+static void
 display_group(int id)
 {
-    register int i, offset;
+    int i, offset;
     int print_grp = 0;
 
     offset = ntohl(prh.idHash[IDHash(id)]);
@@ -470,10 +513,10 @@ display_group(int id)
     }
 }
 
-void
+static void
 fix_pre(struct prentry *pre)
 {
-    register int i;
+    int i;
 
     pre->flags = ntohl(pre->flags);
     pre->id = ntohl(pre->id);
@@ -497,10 +540,10 @@ fix_pre(struct prentry *pre)
     }
 }
 
-char *
+static char *
 id_to_name(int id)
 {
-    register int offset;
+    int offset;
     static struct prentry pre;
     char *name;
 
@@ -524,11 +567,11 @@ id_to_name(int id)
     return 0;
 }
 
-char *
+static char *
 checkin(struct prentry *pre)
 {
     struct hash_entry *he, *last;
-    register int id;
+    int id;
 
     id = pre->id;
     last = (struct hash_entry *)0;
@@ -539,7 +582,7 @@ checkin(struct prentry *pre)
        last = he;
        he = he->next;
     }
-    he = (struct hash_entry *)malloc(sizeof(struct hash_entry));
+    he = malloc(sizeof(struct hash_entry));
     if (he == 0) {
        fprintf(stderr, "pt_util: No Memory for internal hash table.\n");
        exit(1);
@@ -554,8 +597,8 @@ checkin(struct prentry *pre)
     return (he->h_name);
 }
 
-char *
-check_core(register int id)
+static char *
+check_core(int id)
 {
     struct hash_entry *he;
     he = hat[IDHash(id)];