audit: remove static local realms
[openafs.git] / src / vlserver / vlserver.c
index 3108774..9f88278 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,61 +9,48 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
-RCSID
-    ("$Header$");
+#include <roken.h>
 
-#include <afs/stds.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <string.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
 #ifdef AFS_NT40_ENV
-#include <winsock2.h>
 #include <WINNT/afsevent.h>
 #endif
+
 #ifdef HAVE_SYS_FILE_H
 #include <sys/file.h>
 #endif
-#include <time.h>
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#include <stdio.h>
 
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <rx/rx_globals.h>
+#include <rx/rxstat.h>
+#include <afs/cmd.h>
 #include <afs/cellconfig.h>
 #include <afs/keys.h>
 #include <afs/auth.h>
+#include <afs/audit.h>
+#include <afs/com_err.h>
 #include <lock.h>
 #include <ubik.h>
 #include <afs/afsutil.h>
-#include "vlserver.h"
 
+#include "vlserver.h"
+#include "vlserver_internal.h"
 
 #define MAXLWP 16
-const char *vl_dbaseName;
 struct afsconf_dir *vldb_confdir = 0;  /* vldb configuration dir */
 int lwps = 9;
 
 struct vldstats dynamic_statistics;
 struct ubik_dbase *VL_dbase;
-afs_uint32 HostAddress[MAXSERVERID + 1];
-extern int afsconf_CheckAuth();
-extern int afsconf_ServerAuth();
+afs_uint32 rd_HostAddress[MAXSERVERID + 1];
+afs_uint32 wr_HostAddress[MAXSERVERID + 1];
 
-static CheckSignal();
+static void *CheckSignal(void*);
 int LogLevel = 0;
 int smallMem = 0;
-int rxJumbograms = 1;          /* default is to send and receive jumbo grams */
+int rxJumbograms = 0;          /* default is to not send and receive jumbo grams */
 int rxMaxMTU = -1;
 afs_int32 rxBind = 0;
 int rxkadDisableDotCheck = 0;
@@ -72,35 +59,39 @@ int rxkadDisableDotCheck = 0;
 afs_uint32 SHostAddrs[ADDRSPERSITE];
 
 static void
-CheckSignal_Signal()
+CheckSignal_Signal(int unused)
 {
+#if defined(AFS_PTHREAD_ENV)
+    CheckSignal(0);
+#else
     IOMGR_SoftSig(CheckSignal, 0);
+#endif
 }
 
-static
-CheckSignal()
+static void *
+CheckSignal(void *unused)
 {
-    register int i, errorcode;
-    struct ubik_trans *trans;
+    int i, errorcode;
+    struct vl_ctx ctx;
 
-    if (errorcode =
-       Init_VLdbase(&trans, LOCKREAD, VLGETSTATS - VL_LOWEST_OPCODE))
-       return errorcode;
+    if ((errorcode =
+       Init_VLdbase(&ctx, LOCKREAD, VLGETSTATS - VL_LOWEST_OPCODE)))
+       return (void *)(intptr_t)errorcode;
     VLog(0, ("Dump name hash table out\n"));
     for (i = 0; i < HASHSIZE; i++) {
-       HashNDump(trans, i);
+       HashNDump(&ctx, i);
     }
     VLog(0, ("Dump id hash table out\n"));
     for (i = 0; i < HASHSIZE; i++) {
-       HashIdDump(trans, i);
+       HashIdDump(&ctx, i);
     }
-    return (ubik_EndTrans(trans));
+    return ((void *)(intptr_t)ubik_EndTrans(ctx.trans));
 }                              /*CheckSignal */
 
 
 /* Initialize the stats for the opcodes */
 void
-initialize_dstats()
+initialize_dstats(void)
 {
     int i;
 
@@ -113,41 +104,85 @@ initialize_dstats()
 
 /* check whether caller is authorized to manage RX statistics */
 int
-vldb_rxstat_userok(call)
-     struct rx_call *call;
+vldb_rxstat_userok(struct rx_call *call)
 {
     return afsconf_SuperUser(vldb_confdir, call, NULL);
 }
 
+/**
+ * Return true if this name is a member of the local realm.
+ */
+int
+vldb_IsLocalRealmMatch(void *rock, char *name, char *inst, char *cell)
+{
+    struct afsconf_dir *dir = (struct afsconf_dir *)rock;
+    afs_int32 islocal = 0;     /* default to no */
+    int code;
+
+    code = afsconf_IsLocalRealmMatch(dir, &islocal, name, inst, cell);
+    if (code) {
+       ViceLog(0,
+               ("Failed local realm check; code=%d, name=%s, inst=%s, cell=%s\n",
+                code, name, inst, cell));
+    }
+    return islocal;
+}
+
 /* Main server module */
 
 #include "AFS_component_version_number.c"
 
-main(argc, argv)
-     int argc;
-     char **argv;
+enum optionsList {
+    OPT_noauth,
+    OPT_smallmem,
+    OPT_auditlog,
+    OPT_auditiface,
+    OPT_config,
+    OPT_debug,
+    OPT_database,
+    OPT_logfile,
+    OPT_threads,
+    OPT_syslog,
+    OPT_peer,
+    OPT_process,
+    OPT_nojumbo,
+    OPT_jumbo,
+    OPT_rxbind,
+    OPT_rxmaxmtu,
+    OPT_trace,
+    OPT_dotted
+};
+
+int
+main(int argc, char **argv)
 {
-    register afs_int32 code;
-    afs_int32 myHost;
+    afs_int32 code;
+    afs_uint32 myHost;
     struct rx_service *tservice;
-    struct rx_securityClass *sc[3];
-    extern int VL_ExecuteRequest();
-    extern int RXSTATS_ExecuteRequest();
+    struct rx_securityClass **securityClasses;
+    afs_int32 numClasses;
     struct afsconf_dir *tdir;
     struct ktc_encryptionKey tkey;
     struct afsconf_cell info;
     struct hostent *th;
     char hostname[VL_MAXNAMELEN];
-    int noAuth = 0, index, i;
-    extern int rx_extraPackets;
-    char commandLine[150];
+    int noAuth = 0;
     char clones[MAXHOSTSPERCELL];
     afs_uint32 host = ntohl(INADDR_ANY);
+    struct cmd_syndesc *opts;
+
+    char *vl_dbaseName;
+    char *configDir;
+    char *logFile;
+
+    char *auditFileName = NULL;
+    char *interface = NULL;
+    char *optstring = NULL;
 
 #ifdef AFS_AIX32_ENV
     /*
-     * The following signal action for AIX is necessary so that in case of a 
-     * crash (i.e. core is generated) we can include the user's data section 
+     * The following signal action for AIX is necessary so that in case of a
+     * crash (i.e. core is generated) we can include the user's data section
      * in the core dump. Unfortunately, by default, only a partial core is
      * generated which, in many cases, isn't too useful.
      */
@@ -162,109 +197,6 @@ main(argc, argv)
 #endif
     osi_audit_init();
 
-    /* Parse command line */
-    for (index = 1; index < argc; index++) {
-       if (strcmp(argv[index], "-noauth") == 0) {
-           noAuth = 1;
-
-       } else if (strcmp(argv[index], "-p") == 0) {
-           lwps = atoi(argv[++index]);
-           if (lwps > MAXLWP) {
-               printf("Warning: '-p %d' is too big; using %d instead\n",
-                      lwps, MAXLWP);
-               lwps = MAXLWP;
-           }
-
-       } else if (strcmp(argv[index], "-nojumbo") == 0) {
-           rxJumbograms = 0;
-
-       } else if (strcmp(argv[index], "-rxbind") == 0) {
-           rxBind = 1;
-       } else if (strcmp(argv[index], "-allow-dotted-principals") == 0) {
-           rxkadDisableDotCheck = 1;
-       } else if (!strcmp(argv[index], "-rxmaxmtu")) {
-           if ((index + 1) >= argc) {
-               fprintf(stderr, "missing argument for -rxmaxmtu\n"); 
-               return -1; 
-           }
-           rxMaxMTU = atoi(argv[++i]);
-           if ((rxMaxMTU < RX_MIN_PACKET_SIZE) || 
-               (rxMaxMTU > RX_MAX_PACKET_DATA_SIZE)) {
-               printf("rxMaxMTU %d% invalid; must be between %d-%d\n",
-                      rxMaxMTU, RX_MIN_PACKET_SIZE, 
-                      RX_MAX_PACKET_DATA_SIZE);
-               return -1;
-           }
-
-       } else if (strcmp(argv[index], "-smallmem") == 0) {
-           smallMem = 1;
-
-       } else if (strcmp(argv[index], "-trace") == 0) {
-           extern char rxi_tracename[80];
-           strcpy(rxi_tracename, argv[++index]);
-
-       } else if (strcmp(argv[index], "-auditlog") == 0) {
-          int tempfd, flags;
-           FILE *auditout;
-           char oldName[MAXPATHLEN];
-           char *fileName = argv[++index];
-
-#ifndef AFS_NT40_ENV
-           struct stat statbuf;
-
-           if ((lstat(fileName, &statbuf) == 0) 
-               && (S_ISFIFO(statbuf.st_mode))) {
-               flags = O_WRONLY | O_NONBLOCK;
-           } else 
-#endif
-           {
-               strcpy(oldName, fileName);
-               strcat(oldName, ".old");
-               renamefile(fileName, oldName);
-               flags = O_WRONLY | O_TRUNC | O_CREAT;
-           }
-           tempfd = open(fileName, flags, 0666);
-           if (tempfd > -1) {
-               auditout = fdopen(tempfd, "a");
-               if (auditout) {
-                   osi_audit_file(auditout);
-               } else
-                   printf("Warning: auditlog %s not writable, ignored.\n", fileName);
-           } else
-               printf("Warning: auditlog %s not writable, ignored.\n", fileName);
-       } else if (strcmp(argv[index], "-enable_peer_stats") == 0) {
-           rx_enablePeerRPCStats();
-       } else if (strcmp(argv[index], "-enable_process_stats") == 0) {
-           rx_enableProcessRPCStats();
-#ifndef AFS_NT40_ENV
-       } else if (strcmp(argv[index], "-syslog") == 0) {
-           /* set syslog logging flag */
-           serverLogSyslog = 1;
-       } else if (strncmp(argv[index], "-syslog=", 8) == 0) {
-           serverLogSyslog = 1;
-           serverLogSyslogFacility = atoi(argv[index] + 8);
-#endif
-       } else {
-           /* support help flag */
-#ifndef AFS_NT40_ENV
-           printf("Usage: vlserver [-p <number of processes>] [-nojumbo] "
-                  "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
-                  "[-auditlog <log path>] "
-                  "[-syslog[=FACILITY]] "
-                  "[-enable_peer_stats] [-enable_process_stats] "
-                  "[-help]\n");
-#else
-           printf("Usage: vlserver [-p <number of processes>] [-nojumbo] "
-                  "[-rxmaxmtu <bytes>] [-rxbind] [-allow-dotted-principals] "
-                  "[-auditlog <log path>] "
-                  "[-enable_peer_stats] [-enable_process_stats] "
-                  "[-help]\n");
-#endif
-           fflush(stdout);
-           exit(0);
-       }
-    }
-
     /* Initialize dirpaths */
     if (!(initAFSDirPath() & AFSDIR_SERVER_PATHS_OK)) {
 #ifdef AFS_NT40_ENV
@@ -274,21 +206,146 @@ main(argc, argv)
                argv[0]);
        exit(2);
     }
-    vl_dbaseName = AFSDIR_SERVER_VLDB_FILEPATH;
+
+    vl_dbaseName = strdup(AFSDIR_SERVER_VLDB_FILEPATH);
+    configDir = strdup(AFSDIR_SERVER_ETC_DIRPATH);
+    logFile = strdup(AFSDIR_SERVER_VLOG_FILEPATH);
+
+    cmd_DisableAbbreviations();
+    cmd_DisablePositionalCommands();
+    opts = cmd_CreateSyntax(NULL, NULL, NULL, NULL);
+
+    /* vlserver specific options */
+    cmd_AddParmAtOffset(opts, OPT_noauth, "-noauth", CMD_FLAG,
+                       CMD_OPTIONAL, "disable authentication");
+    cmd_AddParmAtOffset(opts, OPT_smallmem, "-smallmem", CMD_FLAG,
+                       CMD_OPTIONAL, "optimise for small memory systems");
+
+    /* general server options */
+    cmd_AddParmAtOffset(opts, OPT_auditlog, "-auditlog", CMD_SINGLE,
+                       CMD_OPTIONAL, "location of audit log");
+    cmd_AddParmAtOffset(opts, OPT_auditiface, "-audit-interface", CMD_SINGLE,
+                       CMD_OPTIONAL, "interface to use for audit logging");
+    cmd_AddParmAtOffset(opts, OPT_config, "-config", CMD_SINGLE,
+                       CMD_OPTIONAL, "configuration location");
+    cmd_AddParmAtOffset(opts, OPT_debug, "-d", CMD_SINGLE,
+                       CMD_OPTIONAL, "debug level");
+    cmd_AddParmAtOffset(opts, OPT_database, "-database", CMD_SINGLE,
+                       CMD_OPTIONAL, "database file");
+    cmd_AddParmAlias(opts, OPT_database, "-db");
+    cmd_AddParmAtOffset(opts, OPT_logfile, "-logfile", CMD_SINGLE,
+                       CMD_OPTIONAL, "location of logfile");
+    cmd_AddParmAtOffset(opts, OPT_threads, "-p", CMD_SINGLE, CMD_OPTIONAL,
+                       "number of threads");
+#if !defined(AFS_NT40_ENV)
+    cmd_AddParmAtOffset(opts, OPT_syslog, "-syslog", CMD_SINGLE_OR_FLAG,
+                       CMD_OPTIONAL, "log to syslog");
+#endif
+
+    /* rx options */
+    cmd_AddParmAtOffset(opts, OPT_peer, "-enable_peer_stats", CMD_FLAG,
+                       CMD_OPTIONAL, "enable RX transport statistics");
+    cmd_AddParmAtOffset(opts, OPT_process, "-enable_process_stats", CMD_FLAG,
+                       CMD_OPTIONAL, "enable RX RPC statistics");
+    cmd_AddParmAtOffset(opts, OPT_nojumbo, "-nojumbo", CMD_FLAG,
+                       CMD_OPTIONAL, "disable jumbograms");
+    cmd_AddParmAtOffset(opts, OPT_jumbo, "-jumbo", CMD_FLAG,
+                       CMD_OPTIONAL, "enable jumbograms");
+    cmd_AddParmAtOffset(opts, OPT_rxbind, "-rxbind", CMD_FLAG,
+                       CMD_OPTIONAL, "bind only to the primary interface");
+    cmd_AddParmAtOffset(opts, OPT_rxmaxmtu, "-rxmaxmtu", CMD_SINGLE,
+                       CMD_OPTIONAL, "maximum MTU for RX");
+    cmd_AddParmAtOffset(opts, OPT_trace, "-trace", CMD_SINGLE,
+                       CMD_OPTIONAL, "rx trace file");
+
+    /* rxkad options */
+    cmd_AddParmAtOffset(opts, OPT_dotted, "-allow-dotted-principals",
+                       CMD_FLAG, CMD_OPTIONAL,
+                       "permit Kerberos 5 principals with dots");
+
+    code = cmd_Parse(argc, argv, &opts);
+    if (code)
+       return -1;
+
+    /* vlserver options */
+    cmd_OptionAsFlag(opts, OPT_noauth, &noAuth);
+    cmd_OptionAsFlag(opts, OPT_smallmem, &smallMem);
+    if (cmd_OptionAsString(opts, OPT_trace, &optstring) == 0) {
+       extern char rxi_tracename[80];
+       strcpy(rxi_tracename, optstring);
+       free(optstring);
+       optstring = NULL;
+    }
+
+    /* general server options */
+
+    cmd_OptionAsString(opts, OPT_auditlog, &auditFileName);
+
+    if (cmd_OptionAsString(opts, OPT_auditiface, &interface) == 0) {
+       if (osi_audit_interface(interface)) {
+           printf("Invalid audit interface '%s'\n", interface);
+           return -1;
+       }
+       free(interface);
+    }
+
+    cmd_OptionAsString(opts, OPT_config, &configDir);
+    cmd_OptionAsInt(opts, OPT_debug, &LogLevel);
+    cmd_OptionAsString(opts, OPT_database, &vl_dbaseName);
+    cmd_OptionAsString(opts, OPT_logfile, &logFile);
+
+    if (cmd_OptionAsInt(opts, OPT_threads, &lwps) == 0) {
+       if (lwps > MAXLWP) {
+            printf("Warning: '-p %d' is too big; using %d instead\n",
+                   lwps, MAXLWP);
+            lwps = MAXLWP;
+       }
+    }
+#ifndef AFS_NT40_ENV
+    if (cmd_OptionPresent(opts, OPT_syslog)) {
+        serverLogSyslog = 1;
+        cmd_OptionAsInt(opts, OPT_syslog, &serverLogSyslogFacility);
+    }
+#endif
+
+    /* rx options */
+    if (cmd_OptionPresent(opts, OPT_peer))
+       rx_enablePeerRPCStats();
+    if (cmd_OptionPresent(opts, OPT_process))
+       rx_enableProcessRPCStats();
+    if (cmd_OptionPresent(opts, OPT_nojumbo))
+       rxJumbograms = 0;
+    if (cmd_OptionPresent(opts, OPT_jumbo))
+       rxJumbograms = 1;
+
+    cmd_OptionAsFlag(opts, OPT_rxbind, &rxBind);
+
+    cmd_OptionAsInt(opts, OPT_rxmaxmtu, &rxMaxMTU);
+
+    /* rxkad options */
+    cmd_OptionAsFlag(opts, OPT_dotted, &rxkadDisableDotCheck);
+
+    if (auditFileName) {
+       osi_audit_file(auditFileName);
+    }
 
 #ifndef AFS_NT40_ENV
     serverLogSyslogTag = "vlserver";
 #endif
-    OpenLog(AFSDIR_SERVER_VLOG_FILEPATH);      /* set up logging */
+    OpenLog(logFile);  /* set up logging */
     SetupLogSignals();
 
-    tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
+    tdir = afsconf_Open(configDir);
     if (!tdir) {
        printf
            ("vlserver: can't open configuration files in dir %s, giving up.\n",
-            AFSDIR_SERVER_ETC_DIRPATH);
+            configDir);
        exit(1);
     }
+
+    /* initialize audit user check */
+    osi_audit_set_user_check(configDir, vldb_IsLocalRealmMatch);
+
 #ifdef AFS_NT40_ENV
     /* initialize winsock */
     if (afs_winsockInit() < 0) {
@@ -305,7 +362,7 @@ main(argc, argv)
               hostname);
        exit(1);
     }
-    memcpy(&myHost, th->h_addr, sizeof(afs_int32));
+    memcpy(&myHost, th->h_addr, sizeof(afs_uint32));
 
 #if !defined(AFS_HPUX_ENV) && !defined(AFS_NT40_ENV)
     signal(SIGXCPU, CheckSignal_Signal);
@@ -313,7 +370,7 @@ main(argc, argv)
     /* get list of servers */
     code =
        afsconf_GetExtendedCellInfo(tdir, NULL, AFSCONF_VLDBSERVICE, &info,
-                                   &clones);
+                                   clones);
     if (code) {
        printf("vlserver: Couldn't get cell server list for 'afsvldb'.\n");
        exit(2);
@@ -329,15 +386,15 @@ main(argc, argv)
     if (rxBind) {
        afs_int32 ccode;
 #ifndef AFS_NT40_ENV
-        if (AFSDIR_SERVER_NETRESTRICT_FILEPATH || 
+        if (AFSDIR_SERVER_NETRESTRICT_FILEPATH ||
             AFSDIR_SERVER_NETINFO_FILEPATH) {
             char reason[1024];
             ccode = parseNetFiles(SHostAddrs, NULL, NULL,
                                  ADDRSPERSITE, reason,
                                  AFSDIR_SERVER_NETINFO_FILEPATH,
                                  AFSDIR_SERVER_NETRESTRICT_FILEPATH);
-        } else 
-#endif 
+        } else
+#endif
        {
             ccode = rx_getAllAddr(SHostAddrs, ADDRSPERSITE);
         }
@@ -348,37 +405,39 @@ main(argc, argv)
     }
 
     ubik_nBuffers = 512;
-    ubik_CRXSecurityProc = afsconf_ClientAuth;
-    ubik_CRXSecurityRock = (char *)tdir;
-    ubik_SRXSecurityProc = afsconf_ServerAuth;
-    ubik_SRXSecurityRock = (char *)tdir;
-    ubik_CheckRXSecurityProc = afsconf_CheckAuth;
-    ubik_CheckRXSecurityRock = (char *)tdir;
+    ubik_SetClientSecurityProcs(afsconf_ClientAuth, afsconf_UpToDate, tdir);
+    ubik_SetServerSecurityProcs(afsconf_BuildServerSecurityObjects,
+                               afsconf_CheckAuth, tdir);
+
+    ubik_SyncWriterCacheProc = vlsynccache;
     code =
-       ubik_ServerInitByInfo(myHost, htons(AFSCONF_VLDBPORT), &info, &clones,
+       ubik_ServerInitByInfo(myHost, htons(AFSCONF_VLDBPORT), &info, clones,
                              vl_dbaseName, &VL_dbase);
     if (code) {
-       printf("vlserver: Ubik init failed with code %d\n", code);
+       printf("vlserver: Ubik init failed: %s\n", afs_error_message(code));
        exit(2);
     }
     if (!rxJumbograms) {
        rx_SetNoJumbo();
     }
     if (rxMaxMTU != -1) {
-       rx_SetMaxMTU(rxMaxMTU);
+       if (rx_SetMaxMTU(rxMaxMTU) != 0) {
+           printf("rxMaxMTU %d invalid\n", rxMaxMTU);
+           return -1;
+       }
     }
     rx_SetRxDeadTime(50);
 
-    memset(HostAddress, 0, sizeof(HostAddress));
+    memset(rd_HostAddress, 0, sizeof(rd_HostAddress));
+    memset(wr_HostAddress, 0, sizeof(wr_HostAddress));
     initialize_dstats();
 
-    sc[0] = rxnull_NewServerSecurityObject();
-    sc[1] = (struct rx_securityClass *)0;
-    sc[2] = rxkad_NewServerSecurityObject(0, tdir, afsconf_GetKey, NULL);
+    afsconf_BuildServerSecurityObjects(tdir, &securityClasses, &numClasses);
 
     tservice =
-       rx_NewServiceHost(host, 0, USER_SERVICE_ID, "Vldb server", sc, 3,
-                     VL_ExecuteRequest);
+       rx_NewServiceHost(host, 0, USER_SERVICE_ID, "Vldb server",
+                         securityClasses, numClasses,
+                         VL_ExecuteRequest);
     if (tservice == (struct rx_service *)0) {
        printf("vlserver: Could not create VLDB_SERVICE rx service\n");
        exit(3);
@@ -390,13 +449,13 @@ main(argc, argv)
 
     if (rxkadDisableDotCheck) {
         rx_SetSecurityConfiguration(tservice, RXS_CONFIG_FLAGS,
-                                    (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK,
-                                    NULL);
+                                    (void *)RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
     }
 
     tservice =
-       rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats", sc, 3,
-                     RXSTATS_ExecuteRequest);
+       rx_NewServiceHost(host, 0, RX_STATS_SERVICE_ID, "rpcstats",
+                         securityClasses, numClasses,
+                         RXSTATS_ExecuteRequest);
     if (tservice == (struct rx_service *)0) {
        printf("vlserver: Could not create rpc stats rx service\n");
        exit(3);
@@ -404,13 +463,7 @@ main(argc, argv)
     rx_SetMinProcs(tservice, 2);
     rx_SetMaxProcs(tservice, 4);
 
-    for (commandLine[0] = '\0', i = 0; i < argc; i++) {
-       if (i > 0)
-           strcat(commandLine, " ");
-       strcat(commandLine, argv[i]);
-    }
-    ViceLog(0,
-           ("Starting AFS vlserver %d (%s)\n", VLDBVERSION_4, commandLine));
+    LogCommandLine(argc, argv, "vlserver", VldbVersion, "Starting AFS", FSLog);
     printf("%s\n", cml_version_number);        /* Goes to the log */
 
     /* allow super users to manage RX statistics */