From c4c36c2ecc0ed1254e02f046ce08b4937fe26ee6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 12 Mar 2019 10:15:05 +0100 Subject: [PATCH 1/5] s3:script: Fix jobid check in test_smbspool.sh BUG: https://bugzilla.samba.org/show_bug.cgi?id=13832 Signed-off-by: Andreas Schneider Reviewed-by: Bryan Mason Signed-off-by: Guenther Deschner (cherry picked from commit fad5e4eaeb9202c1b63c42ea09254c17c473e33a) --- source3/script/tests/test_smbspool.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/script/tests/test_smbspool.sh b/source3/script/tests/test_smbspool.sh index d95ed064634..f28c0909334 100755 --- a/source3/script/tests/test_smbspool.sh +++ b/source3/script/tests/test_smbspool.sh @@ -99,8 +99,8 @@ test_vlp_verify() fi jobid=$(echo "$out" | awk '/[0-9]+/ { print $1 };') - if [ $jobid -lt 1000 || $jobid -gt 2000 ]; then - echo "failed to get jobid" + if [ -z "$jobid" ] || [ $jobid -lt 100 || [ $jobid -gt 2000 ]; then + echo "Invalid jobid: $jobid" echo "$out" return 1 fi -- 2.20.1 From 72f86fe6f41bbe7891fe81811b3234b6662de8da Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 12 Mar 2019 09:40:58 +0100 Subject: [PATCH 2/5] s3:client: Pass DEVICE_URI and AUTH_INFO_REQUIRED env to smbspool BUG: https://bugzilla.samba.org/show_bug.cgi?id=13832 Signed-off-by: Andreas Schneider Reviewed-by: Bryan Mason Signed-off-by: Guenther Deschner (cherry picked from commit 43160184d254a57f87bb2adeba47f48d8539533a) --- source3/client/smbspool_krb5_wrapper.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c index dee3b4c54be..5c4da33238b 100644 --- a/source3/client/smbspool_krb5_wrapper.c +++ b/source3/client/smbspool_krb5_wrapper.c @@ -84,24 +84,36 @@ int main(int argc, char *argv[]) struct passwd *pwd; char gen_cc[PATH_MAX] = {0}; struct stat sb; - char *env; + char *env = NULL; + char auth_info_required[256] = {0}; + char device_uri[4096] = {0}; uid_t uid = (uid_t)-1; gid_t gid = (gid_t)-1; unsigned long tmp; int cmp; int rc; + env = getenv("DEVICE_URI"); + if (env != NULL && strlen(env) > 2) { + snprintf(device_uri, sizeof(device_uri), "%s", env); + } + /* Check if AuthInfoRequired is set to negotiate */ env = getenv("AUTH_INFO_REQUIRED"); /* If not set, then just call smbspool. */ - if (env == NULL) { + if (env == NULL || env[0] == 0) { CUPS_SMB_DEBUG("AUTH_INFO_REQUIRED is not set - " "execute smbspool"); goto smbspool; } else { CUPS_SMB_DEBUG("AUTH_INFO_REQUIRED=%s", env); + snprintf(auth_info_required, + sizeof(auth_info_required), + "%s", + env); + cmp = strcmp(env, "username,password"); if (cmp == 0) { CUPS_SMB_DEBUG("Authenticate using username/password - " @@ -223,12 +235,18 @@ create_env: #else { extern char **environ; - environ = calloc(1, sizeof(*environ)); + environ = calloc(3, sizeof(*environ)); } #endif CUPS_SMB_DEBUG("Setting KRB5CCNAME to '%s'", gen_cc); setenv("KRB5CCNAME", gen_cc, 1); + if (device_uri[0] != '\0') { + setenv("DEVICE_URI", device_uri, 1); + } + if (auth_info_required[0] != '\0') { + setenv("AUTH_INFO_REQUIRED", auth_info_required, 1); + } smbspool: snprintf(smbspool_cmd, -- 2.20.1 From 47771d9ceff2771b5fda430e1836237d85300407 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 4 Jan 2019 09:21:24 +0100 Subject: [PATCH 3/5] s3:client: Evaluate the AUTH_INFO_REQUIRED variable set by cups This should not switch to username,password if cups has been configured to use negotiate (Kerberos authentication). BUG: https://bugzilla.samba.org/show_bug.cgi?id=13832 Signed-off-by: Andreas Schneider Reviewed-by: Bryan Mason Signed-off-by: Guenther Deschner (cherry picked from commit 5274b09fbaa5e45cc58f3301818d4e9f6a402845) --- source3/client/smbspool.c | 42 ++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index d6e944d547c..e94d5b33324 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -60,7 +60,7 @@ * Local functions... */ -static int get_exit_code(struct cli_state * cli, NTSTATUS nt_status, bool use_kerberos); +static int get_exit_code(struct cli_state * cli, NTSTATUS nt_status); static void list_devices(void); static struct cli_state *smb_complete_connection(const char *, const char *, int, const char *, const char *, const char *, const char *, int, bool *need_auth); @@ -72,6 +72,8 @@ static char *uri_unescape_alloc(const char *); static bool smb_encrypt; #endif +static const char *auth_info_required; + /* * 'main()' - Main entry for SMB backend. */ @@ -94,7 +96,7 @@ main(int argc, /* I - Number of command-line arguments */ FILE *fp; /* File to print */ int status = 1; /* Status of LPD job */ struct cli_state *cli; /* SMB interface */ - char null_str[1]; + char empty_str[] = ""; int tries = 0; bool need_auth = true; const char *dev_uri; @@ -106,8 +108,6 @@ main(int argc, /* I - Number of command-line arguments */ int cmp; int len; - null_str[0] = '\0'; - if (argc == 1) { /* * NEW! In CUPS 1.1 the backends are run with no arguments @@ -187,6 +187,11 @@ main(int argc, /* I - Number of command-line arguments */ } } + auth_info_required = getenv("AUTH_INFO_REQUIRED"); + if (auth_info_required == NULL) { + auth_info_required = "none"; + } + cmp = strncmp(dev_uri, "smb://", 6); if (cmp != 0) { fprintf(stderr, @@ -220,21 +225,25 @@ main(int argc, /* I - Number of command-line arguments */ *tmp2++ = '\0'; password = uri_unescape_alloc(tmp2); } else { - password = null_str; + password = empty_str; } username = uri_unescape_alloc(tmp); } else { if ((username = getenv("AUTH_USERNAME")) == NULL) { - username = null_str; + username = empty_str; } if ((password = getenv("AUTH_PASSWORD")) == NULL) { - password = null_str; + password = empty_str; } server = uri + 6; } + if (password != empty_str) { + auth_info_required = "username,password"; + } + tmp = server; if ((sep = strchr_m(tmp, '/')) == NULL) { @@ -354,8 +363,7 @@ done: static int get_exit_code(struct cli_state * cli, - NTSTATUS nt_status, - bool use_kerberos) + NTSTATUS nt_status) { int i; @@ -382,10 +390,7 @@ get_exit_code(struct cli_state * cli, } if (cli) { - if (use_kerberos) - fputs("ATTR: auth-info-required=negotiate\n", stderr); - else - fputs("ATTR: auth-info-required=username,password\n", stderr); + fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required); } /* @@ -454,6 +459,7 @@ smb_complete_connection(const char *myname, } if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + auth_info_required = "negotiate"; use_kerberos = true; } @@ -476,7 +482,7 @@ smb_complete_connection(const char *myname, if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: Session setup failed: %s\n", nt_errstr(nt_status)); - if (get_exit_code(cli, nt_status, use_kerberos) == 2) { + if (get_exit_code(cli, nt_status) == 2) { *need_auth = true; } @@ -490,7 +496,7 @@ smb_complete_connection(const char *myname, fprintf(stderr, "ERROR: Tree connect failed (%s)\n", nt_errstr(nt_status)); - if (get_exit_code(cli, nt_status, use_kerberos) == 2) { + if (get_exit_code(cli, nt_status) == 2) { *need_auth = true; } @@ -679,7 +685,7 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: %s opening remote spool %s\n", nt_errstr(nt_status), title); - return get_exit_code(cli, nt_status, false); + return get_exit_code(cli, nt_status); } /* @@ -697,7 +703,7 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ status = cli_writeall(cli, fnum, 0, (uint8_t *)buffer, tbytes, nbytes, NULL); if (!NT_STATUS_IS_OK(status)) { - int ret = get_exit_code(cli, status, false); + int ret = get_exit_code(cli, status); fprintf(stderr, "ERROR: Error writing spool: %s\n", nt_errstr(status)); fprintf(stderr, "DEBUG: Returning status %d...\n", @@ -713,7 +719,7 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: %s closing remote spool %s\n", nt_errstr(nt_status), title); - return get_exit_code(cli, nt_status, false); + return get_exit_code(cli, nt_status); } else { return (0); } -- 2.20.1 From 6e83c1c9c02889bf9b7d42366ae25cd7b8738810 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 12 Mar 2019 10:09:14 +0100 Subject: [PATCH 4/5] s3:client: Make sure we work on a copy of the title We can't be sure we can write to the input buffer. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13832 Signed-off-by: Andreas Schneider Reviewed-by: Bryan Mason Signed-off-by: Guenther Deschner (cherry picked from commit 129ae27946318a075e99c9e6d1bacf8963f72282) --- source3/client/smbspool.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index e94d5b33324..4d78db7f77c 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -66,7 +66,7 @@ static struct cli_state *smb_complete_connection(const char *, const char *, int, const char *, const char *, const char *, const char *, int, bool *need_auth); static struct cli_state *smb_connect(const char *, const char *, int, const char *, const char *, const char *, const char *, bool *need_auth); -static int smb_print(struct cli_state *, char *, FILE *); +static int smb_print(struct cli_state *, const char *, FILE *); static char *uri_unescape_alloc(const char *); #if 0 static bool smb_encrypt; @@ -655,7 +655,7 @@ kerberos_auth: static int /* O - 0 = success, non-0 = failure */ smb_print(struct cli_state * cli, /* I - SMB connection */ - char *title, /* I - Title/job name */ + const char *print_title, /* I - Title/job name */ FILE * fp) { /* I - File to print */ uint16_t fnum; /* File number */ @@ -663,12 +663,18 @@ smb_print(struct cli_state * cli, /* I - SMB connection */ tbytes; /* Total bytes read */ char buffer[8192], /* Buffer for copy */ *ptr; /* Pointer into title */ + char title[1024] = {0}; + int len; NTSTATUS nt_status; /* - * Sanitize the title... - */ + * Sanitize the title... + */ + len = snprintf(title, sizeof(title), "%s", print_title); + if (len != strlen(print_title)) { + return 2; + } for (ptr = title; *ptr; ptr++) { if (!isalnum((int) *ptr) && !isspace((int) *ptr)) { -- 2.20.1 From 5a17e86e0dde91b52afd4a192fd5a635a83b412d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 12 Mar 2019 11:40:30 +0100 Subject: [PATCH 5/5] s3:client: Fix smbspool device uri handling If we are executed as a CUPS backend, argv[0] is set to the device uri. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13832 Signed-off-by: Andreas Schneider Reviewed-by: Bryan Mason Signed-off-by: Guenther Deschner (cherry picked from commit 69d7a496d3bf52eaa10e81132bb61430863fdd8a) --- source3/client/smbspool.c | 120 ++++++++++++++++++++++++++++++-------- 1 file changed, 96 insertions(+), 24 deletions(-) diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index 4d78db7f77c..8be1009c0a8 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -99,10 +99,12 @@ main(int argc, /* I - Number of command-line arguments */ char empty_str[] = ""; int tries = 0; bool need_auth = true; - const char *dev_uri; + const char *dev_uri = NULL; + const char *env = NULL; const char *config_file = NULL; TALLOC_CTX *frame = talloc_stackframe(); - bool device_uri_cmdline = false; + const char *print_user = NULL; + const char *print_title = NULL; const char *print_file = NULL; const char *print_copies = NULL; int cmp; @@ -139,21 +141,81 @@ main(int argc, /* I - Number of command-line arguments */ } /* - * If we have 6 arguments find out if we have the device_uri from the - * command line or the print data + * Find out if we have the device_uri in the command line. + * + * If we are started as a CUPS backend argv[0] is normally the + * device_uri! */ - if (argc == 7) { - cmp = strncmp(argv[1], "smb://", 6); - if (cmp == 0) { - device_uri_cmdline = true; + if (argc == 8) { + /* + * smbspool <copies> <options> <file> + * 0 1 2 3 4 5 6 7 + */ + + dev_uri = argv[1]; + + print_user = argv[3]; + print_title = argv[4]; + print_copies = argv[5]; + print_file = argv[7]; + } else if (argc == 7) { + int cmp1; + int cmp2; + + /* + * <uri> <job> <user> <title> <copies> <options> <file> + * smbspool <uri> <job> <user> <title> <copies> <options> + * smbspool <job> <user> <title> <copies> <options> <file> | DEVICE_URI + */ + cmp1 = strncmp(argv[0], "smb://", 6); + cmp2 = strncmp(argv[1], "smb://", 6); + + if (cmp1 == 0) { + /* + * <uri> <job> <user> <title> <copies> <options> <file> + * 0 1 2 3 4 5 6 + */ + dev_uri = argv[0]; + + print_user = argv[2]; + print_title = argv[3]; + print_copies = argv[4]; + print_file = argv[6]; + } else if (cmp2 == 0) { + /* + * smbspool <uri> <job> <user> <title> <copies> <options> + * 0 1 2 3 4 5 6 + */ + dev_uri = argv[1]; + + print_user = argv[3]; + print_title = argv[4]; + print_copies = argv[5]; + print_file = NULL; } else { + /* + * smbspool <job> <user> <title> <copies> <options> <file> | DEVICE_URI + * 0 1 2 3 4 5 6 + */ + print_user = argv[2]; + print_title = argv[3]; print_copies = argv[4]; print_file = argv[6]; } - } else if (argc == 8) { - device_uri_cmdline = true; - print_copies = argv[5]; - print_file = argv[7]; + } else if (argc == 6) { + /* + * <uri> <job> <user> <title> <copies> <options> + * smbspool <job> <user> <title> <copies> <options> | DEVICE_URI + * 0 1 2 3 4 5 + */ + cmp = strncmp(argv[0], "smb://", 6); + if (cmp == 0) { + dev_uri = argv[0]; + } + + print_user = argv[2]; + print_title = argv[3]; + print_copies = argv[4]; } if (print_file != NULL) { @@ -178,18 +240,17 @@ main(int argc, /* I - Number of command-line arguments */ /* * Find the URI ... */ - if (device_uri_cmdline) { - dev_uri = argv[1]; - } else { - dev_uri = getenv("DEVICE_URI"); - if (dev_uri == NULL || strlen(dev_uri) == 0) { - dev_uri = ""; + if (dev_uri == NULL) { + env = getenv("DEVICE_URI"); + if (env != NULL && env[0] != '\0') { + dev_uri = env; } } - auth_info_required = getenv("AUTH_INFO_REQUIRED"); - if (auth_info_required == NULL) { - auth_info_required = "none"; + if (dev_uri == NULL) { + fprintf(stderr, + "ERROR: No valid device URI has been specified\n"); + goto done; } cmp = strncmp(dev_uri, "smb://", 6); @@ -205,6 +266,11 @@ main(int argc, /* I - Number of command-line arguments */ goto done; } + auth_info_required = getenv("AUTH_INFO_REQUIRED"); + if (auth_info_required == NULL) { + auth_info_required = "none"; + } + /* * Extract the destination from the URI... */ @@ -301,8 +367,14 @@ main(int argc, /* I - Number of command-line arguments */ load_interfaces(); do { - cli = smb_connect(workgroup, server, port, printer, - username, password, argv[3], &need_auth); + cli = smb_connect(workgroup, + server, + port, + printer, + username, + password, + print_user, + &need_auth); if (cli == NULL) { if (need_auth) { exit(2); @@ -338,7 +410,7 @@ main(int argc, /* I - Number of command-line arguments */ */ for (i = 0; i < copies; i++) { - status = smb_print(cli, argv[4] /* title */ , fp); + status = smb_print(cli, print_title, fp); if (status != 0) { break; } -- 2.20.1