*/
#include "includes.h"
+#include "system/filesys.h"
+#include "popt_common.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, 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 'n':
if (arg) {
- set_global_myname(arg);
+ lp_set_cmdline("netbios name", 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_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,
}
break;
- case DYN_SWATDIR:
- if (arg) {
- set_dyn_SWATDIR(arg);
- }
- break;
-
case DYN_LMHOSTSFILE:
if (arg) {
set_dyn_LMHOSTSFILE(arg);
}
break;
+ case DYN_MODULESDIR:
+ if (arg) {
+ set_dyn_MODULESDIR(arg);
+ }
+ break;
+
case DYN_SHLIBEXT:
if (arg) {
set_dyn_SHLIBEXT(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) {
set_dyn_PIDDIR(arg);
"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));
}
* -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) {
- 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,'%'))) {
- 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, 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;
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 */
+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 */
- 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_password("");
- break;
- case 'e':
- set_cmdline_auth_info_smb_encrypt();
- 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, NULL, 'N', "Don't ask for a password" },
{ "kerberos", 'k', POPT_ARG_NONE, NULL, 'k', "Use kerberos (active directory) authentication" },
{ "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
};