ubik: Avoid use of freed string
[openafs.git] / src / ubik / uinit.c
index 32c6bf1..a61a029 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,35 +9,15 @@
 
 #include <afsconfig.h>
 #include <afs/param.h>
+#include <afs/stds.h>
 
-RCSID
-    ("$Header$");
+#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>
-#endif
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
+# include <sys/statfs.h>
 #endif
 
 #include <afs/dirpath.h>
-#include <errno.h>
 #include <lock.h>
 #include <rx/xdr.h>
 #include <rx/rx.h>
@@ -48,146 +28,64 @@ RCSID
 #include <ubik.h>
 #include <afs/afsint.h>
 #include <afs/cmd.h>
-#include <rx/rxkad.h>
 
-/*
-  Get the appropriate type of ubik client structure out from the system.
-*/
-afs_int32
-ugen_ClientInit(int noAuthFlag, char *confDir, char *cellName, afs_int32 sauth,
-              struct ubik_client **uclientp, int (*secproc) (),
-              char *funcName, afs_int32 gen_rxkad_level, 
-              afs_int32 maxservers, afs_int32 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, scIndex, i;
-    struct afsconf_cell info;
-    struct afsconf_dir *tdir;
-    struct ktc_principal sname;
-    struct ktc_token ttoken;
+    int code, i;
+    afs_int32 scIndex;
     struct rx_securityClass *sc;
     /* This must change if VLDB_MAXSERVERS becomes larger than MAXSERVERS */
     static struct rx_connection *serverconns[MAXSERVERS];
-    char cellstr[64];
+    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);
 
-    if (sauth) {               /* -localauth */
-       tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH);
-       if (!tdir) {
-           fprintf(stderr,
-                   "%s: Could not process files in configuration directory (%s).\n",
-                   funcName, AFSDIR_SERVER_ETC_DIRPATH);
-           return -1;
-       }
-       code = afsconf_ClientAuth(tdir, &sc, &scIndex); /* sets sc,scIndex */
-       if (code) {
-           fprintf(stderr,
-                   "%s: Could not get security object for -localAuth\n",
-                   funcName);
-           return -1;
-       }
-       code =
-           afsconf_GetCellInfo(tdir, tdir->cellName, serviceid,
-                               &info);
-       if (code) {
-           fprintf(stderr,
-                   "%s: can't find cell %s's hosts in %s/%s\n",
-                   funcName, cellName, AFSDIR_SERVER_ETC_DIRPATH,
-                   AFSDIR_CELLSERVDB_FILE);
-           exit(1);
-       }
-    } else {                   /* not -localauth */
-       tdir = afsconf_Open(confDir);
-       if (!tdir) {
-           fprintf(stderr,
-                   "%s: Could not process files in configuration directory (%s).\n",
-                   funcName, confDir);
-           return -1;
-       }
-
-       if (!cellName) {
-           code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr));
-           if (code) {
-               fprintf(stderr,
-                       "%s: can't get local cellname, check %s/%s\n",
-                       funcName, confDir, AFSDIR_THISCELL_FILE);
-               exit(1);
-           }
-           cellName = cellstr;
-       }
-
-       code =
-           afsconf_GetCellInfo(tdir, cellName, serviceid, &info);
-       if (code) {
-           fprintf(stderr,
-                   "%s: can't find cell %s's hosts in %s/%s\n",
-                   funcName, cellName, confDir, AFSDIR_CELLSERVDB_FILE);
-           exit(1);
-       }
-       if (noAuthFlag)         /* -noauth */
-           scIndex = 0;
-       else {                  /* not -noauth */
-           strcpy(sname.cell, info.name);
-           sname.instance[0] = 0;
-           strcpy(sname.name, "afs");
-           code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL);
-           if (code) {         /* did not get ticket */
-               fprintf(stderr,
-                       "%s: Could not get afs tokens, running unauthenticated.\n",
-                       funcName);
-               scIndex = 0;
-           } else {            /* got a ticket */
-               scIndex = 2;
-               if ((ttoken.kvno < 0) || (ttoken.kvno > 256)) {
-                   fprintf(stderr,
-                           "%s: funny kvno (%d) in ticket, proceeding\n",
-                           funcName, ttoken.kvno);
-               }
-           }
-       }
-
-       switch (scIndex) {
-       case 0:
-           sc = rxnull_NewClientSecurityObject();
-           break;
-       case 2:
-           sc = rxkad_NewClientSecurityObject(gen_rxkad_level,
-                                              &ttoken.sessionKey,
-                                              ttoken.kvno, ttoken.ticketLen,
-                                              ttoken.ticket);
-           break;
-       default:
-           fprintf(stderr, "%s: unsupported security index %d\n",
-                   funcName, scIndex);
-           exit(1);
-           break;
-       }
+    code = afsconf_PickClientSecObj(dir, secFlags, info, NULL, &sc,
+                                   &scIndex, NULL);
+    if (code) {
+       fprintf(stderr, "%s: can't create client security object", progname);
+       return code;
     }
 
-    afsconf_Close(tdir);
+    if (scIndex == RX_SECIDX_NULL && !(secFlags & AFSCONF_SECOPTS_NOAUTH)) {
+       fprintf(stderr,
+               "%s: Could not get afs tokens, running unauthenticated.\n",
+               progname);
+    }
 
     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);
-           exit(1);
+                   progname, info->numServers, maxservers);
+           return -1;
        }
-       for (i = 0; i < info.numServers; i++) {
+       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);
        }
     }
@@ -195,12 +93,121 @@ ugen_ClientInit(int noAuthFlag, char *confDir, char *cellName, afs_int32 sauth,
     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);
+}