ubik: Avoid use of freed string
[openafs.git] / src / ubik / uinit.c
index 5b167ae..a61a029 100644 (file)
@@ -9,27 +9,15 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
+#include <roken.h>
 
-#include <afs/stds.h>
-#ifdef AFS_NT40_ENV
-#include <fcntl.h>
-#include <winsock2.h>
-#else
-#include <sys/types.h>
-#include <sys/file.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#endif /* AFS_NT40_ENV */
-#include <sys/stat.h>
 #ifdef AFS_AIX_ENV
-#include <sys/statfs.h>
+# include <sys/statfs.h>
 #endif
 
-#include <string.h>
-
 #include <afs/dirpath.h>
-#include <errno.h>
 #include <lock.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <afs/afsint.h>
 #include <afs/cmd.h>
 
-/*!
- * \brief Get the appropriate type of ubik client structure out from the system.
- */
-afs_int32
-ugen_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 sauth,
-              struct ubik_client **uclientp,
-              int (*secproc) (struct rx_securityClass *, afs_int32),
-              char *funcName, afs_int32 gen_rxkad_level,
-              afs_int32 maxservers, char *serviceid, afs_int32 deadtime,
-              afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
+static int
+internal_client_init(struct afsconf_dir *dir, struct afsconf_cell *info,
+                    int secFlags, struct ubik_client **uclientp,
+                    int (*secproc) (struct rx_securityClass *, afs_int32),
+                    int maxservers, const char *serviceid, int deadtime,
+                    afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
 {
-    afs_int32 code, secFlags, i;
+    int code, i;
     afs_int32 scIndex;
-    struct afsconf_cell info;
-    struct afsconf_dir *tdir;
     struct rx_securityClass *sc;
     /* This must change if VLDB_MAXSERVERS becomes larger than MAXSERVERS */
     static struct rx_connection *serverconns[MAXSERVERS];
-    const char *confdir;
+    const char *progname;
+
+    progname = getprogname();
+    if (progname == NULL)
+       progname = "<unknown>";
 
     code = rx_Init(0);
     if (code) {
-       fprintf(stderr, "%s: could not initialize rx.\n", funcName);
+       fprintf(stderr, "%s: could not initialize rx.\n", progname);
        return code;
     }
     rx_SetRxDeadTime(deadtime);
 
-    secFlags = AFSCONF_SECOPTS_FALLBACK_NULL;
-    if (sauth) {
-       secFlags |= AFSCONF_SECOPTS_LOCALAUTH;
-       confdir = AFSDIR_SERVER_ETC_DIRPATH;
-    } else {
-       confdir = AFSDIR_CLIENT_ETC_DIRPATH;
-    }
-
-    if (noAuthFlag) {
-       secFlags |= AFSCONF_SECOPTS_NOAUTH;
-    }
-
-    tdir = afsconf_Open(confdir);
-    if (!tdir) {
-       fprintf(stderr,
-               "%s: Could not process files in configuration directory (%s).\n",
-               funcName, confdir);
-       return -1;
-    }
-
-    if (sauth)
-       cellName = tdir->cellName;
-
-    code = afsconf_GetCellInfo(tdir, cellName, serviceid, &info);
-    if (code) {
-       afsconf_Close(tdir);
-       fprintf(stderr, "%s: can't find cell %s's hosts in %s/%s\n",
-               funcName, cellName, confdir, AFSDIR_CELLSERVDB_FILE);
-       return -1;
-    }
-    code = afsconf_PickClientSecObj(tdir, secFlags, &info, cellName, &sc,
+    code = afsconf_PickClientSecObj(dir, secFlags, info, NULL, &sc,
                                    &scIndex, NULL);
     if (code) {
-       fprintf(stderr, "%s: can't create client security object", funcName);
-       return -1;
+       fprintf(stderr, "%s: can't create client security object", progname);
+       return code;
     }
-    if (scIndex == RX_SECIDX_NULL && !noAuthFlag) {
+
+    if (scIndex == RX_SECIDX_NULL && !(secFlags & AFSCONF_SECOPTS_NOAUTH)) {
        fprintf(stderr,
                "%s: Could not get afs tokens, running unauthenticated.\n",
-               funcName);
+               progname);
     }
 
-    afsconf_Close(tdir);
-
     if (secproc)       /* tell UV module about default authentication */
        (*secproc) (sc, scIndex);
+
     if (server) {
        serverconns[0] = rx_NewConnection(server, port,
                                          usrvid, sc, scIndex);
     } else {
-       if (info.numServers > maxservers) {
+       if (info->numServers > maxservers) {
            fprintf(stderr,
                    "%s: info.numServers=%d (> maxservers=%d)\n",
-                   funcName, info.numServers, maxservers);
+                   progname, info->numServers, maxservers);
            return -1;
        }
-       for (i = 0; i < info.numServers; i++) {
-           if (!info.hostAddr[i].sin_port && port)
-               info.hostAddr[i].sin_port = port;
+       for (i = 0; i < info->numServers; i++) {
+           if (!info->hostAddr[i].sin_port && port)
+               info->hostAddr[i].sin_port = port;
            serverconns[i] =
-               rx_NewConnection(info.hostAddr[i].sin_addr.s_addr,
-                                info.hostAddr[i].sin_port, usrvid,
+               rx_NewConnection(info->hostAddr[i].sin_addr.s_addr,
+                                info->hostAddr[i].sin_port, usrvid,
                                 sc, scIndex);
        }
     }
@@ -137,12 +93,121 @@ ugen_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 s
     if (uclientp) {
        *uclientp = 0;
        code = ubik_ClientInit(serverconns, uclientp);
-       if (code) {
-           fprintf(stderr, "%s: ubik client init failed.\n", funcName);
+       if (code)
+           fprintf(stderr, "%s: ubik client init failed.\n", progname);
            return code;
-       }
     }
+
     return 0;
 }
 
+int
+ugen_ClientInitCell(struct afsconf_dir *dir, struct afsconf_cell *info,
+                   int secFlags, struct ubik_client **uclientp,
+                   int maxservers, const char *serviceid, int deadtime)
+{
+    return internal_client_init(dir, info, secFlags, uclientp, NULL,
+                               maxservers, serviceid, deadtime, 0, 0,
+                               USER_SERVICE_ID);
+}
+
+static int
+internal_client_init_dir(const char *confDir, char *cellName, int secFlags,
+                     struct ubik_client **uclientp,
+                     int (*secproc) (struct rx_securityClass *, afs_int32),
+                     afs_int32 maxservers, char *serviceid, afs_int32 deadtime,
+                     afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
+{
+    int code;
+    const char *progname;
+    struct afsconf_dir *dir;
+    struct afsconf_cell info;
+
+    progname = getprogname();
+    if (progname == NULL)
+       progname = "<unknown>";
+
+    if (confDir == NULL)
+       confDir = AFSDIR_CLIENT_ETC_DIRPATH;
+
+    dir = afsconf_Open(confDir);
+    if (!dir) {
+       fprintf(stderr,
+               "%s: Could not process files in configuration directory (%s).\n",
+               progname, confDir);
+       return EIO;
+    }
+
+    if (cellName == NULL)
+       cellName = dir->cellName;
+
+    code = afsconf_GetCellInfo(dir, cellName, serviceid, &info);
+    if (code) {
+       fprintf(stderr, "%s: can't find cell %s's hosts in %s/%s\n",
+               progname?progname:"<unknown>", cellName, confDir,
+               AFSDIR_CELLSERVDB_FILE);
+       afsconf_Close(dir);
+       return code;
+    }
+
+    code = internal_client_init(dir, &info, secFlags, uclientp, secproc,
+                               maxservers, serviceid, deadtime, server,
+                               port, usrvid);
+
+    afsconf_Close(dir);
+
+    return code;
+}
+
+int
+ugen_ClientInitServer(const char *confDir, char *cellName, int secFlags,
+                     struct ubik_client **uclientp, int maxservers,
+                     char *serviceid, int deadtime, afs_uint32 server,
+                     afs_uint32 port)
+{
+
+    return internal_client_init_dir(confDir, cellName, secFlags, uclientp,
+                                   NULL, maxservers, serviceid, deadtime,
+                                   server, port, USER_SERVICE_ID);
+}
+
+int
+ugen_ClientInitFlags(const char *confDir, char *cellName, int secFlags,
+                    struct ubik_client **uclientp,
+                    int (*secproc) (struct rx_securityClass *, afs_int32),
+                    int maxservers, char *serviceid, int deadtime)
+{
+    return internal_client_init_dir(confDir, cellName, secFlags, uclientp,
+                                   secproc, maxservers, serviceid, deadtime,
+                                   0, 0, USER_SERVICE_ID);
+}
+
+/*!
+ * \brief Get the appropriate type of ubik client structure out from the system.
+ */
+afs_int32
+ugen_ClientInit(int noAuthFlag, const char *confDir, char *cellName, afs_int32 sauth,
+              struct ubik_client **uclientp,
+              int (*secproc) (struct rx_securityClass *, afs_int32),
+              char *funcName, afs_int32 gen_rxkad_level,
+              afs_int32 maxservers, char *serviceid, afs_int32 deadtime,
+              afs_uint32 server, afs_uint32 port, afs_int32 usrvid)
+{
+    int secFlags;
+
+    secFlags = AFSCONF_SECOPTS_FALLBACK_NULL;
+    if (sauth) {
+       secFlags |= AFSCONF_SECOPTS_LOCALAUTH;
+       confDir = AFSDIR_SERVER_ETC_DIRPATH;
+    }
+
+    secFlags |= AFSCONF_SECOPTS_ALWAYSENCRYPT;
+
+    if (noAuthFlag)
+       secFlags |= AFSCONF_SECOPTS_NOAUTH;
+
+    return internal_client_init_dir(confDir, cellName, secFlags, uclientp,
+                                   secproc, maxservers, serviceid, deadtime,
+                                   server, port, usrvid);
+}