*/
#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 */
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,
{
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;
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;
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;
}
{ "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
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,
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;
"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,
* 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;
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",
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)) {
}
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;
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));
}
* -N,--no-pass
* -S,--signing
* -P --machine-pass
+ * -e --encrypt
+ * -C --use-ccache
*/
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")) {
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;
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':
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
};