bozo: Log each dir and file with bad access rights
[openafs.git] / src / bozo / bosoprocs.c
index 98eaa78..bbf5c33 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -9,37 +9,27 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
 
-#include <afs/stds.h>
-#include <sys/types.h>
 #ifdef AFS_NT40_ENV
-#include <io.h>
-#include <fcntl.h>
 #include <sys/utime.h>
-#else
-#include <sys/file.h>
-#include <netinet/in.h>
 #endif /* AFS_NT40_ENV */
+
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <rx/rxkad.h>
-#include <errno.h>
 #include <afs/cellconfig.h>
 #include <afs/keys.h>
-#include <sys/stat.h>
-#include <des.h>
-#include <dirent.h>
-#include <stdio.h>
 #include <afs/afsutil.h>
 #include <afs/fileutil.h>
 #include <afs/ktime.h>
 #include <afs/audit.h>
-#include <string.h>
+#include <afs/kautils.h>
 
 #include "bnode.h"
+#include "bnode_internal.h"
 #include "bosint.h"
 #include "bosprototypes.h"
 
@@ -48,17 +38,12 @@ extern struct ktime bozo_nextRestartKT, bozo_nextDayKT;
 extern struct afsconf_dir *bozo_confdir;
 extern int bozo_newKTs;
 extern int DoLogging;
-#ifdef BOS_RESTRICTED_MODE
 extern int bozo_isrestricted;
-#endif
 
 afs_int32
-SBOZO_GetRestartTime(acall, atype, aktime)
-     struct rx_call *acall;
-     afs_int32 atype;
-     struct bozo_netKTime *aktime;
+SBOZO_GetRestartTime(struct rx_call *acall, afs_int32 atype, struct bozo_netKTime *aktime)
 {
-    register afs_int32 code;
+    afs_int32 code;
 
     code = 0;                  /* assume success */
     switch (atype) {
@@ -79,12 +64,9 @@ SBOZO_GetRestartTime(acall, atype, aktime)
 }
 
 afs_int32
-SBOZO_SetRestartTime(acall, atype, aktime)
-     struct rx_call *acall;
-     afs_int32 atype;
-     struct bozo_netKTime *aktime;
+SBOZO_SetRestartTime(struct rx_call *acall, afs_int32 atype, struct bozo_netKTime *aktime)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     /* check for proper permissions */
@@ -122,9 +104,7 @@ SBOZO_SetRestartTime(acall, atype, aktime)
 }
 
 afs_int32
-SBOZO_Exec(acall, acmd)
-     struct rx_call *acall;
-     char *acmd;
+SBOZO_Exec(struct rx_call *acall, char *acmd)
 {
 
     char caller[MAXKTCNAMELEN];
@@ -134,12 +114,10 @@ SBOZO_Exec(acall, acmd)
        code = BZACCESS;
        goto fail;
     }
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted) {
        code = BZACCESS;
        goto fail;
     }
-#endif
     if (DoLogging)
        bozo_Log("%s is executing the shell command '%s'\n", caller, acmd);
 
@@ -153,49 +131,50 @@ SBOZO_Exec(acall, acmd)
 }
 
 afs_int32
-SBOZO_GetDates(acall, aname, atime, abakTime, aoldTime)
-     struct rx_call *acall;
-     char *aname;
-     afs_int32 *atime, *abakTime, *aoldTime;
+SBOZO_GetDates(struct rx_call *acall, char *aname, afs_int32 *atime,
+              afs_int32 *abakTime, afs_int32 *aoldTime)
 {
     struct stat tstat;
-    char *strp;
-    char tbuffer[AFSDIR_PATH_MAX];
+    char *filepath = NULL, *fpBak = NULL, *fpOld = NULL;
 
     *atime = *abakTime = *aoldTime = 0;
 
     /* construct local path from canonical (wire-format) path */
-    if (ConstructLocalBinPath(aname, &strp)) {
+    if (ConstructLocalBinPath(aname, &filepath)) {
        return 0;
     }
-    strcpy(tbuffer, strp);
-    free(strp);
-
-    strp = tbuffer + strlen(tbuffer);
+    if (asprintf(&fpBak, "%s.BAK", filepath) < 0) {
+       fpBak = NULL;
+       goto out;
+    }
+    if (asprintf(&fpOld, "%s.OLD", filepath) < 0) {
+       fpOld = NULL;
+       goto out;
+    }
 
-    if (!stat(tbuffer, &tstat)) {
+    if (!stat(filepath, &tstat)) {
        *atime = tstat.st_mtime;
     }
 
-    strcpy(strp, ".BAK");
-    if (!stat(tbuffer, &tstat)) {
+    if (!stat(fpBak, &tstat)) {
        *abakTime = tstat.st_mtime;
     }
 
-    strcpy(strp, ".OLD");
-    if (!stat(tbuffer, &tstat)) {
+    if (!stat(fpOld, &tstat)) {
        *aoldTime = tstat.st_mtime;
     }
+out:
+    free(fpOld);
+    free(fpBak);
+    free(filepath);
     return 0;
 }
 
 afs_int32
-SBOZO_UnInstall(acall, aname)
-     struct rx_call *acall;
-     register char *aname;
+SBOZO_UnInstall(struct rx_call *acall, char *aname)
 {
-    char *filepath;
-    char fpOld[AFSDIR_PATH_MAX], fpBak[AFSDIR_PATH_MAX];
+    char *filepath = NULL;
+    char *fpOld = NULL, *fpBak = NULL;
     afs_int32 code;
     char caller[MAXKTCNAMELEN];
     struct stat tstat;
@@ -205,13 +184,11 @@ SBOZO_UnInstall(acall, aname)
        osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
        return code;
     }
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted) {
        code = BZACCESS;
        osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, aname, AUD_END);
        return code;
     }
-#endif
 
     /* construct local path from canonical (wire-format) path */
     if (ConstructLocalBinPath(aname, &filepath)) {
@@ -221,26 +198,35 @@ SBOZO_UnInstall(acall, aname)
     if (DoLogging)
        bozo_Log("%s is executing UnInstall '%s'\n", caller, filepath);
 
-    strcpy(fpBak, filepath);
-    strcat(fpBak, ".BAK");
-    strcpy(fpOld, filepath);
-    strcat(fpOld, ".OLD");
+    if (asprintf(&fpBak, "%s.BAK", filepath) < 0) {
+       code = BZIO;
+       fpBak = NULL;
+       goto out;
+    }
+    if (asprintf(&fpOld, "%s.OLD", filepath) < 0) {
+       code = BZIO;
+       fpOld = NULL;
+       goto out;
+    }
 
-    code = renamefile(fpBak, filepath);
+    code = rk_rename(fpBak, filepath);
     if (code) {
        /* can't find .BAK, try .OLD */
-       code = renamefile(fpOld, filepath);
+       code = rk_rename(fpOld, filepath);
        if (code && errno == ENOENT)    /* If doesn't exist don't fail */
            code = 0;
     } else {
        /* now rename .OLD to .BAK */
        if (stat(fpOld, &tstat) == 0)
-           code = renamefile(fpOld, fpBak);
+           code = rk_rename(fpOld, fpBak);
     }
     if (code)
        code = errno;
 
+out:
     osi_auditU(acall, BOS_UnInstallEvent, code, AUD_STR, filepath, AUD_END);
+    free(fpBak);
+    free(fpOld);
     free(filepath);
 
     return code;
@@ -250,22 +236,26 @@ SBOZO_UnInstall(acall, aname)
 static void
 SaveOldFiles(char *aname)
 {
-    register afs_int32 code;
-    char bbuffer[AFSDIR_PATH_MAX], obuffer[AFSDIR_PATH_MAX];
+    afs_int32 code;
+    char *bbuffer = NULL, *obuffer = NULL;
     struct stat tstat;
-    register afs_int32 now;
+    afs_int32 now;
     afs_int32 oldTime, bakTime;
 
-    strcpy(bbuffer, aname);
-    strcat(bbuffer, ".BAK");
-    strcpy(obuffer, aname);
-    strcat(obuffer, ".OLD");
     now = FT_ApproxTime();
 
     code = stat(aname, &tstat);
     if (code < 0)
        return;                 /* can't stat file */
 
+    if (asprintf(&bbuffer, "%s.BAK", aname) < 0)
+       return;
+
+    if (asprintf(&obuffer, "%s.OLD", aname) < 0) {
+       obuffer = NULL;
+       goto out;
+    }
+
     code = stat(obuffer, &tstat);      /* discover old file's time */
     if (code)
        oldTime = 0;
@@ -280,23 +270,22 @@ SaveOldFiles(char *aname)
 
     if (bakTime && (oldTime == 0 || bakTime < now - BOZO_OLDTIME)) {
        /* no .OLD file, or .BAK is at least a week old */
-       code = renamefile(bbuffer, obuffer);
+       rk_rename(bbuffer, obuffer);
     }
 
     /* finally rename to .BAK extension */
-    renamefile(aname, bbuffer);
+    rk_rename(aname, bbuffer);
+
+out:
+    free(bbuffer);
+    free(obuffer);
 }
 
 afs_int32
-SBOZO_Install(acall, aname, asize, mode, amtime)
-     struct rx_call *acall;
-     char *aname;
-     afs_int32 asize;
-     afs_int32 amtime;
-     afs_int32 mode;
+SBOZO_Install(struct rx_call *acall, char *aname, afs_int32 asize, afs_int32 mode, afs_int32 amtime)
 {
-    afs_int32 code;
-    int fd;
+    afs_int32 code, ret = 0;
+    int fd = -1;
     afs_int32 len;
     afs_int32 total;
 #ifdef AFS_NT40_ENV
@@ -304,64 +293,67 @@ SBOZO_Install(acall, aname, asize, mode, amtime)
 #else
     struct timeval tvb[2];
 #endif
-    char filepath[AFSDIR_PATH_MAX], tbuffer[AFSDIR_PATH_MAX], *fpp;
+    char *filepath = NULL, *fpNew = NULL, *tbuffer = NULL;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller))
        return BZACCESS;
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted)
        return BZACCESS;
-#endif
 
     /* construct local path from canonical (wire-format) path */
-    if (ConstructLocalBinPath(aname, &fpp)) {
+    if (ConstructLocalBinPath(aname, &filepath)) {
        return BZNOENT;
     }
-    strcpy(filepath, fpp);
-    free(fpp);
+    if (asprintf(&fpNew, "%s.NEW", filepath) < 0) {
+       ret = ENOMEM;
+       fpNew = NULL;
+       goto out;
+    }
+    tbuffer = malloc(AFSDIR_PATH_MAX);
+    if (tbuffer == NULL) {
+       ret =  ENOMEM;
+       goto out;
+    }
 
     if (DoLogging)
        bozo_Log("%s is executing Install '%s'\n", caller, filepath);
 
     /* open file */
-    fpp = filepath + strlen(filepath);
-    strcpy(fpp, ".NEW");       /* append ".NEW" to end of filepath */
-    fd = open(filepath, O_CREAT | O_RDWR | O_TRUNC, 0777);
-    if (fd < 0)
-       return errno;
+    fd = open(fpNew, O_CREAT | O_RDWR | O_TRUNC, 0777);
+    if (fd < 0) {
+       ret =  errno;
+       goto out;
+    }
     total = 0;
     while (1) {
        len = rx_Read(acall, tbuffer, sizeof(tbuffer));
        if (len < 0) {
-           close(fd);
-           unlink(filepath);
-           return 102;
+           unlink(fpNew);
+           ret =  102;
+           goto out;
        }
        if (len == 0)
            break;              /* no more input */
        code = write(fd, tbuffer, len);
        if (code != len) {
-           close(fd);
-           unlink(filepath);
-           return 100;
+           unlink(fpNew);
+           ret =  100;
+           goto out;
        }
        total += len;           /* track total written for safety check at end */
     }
-    close(fd);
     if (asize != total) {
-       unlink(filepath);
-       return 101;             /* wrong size */
+       unlink(fpNew);
+       ret =  101;             /* wrong size */
+       goto out;
     }
 
     /* save old files */
-    *fpp = '\0';               /* remove ".NEW" from end of filepath */
     SaveOldFiles(filepath);    /* don't care if it works, still install */
 
     /* all done, rename to final name */
-    strcpy(tbuffer, filepath);
-    strcat(tbuffer, ".NEW");
-    code = (renamefile(tbuffer, filepath) ? errno : 0);
+    code = (rk_rename(fpNew, filepath) ? errno : 0);
 
     /* label file with same time for our sanity */
 #ifdef AFS_NT40_ENV
@@ -378,18 +370,24 @@ SBOZO_Install(acall, aname, asize, mode, amtime)
 
     if (code < 0) {
        osi_auditU(acall, BOS_InstallEvent, code, AUD_STR, filepath, AUD_END);
-       return errno;
-    } else
-       return 0;
+       ret = errno;
+       goto out;
+    }
+    ret = 0;
+out:
+    if (fd >= 0)
+       close(fd);
+    free(filepath);
+    free(fpNew);
+    free(tbuffer);
+    return ret;
 }
 
 afs_int32
-SBOZO_SetCellName(acall, aname)
-     struct rx_call *acall;
-     char *aname;
+SBOZO_SetCellName(struct rx_call *acall, char *aname)
 {
     struct afsconf_cell tcell;
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
     char clones[MAXHOSTSPERCELL];
 
@@ -402,7 +400,7 @@ SBOZO_SetCellName(acall, aname)
 
     code =
        afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
-                                   &clones);
+                                   clones);
     if (code)
        goto fail;
 
@@ -418,7 +416,7 @@ SBOZO_SetCellName(acall, aname)
     strcpy(tcell.name, aname);
     code =
        afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
-                                   &tcell, &clones);
+                                   &tcell, clones);
 
   fail:
     osi_auditU(acall, BOS_SetCellEvent, code, AUD_STR, aname, AUD_END);
@@ -426,40 +424,34 @@ SBOZO_SetCellName(acall, aname)
 }
 
 afs_int32
-SBOZO_GetCellName(acall, aname)
-     struct rx_call *acall;
-     char **aname;
+SBOZO_GetCellName(struct rx_call *acall, char **aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char tname[MAXCELLCHARS];
 
     code = afsconf_GetLocalCell(bozo_confdir, tname, sizeof(tname));
     if (code) {
        /* must set output parameters even if aborting */
-       *aname = (char *)malloc(1);
+       *aname = malloc(1);
        **aname = 0;
     } else {
-       *aname = (char *)malloc(strlen(tname) + 1);
-       strcpy(*aname, tname);
+       *aname = strdup(tname);
     }
 
     return code;
 }
 
 afs_int32
-SBOZO_GetCellHost(acall, awhich, aname)
-     struct rx_call *acall;
-     afs_uint32 awhich;
-     char **aname;
+SBOZO_GetCellHost(struct rx_call *acall, afs_uint32 awhich, char **aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct afsconf_cell tcell;
-    register char *tp;
+    char *tp;
     char clones[MAXHOSTSPERCELL];
 
     code =
        afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
-                                   &clones);
+                                   clones);
     if (code)
        goto fail;
 
@@ -469,17 +461,19 @@ SBOZO_GetCellHost(acall, awhich, aname)
     }
 
     tp = tcell.hostName[awhich];
-    *aname = (char *)malloc(strlen(tp) + 3);
     if (clones[awhich]) {
-       strcpy(*aname, "[");
-       strcat(*aname, tp);
-       strcat(*aname, "]");
+       if (asprintf(aname, "[%s]", tp) < 0)
+           *aname = NULL;
     } else
-       strcpy(*aname, tp);
+       *aname = strdup(tp);
+    if (*aname == NULL) {
+       code = BZIO;
+       goto fail;
+    }
     goto done;
 
   fail:
-    *aname = (char *)malloc(1);        /* return fake string */
+    *aname = malloc(1);        /* return fake string */
     **aname = 0;
 
   done:
@@ -487,14 +481,12 @@ SBOZO_GetCellHost(acall, awhich, aname)
 }
 
 afs_int32
-SBOZO_DeleteCellHost(acall, aname)
-     struct rx_call *acall;
-     char *aname;
+SBOZO_DeleteCellHost(struct rx_call *acall, char *aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct afsconf_cell tcell;
     afs_int32 which;
-    register int i;
+    int i;
     char caller[MAXKTCNAMELEN];
     char clones[MAXHOSTSPERCELL];
 
@@ -507,7 +499,7 @@ SBOZO_DeleteCellHost(acall, aname)
 
     code =
        afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
-                                   &clones);
+                                   clones);
     if (code)
        goto fail;
 
@@ -528,7 +520,7 @@ SBOZO_DeleteCellHost(acall, aname)
     memset(tcell.hostName[which], 0, MAXHOSTCHARS);
     code =
        afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
-                                   &tcell, &clones);
+                                   &tcell, clones);
 
   fail:
     osi_auditU(acall, BOS_DeleteHostEvent, code, AUD_STR, aname, AUD_END);
@@ -536,14 +528,12 @@ SBOZO_DeleteCellHost(acall, aname)
 }
 
 afs_int32
-SBOZO_AddCellHost(acall, aname)
-     struct rx_call *acall;
-     char *aname;
+SBOZO_AddCellHost(struct rx_call *acall, char *aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     struct afsconf_cell tcell;
     afs_int32 which;
-    register int i;
+    int i;
     char caller[MAXKTCNAMELEN];
     char clones[MAXHOSTSPERCELL];
     char *n;
@@ -558,7 +548,7 @@ SBOZO_AddCellHost(acall, aname)
 
     code =
        afsconf_GetExtendedCellInfo(bozo_confdir, NULL, NULL, &tcell,
-                                   &clones);
+                                   clones);
     if (code)
        goto fail;
 
@@ -611,7 +601,7 @@ SBOZO_AddCellHost(acall, aname)
     clones[which] = isClone;
     code =
        afsconf_SetExtendedCellInfo(bozo_confdir, AFSDIR_SERVER_ETC_DIRPATH,
-                                   &tcell, &clones);
+                                   &tcell, clones);
 
   fail:
     osi_auditU(acall, BOS_AddHostEvent, code, AUD_STR, aname, AUD_END);
@@ -619,17 +609,13 @@ SBOZO_AddCellHost(acall, aname)
 }
 
 afs_int32
-SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
-     struct rx_call *acall;
-     afs_int32 an;
-     afs_int32 *akvno;
-     struct bozo_keyInfo *akeyinfo;
-     struct bozo_key *akey;
+SBOZO_ListKeys(struct rx_call *acall, afs_int32 an, afs_int32 *akvno,
+              struct bozo_key *akey, struct bozo_keyInfo *akeyinfo)
 {
     struct afsconf_keys tkeys;
-    register afs_int32 code;
+    afs_int32 code;
     struct stat tstat;
-    int noauth;
+    int noauth = 0;
     char caller[MAXKTCNAMELEN];
     rxkad_level enc_level = rxkad_clear;
 
@@ -652,8 +638,8 @@ SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
     memset(akeyinfo, 0, sizeof(struct bozo_keyInfo));
 
     noauth = afsconf_GetNoAuthFlag(bozo_confdir);
-    rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
-    /* 
+    rxkad_GetServerInfo(rx_ConnectionOf(acall), &enc_level, 0, 0, 0, 0, 0);
+    /*
      * only return actual keys in noauth or if this is an encrypted connection
      */
 
@@ -666,8 +652,11 @@ SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
     if (code == 0) {
        akeyinfo->mod_sec = tstat.st_mtime;
     }
-    ka_KeyCheckSum(tkeys.key[an].key, &akeyinfo->keyCheckSum);
-    /* only errors is bad key parity */
+
+    /* This will return an error if the key is 'bad' (bad checksum, weak DES
+     * key, etc). But we don't care, since we can still return the other
+     * information about the key, so ignore the result. */
+    (void)ka_KeyCheckSum(tkeys.key[an].key, &akeyinfo->keyCheckSum);
 
   fail:
     if (noauth)
@@ -677,12 +666,9 @@ SBOZO_ListKeys(acall, an, akvno, akey, akeyinfo)
 }
 
 afs_int32
-SBOZO_AddKey(acall, an, akey)
-     struct rx_call *acall;
-     afs_int32 an;
-     struct bozo_key *akey;
+SBOZO_AddKey(struct rx_call *acall, afs_int32 an, struct bozo_key *akey)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
     rxkad_level enc_level = rxkad_clear;
     int noauth;
@@ -692,7 +678,7 @@ SBOZO_AddKey(acall, an, akey)
        goto fail;
     }
     noauth = afsconf_GetNoAuthFlag(bozo_confdir);
-    rxkad_GetServerInfo(acall->conn, &enc_level, 0, 0, 0, 0, 0);
+    rxkad_GetServerInfo(rx_ConnectionOf(acall), &enc_level, 0, 0, 0, 0, 0);
     if ((!noauth) && (enc_level != rxkad_crypt)) {
        code = BZENCREQ;
        goto fail;
@@ -700,7 +686,7 @@ SBOZO_AddKey(acall, an, akey)
     if (DoLogging)
        bozo_Log("%s is executing AddKey\n", caller);
 
-    code = afsconf_AddKey(bozo_confdir, an, akey, 0);
+    code = afsconf_AddKey(bozo_confdir, an, akey->data, 0);
     if (code == AFSCONF_KEYINUSE)
        code = BZKEYINUSE;      /* Unique code for afs rpc calls */
   fail:
@@ -709,11 +695,9 @@ SBOZO_AddKey(acall, an, akey)
 }
 
 afs_int32
-SBOZO_SetNoAuthFlag(acall, aflag)
-     register struct rx_call *acall;
-     afs_int32 aflag;
+SBOZO_SetNoAuthFlag(struct rx_call *acall, afs_int32 aflag)
 {
-    register afs_int32 code = 0;
+    afs_int32 code = 0;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -731,11 +715,9 @@ SBOZO_SetNoAuthFlag(acall, aflag)
 }
 
 afs_int32
-SBOZO_DeleteKey(acall, an)
-     struct rx_call *acall;
-     afs_int32 an;
+SBOZO_DeleteKey(struct rx_call *acall, afs_int32 an)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -754,15 +736,12 @@ SBOZO_DeleteKey(acall, an)
 
 
 afs_int32
-SBOZO_ListSUsers(acall, an, aname)
-     struct rx_call *acall;
-     afs_int32 an;
-     register char **aname;
+SBOZO_ListSUsers(struct rx_call *acall, afs_int32 an, char **aname)
 {
-    register afs_int32 code;
-    register char *tp;
+    afs_int32 code;
+    char *tp;
 
-    tp = *aname = (char *)malloc(256);
+    tp = *aname = malloc(256);
     *tp = 0;                   /* in case getnthuser doesn't null-terminate the string */
     code = afsconf_GetNthUser(bozo_confdir, an, tp, 256);
 
@@ -772,11 +751,9 @@ SBOZO_ListSUsers(acall, an, aname)
 }
 
 afs_int32
-SBOZO_AddSUser(acall, aname)
-     struct rx_call *acall;
-     char *aname;
+SBOZO_AddSUser(struct rx_call *acall, char *aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -794,11 +771,9 @@ SBOZO_AddSUser(acall, aname)
 }
 
 afs_int32
-SBOZO_DeleteSUser(acall, aname)
-     struct rx_call *acall;
-     char *aname;
+SBOZO_DeleteSUser(struct rx_call *acall, char *aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -817,12 +792,9 @@ SBOZO_DeleteSUser(acall, aname)
 }
 
 afs_int32
-SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
-     struct rx_call *acall;
-     char *atype;
-     char *ainstance;
-     char *ap1, *ap2, *ap3, *ap4, *ap5;
-     char *notifier;
+SBOZO_CreateBnode(struct rx_call *acall, char *atype, char *ainstance,
+                 char *ap1, char *ap2, char *ap3, char *ap4, char *ap5,
+                  char *notifier)
 {
     struct bnode *tb;
     afs_int32 code;
@@ -832,17 +804,21 @@ SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
        code = BZACCESS;
        goto fail;
     }
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted) {
+       const char *salvpath = AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH;
+       /* for DAFS, 'bos salvage' will pass "salvageserver -client" instead */
+       const char *salsrvpath = AFSDIR_CANONICAL_SERVER_SALSRV_FILEPATH " -client ";
+
+       /* still allow 'bos salvage' to work */
        if (strcmp(atype, "cron") || strcmp(ainstance, "salvage-tmp")
            || strcmp(ap2, "now")
-           || strncmp(ap1, AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH,
-                      strlen(AFSDIR_CANONICAL_SERVER_SALVAGER_FILEPATH))) {
+           || (strncmp(ap1, salvpath, strlen(salvpath))
+               && strncmp(ap1, salsrvpath, strlen(salsrvpath)))) {
+
            code = BZACCESS;
            goto fail;
        }
     }
-#endif
 
     code =
        bnode_Create(atype, ainstance, &tb, ap1, ap2, ap3, ap4, ap5, notifier,
@@ -856,10 +832,9 @@ SBOZO_CreateBnode(acall, atype, ainstance, ap1, ap2, ap3, ap4, ap5, notifier)
 }
 
 afs_int32
-SBOZO_WaitAll(acall)
-     register struct rx_call *acall;
+SBOZO_WaitAll(struct rx_call *acall)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -878,23 +853,19 @@ SBOZO_WaitAll(acall)
 }
 
 afs_int32
-SBOZO_DeleteBnode(acall, ainstance)
-     struct rx_call *acall;
-     char *ainstance;
+SBOZO_DeleteBnode(struct rx_call *acall, char *ainstance)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
        code = BZACCESS;
        goto fail;
     }
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted) {
        code = BZACCESS;
        goto fail;
     }
-#endif
     if (DoLogging)
        bozo_Log("%s is executing DeleteBnode '%s'\n", caller, ainstance);
 
@@ -906,10 +877,8 @@ SBOZO_DeleteBnode(acall, ainstance)
     return code;
 }
 
-static
-swproc(abnode, arock)
-     register struct bnode *abnode;
-     char *arock;
+static int
+swproc(struct bnode *abnode, void *arock)
 {
     if (abnode->goal == BSTAT_NORMAL)
        return 0;               /* this one's not shutting down */
@@ -920,24 +889,21 @@ swproc(abnode, arock)
     return 0;                  /* don't stop apply function early, no matter what */
 }
 
-static
-stproc(abnode, arock)
-     struct bnode *abnode;
-     char *arock;
+static int
+stproc(struct bnode *abnode, void *arock)
 {
     if (abnode->fileGoal == BSTAT_SHUTDOWN)
        return 0;               /* don't do these guys */
 
     bnode_Hold(abnode);
+    bnode_ResetErrorCount(abnode);
     bnode_SetStat(abnode, BSTAT_NORMAL);
     bnode_Release(abnode);
     return 0;
 }
 
-static
-sdproc(abnode, arock)
-     struct bnode *abnode;
-     char *arock;
+static int
+sdproc(struct bnode *abnode, void *arock)
 {
     bnode_Hold(abnode);
     bnode_SetStat(abnode, BSTAT_SHUTDOWN);
@@ -947,11 +913,10 @@ sdproc(abnode, arock)
 
 /* shutdown and leave down */
 afs_int32
-SBOZO_ShutdownAll(acall)
-     struct rx_call *acall;
+SBOZO_ShutdownAll(struct rx_call *acall)
 {
     /* iterate over all bnodes, setting the status to temporarily disabled */
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     /* check for authorization */
@@ -971,10 +936,9 @@ SBOZO_ShutdownAll(acall)
 
 /* shutdown and restart */
 afs_int32
-SBOZO_RestartAll(acall)
-     struct rx_call *acall;
+SBOZO_RestartAll(struct rx_call *acall)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -1003,10 +967,9 @@ SBOZO_RestartAll(acall)
 }
 
 afs_int32
-SBOZO_ReBozo(acall)
-     register struct rx_call *acall;
+SBOZO_ReBozo(struct rx_call *acall)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     /* acall is null if called internally to restart bosserver */
@@ -1048,10 +1011,9 @@ SBOZO_ReBozo(acall)
 
 /* make sure all are running */
 afs_int32
-SBOZO_StartupAll(acall)
-     struct rx_call *acall;
+SBOZO_StartupAll(struct rx_call *acall)
 {
-    register afs_int32 code;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -1068,12 +1030,10 @@ SBOZO_StartupAll(acall)
 }
 
 afs_int32
-SBOZO_Restart(acall, ainstance)
-     struct rx_call *acall;
-     register char *ainstance;
+SBOZO_Restart(struct rx_call *acall, char *ainstance)
 {
-    register struct bnode *tb;
-    register afs_int32 code;
+    struct bnode *tb;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -1089,12 +1049,10 @@ SBOZO_Restart(acall, ainstance)
        goto fail;
     }
 
-    /* setup return code */
-    code = 0;
-
     bnode_Hold(tb);
     bnode_SetStat(tb, BSTAT_SHUTDOWN);
     code = bnode_WaitStatus(tb, BSTAT_SHUTDOWN);       /* this can fail */
+    bnode_ResetErrorCount(tb);
     bnode_SetStat(tb, BSTAT_NORMAL);
     bnode_Release(tb);
 
@@ -1105,13 +1063,10 @@ SBOZO_Restart(acall, ainstance)
 
 /* set temp status */
 afs_int32
-SBOZO_SetTStatus(acall, ainstance, astatus)
-     struct rx_call *acall;
-     char *ainstance;
-     afs_int32 astatus;
+SBOZO_SetTStatus(struct rx_call *acall, char *ainstance, afs_int32 astatus)
 {
-    register struct bnode *tb;
-    register afs_int32 code;
+    struct bnode *tb;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -1127,6 +1082,7 @@ SBOZO_SetTStatus(acall, ainstance, astatus)
        goto fail;
     }
     bnode_Hold(tb);
+    bnode_ResetErrorCount(tb);
     code = bnode_SetStat(tb, astatus);
     bnode_Release(tb);
 
@@ -1137,13 +1093,10 @@ SBOZO_SetTStatus(acall, ainstance, astatus)
 }
 
 afs_int32
-SBOZO_SetStatus(acall, ainstance, astatus)
-     struct rx_call *acall;
-     char *ainstance;
-     afs_int32 astatus;
+SBOZO_SetStatus(struct rx_call *acall, char *ainstance, afs_int32 astatus)
 {
-    register struct bnode *tb;
-    register afs_int32 code;
+    struct bnode *tb;
+    afs_int32 code;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
@@ -1170,14 +1123,11 @@ SBOZO_SetStatus(acall, ainstance, astatus)
 }
 
 afs_int32
-SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
-     struct rx_call *acall;
-     char *ainstance;
-     afs_int32 *astat;
-     char **astatDescr;
+SBOZO_GetStatus(struct rx_call *acall, char *ainstance, afs_int32 *astat,
+               char **astatDescr)
 {
-    register struct bnode *tb;
-    register afs_int32 code;
+    struct bnode *tb;
+    afs_int32 code;
 
     tb = bnode_FindInstance(ainstance);
     if (!tb) {
@@ -1192,7 +1142,7 @@ SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
        goto fail;
     }
 
-    *astatDescr = (char *)malloc(BOZO_BSSIZE);
+    *astatDescr = malloc(BOZO_BSSIZE);
     code = bnode_GetString(tb, *astatDescr, BOZO_BSSIZE);
     bnode_Release(tb);
     if (code)
@@ -1200,7 +1150,7 @@ SBOZO_GetStatus(acall, ainstance, astat, astatDescr)
     return 0;
 
   fail:
-    *astatDescr = (char *)malloc(1);
+    *astatDescr = malloc(1);
     **astatDescr = 0;
     return code;
 }
@@ -1210,11 +1160,11 @@ struct eidata {
     int counter;
 };
 
-static
-eifunc(abnode, arock)
-     struct bnode *abnode;
-     struct eidata *arock;
+static int
+eifunc(struct bnode *abnode, void *param)
 {
+    struct eidata *arock = (struct eidata *)param;
+
     if (arock->counter-- == 0) {
        /* done */
        strcpy(arock->iname, abnode->name);
@@ -1225,39 +1175,33 @@ eifunc(abnode, arock)
     }
 }
 
-static
-ZapFile(adir, aname)
-     register char *adir;
-     register char *aname;
+static int
+ZapFile(const char *adir, const char *aname)
 {
     char tbuffer[256];
-    strcpy(tbuffer, adir);
-    strcat(tbuffer, "/");
-    strcat(tbuffer, aname);
-    return unlink(tbuffer);
+    if (snprintf(tbuffer, 256, "%s/%s", adir, aname)<256)
+       return unlink(tbuffer);
+    else
+       return -1;
 }
 
 afs_int32
-SBOZO_Prune(acall, aflags)
-     struct rx_call *acall;
-     afs_int32 aflags;
+SBOZO_Prune(struct rx_call *acall, afs_int32 aflags)
 {
-    register afs_int32 code;
+    afs_int32 code;
     DIR *dirp;
-    register struct dirent *tde;
-    register int i;
+    struct dirent *tde;
+    int i;
     char caller[MAXKTCNAMELEN];
 
     if (!afsconf_SuperUser(bozo_confdir, acall, caller)) {
        code = BZACCESS;
        goto fail;
     }
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted) {
        code = BZACCESS;
        goto fail;
     }
-#endif
     if (DoLogging)
        bozo_Log("%s is executing Prune (flags=%d)\n", caller, aflags);
 
@@ -1297,14 +1241,12 @@ SBOZO_Prune(acall, aflags)
 }
 
 afs_int32
-SBOZO_EnumerateInstance(acall, anum, ainstance)
-     struct rx_call *acall;
-     afs_int32 anum;
-     char **ainstance;
+SBOZO_EnumerateInstance(struct rx_call *acall, afs_int32 anum,
+                       char **ainstance)
 {
     struct eidata tdata;
 
-    *ainstance = (char *)malloc(BOZO_BSSIZE);
+    *ainstance = malloc(BOZO_BSSIZE);
     **ainstance = 0;
     tdata.counter = anum;
     tdata.iname = *ainstance;
@@ -1324,20 +1266,22 @@ struct bozo_bosEntryStats bozo_bosEntryStats[] = {
     {NULL, 1, 1, 0700, 07},    /* AFSDIR_SERVER_DB_DIRPATH     */
     {NULL, 1, 1, 0700, 07},    /* AFSDIR_SERVER_LOCAL_DIRPATH  */
     {NULL, 0, 1, 0600, 07},    /* AFSDIR_SERVER_KEY_FILEPATH   */
-    {NULL, 0, 1, 0600, 03}
-};                             /* AFSDIR_SERVER_ULIST_FILEPATH */
+    {NULL, 0, 1, 0600, 03},    /* AFSDIR_SERVER_ULIST_FILEPATH */
+    {NULL, 0, 1, 0600, 07},    /* AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH   */
+    {NULL, 0, 1, 0600, 07}     /* AFSDIR_SERVER_EXT_KEY_FILEPATH   */
+};
 int bozo_nbosEntryStats =
     sizeof(bozo_bosEntryStats) / sizeof(bozo_bosEntryStats[0]);
 
 /* This function performs initialization of the bozo_bosEntrystats[]
- * array. This array contains the list of dirs that the bosserver 
+ * array. This array contains the list of dirs that the bosserver
  * is interested in along with their recommended permissions
  * NOTE: This initialization is a bit ugly. This was caused because
  * the path names require procedural as opposed to static initialization.
  * The other fields in the struct are however, statically initialized.
  */
 int
-initBosEntryStats()
+initBosEntryStats(void)
 {
     bozo_bosEntryStats[0].path = AFSDIR_SERVER_AFS_DIRPATH;
     bozo_bosEntryStats[1].path = AFSDIR_SERVER_ETC_DIRPATH;
@@ -1348,6 +1292,8 @@ initBosEntryStats()
     bozo_bosEntryStats[6].path = AFSDIR_SERVER_LOCAL_DIRPATH;
     bozo_bosEntryStats[7].path = AFSDIR_SERVER_KEY_FILEPATH;
     bozo_bosEntryStats[8].path = AFSDIR_SERVER_ULIST_FILEPATH;
+    bozo_bosEntryStats[9].path = AFSDIR_SERVER_RXKAD_KEYTAB_FILEPATH;
+    bozo_bosEntryStats[10].path = AFSDIR_SERVER_EXT_KEY_FILEPATH;
 
     return 0;
 }
@@ -1357,8 +1303,7 @@ initBosEntryStats()
  * read. */
 
 static int
-StatEachEntry(stats)
-     IN struct bozo_bosEntryStats *stats;
+StatEachEntry(IN struct bozo_bosEntryStats *stats)
 {
     struct stat info;
     if (stat(stats->path, &info)) {
@@ -1385,7 +1330,7 @@ StatEachEntry(stats)
  * this check more often than every 5 seconds. */
 
 int
-DirAccessOK()
+DirAccessOK(void)
 {
 #ifdef AFS_NT40_ENV
     /* underlying filesystem may not support directory protection */
@@ -1407,11 +1352,10 @@ DirAccessOK()
        if (!StatEachEntry(e)) {
            bozo_Log("unhappy with %s which is a %s that should "
                     "have at least rights %o, at most rights %o %s\n",
-                    e->path, e->dir ? "dir" : "file", e->reqPerm, 
-                    (~e->proPerm & 0777), 
+                    e->path, e->dir ? "dir" : "file", e->reqPerm,
+                    (~e->proPerm & 0777),
                     e->rootOwner ? ", owned by root" : "");
            result = 0;
-           break;
        }
     }
 
@@ -1425,8 +1369,7 @@ DirAccessOK()
 }
 
 int
-GetRequiredDirPerm(path)
-     IN char *path;
+GetRequiredDirPerm(const char *path)
 {
     int i;
     for (i = 0; i < bozo_nbosEntryStats; i++)
@@ -1436,16 +1379,15 @@ GetRequiredDirPerm(path)
 }
 
 afs_int32
-SBOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
-     IN struct rx_call *acall;
-     IN char *ainstance;
-     OUT char **atype;
-     OUT struct bozo_status *astatus;
+SBOZO_GetInstanceInfo(IN struct rx_call *acall,
+                     IN char *ainstance,
+                     OUT char **atype,
+                     OUT struct bozo_status *astatus)
 {
-    register struct bnode *tb;
+    struct bnode *tb;
 
     tb = bnode_FindInstance(ainstance);
-    *atype = (char *)malloc(BOZO_BSSIZE);
+    *atype = malloc(BOZO_BSSIZE);
     **atype = 0;
     if (!tb)
        return BZNOENT;
@@ -1472,17 +1414,16 @@ SBOZO_GetInstanceInfo(acall, ainstance, atype, astatus)
 }
 
 afs_int32
-SBOZO_GetInstanceParm(acall, ainstance, anum, aparm)
-     struct rx_call *acall;
-     char *ainstance;
-     afs_int32 anum;
-     char **aparm;
+SBOZO_GetInstanceParm(struct rx_call *acall,
+                     char *ainstance,
+                     afs_int32 anum,
+                     char **aparm)
 {
-    register struct bnode *tb;
-    register char *tp;
-    register afs_int32 code;
+    struct bnode *tb;
+    char *tp;
+    afs_int32 code;
 
-    tp = (char *)malloc(BOZO_BSSIZE);
+    tp = malloc(BOZO_BSSIZE);
     *aparm = tp;
     *tp = 0;                   /* null-terminate string in error case */
     tb = bnode_FindInstance(ainstance);
@@ -1504,11 +1445,9 @@ SBOZO_GetInstanceParm(acall, ainstance, anum, aparm)
 }
 
 afs_int32
-SBOZO_GetLog(acall, aname)
-     register struct rx_call *acall;
-     char *aname;
+SBOZO_GetLog(struct rx_call *acall, char *aname)
 {
-    register afs_int32 code;
+    afs_int32 code;
     FILE *tfile;
     int tc;
     char *logpath;
@@ -1522,13 +1461,11 @@ SBOZO_GetLog(acall, aname)
        code = BZACCESS;
        goto fail;
     }
-#ifdef BOS_RESTRICTED_MODE
     if (bozo_isrestricted && strchr(aname, '/')
        && strcmp(aname, AFSDIR_CANONICAL_SERVER_SLVGLOG_FILEPATH)) {
        code = BZACCESS;
        goto fail;
     }
-#endif
 
     /* construct local path from canonical (wire-format) path */
     if (ConstructLocalLogPath(aname, &logpath)) {
@@ -1572,18 +1509,16 @@ SBOZO_GetLog(acall, aname)
 }
 
 afs_int32
-SBOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
-     struct rx_call *acall;
-     char *abnodeName;
-     char **as1, **as2, **as3, **as4;
+SBOZO_GetInstanceStrings(struct rx_call *acall, char *abnodeName,
+                        char **as1, char **as2, char **as3, char **as4)
 {
-    register struct bnode *tb;
+    struct bnode *tb;
 
-    *as2 = (char *)malloc(1);
+    *as2 = malloc(1);
     **as2 = 0;
-    *as3 = (char *)malloc(1);
+    *as3 = malloc(1);
     **as3 = 0;
-    *as4 = (char *)malloc(1);
+    *as4 = malloc(1);
     **as4 = 0;
     tb = bnode_FindInstance(abnodeName);
     if (!tb)
@@ -1591,34 +1526,28 @@ SBOZO_GetInstanceStrings(acall, abnodeName, as1, as2, as3, as4)
 
     /* now, return the appropriate error string, if any */
     if (tb->lastErrorName) {
-       *as1 = (char *)malloc(strlen(tb->lastErrorName) + 1);
-       strcpy(*as1, tb->lastErrorName);
+       *as1 = strdup(tb->lastErrorName);
     } else {
-       *as1 = (char *)malloc(1);
+       *as1 = malloc(1);
        **as1 = 0;
     }
     return 0;
 
   fail:
-    *as1 = (char *)malloc(1);
+    *as1 = malloc(1);
     **as1 = 0;
     return BZNOENT;
 }
 
-#ifdef BOS_RESTRICTED_MODE
 afs_int32
-SBOZO_GetRestrictedMode(acall, arestmode)
-     struct rx_call *acall;
-     afs_int32 *arestmode;
+SBOZO_GetRestrictedMode(struct rx_call *acall, afs_int32 *arestmode)
 {
     *arestmode = bozo_isrestricted;
     return 0;
 }
 
 afs_int32
-SBOZO_SetRestrictedMode(acall, arestmode)
-     struct rx_call *acall;
-     afs_int32 arestmode;
+SBOZO_SetRestrictedMode(struct rx_call *acall, afs_int32 arestmode)
 {
     afs_int32 code;
     char caller[MAXKTCNAMELEN];
@@ -1634,30 +1563,14 @@ SBOZO_SetRestrictedMode(acall, arestmode)
     }
     bozo_isrestricted = arestmode;
     code = WriteBozoFile(0);
-  fail:
-    return code;
-}
-#else
-afs_int32
-SBOZO_GetRestrictedMode(acall, arestmode)
-     struct rx_call *acall;
-     afs_int32 *arestmode;
-{
-    return RXGEN_OPCODE;
-}
 
-afs_int32
-SBOZO_SetRestrictedMode(acall, arestmode)
-     struct rx_call *acall;
-     afs_int32 arestmode;
-{
-    return RXGEN_OPCODE;
+    return code;
 }
-#endif
 
-void
-bozo_ShutdownAndExit(int asignal)
+void *
+bozo_ShutdownAndExit(void *param)
 {
+    int asignal = (intptr_t)param;
     int code;
 
     bozo_Log