[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Thu May 23 11:11:02 UTC 2019


The branch, master has been updated
       via  3b608510e4b third_party: Update nss_wrapper to version 1.1.6
       via  d9af3dc02e9 s3:smbspool: Use NTSTATUS return codes
       via  93acd880801 s3:smbspool: Add debug messages to kerberos_ccache_is_valid()
       via  3d719a1f85d s3:smbspool: Always try to authenticate using Kerberos
       via  281274572bc s3:smbspool: Print the filename we failed to open
       via  6bbdf69e406 s3:smbspool: Fallback to default ccache if KRB5CCNAME is not set
       via  be596ce3d24 s3:smbspool: Use %u format specifier to print uid
       via  3632bfef25e s3:smbspool: Add debug for finding KRB5CCNAME
       via  42492d54766 s3:smbspool: Print the principal we use to authenticate with
       via  6086efb6808 s3:smbspool: Add the 'lp' group to the users groups
      from  30622ed876c smbd: Fix a panic

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3b608510e4be190d2aacf69dceefc937a25e10e7
Author: Andreas Schneider <asn at samba.org>
Date:   Tue May 21 08:00:05 2019 +0200

    third_party: Update nss_wrapper to version 1.1.6
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Gary Lockyer <gary at samba.org>
    
    Autobuild-User(master): Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date(master): Thu May 23 11:10:28 UTC 2019 on sn-devel-184

commit d9af3dc02e98a3eb22441dfbdeddbaca0af078ea
Author: Andreas Schneider <asn at samba.org>
Date:   Tue May 14 11:35:46 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 93acd880801524c5e621df7b5bf5ad650f93cec3
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 16 18:24:32 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 3d719a1f85db8e423dc3a4116a2228961d5ac48d
Author: Andreas Schneider <asn at samba.org>
Date:   Mon May 13 18:54:02 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 281274572bcc3125fe6026a01ef7bf7ef584a0dd
Author: Andreas Schneider <asn at samba.org>
Date:   Mon May 13 16:48:31 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 6bbdf69e406916107400e2cabdbc831e2a2bbee3
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 16 17:40:43 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit be596ce3d2455bd49a8ebd311d8c764c37852858
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 16 17:10:57 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 3632bfef25e471075886eb7aecddd4cc260db8ba
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 16 14:25:00 2019 +0200

    s3:smbspool: Add debug for finding KRB5CCNAME
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13939
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 42492d547661cb7a98c237b32d42ee93de35aba5
Author: Andreas Schneider <asn at samba.org>
Date:   Thu May 16 13:41:02 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

commit 6086efb6808089c431e7307fa239924bfda1185b
Author: Andreas Schneider <asn at samba.org>
Date:   Mon May 13 16:55:49 2019 +0200

    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 at samba.org>
    Reviewed-by: Guenther Deschner <gd at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 buildtools/wafsamba/samba_third_party.py |   2 +-
 source3/client/smbspool.c                | 323 +++++++++++++++++++------------
 source3/client/smbspool_krb5_wrapper.c   | 101 +++++++---
 source3/wscript_build                    |   1 +
 third_party/nss_wrapper/nss_wrapper.c    | 206 ++++++++++++++------
 third_party/nss_wrapper/wscript          |   2 +-
 6 files changed, 424 insertions(+), 211 deletions(-)


Changeset truncated at 500 lines:

diff --git a/buildtools/wafsamba/samba_third_party.py b/buildtools/wafsamba/samba_third_party.py
index 1fe91d51aad..f7410ecba52 100644
--- a/buildtools/wafsamba/samba_third_party.py
+++ b/buildtools/wafsamba/samba_third_party.py
@@ -47,7 +47,7 @@ Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER
 
 @conf
 def CHECK_NSS_WRAPPER(conf):
-    return conf.CHECK_BUNDLED_SYSTEM_PKG('nss_wrapper', minversion='1.1.5')
+    return conf.CHECK_BUNDLED_SYSTEM_PKG('nss_wrapper', minversion='1.1.6')
 Build.BuildContext.CHECK_NSS_WRAPPER = CHECK_NSS_WRAPPER
 
 @conf
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 22071613677..ad988eb0df9 100644
--- a/source3/client/smbspool.c
+++ b/source3/client/smbspool.c
@@ -61,12 +61,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
@@ -88,18 +103,17 @@ 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 */
-	char           *username,	/* Username */
-	               *server,	/* Server name */
+	               *tmp, *tmp2;	/* Temp pointers to do escaping */
+	const char     *password = NULL;	/* Password */
+	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;
@@ -224,7 +238,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;
 		}
 
@@ -291,23 +307,23 @@ 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 {
-		if ((username = getenv("AUTH_USERNAME")) == NULL) {
-			username = empty_str;
+		env = getenv("AUTH_USERNAME");
+		if (env != NULL && strlen(env) > 0) {
+			username = env;
 		}
 
-		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";
 	}
 
@@ -368,27 +384,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 +463,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 +481,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,71 +523,61 @@ 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;
 	struct cli_credentials *creds = NULL;
 	bool use_kerberos = false;
+	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;
-	}
-
-	/*
-	 * We pretty much guarantee password must be valid or a pointer to a
-	 * 0 char.
-	 */
-	if (!password) {
-		*need_auth = true;
-		return NULL;
+		return nt_status;
 	}
 
 	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) {
 		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);
@@ -569,13 +585,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. */
@@ -588,7 +600,8 @@ smb_complete_connection(const char *myname,
 	}
 #endif
 
-	return cli;
+	*output_cli = cli;
+	return NT_STATUS_OK;
 }
 
 static bool kerberos_ccache_is_valid(void) {
@@ -606,25 +619,42 @@ 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 {
 		krb5_principal default_princ = NULL;
+		char *princ_name = NULL;
 
 		code = krb5_cc_get_principal(ctx,
 					     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;
 		}
+
+		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);
@@ -637,91 +667,132 @@ 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;
+	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;
 	}
 
-	/*
-	 * 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;
+	if (strcmp(auth_info_required, "negotiate") == 0) {
+		if (!kerberos_ccache_is_valid()) {
+			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");
+	} else if (strcmp(auth_info_required, "username,password") == 0) {
+		if (username == NULL) {
+			return NT_STATUS_INVALID_ACCOUNT_NAME;
+		}
+
+		/* Fallback to NTLM */
+		flags |= CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS;
+
+		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";
 
-	cli = smb_complete_connection(myname,
-				      server,
-				      port,
-				      username,
-				      password,
-				      workgroup,
-				      share,
-				      0,
-				      need_auth);
-	if (cli != NULL) {
-		fputs("DEBUG: Connected with username/password...\n", stderr);
-		return (cli);
+			user = jobusername;
+			use_kerberos = true;
+		} else {
+			fprintf(stderr,
+				"DEBUG: This backend requires credentials!\n");
+			return NT_STATUS_ACCESS_DENIED;
+		}
 	}
 
-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);
+	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");
 
-	if (cli) {
-		fputs("DEBUG: Connected using Kerberos...\n", stderr);
-		return (cli);
+		*output_cli = cli;
+		return NT_STATUS_OK;
+	}
+
+	if (!use_kerberos) {
+		fprintf(stderr, "ERROR: SMB connection failed!\n");
+		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,


-- 
Samba Shared Repository



More information about the samba-cvs mailing list