*/
#include "includes.h"
+#include "system/filesys.h"
+#include "popt_common.h"
+#include "lib/param/param.h"
+#include "lib/util/xfile.h"
/* Handle command line options:
* -d,--debuglevel
* -i,--scope
*/
-extern bool AllowDebugChange;
+enum {OPT_OPTION=1};
+
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:
+ {
+ struct loadparm_context *lp_ctx;
+
+ lp_ctx = loadparm_init_s3(talloc_tos(), loadparm_s3_helpers());
+ if (lp_ctx == NULL) {
+ fprintf(stderr, "loadparm_init_s3() failed!\n");
+ exit(1);
+ }
+
+ if (!lpcfg_set_option(lp_ctx, arg)) {
+ fprintf(stderr, "Error setting option '%s'\n", arg);
+ exit(1);
+ }
+ TALLOC_FREE(lp_ctx);
+ break;
+ }
case 'd':
if (arg) {
- debug_parse_levels(arg);
- AllowDebugChange = False;
+ lp_set_cmdline("log level", arg);
}
break;
case 'O':
if (arg) {
- lp_do_parameter(-1, "socket options", arg);
+ lp_set_cmdline("socket options", 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
};
-
-/* Handle command line options:
- * --sbindir
- * --bindir
- * --swatdir
- * --lmhostsfile
- * --libdir
- * --shlibext
- * --lockdir
- * --piddir
- * --smb-passwd-file
- * --private-dir
- */
-
-enum dyn_item{
- DYN_SBINDIR = 1,
- DYN_BINDIR,
- DYN_SWATDIR,
- DYN_LMHOSTSFILE,
- DYN_LIBDIR,
- DYN_SHLIBEXT,
- DYN_LOCKDIR,
- DYN_PIDDIR,
- DYN_SMB_PASSWD_FILE,
- DYN_PRIVATE_DIR,
+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
};
-
-static void popt_dynconfig_callback(poptContext con,
- enum poptCallbackReason reason,
- const struct poptOption *opt,
- const char *arg, const void *data)
-{
-
- switch (opt->val) {
- case DYN_SBINDIR:
- if (arg) {
- dyn_SBINDIR = SMB_STRDUP(arg);
- }
- break;
-
- case DYN_BINDIR:
- if (arg) {
- dyn_BINDIR = SMB_STRDUP(arg);
- }
- break;
-
- case DYN_SWATDIR:
- if (arg) {
- dyn_SWATDIR = SMB_STRDUP(arg);
- }
- break;
-
- case DYN_LMHOSTSFILE:
- if (arg) {
- strlcpy(dyn_LMHOSTSFILE, arg,sizeof(dyn_LMHOSTSFILE));
- }
- break;
-
- case DYN_LIBDIR:
- if (arg) {
- strlcpy(dyn_LIBDIR, arg,sizeof(dyn_LIBDIR));
- }
- break;
-
- case DYN_SHLIBEXT:
- if (arg) {
- fstrcpy(dyn_SHLIBEXT, arg);
- }
- break;
-
- case DYN_LOCKDIR:
- if (arg) {
- strlcpy(dyn_LOCKDIR, arg,sizeof(dyn_LOCKDIR));
- }
- break;
-
- case DYN_PIDDIR:
- if (arg) {
- strlcpy(dyn_PIDDIR, arg,sizeof(dyn_PIDDIR));
- }
- break;
-
- case DYN_SMB_PASSWD_FILE:
- if (arg) {
- strlcpy(dyn_SMB_PASSWD_FILE, arg,sizeof(dyn_SMB_PASSWD_FILE));
- }
- break;
-
- case DYN_PRIVATE_DIR:
- if (arg) {
- strlcpy(dyn_PRIVATE_DIR, arg, sizeof(dyn_PRIVATE_DIR));
- }
- break;
-
- }
-}
-
-const struct poptOption popt_common_dynconfig[] = {
-
- { NULL, '\0', POPT_ARG_CALLBACK, (void *)popt_dynconfig_callback },
-
- { "sbindir", '\0' , POPT_ARG_STRING, NULL, DYN_SBINDIR,
- "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" },
- { "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" },
- { "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,
- "Path to smbpasswd file", "SMB_PASSWD_FILE" },
- { "private-dir", '\0' , POPT_ARG_STRING, NULL, DYN_PRIVATE_DIR,
- "Path to private data directory", "PRIVATE_DIR" },
-
+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
};
* 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;
- uint16 len = 0;
+ uint16_t len = 0;
char *ptr, *val, *param;
if ((auth=x_fopen(file, O_RDONLY, 0)) == NULL)
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
*/
+struct user_auth_info *cmdline_auth_info;
+static bool popt_common_credentials_delay_post;
+
+void popt_common_credentials_set_delay_post(void)
+{
+ popt_common_credentials_delay_post = true;
+}
+
+void popt_common_credentials_post(void)
+{
+ struct user_auth_info *auth_info = cmdline_auth_info;
+
+ if (get_cmdline_auth_info_use_machine_account(auth_info) &&
+ !set_cmdline_auth_info_machine_account_creds(auth_info))
+ {
+ fprintf(stderr,
+ "Failed to use machine account credentials\n");
+ exit(1);
+ }
+
+ set_cmdline_auth_info_getpass(auth_info);
+}
static void popt_common_credentials_callback(poptContext con,
enum poptCallbackReason reason,
const struct poptOption *opt,
const char *arg, const void *data)
{
- char *p;
+ struct user_auth_info *auth_info = cmdline_auth_info;
if (reason == POPT_CALLBACK_REASON_PRE) {
- set_cmdline_auth_info_username("GUEST");
+ if (auth_info == NULL) {
+ auth_info = user_auth_info_init(talloc_autofree_context());
+ if (auth_info == NULL) {
+ fprintf(stderr, "user_auth_info_init() failed\n");
+ exit(1);
+ }
+ cmdline_auth_info = auth_info;
+ }
+
+ 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")) {
- char *puser = SMB_STRDUP(getenv("USER"));
- if (!puser) {
- exit(ENOMEM);
- }
- set_cmdline_auth_info_username(puser);
-
- if ((p = strchr_m(puser,'%'))) {
- size_t len;
- *p = 0;
- len = strlen(p+1);
- set_cmdline_auth_info_password(p+1);
- memset(strchr_m(getenv("USER"),'%')+1,'X',len);
- }
- SAFE_FREE(puser);
+ set_cmdline_auth_info_username(auth_info,
+ getenv("USER"));
}
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;
+ }
+
+ if (reason == POPT_CALLBACK_REASON_POST) {
+ if (popt_common_credentials_delay_post) {
+ return;
}
+ popt_common_credentials_post();
return;
}
if ((lp=strchr_m(puser,'%'))) {
size_t len;
- *lp = 0;
- set_cmdline_auth_info_username(puser);
- set_cmdline_auth_info_password(lp+1);
+ *lp = '\0';
+ set_cmdline_auth_info_username(auth_info,
+ puser);
+ set_cmdline_auth_info_password(auth_info,
+ lp+1);
len = strlen(lp+1);
- memset(strchr_m(arg,'%')+1,'X',len);
+ memset(lp + 1, '\0', len);
} else {
- set_cmdline_auth_info_username(puser);
+ 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
- set_cmdline_auth_info_use_krb5_ticket();
+ set_cmdline_auth_info_use_krb5_ticket(auth_info);
#endif
break;
case 'S':
- if (!set_cmdline_auth_info_signing_state(arg)) {
+ 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 */
+/**
+ * @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 (!secrets_init()) {
- d_printf("ERROR: Unable to open secrets database\n");
- exit(1);
+ if (found) {
+ if (p == NULL) {
+ return;
}
- opt_password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
-
- if (!opt_password) {
- d_printf("ERROR: Unable to fetch machine password\n");
- exit(1);
- }
- 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 */
- set_cmdline_auth_info_use_krb5_ticket();
+ p = strchr_m(p, '%');
+ if (p != NULL) {
+ memset(p, '\0', strlen(p));
+ }
+ found = false;
}
- break;
- case 'N':
- set_cmdline_auth_info_no_password();
- 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|POPT_CBFLAG_POST,
+ (void *)popt_common_credentials_callback, 0, NULL },
{ "user", 'U', POPT_ARG_STRING, NULL, 'U', "Set the network username", "USERNAME" },
{ "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" },
+ {"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
};