Samba RPM rebuilt on el7 with DC support
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

1094 lines
31 KiB

From 1f64c74fec614bde510411b339e731f53b4707dd Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 13 May 2019 16:55:49 +0200
Subject: [PATCH 1/9] s3:smbspool: Add the 'lp' group to the users groups
This is required to access files in /var/spool/cups which have been
temporarily created in there by CUPS.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 6086efb6808089c431e7307fa239924bfda1185b)
---
source3/client/smbspool_krb5_wrapper.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c
index 5c4da33238b..e6684fc0d0c 100644
--- a/source3/client/smbspool_krb5_wrapper.c
+++ b/source3/client/smbspool_krb5_wrapper.c
@@ -82,6 +82,7 @@ int main(int argc, char *argv[])
{
char smbspool_cmd[PATH_MAX] = {0};
struct passwd *pwd;
+ struct group *g = NULL;
char gen_cc[PATH_MAX] = {0};
struct stat sb;
char *env = NULL;
@@ -89,6 +90,7 @@ int main(int argc, char *argv[])
char device_uri[4096] = {0};
uid_t uid = (uid_t)-1;
gid_t gid = (gid_t)-1;
+ gid_t groups[1] = { (gid_t)-1 };
unsigned long tmp;
int cmp;
int rc;
@@ -176,6 +178,26 @@ int main(int argc, char *argv[])
return CUPS_BACKEND_FAILED;
}
+ /*
+ * We need the primary group of the 'lp' user. This is needed to access
+ * temporary files in /var/spool/cups/.
+ */
+ g = getgrnam("lp");
+ if (g == NULL) {
+ CUPS_SMB_ERROR("Failed to find user 'lp' - %s",
+ strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+
+ CUPS_SMB_DEBUG("Adding group 'lp' (%u)", g->gr_gid);
+ groups[0] = g->gr_gid;
+ rc = setgroups(sizeof(groups), groups);
+ if (rc != 0) {
+ CUPS_SMB_ERROR("Failed to set groups for 'lp' - %s",
+ strerror(errno));
+ return CUPS_BACKEND_FAILED;
+ }
+
CUPS_SMB_DEBUG("Switching to gid=%d", gid);
rc = setgid(gid);
if (rc != 0) {
--
2.21.0
From e634ee57d57cf4e5e2c8922f27576d402c6f06af Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 16 May 2019 13:41:02 +0200
Subject: [PATCH 2/9] s3:smbspool: Print the principal we use to authenticate
with
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 42492d547661cb7a98c237b32d42ee93de35aba5)
---
source3/client/smbspool.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index c404b3a3f69..78c13b9ebdb 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -612,6 +612,7 @@ static bool kerberos_ccache_is_valid(void) {
return false;
} else {
krb5_principal default_princ = NULL;
+ char *princ_name = NULL;
code = krb5_cc_get_principal(ctx,
ccache,
@@ -621,6 +622,16 @@ static bool kerberos_ccache_is_valid(void) {
krb5_free_context(ctx);
return false;
}
+
+ code = krb5_unparse_name(ctx,
+ default_princ,
+ &princ_name);
+ if (code == 0) {
+ fprintf(stderr,
+ "DEBUG: Try to authenticate as %s\n",
+ princ_name);
+ krb5_free_unparsed_name(ctx, princ_name);
+ }
krb5_free_principal(ctx, default_princ);
}
krb5_cc_close(ctx, ccache);
--
2.21.0
From 997a9c4e9eed11d5c9e1635db3fe402c3c686989 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 16 May 2019 14:25:00 +0200
Subject: [PATCH 3/9] s3:smbspool: Add debug for finding KRB5CCNAME
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 3632bfef25e471075886eb7aecddd4cc260db8ba)
---
source3/client/smbspool_krb5_wrapper.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c
index e6684fc0d0c..2cdcd372ec6 100644
--- a/source3/client/smbspool_krb5_wrapper.c
+++ b/source3/client/smbspool_krb5_wrapper.c
@@ -219,10 +219,14 @@ int main(int argc, char *argv[])
env = getenv("KRB5CCNAME");
if (env != NULL && env[0] != 0) {
snprintf(gen_cc, sizeof(gen_cc), "%s", env);
+ CUPS_SMB_DEBUG("User already set KRB5CCNAME [%s] as ccache",
+ gen_cc);
goto create_env;
}
+ CUPS_SMB_DEBUG("Trying to guess KRB5CCNAME (FILE, DIR, KEYRING)");
+
snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%d", uid);
rc = lstat(gen_cc, &sb);
--
2.21.0
From 793b16c22b0732a48de9bc927aab012bab87e8e4 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 16 May 2019 17:10:57 +0200
Subject: [PATCH 4/9] s3:smbspool: Use %u format specifier to print uid
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit be596ce3d2455bd49a8ebd311d8c764c37852858)
---
source3/client/smbspool_krb5_wrapper.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c
index 2cdcd372ec6..3266b90ec1a 100644
--- a/source3/client/smbspool_krb5_wrapper.c
+++ b/source3/client/smbspool_krb5_wrapper.c
@@ -227,13 +227,13 @@ int main(int argc, char *argv[])
CUPS_SMB_DEBUG("Trying to guess KRB5CCNAME (FILE, DIR, KEYRING)");
- snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%d", uid);
+ snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%u", uid);
rc = lstat(gen_cc, &sb);
if (rc == 0) {
- snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%d", uid);
+ snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%u", uid);
} else {
- snprintf(gen_cc, sizeof(gen_cc), "/run/user/%d/krb5cc", uid);
+ snprintf(gen_cc, sizeof(gen_cc), "/run/user/%u/krb5cc", uid);
rc = lstat(gen_cc, &sb);
if (rc == 0 && S_ISDIR(sb.st_mode)) {
--
2.21.0
From a2eb883469617688bef4f5c5dbbb1fc916299923 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 16 May 2019 17:40:43 +0200
Subject: [PATCH 5/9] s3:smbspool: Fallback to default ccache if KRB5CCNAME is
not set
This could also support the new KCM credential cache storage.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 6bbdf69e406916107400e2cabdbc831e2a2bbee3)
---
source3/client/smbspool_krb5_wrapper.c | 79 ++++++++++++++++++--------
source3/wscript_build | 1 +
2 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/source3/client/smbspool_krb5_wrapper.c b/source3/client/smbspool_krb5_wrapper.c
index 3266b90ec1a..bff1df417e8 100644
--- a/source3/client/smbspool_krb5_wrapper.c
+++ b/source3/client/smbspool_krb5_wrapper.c
@@ -21,6 +21,7 @@
#include "includes.h"
#include "system/filesys.h"
+#include "system/kerberos.h"
#include "system/passwd.h"
#include <errno.h>
@@ -68,6 +69,50 @@ static void cups_smb_debug(enum cups_smb_dbglvl_e lvl, const char *format, ...)
buffer);
}
+static bool kerberos_get_default_ccache(char *ccache_buf, size_t len)
+{
+ krb5_context ctx;
+ const char *ccache_name = NULL;
+ char *full_ccache_name = NULL;
+ krb5_ccache ccache = NULL;
+ krb5_error_code code;
+
+ code = krb5_init_context(&ctx);
+ if (code != 0) {
+ return false;
+ }
+
+ ccache_name = krb5_cc_default_name(ctx);
+ if (ccache_name == NULL) {
+ krb5_free_context(ctx);
+ return false;
+ }
+
+ code = krb5_cc_resolve(ctx, ccache_name, &ccache);
+ if (code != 0) {
+ krb5_free_context(ctx);
+ return false;
+ }
+
+ code = krb5_cc_get_full_name(ctx, ccache, &full_ccache_name);
+ krb5_cc_close(ctx, ccache);
+ if (code != 0) {
+ krb5_free_context(ctx);
+ return false;
+ }
+
+ snprintf(ccache_buf, len, "%s", full_ccache_name);
+
+#ifdef SAMBA4_USES_HEIMDAL
+ free(full_ccache_name);
+#else
+ krb5_free_string(ctx, full_ccache_name);
+#endif
+ krb5_free_context(ctx);
+
+ return true;
+}
+
/*
* This is a helper binary to execute smbspool.
*
@@ -84,7 +129,6 @@ int main(int argc, char *argv[])
struct passwd *pwd;
struct group *g = NULL;
char gen_cc[PATH_MAX] = {0};
- struct stat sb;
char *env = NULL;
char auth_info_required[256] = {0};
char device_uri[4096] = {0};
@@ -92,6 +136,7 @@ int main(int argc, char *argv[])
gid_t gid = (gid_t)-1;
gid_t groups[1] = { (gid_t)-1 };
unsigned long tmp;
+ bool ok;
int cmp;
int rc;
@@ -225,32 +270,16 @@ int main(int argc, char *argv[])
goto create_env;
}
- CUPS_SMB_DEBUG("Trying to guess KRB5CCNAME (FILE, DIR, KEYRING)");
-
- snprintf(gen_cc, sizeof(gen_cc), "/tmp/krb5cc_%u", uid);
-
- rc = lstat(gen_cc, &sb);
- if (rc == 0) {
- snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%u", uid);
- } else {
- snprintf(gen_cc, sizeof(gen_cc), "/run/user/%u/krb5cc", uid);
-
- rc = lstat(gen_cc, &sb);
- if (rc == 0 && S_ISDIR(sb.st_mode)) {
- snprintf(gen_cc,
- sizeof(gen_cc),
- "DIR:/run/user/%d/krb5cc",
- uid);
- } else {
-#if defined(__linux__)
- snprintf(gen_cc,
- sizeof(gen_cc),
- "KEYRING:persistent:%d",
- uid);
-#endif
- }
+ ok = kerberos_get_default_ccache(gen_cc, sizeof(gen_cc));
+ if (ok) {
+ CUPS_SMB_DEBUG("Use default KRB5CCNAME [%s]",
+ gen_cc);
+ goto create_env;
}
+ /* Fallback to a FILE ccache */
+ snprintf(gen_cc, sizeof(gen_cc), "FILE:/tmp/krb5cc_%u", uid);
+
create_env:
/*
* Make sure we do not have LD_PRELOAD or other security relevant
diff --git a/source3/wscript_build b/source3/wscript_build
index bbcfc72a714..a601ab4e9b1 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -1137,6 +1137,7 @@ bld.SAMBA3_BINARY('smbspool_krb5_wrapper',
deps='''
DYNCONFIG
cups
+ krb5
''',
install_path='${LIBEXECDIR}/samba',
enabled=bld.CONFIG_SET('HAVE_CUPS'))
--
2.21.0
From ec526ef97fc6edf0342dea9ee82ecc14433cc063 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 13 May 2019 16:48:31 +0200
Subject: [PATCH 6/9] s3:smbspool: Print the filename we failed to open
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 281274572bcc3125fe6026a01ef7bf7ef584a0dd)
---
source3/client/smbspool.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 78c13b9ebdb..805ad88b88d 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -223,7 +223,9 @@ main(int argc, /* I - Number of command-line arguments */
fp = fopen(print_file, "rb");
if (fp == NULL) {
- perror("ERROR: Unable to open print file");
+ fprintf(stderr,
+ "ERROR: Unable to open print file: %s",
+ print_file);
goto done;
}
--
2.21.0
From cd9e3a2a7666dfe545a8d0e9a68def6aa536641b Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Mon, 13 May 2019 18:54:02 +0200
Subject: [PATCH 7/9] s3:smbspool: Always try to authenticate using Kerberos
If username and password is given, then fallback to NTLM. However try
kinit first. Also we correctly handle NULL passwords in the meantime and
this makes it easier to deal with issues.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 3d719a1f85db8e423dc3a4116a2228961d5ac48d)
---
source3/client/smbspool.c | 90 ++++++++++++++++++++++-----------------
1 file changed, 51 insertions(+), 39 deletions(-)
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 805ad88b88d..d336cd08209 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -87,8 +87,8 @@ main(int argc, /* I - Number of command-line arguments */
int port; /* Port number */
char uri[1024], /* URI */
*sep, /* Pointer to separator */
- *tmp, *tmp2, /* Temp pointers to do escaping */
- *password; /* Password */
+ *tmp, *tmp2; /* Temp pointers to do escaping */
+ const char *password = NULL; /* Password */
char *username, /* Username */
*server, /* Server name */
*printer;/* Printer name */
@@ -292,8 +292,6 @@ main(int argc, /* I - Number of command-line arguments */
if ((tmp2 = strchr_m(tmp, ':')) != NULL) {
*tmp2++ = '\0';
password = uri_unescape_alloc(tmp2);
- } else {
- password = empty_str;
}
username = uri_unescape_alloc(tmp);
} else {
@@ -301,14 +299,15 @@ main(int argc, /* I - Number of command-line arguments */
username = empty_str;
}
- if ((password = getenv("AUTH_PASSWORD")) == NULL) {
- password = empty_str;
+ env = getenv("AUTH_PASSWORD");
+ if (env != NULL && strlen(env) > 0) {
+ password = env;
}
server = uri + 6;
}
- if (password != empty_str) {
+ if (password != NULL) {
auth_info_required = "username,password";
}
@@ -513,6 +512,7 @@ smb_complete_connection(const char *myname,
NTSTATUS nt_status;
struct cli_credentials *creds = NULL;
bool use_kerberos = false;
+ bool fallback_after_kerberos = false;
/* Start the SMB connection */
*need_auth = false;
@@ -523,27 +523,21 @@ smb_complete_connection(const char *myname,
return NULL;
}
- /*
- * We pretty much guarantee password must be valid or a pointer to a
- * 0 char.
- */
- if (!password) {
- *need_auth = true;
- return NULL;
- }
-
if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
- auth_info_required = "negotiate";
use_kerberos = true;
}
+ if (flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) {
+ fallback_after_kerberos = true;
+ }
+
creds = cli_session_creds_init(cli,
username,
workgroup,
NULL, /* realm */
password,
use_kerberos,
- false, /* fallback_after_kerberos */
+ fallback_after_kerberos,
false, /* use_ccache */
false); /* password_is_nt_hash */
if (creds == NULL) {
@@ -659,6 +653,10 @@ smb_connect(const char *workgroup, /* I - Workgroup */
struct cli_state *cli; /* New connection */
char *myname = NULL; /* Client name */
struct passwd *pwd;
+ int flags = CLI_FULL_CONNECTION_USE_KERBEROS;
+ bool use_kerberos = false;
+ const char *user = username;
+ int cmp;
/*
* Get the names and addresses of the client and server...
@@ -668,42 +666,56 @@ smb_connect(const char *workgroup, /* I - Workgroup */
return NULL;
}
- /*
- * See if we have a username first. This is for backwards compatible
- * behavior with 3.0.14a
- */
- if (username == NULL || username[0] == '\0') {
- if (kerberos_ccache_is_valid()) {
- goto kerberos_auth;
+ cmp = strcmp(auth_info_required, "negotiate");
+ if (cmp == 0) {
+ if (!kerberos_ccache_is_valid()) {
+ return NULL;
}
+ user = jobusername;
+
+ use_kerberos = true;
+ fprintf(stderr,
+ "DEBUG: Try to connect using Kerberos ...\n");
+ }
+
+ cmp = strcmp(auth_info_required, "username,password");
+ if (cmp == 0) {
+ if (username == NULL || username[0] == '\0') {
+ return NULL;
+ }
+
+ /* Fallback to NTLM */
+ flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+
+ fprintf(stderr,
+ "DEBUG: Try to connect using username/password ...\n");
+ }
+
+ cmp = strcmp(auth_info_required, "none");
+ if (cmp == 0) {
+ fprintf(stderr,
+ "DEBUG: This backend doesn't support none auth ...\n");
+ return NULL;
}
cli = smb_complete_connection(myname,
server,
port,
- username,
+ user,
password,
workgroup,
share,
- 0,
+ flags,
need_auth);
if (cli != NULL) {
- fputs("DEBUG: Connected with username/password...\n", stderr);
+ fprintf(stderr, "DEBUG: SMB connection established.\n");
return (cli);
}
-kerberos_auth:
- /*
- * Try to use the user kerberos credentials (if any) to authenticate
- */
- cli = smb_complete_connection(myname, server, port, jobusername, "",
- workgroup, share,
- CLI_FULL_CONNECTION_USE_KERBEROS, need_auth);
-
- if (cli) {
- fputs("DEBUG: Connected using Kerberos...\n", stderr);
- return (cli);
+ if (!use_kerberos) {
+ fprintf(stderr, "ERROR: SMB connection failed!\n");
+ return NULL;
}
/* give a chance for a passwordless NTLMSSP session setup */
--
2.21.0
From f470477d71214b00a4b33f6934d7dbef3b3fce1d Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Thu, 16 May 2019 18:24:32 +0200
Subject: [PATCH 8/9] s3:smbspool: Add debug messages to
kerberos_ccache_is_valid()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit 93acd880801524c5e621df7b5bf5ad650f93cec3)
---
source3/client/smbspool.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index d336cd08209..221c50af196 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -599,11 +599,15 @@ static bool kerberos_ccache_is_valid(void) {
ccache_name = krb5_cc_default_name(ctx);
if (ccache_name == NULL) {
+ DBG_ERR("Failed to get default ccache name\n");
+ krb5_free_context(ctx);
return false;
}
code = krb5_cc_resolve(ctx, ccache_name, &ccache);
if (code != 0) {
+ DBG_ERR("Failed to resolve ccache name: %s\n",
+ ccache_name);
krb5_free_context(ctx);
return false;
} else {
@@ -614,6 +618,9 @@ static bool kerberos_ccache_is_valid(void) {
ccache,
&default_princ);
if (code != 0) {
+ DBG_ERR("Failed to get default principal from "
+ "ccache: %s\n",
+ ccache_name);
krb5_cc_close(ctx, ccache);
krb5_free_context(ctx);
return false;
--
2.21.0
From 27511ca2bbb05134681714475c634473b5125503 Mon Sep 17 00:00:00 2001
From: Andreas Schneider <asn@samba.org>
Date: Tue, 14 May 2019 11:35:46 +0200
Subject: [PATCH 9/9] s3:smbspool: Use NTSTATUS return codes
This allows us to simplify some code and return better errors.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
(cherry picked from commit d9af3dc02e98a3eb22441dfbdeddbaca0af078ea)
---
source3/client/smbspool.c | 250 ++++++++++++++++++++++----------------
1 file changed, 145 insertions(+), 105 deletions(-)
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 221c50af196..5ab286cd3e9 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -60,12 +60,27 @@
* Local functions...
*/
-static int get_exit_code(struct cli_state * cli, NTSTATUS nt_status);
+static int get_exit_code(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);
-static struct cli_state *smb_connect(const char *, const char *, int, const
- char *, const char *, const char *, const char *, bool *need_auth);
+static NTSTATUS
+smb_complete_connection(struct cli_state **output_cli,
+ const char *myname,
+ const char *server,
+ int port,
+ const char *username,
+ const char *password,
+ const char *workgroup,
+ const char *share,
+ int flags);
+static NTSTATUS
+smb_connect(struct cli_state **output_cli,
+ const char *workgroup,
+ const char *server,
+ const int port,
+ const char *share,
+ const char *username,
+ const char *password,
+ const char *jobusername);
static int smb_print(struct cli_state *, const char *, FILE *);
static char *uri_unescape_alloc(const char *);
#if 0
@@ -89,16 +104,15 @@ main(int argc, /* I - Number of command-line arguments */
*sep, /* Pointer to separator */
*tmp, *tmp2; /* Temp pointers to do escaping */
const char *password = NULL; /* Password */
- char *username, /* Username */
- *server, /* Server name */
+ const char *username = NULL; /* Username */
+ char *server, /* Server name */
*printer;/* Printer name */
const char *workgroup; /* Workgroup */
FILE *fp; /* File to print */
int status = 1; /* Status of LPD job */
- struct cli_state *cli; /* SMB interface */
- char empty_str[] = "";
+ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL;
+ struct cli_state *cli = NULL; /* SMB interface */
int tries = 0;
- bool need_auth = true;
const char *dev_uri = NULL;
const char *env = NULL;
const char *config_file = NULL;
@@ -295,8 +309,9 @@ main(int argc, /* I - Number of command-line arguments */
}
username = uri_unescape_alloc(tmp);
} else {
- if ((username = getenv("AUTH_USERNAME")) == NULL) {
- username = empty_str;
+ env = getenv("AUTH_USERNAME");
+ if (env != NULL && strlen(env) > 0) {
+ username = env;
}
env = getenv("AUTH_PASSWORD");
@@ -368,27 +383,39 @@ main(int argc, /* I - Number of command-line arguments */
load_interfaces();
do {
- cli = smb_connect(workgroup,
- server,
- port,
- printer,
- username,
- password,
- print_user,
- &need_auth);
- if (cli == NULL) {
- if (need_auth) {
- exit(2);
+ nt_status = smb_connect(&cli,
+ workgroup,
+ server,
+ port,
+ printer,
+ username,
+ password,
+ print_user);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ status = get_exit_code(nt_status);
+ if (status == 2) {
+ fprintf(stderr,
+ "DEBUG: Unable to connect to CIFS "
+ "host: %s",
+ nt_errstr(nt_status));
+ goto done;
} else if (getenv("CLASS") == NULL) {
- fprintf(stderr, "ERROR: Unable to connect to CIFS host, will retry in 60 seconds...\n");
+ fprintf(stderr,
+ "ERROR: Unable to connect to CIFS "
+ "host: %s. Will retry in 60 "
+ "seconds...\n",
+ nt_errstr(nt_status));
sleep(60);
tries++;
} else {
- fprintf(stderr, "ERROR: Unable to connect to CIFS host, trying next printer...\n");
+ fprintf(stderr,
+ "ERROR: Unable to connect to CIFS "
+ "host: %s. Trying next printer...\n",
+ nt_errstr(nt_status));
goto done;
}
}
- } while ((cli == NULL) && (tries < MAX_RETRY_CONNECT));
+ } while (!NT_STATUS_IS_OK(nt_status) && (tries < MAX_RETRY_CONNECT));
if (cli == NULL) {
fprintf(stderr, "ERROR: Unable to connect to CIFS host after (tried %d times)\n", tries);
@@ -435,10 +462,9 @@ done:
*/
static int
-get_exit_code(struct cli_state * cli,
- NTSTATUS nt_status)
+get_exit_code(NTSTATUS nt_status)
{
- int i;
+ size_t i;
/* List of NTSTATUS errors that are considered
* authentication errors
@@ -454,17 +480,16 @@ get_exit_code(struct cli_state * cli,
};
- fprintf(stderr, "DEBUG: get_exit_code(cli=%p, nt_status=%s [%x])\n",
- cli, nt_errstr(nt_status), NT_STATUS_V(nt_status));
+ fprintf(stderr,
+ "DEBUG: get_exit_code(nt_status=%s [%x])\n",
+ nt_errstr(nt_status), NT_STATUS_V(nt_status));
for (i = 0; i < ARRAY_SIZE(auth_errors); i++) {
if (!NT_STATUS_EQUAL(nt_status, auth_errors[i])) {
continue;
}
- if (cli) {
- fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required);
- }
+ fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required);
/*
* 2 = authentication required...
@@ -497,16 +522,16 @@ list_devices(void)
}
-static struct cli_state *
-smb_complete_connection(const char *myname,
+static NTSTATUS
+smb_complete_connection(struct cli_state **output_cli,
+ const char *myname,
const char *server,
int port,
const char *username,
const char *password,
const char *workgroup,
const char *share,
- int flags,
- bool *need_auth)
+ int flags)
{
struct cli_state *cli; /* New connection */
NTSTATUS nt_status;
@@ -515,12 +540,11 @@ smb_complete_connection(const char *myname,
bool fallback_after_kerberos = false;
/* Start the SMB connection */
- *need_auth = false;
nt_status = cli_start_connection(&cli, myname, server, NULL, port,
SMB_SIGNING_DEFAULT, flags);
if (!NT_STATUS_IS_OK(nt_status)) {
fprintf(stderr, "ERROR: Connection failed: %s\n", nt_errstr(nt_status));
- return NULL;
+ return nt_status;
}
if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) {
@@ -543,20 +567,16 @@ smb_complete_connection(const char *myname,
if (creds == NULL) {
fprintf(stderr, "ERROR: cli_session_creds_init failed\n");
cli_shutdown(cli);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
nt_status = cli_session_setup_creds(cli, creds);
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) == 2) {
- *need_auth = true;
- }
-
cli_shutdown(cli);
- return NULL;
+ return nt_status;
}
nt_status = cli_tree_connect_creds(cli, share, "?????", creds);
@@ -564,13 +584,9 @@ 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) == 2) {
- *need_auth = true;
- }
-
cli_shutdown(cli);
- return NULL;
+ return nt_status;
}
#if 0
/* Need to work out how to specify this on the URL. */
@@ -583,7 +599,8 @@ smb_complete_connection(const char *myname,
}
#endif
- return cli;
+ *output_cli = cli;
+ return NT_STATUS_OK;
}
static bool kerberos_ccache_is_valid(void) {
@@ -647,49 +664,48 @@ static bool kerberos_ccache_is_valid(void) {
* 'smb_connect()' - Return a connection to a server.
*/
-static struct cli_state * /* O - SMB connection */
-smb_connect(const char *workgroup, /* I - Workgroup */
+static NTSTATUS
+smb_connect(struct cli_state **output_cli,
+ const char *workgroup, /* I - Workgroup */
const char *server, /* I - Server */
const int port, /* I - Port */
const char *share, /* I - Printer */
const char *username, /* I - Username */
const char *password, /* I - Password */
- const char *jobusername, /* I - User who issued the print job */
- bool *need_auth)
-{ /* O - Need authentication? */
- struct cli_state *cli; /* New connection */
+ const char *jobusername) /* I - User who issued the print job */
+{
+ struct cli_state *cli = NULL; /* New connection */
char *myname = NULL; /* Client name */
struct passwd *pwd;
int flags = CLI_FULL_CONNECTION_USE_KERBEROS;
bool use_kerberos = false;
const char *user = username;
- int cmp;
+ NTSTATUS nt_status;
/*
* Get the names and addresses of the client and server...
*/
myname = get_myname(talloc_tos());
if (!myname) {
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
- cmp = strcmp(auth_info_required, "negotiate");
- if (cmp == 0) {
+ if (strcmp(auth_info_required, "negotiate") == 0) {
if (!kerberos_ccache_is_valid()) {
- return NULL;
+ fprintf(stderr,
+ "ERROR: No valid Kerberos credential cache "
+ "found!\n");
+ return NT_STATUS_LOGON_FAILURE;
}
user = jobusername;
use_kerberos = true;
fprintf(stderr,
"DEBUG: Try to connect using Kerberos ...\n");
- }
-
- cmp = strcmp(auth_info_required, "username,password");
- if (cmp == 0) {
- if (username == NULL || username[0] == '\0') {
- return NULL;
+ } else if (strcmp(auth_info_required, "username,password") == 0) {
+ if (username == NULL) {
+ return NT_STATUS_INVALID_ACCOUNT_NAME;
}
/* Fallback to NTLM */
@@ -697,59 +713,83 @@ smb_connect(const char *workgroup, /* I - Workgroup */
fprintf(stderr,
"DEBUG: Try to connect using username/password ...\n");
- }
+ } else {
+ if (username != NULL) {
+ flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+ } else if (kerberos_ccache_is_valid()) {
+ auth_info_required = "negotiate";
- cmp = strcmp(auth_info_required, "none");
- if (cmp == 0) {
- fprintf(stderr,
- "DEBUG: This backend doesn't support none auth ...\n");
- return NULL;
+ user = jobusername;
+ use_kerberos = true;
+ } else {
+ fprintf(stderr,
+ "DEBUG: This backend requires credentials!\n");
+ return NT_STATUS_ACCESS_DENIED;
+ }
}
- cli = smb_complete_connection(myname,
- server,
- port,
- user,
- password,
- workgroup,
- share,
- flags,
- need_auth);
- if (cli != NULL) {
+ nt_status = smb_complete_connection(&cli,
+ myname,
+ server,
+ port,
+ user,
+ password,
+ workgroup,
+ share,
+ flags);
+ if (NT_STATUS_IS_OK(nt_status)) {
fprintf(stderr, "DEBUG: SMB connection established.\n");
- return (cli);
+
+ *output_cli = cli;
+ return NT_STATUS_OK;
}
if (!use_kerberos) {
fprintf(stderr, "ERROR: SMB connection failed!\n");
- return NULL;
+ return nt_status;
}
/* give a chance for a passwordless NTLMSSP session setup */
pwd = getpwuid(geteuid());
if (pwd == NULL) {
- return NULL;
- }
-
- cli = smb_complete_connection(myname, server, port, pwd->pw_name, "",
- workgroup, share, 0, need_auth);
-
- if (cli) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ nt_status = smb_complete_connection(&cli,
+ myname,
+ server,
+ port,
+ pwd->pw_name,
+ "",
+ workgroup,
+ share,
+ 0);
+ if (NT_STATUS_IS_OK(nt_status)) {
fputs("DEBUG: Connected with NTLMSSP...\n", stderr);
- return (cli);
+
+ *output_cli = cli;
+ return NT_STATUS_OK;
}
/*
* last try. Use anonymous authentication
*/
- cli = smb_complete_connection(myname, server, port, "", "",
- workgroup, share, 0, need_auth);
- /*
- * Return the new connection...
- */
-
- return (cli);
+ nt_status = smb_complete_connection(&cli,
+ myname,
+ server,
+ port,
+ "",
+ "",
+ workgroup,
+ share,
+ 0);
+ if (NT_STATUS_IS_OK(nt_status)) {
+ *output_cli = cli;
+ return NT_STATUS_OK;
+ }
+
+ return nt_status;
}
@@ -795,7 +835,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);
+ return get_exit_code(nt_status);
}
/*
@@ -813,7 +853,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);
+ int ret = get_exit_code(status);
fprintf(stderr, "ERROR: Error writing spool: %s\n",
nt_errstr(status));
fprintf(stderr, "DEBUG: Returning status %d...\n",
@@ -829,7 +869,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);
+ return get_exit_code(nt_status);
} else {
return (0);
}
--
2.21.0