From b7464fd89bc22b71c82bbaa424bcbfcf947db651 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Mon, 13 Aug 2018 15:39:08 -0700 Subject: s3:lib: Move popt_common_credentials to separate file This is only used by command line utilities and has additional dependencies. Move to a separate file to contain the dependencies to the command line tools. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13465 Signed-off-by: Christof Schmitt Reviewed-by: Ralph Boehme --- source3/lib/popt_common_cmdline.c | 241 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 source3/lib/popt_common_cmdline.c (limited to 'source3/lib/popt_common_cmdline.c') diff --git a/source3/lib/popt_common_cmdline.c b/source3/lib/popt_common_cmdline.c new file mode 100644 index 00000000000..57f77e0868a --- /dev/null +++ b/source3/lib/popt_common_cmdline.c @@ -0,0 +1,241 @@ +/* + Unix SMB/CIFS implementation. + Common popt routines only used by cmdline utils + + Copyright (C) Tim Potter 2001,2002 + Copyright (C) Jelmer Vernooij 2002,2003 + Copyright (C) James Peach 2006 + Copyright (C) Christof Schmitt 2018 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* Handle command line options: + * -U,--user + * -A,--authentication-file + * -k,--use-kerberos + * -N,--no-pass + * -S,--signing + * -P --machine-pass + * -e --encrypt + * -C --use-ccache + */ + +#include "popt_common_cmdline.h" +#include "includes.h" +#include "auth_info.h" + +static struct user_auth_info *cmdline_auth_info; + +struct user_auth_info *popt_get_cmdline_auth_info(void) +{ + return cmdline_auth_info; +} +void popt_free_cmdline_auth_info(void) +{ + TALLOC_FREE(cmdline_auth_info); +} + +static bool popt_common_credentials_ignore_missing_conf; +static bool popt_common_credentials_delay_post; + +void popt_common_credentials_set_ignore_missing_conf(void) +{ + popt_common_credentials_delay_post = true; +} + +void popt_common_credentials_set_delay_post(void) +{ + popt_common_credentials_delay_post = true; +} + +void popt_common_credentials_post(void) +{ + if (get_cmdline_auth_info_use_machine_account(cmdline_auth_info) && + !set_cmdline_auth_info_machine_account_creds(cmdline_auth_info)) + { + fprintf(stderr, + "Failed to use machine account credentials\n"); + exit(1); + } + + set_cmdline_auth_info_getpass(cmdline_auth_info); + + /* + * When we set the username during the handling of the options passed to + * the binary we haven't loaded the config yet. This means that we + * didn't take the 'winbind separator' into account. + * + * The username might contain the domain name and thus it hasn't been + * correctly parsed yet. If we have a username we need to set it again + * to run the string parser for the username correctly. + */ + reset_cmdline_auth_info_username(cmdline_auth_info); +} + +static void popt_common_credentials_callback(poptContext con, + enum poptCallbackReason reason, + const struct poptOption *opt, + const char *arg, const void *data) +{ + if (reason == POPT_CALLBACK_REASON_PRE) { + struct user_auth_info *auth_info = + user_auth_info_init(NULL); + if (auth_info == NULL) { + fprintf(stderr, "user_auth_info_init() failed\n"); + exit(1); + } + cmdline_auth_info = auth_info; + return; + } + + if (reason == POPT_CALLBACK_REASON_POST) { + bool ok; + + ok = lp_load_client(get_dyn_CONFIGFILE()); + if (!ok) { + const char *pname = poptGetInvocationName(con); + + fprintf(stderr, "%s: Can't load %s - run testparm to debug it\n", + pname, get_dyn_CONFIGFILE()); + if (!popt_common_credentials_ignore_missing_conf) { + exit(1); + } + } + + load_interfaces(); + + set_cmdline_auth_info_guess(cmdline_auth_info); + + if (popt_common_credentials_delay_post) { + return; + } + + popt_common_credentials_post(); + return; + } + + switch(opt->val) { + case 'U': + set_cmdline_auth_info_username(cmdline_auth_info, arg); + break; + + case 'A': + set_cmdline_auth_info_from_file(cmdline_auth_info, arg); + break; + + case 'k': +#ifndef HAVE_KRB5 + d_printf("No kerberos support compiled in\n"); + exit(1); +#else + set_cmdline_auth_info_use_krb5_ticket(cmdline_auth_info); +#endif + break; + + case 'S': + if (!set_cmdline_auth_info_signing_state(cmdline_auth_info, + arg)) { + fprintf(stderr, "Unknown signing option %s\n", arg ); + exit(1); + } + break; + case 'P': + set_cmdline_auth_info_use_machine_account(cmdline_auth_info); + break; + case 'N': + set_cmdline_auth_info_password(cmdline_auth_info, ""); + break; + case 'e': + set_cmdline_auth_info_smb_encrypt(cmdline_auth_info); + break; + case 'C': + set_cmdline_auth_info_use_ccache(cmdline_auth_info, true); + break; + case 'H': + set_cmdline_auth_info_use_pw_nt_hash(cmdline_auth_info, true); + break; + } +} + +/** + * @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 (found) { + if (p == NULL) { + return; + } + + if (strlen(p) == ulen) { + continue; + } + + p = strchr_m(p, '%'); + if (p != NULL) { + memset(p, '\0', strlen(p)); + } + found = false; + } + } +} + +struct poptOption popt_common_credentials[] = { + { 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 +}; -- cgit v1.2.1