swat: Remove swat.
[samba.git] / source3 / lib / popt_common.c
index d454a798acc8a319b69248127cd901548ad6bfc0..eb3e2a455c49a34a838b830b6dd857c37c8c50f2 100644 (file)
@@ -21,6 +21,8 @@
 */
 
 #include "includes.h"
+#include "system/filesys.h"
+#include "popt_common.h"
 
 /* Handle command line options:
  *             -d,--debuglevel 
  *             -i,--scope
  */
 
-extern bool AllowDebugChange;
-extern bool override_logfile;
-
-static struct user_auth_info cmdline_auth_info;
-
-const char *get_cmdline_auth_info_username(void)
-{
-       if (!cmdline_auth_info.username) {
-               return "";
-       }
-       return cmdline_auth_info.username;
-}
-
-void set_cmdline_auth_info_username(const char *username)
-{
-       SAFE_FREE(cmdline_auth_info.username);
-       cmdline_auth_info.username = SMB_STRDUP(username);
-       if (!cmdline_auth_info.username) {
-               exit(ENOMEM);
-       }
-}
-
-const char *get_cmdline_auth_info_password(void)
-{
-       if (!cmdline_auth_info.password) {
-               return "";
-       }
-       return cmdline_auth_info.password;
-}
-
-void set_cmdline_auth_info_password(const char *password)
-{
-       SAFE_FREE(cmdline_auth_info.password);
-       cmdline_auth_info.password = SMB_STRDUP(password);
-       if (!cmdline_auth_info.password) {
-               exit(ENOMEM);
-       }
-       cmdline_auth_info.got_pass = true;
-}
-
-int get_cmdline_auth_info_signing_state(void)
-{
-       return cmdline_auth_info.signing_state;
-}
-
-bool get_cmdline_auth_info_use_kerberos(void)
-{
-       return cmdline_auth_info.use_kerberos;
-}
+enum {OPT_OPTION=1};
 
-bool get_cmdline_auth_info_got_pass(void)
-{
-       return cmdline_auth_info.got_pass;
-}
+extern bool override_logfile;
 
 static void set_logfile(poptContext con, const char * arg)
 {
 
-       char *logfile = NULL;
+       char *lfile = NULL;
        const char *pname;
 
        /* Find out basename of current program */
@@ -102,15 +53,20 @@ static void set_logfile(poptContext con, const char * arg)
        else
                pname++;
 
-       if (asprintf(&logfile, "%s/log.%s", arg, pname) < 0) {
+       if (asprintf(&lfile, "%s/log.%s", arg, pname) < 0) {
                return;
        }
-       lp_set_logfile(logfile);
-       SAFE_FREE(logfile);
+       lp_set_logfile(lfile);
+       SAFE_FREE(lfile);
 }
 
 static bool PrintSambaVersionString;
 
+static void popt_s3_talloc_log_fn(const char *message)
+{
+       DEBUG(0,("%s", message));
+}
+
 static void popt_common_callback(poptContext con,
                           enum poptCallbackReason reason,
                           const struct poptOption *opt,
@@ -118,23 +74,40 @@ static void popt_common_callback(poptContext con,
 {
 
        if (reason == POPT_CALLBACK_REASON_PRE) {
-               set_logfile(con, dyn_LOGFILEBASE);
+               set_logfile(con, get_dyn_LOGFILEBASE());
+               talloc_set_log_fn(popt_s3_talloc_log_fn);
+               talloc_set_abort_fn(smb_panic);
                return;
        }
 
        if (reason == POPT_CALLBACK_REASON_POST) {
-               if (!PrintSambaVersionString) return;
 
-               printf( "Version %s\n", SAMBA_VERSION_STRING);
-               exit(0);
+               if (PrintSambaVersionString) {
+                       printf( "Version %s\n", samba_version_string());
+                       exit(0);
+               }
+
+               if (is_default_dyn_CONFIGFILE()) {
+                       if(getenv("SMB_CONF_PATH")) {
+                               set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
+                       }
+               }
+
+               /* Further 'every Samba program must do this' hooks here. */
                return;
        }
 
        switch(opt->val) {
+       case OPT_OPTION:
+               if (!lp_set_option(arg)) {
+                       fprintf(stderr, "Error setting option '%s'\n", arg);
+                       exit(1);
+               }
+               break;
+
        case 'd':
                if (arg) {
-                       debug_parse_levels(arg);
-                       AllowDebugChange = False;
+                       lp_set_cmdline("log level", arg);
                }
                break;
 
@@ -150,13 +123,13 @@ static void popt_common_callback(poptContext con,
 
        case 's':
                if (arg) {
-                       strlcpy(dyn_CONFIGFILE, arg,sizeof(dyn_CONFIGFILE));
+                       set_dyn_CONFIGFILE(arg);
                }
                break;
 
        case 'n':
                if (arg) {
-                       set_global_myname(arg);
+                       lp_set_cmdline("netbios name", arg);
                }
                break;
 
@@ -164,19 +137,19 @@ static void popt_common_callback(poptContext con,
                if (arg) {
                        set_logfile(con, arg);
                        override_logfile = True;
-                       pstr_sprintf(dyn_LOGFILEBASE, "%s", arg);
+                       set_dyn_LOGFILEBASE(arg);
                }
                break;
 
        case 'i':
                if (arg) {
-                         set_global_scope(arg);
+                       lp_set_cmdline("netbios scope", arg);
                }
                break;
 
        case 'W':
                if (arg) {
-                       set_global_myworkgroup(arg);
+                       lp_set_cmdline("workgroup", arg);
                }
                break;
        }
@@ -199,24 +172,44 @@ struct poptOption popt_common_samba[] = {
        { "configfile", 's', POPT_ARG_STRING, NULL, 's', "Use alternate configuration file", "CONFIGFILE" },
        { "log-basename", 'l', POPT_ARG_STRING, NULL, 'l', "Base name for log files", "LOGFILEBASE" },
        { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" },
+       { "option",         0, POPT_ARG_STRING, NULL, OPT_OPTION, "Set smb.conf option from command line", "name=value" },
+       POPT_TABLEEND
+};
+
+struct poptOption popt_common_configfile[] = {
+       { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, (void *)popt_common_callback },
+       { "configfile", 0, POPT_ARG_STRING, NULL, 's', "Use alternate configuration file", "CONFIGFILE" },
        POPT_TABLEEND
 };
 
 struct poptOption popt_common_version[] = {
-       { NULL, 0, POPT_ARG_CALLBACK, (void *)popt_common_callback },
+       { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_POST, (void *)popt_common_callback },
        { "version", 'V', POPT_ARG_NONE, NULL, 'V', "Print version" },
        POPT_TABLEEND
 };
 
+struct poptOption popt_common_debuglevel[] = {
+       { NULL, 0, POPT_ARG_CALLBACK, (void *)popt_common_callback },
+       { "debuglevel", 'd', POPT_ARG_STRING, NULL, 'd', "Set debug level", "DEBUGLEVEL" },
+       POPT_TABLEEND
+};
+
+struct poptOption popt_common_option[] = {
+       { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_POST, (void *)popt_common_callback },
+       { "option",         0, POPT_ARG_STRING, NULL, OPT_OPTION, "Set smb.conf option from command line", "name=value" },
+       POPT_TABLEEND
+};
 
 /* Handle command line options:
  *             --sbindir
  *             --bindir
- *             --swatdir
  *             --lmhostsfile
  *             --libdir
+ *             --modulesdir
  *             --shlibext
  *             --lockdir
+ *             --statedir
+ *             --cachedir
  *             --piddir
  *             --smb-passwd-file
  *             --private-dir
@@ -225,11 +218,13 @@ struct poptOption popt_common_version[] = {
 enum dyn_item{
        DYN_SBINDIR = 1,
        DYN_BINDIR,
-       DYN_SWATDIR,
        DYN_LMHOSTSFILE,
        DYN_LIBDIR,
+       DYN_MODULESDIR,
        DYN_SHLIBEXT,
        DYN_LOCKDIR,
+       DYN_STATEDIR,
+       DYN_CACHEDIR,
        DYN_PIDDIR,
        DYN_SMB_PASSWD_FILE,
        DYN_PRIVATE_DIR,
@@ -245,61 +240,73 @@ static void popt_dynconfig_callback(poptContext con,
        switch (opt->val) {
        case DYN_SBINDIR:
                if (arg) {
-                       dyn_SBINDIR = SMB_STRDUP(arg);
+                       set_dyn_SBINDIR(arg);
                }
                break;
 
        case DYN_BINDIR:
                if (arg) {
-                       dyn_BINDIR = SMB_STRDUP(arg);
+                       set_dyn_BINDIR(arg);
                }
                break;
 
-       case DYN_SWATDIR:
+       case DYN_LMHOSTSFILE:
                if (arg) {
-                       dyn_SWATDIR = SMB_STRDUP(arg);
+                       set_dyn_LMHOSTSFILE(arg);
                }
                break;
 
-       case DYN_LMHOSTSFILE:
+       case DYN_LIBDIR:
                if (arg) {
-                       strlcpy(dyn_LMHOSTSFILE, arg,sizeof(dyn_LMHOSTSFILE));
+                       set_dyn_LIBDIR(arg);
                }
                break;
 
-       case DYN_LIBDIR:
+       case DYN_MODULESDIR:
                if (arg) {
-                       strlcpy(dyn_LIBDIR, arg,sizeof(dyn_LIBDIR));
+                       set_dyn_MODULESDIR(arg);
                }
                break;
 
        case DYN_SHLIBEXT:
                if (arg) {
-                       fstrcpy(dyn_SHLIBEXT, arg);
+                       set_dyn_SHLIBEXT(arg);
                }
                break;
 
        case DYN_LOCKDIR:
                if (arg) {
-                       strlcpy(dyn_LOCKDIR, arg,sizeof(dyn_LOCKDIR));
+                       set_dyn_LOCKDIR(arg);
+               }
+               break;
+
+       case DYN_STATEDIR:
+               if (arg) {
+                       set_dyn_STATEDIR(arg);
+               }
+               break;
+
+       case DYN_CACHEDIR:
+               if (arg) {
+                       set_dyn_CACHEDIR(arg);
                }
                break;
 
        case DYN_PIDDIR:
                if (arg) {
-                       strlcpy(dyn_PIDDIR, arg,sizeof(dyn_PIDDIR));
+                       set_dyn_PIDDIR(arg);
                }
                break;
 
        case DYN_SMB_PASSWD_FILE:
                if (arg) {
-                       strlcpy(dyn_SMB_PASSWD_FILE, arg,sizeof(dyn_SMB_PASSWD_FILE));
+                       set_dyn_SMB_PASSWD_FILE(arg);
                }
                break;
 
        case DYN_PRIVATE_DIR:
                if (arg) {
-                       strlcpy(dyn_PRIVATE_DIR, arg, sizeof(dyn_PRIVATE_DIR));
+                       set_dyn_PRIVATE_DIR(arg);
                }
                break;
 
@@ -314,16 +321,20 @@ const struct poptOption popt_common_dynconfig[] = {
            "Path to sbin directory", "SBINDIR" },
        { "bindir", '\0' , POPT_ARG_STRING, NULL, DYN_BINDIR,
            "Path to bin directory", "BINDIR" },
-       { "swatdir", '\0' , POPT_ARG_STRING, NULL, DYN_SWATDIR,
-           "Path to SWAT installation directory", "SWATDIR" },
        { "lmhostsfile", '\0' , POPT_ARG_STRING, NULL, DYN_LMHOSTSFILE,
            "Path to lmhosts file", "LMHOSTSFILE" },
        { "libdir", '\0' , POPT_ARG_STRING, NULL, DYN_LIBDIR,
            "Path to shared library directory", "LIBDIR" },
+       { "modulesdir", '\0' , POPT_ARG_STRING, NULL, DYN_MODULESDIR,
+           "Path to shared modules directory", "MODULESDIR" },
        { "shlibext", '\0' , POPT_ARG_STRING, NULL, DYN_SHLIBEXT,
            "Shared library extension", "SHLIBEXT" },
        { "lockdir", '\0' , POPT_ARG_STRING, NULL, DYN_LOCKDIR,
            "Path to lock file directory", "LOCKDIR" },
+       { "statedir", '\0' , POPT_ARG_STRING, NULL, DYN_STATEDIR,
+           "Path to persistent state file directory", "STATEDIR" },
+       { "cachedir", '\0' , POPT_ARG_STRING, NULL, DYN_CACHEDIR,
+           "Path to temporary cache file directory", "CACHEDIR" },
        { "piddir", '\0' , POPT_ARG_STRING, NULL, DYN_PIDDIR,
            "Path to PID file directory", "PIDDIR" },
        { "smb-passwd-file", '\0' , POPT_ARG_STRING, NULL, DYN_SMB_PASSWD_FILE,
@@ -339,7 +350,7 @@ const struct poptOption popt_common_dynconfig[] = {
  * exit on failure
  * ****************************************************************************/
 
-static void get_password_file(void)
+static void get_password_file(struct user_auth_info *auth_info)
 {
        int fd = -1;
        char *p;
@@ -354,7 +365,7 @@ static void get_password_file(void)
                sscanf(p, "%d", &fd);
                close_it = false;
        } else if ((p = getenv("PASSWD_FILE")) != NULL) {
-               fd = sys_open(p, O_RDONLY, 0);
+               fd = open(p, O_RDONLY, 0);
                spec = SMB_STRDUP(p);
                if (fd < 0) {
                        fprintf(stderr, "Error opening PASSWD_FILE %s: %s\n",
@@ -364,6 +375,11 @@ static void get_password_file(void)
                close_it = True;
        }
 
+       if (fd < 0) {
+               fprintf(stderr, "fd = %d, < 0\n", fd);
+               exit(1);
+       }
+
        for(p = pass, *p = '\0'; /* ensure that pass is null-terminated */
                p && p - pass < sizeof(pass);) {
                switch (read(fd, p, 1)) {
@@ -393,13 +409,14 @@ static void get_password_file(void)
        }
        SAFE_FREE(spec);
 
-       set_cmdline_auth_info_password(pass);
+       set_cmdline_auth_info_password(auth_info, pass);
        if (close_it) {
                close(fd);
        }
 }
 
-static void get_credentials_file(const char *file)
+static void get_credentials_file(struct user_auth_info *auth_info,
+                                const char *file)
 {
        XFILE *auth;
        fstring buf;
@@ -442,11 +459,11 @@ static void get_credentials_file(const char *file)
                        val++;
 
                if (strwicmp("password", param) == 0) {
-                       set_cmdline_auth_info_password(val);
+                       set_cmdline_auth_info_password(auth_info, val);
                } else if (strwicmp("username", param) == 0) {
-                       set_cmdline_auth_info_username(val);
+                       set_cmdline_auth_info_username(auth_info, val);
                } else if (strwicmp("domain", param) == 0) {
-                       set_global_myworkgroup(val);
+                       set_cmdline_auth_info_domain(auth_info, val);
                }
                memset(buf, 0, sizeof(buf));
        }
@@ -460,6 +477,8 @@ static void get_credentials_file(const char *file)
  *             -N,--no-pass
  *             -S,--signing
  *              -P --machine-pass
+ *             -e --encrypt
+ *             -C --use-ccache
  */
 
 
@@ -468,16 +487,16 @@ static void popt_common_credentials_callback(poptContext con,
                                        const struct poptOption *opt,
                                        const char *arg, const void *data)
 {
+       struct user_auth_info *auth_info = talloc_get_type_abort(
+               *((const char **)data), struct user_auth_info);
        char *p;
 
        if (reason == POPT_CALLBACK_REASON_PRE) {
-               cmdline_auth_info.use_kerberos = False;
-               cmdline_auth_info.got_pass = False;
-               cmdline_auth_info.signing_state = Undefined;
-               set_cmdline_auth_info_username("GUEST");
+               set_cmdline_auth_info_username(auth_info, "GUEST");
 
                if (getenv("LOGNAME")) {
-                       set_cmdline_auth_info_username(getenv("LOGNAME"));
+                       set_cmdline_auth_info_username(auth_info,
+                                                      getenv("LOGNAME"));
                }
 
                if (getenv("USER")) {
@@ -485,22 +504,16 @@ static void popt_common_credentials_callback(poptContext con,
                        if (!puser) {
                                exit(ENOMEM);
                        }
-                       set_cmdline_auth_info_username(puser);
-
-                       if ((p = strchr_m(puser,'%'))) {
-                               *p = 0;
-                               set_cmdline_auth_info_password(p+1);
-                               memset(strchr_m(getenv("USER"),'%')+1,'X',strlen(cmdline_auth_info.password));
-                       }
-                       SAFE_FREE(puser);
+                       set_cmdline_auth_info_username(auth_info, puser);
                }
 
                if (getenv("PASSWD")) {
-                       set_cmdline_auth_info_password(getenv("PASSWD"));
+                       set_cmdline_auth_info_password(auth_info,
+                                                      getenv("PASSWD"));
                }
 
                if (getenv("PASSWD_FD") || getenv("PASSWD_FILE")) {
-                       get_password_file();
+                       get_password_file(auth_info);
                }
 
                return;
@@ -510,19 +523,27 @@ static void popt_common_credentials_callback(poptContext con,
        case 'U':
                {
                        char *lp;
-
-                       pstrcpy(cmdline_auth_info.username,arg);
-                       if ((lp=strchr_m(cmdline_auth_info.username,'%'))) {
-                               *lp = 0;
-                               pstrcpy(cmdline_auth_info.password,lp+1);
-                               cmdline_auth_info.got_pass = True;
-                               memset(strchr_m(arg,'%')+1,'X',strlen(cmdline_auth_info.password));
+                       char *puser = SMB_STRDUP(arg);
+
+                       if ((lp=strchr_m(puser,'%'))) {
+                               size_t len;
+                               *lp = '\0';
+                               set_cmdline_auth_info_username(auth_info,
+                                                              puser);
+                               set_cmdline_auth_info_password(auth_info,
+                                                              lp+1);
+                               len = strlen(lp+1);
+                               memset(lp + 1, '\0', len);
+                       } else {
+                               set_cmdline_auth_info_username(auth_info,
+                                                              puser);
                        }
+                       SAFE_FREE(puser);
                }
                break;
 
        case 'A':
-               get_credentials_file(arg);
+               get_credentials_file(auth_info, arg);
                break;
 
        case 'k':
@@ -530,68 +551,102 @@ static void popt_common_credentials_callback(poptContext con,
                d_printf("No kerberos support compiled in\n");
                exit(1);
 #else
-               cmdline_auth_info.use_kerberos = true;
-               cmdline_auth_info.got_pass = true;
+               set_cmdline_auth_info_use_krb5_ticket(auth_info);
 #endif
                break;
 
        case 'S':
-               {
-                       cmdline_auth_info.signing_state = -1;
-                       if (strequal(arg, "off") || strequal(arg, "no") || strequal(arg, "false")) {
-                               cmdline_auth_info.signing_state = false;
-                       } else if (strequal(arg, "on") || strequal(arg, "yes") || strequal(arg, "true") ||
-                                       strequal(arg, "auto")) {
-                               cmdline_auth_info.signing_state = true;
-                       } else if (strequal(arg, "force") || strequal(arg, "required") || strequal(arg, "forced")) {
-                               cmdline_auth_info.signing_state = Required;
-                       } else {
-                               fprintf(stderr, "Unknown signing option %s\n", arg );
-                               exit(1);
-                       }
+               if (!set_cmdline_auth_info_signing_state(auth_info, arg)) {
+                       fprintf(stderr, "Unknown signing option %s\n", arg );
+                       exit(1);
                }
                break;
        case 'P':
-               {
-                       char *opt_password = NULL;
-                       char *pwd = NULL;
+               set_cmdline_auth_info_use_machine_account(auth_info);
+               break;
+       case 'N':
+               set_cmdline_auth_info_password(auth_info, "");
+               break;
+       case 'e':
+               set_cmdline_auth_info_smb_encrypt(auth_info);
+               break;
+       case 'C':
+               set_cmdline_auth_info_use_ccache(auth_info, true);
+               break;
+       case 'H':
+               set_cmdline_auth_info_use_pw_nt_hash(auth_info, true);
+               break;
+       }
+}
 
-                       /* it is very useful to be able to make ads queries as the
-                          machine account for testing purposes and for domain leave */
+static struct user_auth_info *global_auth_info;
 
-                       if (!secrets_init()) {
-                               d_printf("ERROR: Unable to open secrets database\n");
-                               exit(1);
-                       }
+void popt_common_set_auth_info(struct user_auth_info *auth_info)
+{
+       global_auth_info = auth_info;
+}
 
-                       opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
+/**
+ * @brief Burn the commandline password.
+ *
+ * This function removes the password from the command line so we
+ * don't leak the password e.g. in 'ps aux'.
+ *
+ * It should be called after processing the options and you should pass down
+ * argv from main().
+ *
+ * @param[in]  argc     The number of arguments.
+ *
+ * @param[in]  argv[]   The argument array we will find the array.
+ */
+void popt_burn_cmdline_password(int argc, char *argv[])
+{
+       bool found = false;
+       char *p = NULL;
+       int i, ulen = 0;
+
+       for (i = 0; i < argc; i++) {
+               p = argv[i];
+               if (strncmp(p, "-U", 2) == 0) {
+                       ulen = 2;
+                       found = true;
+               } else if (strncmp(p, "--user", 6) == 0) {
+                       ulen = 6;
+                       found = true;
+               }
 
-                       if (!opt_password) {
-                               d_printf("ERROR: Unable to fetch machine password\n");
-                               exit(1);
+               if (found) {
+                       if (p == NULL) {
+                               return;
                        }
-                       if (asprintf(&pwd, "%s$", global_myname()) < 0) {
-                               exit(ENOMEM);
+
+                       if (strlen(p) == ulen) {
+                               continue;
                        }
-                       set_cmdline_auth_info_username(pwd);
-                       set_cmdline_auth_info_password(opt_password);
-                       SAFE_FREE(pwd);
-                       SAFE_FREE(opt_password);
 
-                       /* machine accounts only work with kerberos */
-                       cmdline_auth_info.use_kerberos = true;
+                       p = strchr_m(p, '%');
+                       if (p != NULL) {
+                               memset(p, '\0', strlen(p));
+                       }
+                       found = false;
                }
-               break;
        }
 }
 
 struct poptOption popt_common_credentials[] = {
-       { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE, (void *)popt_common_credentials_callback },
+       { NULL, 0, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE,
+         (void *)popt_common_credentials_callback, 0,
+         (const char *)&global_auth_info },
        { "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "USERNAME" },
-       { "no-pass", 'N', POPT_ARG_NONE, &cmdline_auth_info.got_pass, 0, "Don't ask for a password" },
-       { "kerberos", 'k', POPT_ARG_NONE, &cmdline_auth_info.use_kerberos, 'k', "Use kerberos (active directory) authentication" },
+       { "no-pass", 'N', POPT_ARG_NONE, NULL, 'N', "Don't ask for a password" },
+       { "kerberos", 'k', POPT_ARG_NONE, NULL, 'k', "Use kerberos (active directory) authentication" },
        { "authentication-file", 'A', POPT_ARG_STRING, NULL, 'A', "Get the credentials from a file", "FILE" },
        { "signing", 'S', POPT_ARG_STRING, NULL, 'S', "Set the client signing state", "on|off|required" },
        {"machine-pass", 'P', POPT_ARG_NONE, NULL, 'P', "Use stored machine account password" },
+       {"encrypt", 'e', POPT_ARG_NONE, NULL, 'e', "Encrypt SMB transport (UNIX extended servers only)" },
+       {"use-ccache", 'C', POPT_ARG_NONE, NULL, 'C',
+        "Use the winbind ccache for authentication" },
+       {"pw-nt-hash", '\0', POPT_ARG_NONE, NULL, 'H',
+        "The supplied password is the NT hash" },
        POPT_TABLEEND
 };