From: Andreas Schneider Date: Thu, 30 Mar 2023 09:19:01 +0000 (+0200) Subject: s3:utils: Use common command line parser for smbget X-Git-Tag: talloc-2.4.1~1114 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=20b5d98ce58526fb0fc78f5482988aebb95c7e80;p=thirdparty%2Fsamba.git s3:utils: Use common command line parser for smbget Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- diff --git a/source3/script/tests/test_smbget.sh b/source3/script/tests/test_smbget.sh index 7f0a1800b23..bb9fde3838c 100755 --- a/source3/script/tests/test_smbget.sh +++ b/source3/script/tests/test_smbget.sh @@ -142,13 +142,16 @@ test_singlefile_smburl() return 0 } -test_singlefile_rcfile() +test_singlefile_authfile() { clear_download_area - echo "user $USERNAME%$PASSWORD" >$TMPDIR/rcfile - $SMBGET --verbose --nonprompt --rcfile $TMPDIR/rcfile smb://$SERVER_IP/smbget/testfile + cat >"${TMPDIR}/authfile" << EOF +username = $USERNAME +password = $PASSWORD +EOF + $SMBGET --verbose --authentication-file="${TMPDIR}/authfile" smb://$SERVER_IP/smbget/testfile rc=$? - rm -f $TMPDIR/rcfile + rm -f $TMPDIR/authfile if [ $rc -ne 0 ]; then echo 'ERROR: RC does not match, expected: 0' return 1 @@ -306,7 +309,7 @@ test_msdfs_link() { clear_download_area - ${SMBGET} --verbose "-U${USERNAME}%${PASSWORD}" \ + ${SMBGET} --verbose "-U${SERVER}/${USERNAME}%${PASSWORD}" \ "smb://${SERVER}/msdfs-share/deeppath/msdfs-src2/readable_file" ret=$? if [ ${ret} -ne 0 ]; then @@ -393,7 +396,7 @@ testit "download single file with --update and UPN" test_singlefile_U_UPN || testit "download single file with smb URL" test_singlefile_smburl || failed=$(expr $failed + 1) -testit "download single file with rcfile" test_singlefile_rcfile || +testit "download single file with authfile" test_singlefile_authfile || failed=$(expr $failed + 1) testit "recursive download" test_recursive_U || diff --git a/source3/utils/smbget.c b/source3/utils/smbget.c index dca5ded4a9c..36b0fd3a894 100644 --- a/source3/utils/smbget.c +++ b/source3/utils/smbget.c @@ -21,7 +21,7 @@ #include "lib/cmdline/cmdline.h" #include "libsmbclient.h" #include "cmdline_contexts.h" -#include "lib/param/param.h" +#include "auth/credentials/credentials.h" static int columns = 0; @@ -41,22 +41,14 @@ static off_t total_bytes = 0; #define SMB_DEFAULT_BLOCKSIZE 64000 struct opt { - char *workgroup; - bool username_specified; - char *username; - bool password_specified; - char *password; - char *outputfile; size_t blocksize; - bool nonprompt; bool quiet; bool dots; bool verbose; bool send_stdout; bool update; - int debuglevel; unsigned limit_rate; }; static struct opt opt = { .blocksize = SMB_DEFAULT_BLOCKSIZE }; @@ -101,65 +93,76 @@ static void human_readable(off_t s, char *buffer, int l) } } +/* + * Authentication callback for libsmbclient. + * + * The command line parser will take care asking for a password interactively! + */ static void get_auth_data(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen) { - static bool hasasked = false; - static char *savedwg; - static char *savedun; - static char *savedpw; - - if (hasasked) { - strncpy(wg, savedwg, wglen - 1); - strncpy(un, savedun, unlen - 1); - strncpy(pw, savedpw, pwlen - 1); - return; - } - hasasked = true; - - /* - * If no user has been specified un is initialized with the current - * username of the user who started smbget. - */ - if (opt.username_specified) { - strncpy(un, opt.username, unlen - 1); - } - - if (!opt.nonprompt && !opt.password_specified && pw[0] == '\0') { - char *prompt; - int rc; - - rc = asprintf(&prompt, - "Password for [%s] connecting to //%s/%s: ", - un, srv, shr); - if (rc == -1) { - return; + struct cli_credentials *creds = samba_cmdline_get_creds(); + const char *username = NULL; + const char *password = NULL; + const char *domain = NULL; + enum smb_signing_setting signing_state = + cli_credentials_get_smb_signing(creds); + enum credentials_use_kerberos use_kerberos = + cli_credentials_get_kerberos_state(creds); + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(creds); + const char *use_signing = "auto"; + + if (encryption_state >= SMB_ENCRYPTION_DESIRED) { + signing_state = SMB_SIGNING_REQUIRED; + } + + username = cli_credentials_get_username(creds); + if (username != NULL) { + strncpy(un, username, unlen - 1); + } + + password = cli_credentials_get_password(creds); + if (password != NULL) { + strncpy(pw, password, pwlen-1); + } + + domain = cli_credentials_get_domain(creds); + if (domain != NULL) { + strncpy(wg, domain, wglen-1); + } + + switch (signing_state) { + case SMB_SIGNING_REQUIRED: + use_signing = "required"; + break; + case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_DESIRED: + case SMB_SIGNING_IF_REQUIRED: + use_signing = "yes"; + break; + case SMB_SIGNING_OFF: + use_signing = "off"; + break; + default: + use_signing = "auto"; + break; + } + + smbc_set_credentials(domain, + username, + password, + use_kerberos > CRED_USE_KERBEROS_DISABLED, + use_signing); + + if (!opt.quiet && username != NULL) { + if (username[0] == '\0') { + printf("Using guest user\n"); + } else { + printf("Using domain: %s, user: %s\n", + domain, + username); } - (void)samba_getpass(prompt, pw, pwlen, false, false); - free(prompt); - } else if (opt.password != NULL) { - strncpy(pw, opt.password, pwlen-1); - } - - if (opt.workgroup != NULL) { - strncpy(wg, opt.workgroup, wglen-1); - } - - /* save the values found for later */ - savedwg = SMB_STRDUP(wg); - savedun = SMB_STRDUP(un); - savedpw = SMB_STRDUP(pw); - - if (!opt.quiet) { - char *wgtmp, *usertmp; - wgtmp = SMB_STRNDUP(wg, wglen); - usertmp = SMB_STRNDUP(un, unlen); - printf("Using workgroup %s, %s%s\n", - wgtmp, - *usertmp ? "user " : "guest user", - usertmp); - free(wgtmp); - free(usertmp); } } @@ -736,122 +739,18 @@ static void signal_quit(int v) clean_exit(); } -static int readrcfile(const char *name, const struct poptOption long_options[]) -{ - FILE *fd = fopen(name, "r"); - int lineno = 0, i; - char var[101], val[101]; - bool found; - int *intdata; - char **stringdata; - if (!fd) { - fprintf(stderr, "Can't open RC file %s\n", name); - return 1; - } - - while (!feof(fd)) { - lineno++; - if (fscanf(fd, "%100s %100s\n", var, val) < 2) { - fprintf(stderr, - "Can't parse line %d of %s, ignoring.\n", - lineno, name); - continue; - } - - found = false; - - for (i = 0; long_options[i].argInfo; i++) { - if (!long_options[i].longName) { - continue; - } - if (strcmp(long_options[i].longName, var)) { - continue; - } - if (!long_options[i].arg) { - continue; - } - - switch (long_options[i].argInfo) { - case POPT_ARG_NONE: - intdata = (int *)long_options[i].arg; - if (!strcmp(val, "on")) { - *intdata = 1; - } else if (!strcmp(val, "off")) { - *intdata = 0; - } else { - fprintf(stderr, "Illegal value %s for " - "%s at line %d in %s\n", - val, var, lineno, name); - } - break; - case POPT_ARG_INT: - intdata = (int *)long_options[i].arg; - *intdata = atoi(val); - break; - case POPT_ARG_STRING: - stringdata = (char **)long_options[i].arg; - *stringdata = SMB_STRDUP(val); - if (long_options[i].shortName == 'U') { - char *p; - opt.username_specified = true; - p = strchr(*stringdata, '%'); - if (p != NULL) { - *p = '\0'; - opt.password = p + 1; - opt.password_specified = true; - } - } - break; - default: - fprintf(stderr, "Invalid variable %s at " - "line %d in %s\n", - var, lineno, name); - break; - } - - found = true; - } - if (!found) { - fprintf(stderr, - "Invalid variable %s at line %d in %s\n", var, - lineno, name); - } - } - - fclose(fd); - return 0; -} - int main(int argc, char **argv) { int c = 0; const char *file = NULL; - char *rcfile = NULL; bool smb_encrypt = false; int resume = 0, recursive = 0; TALLOC_CTX *frame = talloc_stackframe(); bool ok = false; - char *p; const char **argv_const = discard_const_p(const char *, argv); struct poptOption long_options[] = { POPT_AUTOHELP - { - .longName = "workgroup", - .shortName = 'w', - .argInfo = POPT_ARG_STRING, - .arg = &opt.workgroup, - .val = 'w', - .descrip = "Workgroup/domain to use (optional)" - }, - { - .longName = "user", - .shortName = 'U', - .argInfo = POPT_ARG_STRING, - .arg = &opt.username, - .val = 'U', - .descrip = "Username to use" - }, { .longName = "guest", .shortName = 'a', @@ -860,56 +759,38 @@ int main(int argc, char **argv) .val = 'a', .descrip = "Work as user guest" }, - - { - .longName = "nonprompt", - .shortName = 'n', - .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'n', - .descrip = "Don't ask anything (non-interactive)" - }, - { - .longName = "debuglevel", - .shortName = 'd', - .argInfo = POPT_ARG_INT, - .arg = &opt.debuglevel, - .val = 'd', - .descrip = "Debuglevel to use" - }, - { .longName = "encrypt", .shortName = 'e', .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'e', + .arg = &smb_encrypt, + .val = 1, .descrip = "Encrypt SMB transport" }, { .longName = "resume", .shortName = 'r', .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'r', + .arg = &resume, + .val = 1, .descrip = "Automatically resume aborted files" }, { .longName = "update", .shortName = 'u', .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'u', + .arg = &opt.update, + .val = 1, .descrip = "Download only when remote file is " "newer than local file or local file " "is missing" }, { .longName = "recursive", - .shortName = 'R', + .shortName = 0, .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'R', + .arg = &recursive, + .val = true, .descrip = "Recursively download files" }, { @@ -931,69 +812,60 @@ int main(int argc, char **argv) }, { .longName = "stdout", - .shortName = 'O', + .shortName = 0, .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'O', + .arg = &opt.send_stdout, + .val = true, .descrip = "Write data to stdout" }, { .longName = "dots", .shortName = 'D', .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'D', + .arg = &opt.dots, + .val = 1, .descrip = "Show dots as progress indication" }, { .longName = "quiet", .shortName = 'q', .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'q', + .arg = &opt.quiet, + .val = 1, .descrip = "Be quiet" }, { .longName = "verbose", .shortName = 'v', .argInfo = POPT_ARG_NONE, - .arg = NULL, - .val = 'v', + .arg = &opt.verbose, + .val = 1, .descrip = "Be verbose" }, - { - .longName = "rcfile", - .shortName = 'f', - .argInfo = POPT_ARG_STRING, - .arg = NULL, - .val = 'f', - .descrip = "Use specified rc file" - }, { .longName = "limit-rate", + .shortName = 0, .argInfo = POPT_ARG_INT, .arg = &opt.limit_rate, .val = 'l', .descrip = "Limit download speed to this many KB/s" }, + POPT_COMMON_SAMBA + POPT_COMMON_CONNECTION + POPT_COMMON_CREDENTIALS + POPT_LEGACY_S3 + POPT_COMMON_VERSION POPT_TABLEEND }; poptContext pc = NULL; + struct cli_credentials *creds = NULL; smb_init_locale(); - /* only read rcfile if it exists */ - if (asprintf(&rcfile, "%s/.smbgetrc", getenv("HOME")) == -1) { - ok = false; - goto done; - } - if (access(rcfile, F_OK) == 0) { - readrcfile(rcfile, long_options); - } - free(rcfile); - - ok = lp_load_client(lp_default_path()); + ok = samba_cmdline_init(frame, + SAMBA_CMDLINE_CONFIG_CLIENT, + false); if (!ok) { goto done; } @@ -1004,73 +876,22 @@ int main(int argc, char **argv) signal(SIGINT, signal_quit); signal(SIGTERM, signal_quit); - pc = poptGetContext(argv[0], argc, argv_const, long_options, 0); + pc = samba_popt_get_context(getprogname(), + argc, + argv_const, + long_options, + 0); + if (pc == NULL) { + ok = false; + goto done; + } + + creds = samba_cmdline_get_creds(); - while ((c = poptGetNextOpt(pc)) > 0) { + while ((c = poptGetNextOpt(pc)) != -1) { switch (c) { - case 'f': - readrcfile(poptGetOptArg(pc), long_options); - break; case 'a': - opt.username_specified = true; - opt.username = talloc_strdup(frame, ""); - opt.password_specified = true; - opt.password = talloc_strdup(frame, ""); - break; - case 'e': - smb_encrypt = true; - break; - case 'U': { - const char *separator = lp_winbind_separator(); - opt.username_specified = true; - opt.username = talloc_strdup(frame, opt.username); - p = strchr(opt.username,'%'); - if (p != NULL) { - *p = '\0'; - opt.password = p + 1; - opt.password_specified = true; - } - - /* UPN support */ - p = strchr(opt.username, '@'); - if (p != NULL && opt.workgroup == NULL) { - *p = '\0'; - opt.workgroup = p + 1; - } - - /* Domain support */ - p = strchr(opt.username, separator[0]); - if (p != NULL && opt.workgroup == NULL) { - *p = '\0'; - opt.workgroup = opt.username; - opt.username = p + 1; - } - - break; - } - case 'n': - opt.nonprompt = true; - break; - case 'r': - resume = true; - break; - case 'u': - opt.update = true; - break; - case 'R': - recursive = true; - break; - case 'O': - opt.send_stdout = true; - break; - case 'D': - opt.dots = true; - break; - case 'q': - opt.quiet = true; - break; - case 'v': - opt.verbose = true; + cli_credentials_set_anonymous(creds); break; case POPT_ERROR_BADOPT: fprintf(stderr, "\nInvalid option %s: %s\n\n", @@ -1111,7 +932,7 @@ int main(int argc, char **argv) samba_cmdline_burn(argc, argv); - if (smbc_init(get_auth_data, opt.debuglevel) < 0) { + if (smbc_init(get_auth_data, debuglevel_get()) < 0) { fprintf(stderr, "Unable to initialize libsmbclient\n"); ok = true; goto done; diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build index 49f97af8c7c..172457f4b57 100644 --- a/source3/utils/wscript_build +++ b/source3/utils/wscript_build @@ -63,7 +63,7 @@ bld.SAMBA3_BINARY('smbget', source='smbget.c', deps=''' talloc - cmdline + CMDLINE_S3 smbclient''') bld.SAMBA3_BINARY('nmblookup',