[SCM] Samba Shared Repository - branch v4-20-stable updated

Stefan Metzmacher metze at samba.org
Fri Aug 2 12:14:01 UTC 2024


The branch, v4-20-stable has been updated
       via  803665cb481 VERSION: Disable GIT_SNAPSHOT for the 4.20.3 release.
       via  a13bed3b9ef WHATSNEW: Add release notes for Samba 4.20.3.
       via  f8e50d04e9f libcli:security: allow spaces after BAD:
       via  4cf9af9186d s3:printing: Allow to run samba-bgqd as a standalone systemd service
       via  d6f010090ce cmdline:burn: list commands to always burn; warn on unknown
       via  93d345467e7 cmdline: samba-tool test for bad option warning
       via  957654ebe9d cmdline:burn: add a note about short option combinations
       via  8560c854d4c cmdline:burn: explicitly burn --username
       via  481eb6ab31e cmdline:burn: use allowlist to ensure more passwords burn
       via  6bcdbdab57c cmdline: test_cmdline tests more burning
       via  0d89d09674a cmdline:burn: do not burn options starting --user-*, --password-*
       via  66da23459f5 cmdline:burn: localise some variables
       via  1315b61e1fb cmdline:burn: always return true if burnt
       via  916d5bde84a cmdline:burn: handle arguments separated from their --options
       via  25329b38634 cmdline:burn: do not retain false memories
       via  f900e532c3d cmdline:tests: extend cmdline_burn tests
       via  9cbb5bdd333 selftest: run the cmdline tests that we already have
       via  5d99875ba0f cmdline:burn: '-U' does not imply secrets without '%'
       via  73207ff834f docs-xml:manpages: allow for longer version strings
       via  f5920ceea32 .gitlab-ci-main.yml: Add safe.directory '*'
       via  6b0b6d06410 gitlab-ci: Also add the git directory for pipeline in the main mirror
       via  f4604a86fe1 third_party/heimdal: Import lorikeet-heimdal-202407041740 (commit 42ba2a6e5dd1bc14a8b5ada8c9b8ace85956f6a0)
       via  16b430e7401 s4:selftest: also test samba4.ldb.simple.ldap*SASL-BIND with ldap_testing:{channel_bound,tls_channel_bindings,forced_channel_binding}
       via  ac22551de3e selftest: split out selftest/expectedfail.d/samba4.ldb.simple.ldap-tls
       via  7c6c742106b s4:libcli/ldap: add tls channel binding support for ldap_bind_sasl()
       via  7f2e3839f25 s4:ldap_server: add support for tls channel bindings
       via  64d4c1cdcc3 s3:crypto/gse: implement channel binding support
       via  7b62c5f7d24 s4:gensec_gssapi: implement channel binding support
       via  1219bf38301 auth/ntlmssp: implement channel binding support
       via  c41feb6c2a4 auth/gensec: add gensec_set_channel_bindings() function
       via  2668243de22 wscript_configure_embedded_heimdal: define HAVE_CLIENT_GSS_C_CHANNEL_BOUND_FLAG
       via  c86e8742373 third_party/heimdal: import lorikeet-heimdal-202404171655 (commit 28a56d818074e049f0361ef74d7017f2a9391847)
       via  20d5335dc1f s4:lib/tls: add tstream_tls_channel_bindings()
       via  6fec41bdb31 lib/crypto: add legacy_gnutls_server_end_point_cb() if needed
       via  b2f44b81751 s4:libcli/ldap: make use of tstream_tls_params_client_lpcfg()
       via  254fa5041d6 s4:librpc/rpc: make use of tstream_tls_params_client_lpcfg()
       via  7a6ce2be813 s3:rpc_server/mdssvc: make use of tstream_tls_params_client_lpcfg()
       via  8989c3cd8ba s4:lib/tls: add tstream_tls_params_client_lpcfg()
       via  f1ca22f5577 s4:lib/tls: split out tstream_tls_verify_peer() helper
       via  1f0e6a44747 s4:lib/tls: include a TLS server name indication in the client handshake
       via  a55356b7cde s4:lib/tls: we no longer need ifdef GNUTLS_NO_TICKETS
       via  0c8fd43cc83 s4:lib/tls: split out tstream_tls_prepare_gnutls()
       via  3e90d30bab9 s4:lib/tls: assert that event contexts are not mixed
       via  c117f54ceed s3:lib/tls: we need to call tstream_tls_retry_handshake/disconnect() until all buffers are flushed
       via  52adc59a926 s4:lib/tls: remove tstream_tls_push_trigger_write step
       via  461f14259e2 s4:libcli/ldap: force GSS-SPNEGO in ldap_bind_sasl()
       via  39ffaf056b2 s4:libcli/ldap: fix no memory error code in ldap_bind_sasl()
       via  5545d934ec0 ldb_ildap: require ldb_get_opaque(ldb, "loadparm") to be valid
       via  07e707c4de4 s4:libcli/ldap: ldap4_new_connection() requires a valid lp_ctx
       via  52fc65513f4 selftest: move some more expected failures to expectedfail.d
       via  63b47dc0edc Fix starvation of pending writes in CTDB queues
       via  95058b97865 build: --vendor-suffix instead of --vendor-patch-revision --vendor-name
       via  5531ef4d2b0 buildtools: sanitise strange characters in vendor strings
       via  bff728a842f third_party/heimdal: Import lorikeet-heimdal-202406240121 (commit 4315286377278234be2f3b6d52225a17b6116d54)
       via  41c8a42c8ae tests/krb5: Add tests for errors produced when logging in with unusable accounts
       via  d4c1e215a9b tests/krb5: Allow creation of disabled accounts for testing
       via  50a417a2240 python/tests/krb5: Prepare for PKINIT tests with UF_SMARTCARD_REQUIRED
       via  c1433f821f7 tests/krb5: Fix PK-INIT test framework to allow expired password keys
       via  4e57b8a5fe6 dsdb: Reduce minimum maxPwdAge from 1 day to nil
       via  eeae9fe4b01 VERSION: Bump version up to Samba 4.20.3...
      from  569d541c9bb VERSION: Disable GIT_SNAPSHOT for the 4.20.2 release.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-20-stable


- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 .gitlab-ci-main.yml                                |   3 +-
 VERSION                                            |   2 +-
 WHATSNEW.txt                                       | 107 +++-
 auth/gensec/gensec.c                               |  63 +++
 auth/gensec/gensec.h                               |   8 +
 auth/gensec/gensec_internal.h                      |  18 +
 auth/gensec/gensec_start.c                         |   1 +
 auth/ntlmssp/ntlmssp_client.c                      |  13 +-
 auth/ntlmssp/ntlmssp_private.h                     |   2 +
 auth/ntlmssp/ntlmssp_server.c                      |  47 ++
 auth/ntlmssp/ntlmssp_util.c                        |  98 ++++
 buildtools/wafsamba/samba_abi.py                   |   6 +-
 ctdb/common/ctdb_io.c                              |  17 +-
 .../ldap/ldapserverrequirestrongauth.xml           |  38 +-
 docs-xml/xslt/man.xsl                              |   3 +
 lib/cmdline/cmdline.c                              | 217 +++++++-
 lib/cmdline/tests/test_cmdline.c                   |  54 +-
 lib/crypto/gnutls_helpers.h                        |   6 +
 lib/crypto/gnutls_server_end_point_cb.c            | 130 +++++
 lib/crypto/wscript                                 |   6 +-
 lib/ldb-samba/ldb_ildap.c                          |   9 +-
 lib/param/loadparm.h                               |   1 +
 lib/param/param_table.c                            |   2 +
 libcli/security/sddl.c                             |   5 +
 python/samba/netcmd/testparm.py                    |  10 +
 python/samba/tests/krb5/kdc_base_test.py           |  24 +-
 python/samba/tests/krb5/lockout_tests.py           | 210 ++++++-
 python/samba/tests/krb5/pkinit_tests.py            |  15 +-
 python/samba/tests/krb5/raw_testcase.py            |  18 +-
 python/samba/tests/krb5/rfc4120_constants.py       |   1 +
 python/samba/tests/samba_tool/help.py              |   9 +
 python/samba/tests/sddl.py                         |  10 +-
 script/autobuild.py                                |   4 +-
 selftest/expectedfail.d/ldap-tlsverifypeer         |  10 +
 selftest/expectedfail.d/samba4.ldb.simple.ldap-tls |  21 +
 selftest/expectedfail_heimdal                      |  12 +
 selftest/knownfail                                 |  16 -
 selftest/knownfail_mit_kdc                         |   5 +
 selftest/target/Samba4.pm                          |   2 +-
 selftest/tests.py                                  |   2 +
 selftest/wscript                                   |   4 +
 source3/librpc/crypto/gse.c                        |  95 +++-
 source3/printing/samba-bgqd.c                      |   8 +-
 source3/rpc_server/mdssvc/mdssvc_es.c              |  25 +-
 source3/utils/testparm.c                           |  12 +
 source4/auth/gensec/gensec_gssapi.c                |  77 ++-
 source4/auth/gensec/gensec_gssapi.h                |   1 +
 source4/dsdb/samdb/ldb_modules/operational.c       |   4 +-
 source4/ldap_server/ldap_bind.c                    |  62 ++-
 source4/ldap_server/ldap_server.c                  |  11 +
 source4/lib/tls/tls.h                              |   7 +
 source4/lib/tls/tls_tstream.c                      | 611 ++++++++++++---------
 source4/lib/tls/wscript_build                      |   1 +
 source4/libcli/ldap/ldap_bind.c                    | 111 ++--
 source4/libcli/ldap/ldap_client.c                  |  20 +-
 source4/librpc/rpc/dcerpc_roh.c                    |  20 +-
 source4/selftest/tests.py                          |  31 +-
 third_party/heimdal/kdc/fast.c                     |  13 +-
 third_party/heimdal/lib/gssapi/krb5/8003.c         |   5 +
 .../heimdal/lib/gssapi/krb5/init_sec_context.c     |  10 +
 third_party/heimdal/lib/gssapi/test_context.c      |   4 +
 third_party/heimdal/lib/krb5/build_auth.c          | 100 +++-
 third_party/heimdal/lib/krb5/fast.c                |  12 +-
 third_party/heimdal/lib/krb5/mcache.c              |   2 +-
 third_party/heimdal/lib/krb5/mk_req_ext.c          |   1 +
 third_party/heimdal/tests/gss/check-context.in     |  35 ++
 wscript                                            |  12 +-
 wscript_configure_embedded_heimdal                 |   7 +
 wscript_configure_system_gnutls                    |   5 +
 69 files changed, 2059 insertions(+), 472 deletions(-)
 create mode 100644 lib/crypto/gnutls_server_end_point_cb.c
 create mode 100644 selftest/expectedfail.d/ldap-tlsverifypeer
 create mode 100644 selftest/expectedfail.d/samba4.ldb.simple.ldap-tls
 create mode 100644 selftest/expectedfail_heimdal


Changeset truncated at 500 lines:

diff --git a/.gitlab-ci-main.yml b/.gitlab-ci-main.yml
index face2103327..08865ca2c42 100644
--- a/.gitlab-ci-main.yml
+++ b/.gitlab-ci-main.yml
@@ -146,8 +146,7 @@ include:
     - ccache -z -M 500M
     - ccache -s
       # We are already running .gitlab-ci directives from this repo, remove additional checks that break our CI
-    - git config --global --add safe.directory `pwd`
-    - git config --global --add safe.directory /builds/samba-team/devel/samba/.git
+    - git config --global --add safe.directory '*'
   after_script:
     - mount
     - df -h
diff --git a/VERSION b/VERSION
index 200f6ccac3e..b0f4f114077 100644
--- a/VERSION
+++ b/VERSION
@@ -27,7 +27,7 @@ SAMBA_COPYRIGHT_STRING="Copyright Andrew Tridgell and the Samba Team 1992-2024"
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=20
-SAMBA_VERSION_RELEASE=2
+SAMBA_VERSION_RELEASE=3
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index fb964d7a6f4..93dd250d052 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,106 @@
+                   ==============================
+                   Release Notes for Samba 4.20.3
+                           August 02, 2024
+                   ==============================
+
+
+This is the latest stable release of the Samba 4.20 release series.
+
+LDAP TLS/SASL channel binding support
+-------------------------------------
+
+The ldap server supports SASL binds with
+kerberos or NTLMSSP over TLS connections
+now (either ldaps or starttls).
+
+Setups where 'ldap server require strong auth = allow_sasl_over_tls'
+was required before, can now most likely move to the
+default of 'ldap server require strong auth = yes'.
+
+If SASL binds without correct tls channel bindings are required
+'ldap server require strong auth = allow_sasl_without_tls_channel_bindings'
+should be used now, as 'allow_sasl_over_tls' will generate a
+warning in every start of 'samba', as well as '[samba-tool ]testparm'.
+
+This is similar to LdapEnforceChannelBinding under
+HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters
+on Windows.
+
+All client tools using ldaps also include the correct
+channel bindings now.
+
+smb.conf changes
+================
+
+  Parameter Name                          Description     Default
+  --------------                          -----------     -------
+  ldap server require strong auth         new values
+
+Changes since 4.20.2
+--------------------
+
+o  Andreas Schneider <asn at samba.org>
+   * BUG 15683: Running samba-bgqd a a standalone systemd service does not work.
+
+o  Andrew Bartlett <abartlet at samba.org>
+   * BUG 15655: When claims enabled with heimdal kerberos, unable to log on to a
+     Windows computer when user account need to change their own password.
+
+o  Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
+   * BUG 15671: Invalid client warning about command line passwords.
+   * BUG 15672: Version string is truncated in manpages.
+   * BUG 15673: --version-* options are still not ergonomic, and they reject
+     tilde characters.
+   * BUG 15674: cmdline_burn does not always burn secrets.
+   * BUG 15685: Samba does not parse SDDL found in defaultSecurityDescriptor in
+     AD_DS_Classes_Windows_Server_v1903.ldf.
+
+o  Jo Sutton <josutton at catalyst.net.nz>
+   * BUG 15655: When claims enabled with heimdal kerberos, unable to log on to a
+     Windows computer when user account need to change their own password.
+
+o  Pavel Filipenský <pfilipensky at samba.org>
+   * BUG 15660: The images don\'t build after the git security release and
+     CentOS 8 Stream is EOL.
+
+o  Ralph Boehme <slow at samba.org>
+   * BUG 15676: Fix clock skew error message and memory cache clock skew
+     recovery.
+
+o  Stefan Metzmacher <metze at samba.org>
+   * BUG 15603: Heimdal ignores _gsskrb5_decapsulate errors in
+     init_sec_context/repl_mutual.
+   * BUG 15621: s4:ldap_server: does not support tls channel bindings
+     for sasl binds.
+
+o  Xavi Hernandez <xhernandez at redhat.com>
+   * BUG 15678: CTDB socket output queues may suffer unbounded delays under some
+     special conditions.
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical:matrix.org matrix room, or
+#samba-technical IRC channel on irc.libera.chat.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
                    ==============================
                    Release Notes for Samba 4.20.2
                            June 19, 2024
@@ -79,8 +182,7 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
                    ==============================
                    Release Notes for Samba 4.20.1
                             May 08, 2024
@@ -404,6 +506,7 @@ smb.conf changes
 
   Parameter Name                          Description     Default
   --------------                          -----------     -------
+  ldap server require strong auth         new values             (4.20.3)
   acl claims evaluation                   new             AD DC only
   smb3 unix extensions                    Per share       -
   smb3 share cap:ASYMMETRIC               new             no
diff --git a/auth/gensec/gensec.c b/auth/gensec/gensec.c
index 26b5865bff5..8785e69be63 100644
--- a/auth/gensec/gensec.c
+++ b/auth/gensec/gensec.c
@@ -854,3 +854,66 @@ _PUBLIC_ const char *gensec_get_target_principal(struct gensec_security *gensec_
 
 	return NULL;
 }
+
+static int gensec_channel_bindings_destructor(struct gensec_channel_bindings *cb)
+{
+	data_blob_clear_free(&cb->initiator_address);
+	data_blob_clear_free(&cb->acceptor_address);
+	data_blob_clear_free(&cb->application_data);
+	*cb = (struct gensec_channel_bindings) { .initiator_addrtype = 0, };
+	return 0;
+}
+
+_PUBLIC_ NTSTATUS gensec_set_channel_bindings(struct gensec_security *gensec_security,
+					      uint32_t initiator_addrtype,
+					      const DATA_BLOB *initiator_address,
+					      uint32_t acceptor_addrtype,
+					      const DATA_BLOB *acceptor_address,
+					      const DATA_BLOB *application_data)
+{
+	struct gensec_channel_bindings *cb = NULL;
+
+	if (gensec_security->subcontext) {
+		return NT_STATUS_INTERNAL_ERROR;
+	}
+
+	if (gensec_security->channel_bindings != NULL) {
+		return NT_STATUS_ALREADY_REGISTERED;
+	}
+
+	cb = talloc_zero(gensec_security, struct gensec_channel_bindings);
+	if (cb == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	talloc_set_destructor(cb, gensec_channel_bindings_destructor);
+
+	cb->initiator_addrtype = initiator_addrtype;
+	if (initiator_address != NULL) {
+		cb->initiator_address = data_blob_dup_talloc(cb,
+							     *initiator_address);
+		if (cb->initiator_address.length != initiator_address->length) {
+			TALLOC_FREE(cb);
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+	cb->acceptor_addrtype = acceptor_addrtype;
+	if (acceptor_address != NULL) {
+		cb->acceptor_address = data_blob_dup_talloc(cb,
+						            *acceptor_address);
+		if (cb->acceptor_address.length != acceptor_address->length) {
+			TALLOC_FREE(cb);
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+	if (application_data != NULL) {
+		cb->application_data = data_blob_dup_talloc(cb,
+							    *application_data);
+		if (cb->application_data.length != application_data->length) {
+			TALLOC_FREE(cb);
+			return NT_STATUS_NO_MEMORY;
+		}
+	}
+
+	gensec_security->channel_bindings = cb;
+	return NT_STATUS_OK;
+}
diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h
index 29d5e92c130..25242384f55 100644
--- a/auth/gensec/gensec.h
+++ b/auth/gensec/gensec.h
@@ -70,6 +70,7 @@ struct gensec_target {
 #define GENSEC_FEATURE_NO_AUTHZ_LOG	0x00000800
 #define GENSEC_FEATURE_SMB_TRANSPORT	0x00001000
 #define GENSEC_FEATURE_LDAPS_TRANSPORT	0x00002000
+#define GENSEC_FEATURE_CB_OPTIONAL	0x00004000
 
 #define GENSEC_EXPIRE_TIME_INFINITY (NTTIME)0x8000000000000000LL
 
@@ -313,6 +314,13 @@ bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism
 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal);
 const char *gensec_get_target_principal(struct gensec_security *gensec_security);
 
+NTSTATUS gensec_set_channel_bindings(struct gensec_security *gensec_security,
+				     uint32_t initiator_addrtype,
+				     const DATA_BLOB *initiator_address,
+				     uint32_t acceptor_addrtype,
+				     const DATA_BLOB *acceptor_address,
+				     const DATA_BLOB *application_data);
+
 NTSTATUS gensec_generate_session_info_pac(TALLOC_CTX *mem_ctx,
 					  struct gensec_security *gensec_security,
 					  struct smb_krb5_context *smb_krb5_context,
diff --git a/auth/gensec/gensec_internal.h b/auth/gensec/gensec_internal.h
index 8efb1bdff0f..4d8eca99881 100644
--- a/auth/gensec/gensec_internal.h
+++ b/auth/gensec/gensec_internal.h
@@ -95,6 +95,23 @@ struct gensec_security_ops_wrapper {
 	const char *oid;
 };
 
+/*
+ * typedef struct gss_channel_bindings_struct {
+ *       OM_uint32 initiator_addrtype;
+ *       gss_buffer_desc initiator_address;
+ *       OM_uint32 acceptor_addrtype;
+ *       gss_buffer_desc acceptor_address;
+ *       gss_buffer_desc application_data;
+ * } *gss_channel_bindings_t;
+ */
+struct gensec_channel_bindings {
+	uint32_t initiator_addrtype;
+	DATA_BLOB initiator_address;
+	uint32_t acceptor_addrtype;
+	DATA_BLOB acceptor_address;
+	DATA_BLOB application_data;
+};
+
 struct gensec_security {
 	const struct gensec_security_ops *ops;
 	void *private_data;
@@ -106,6 +123,7 @@ struct gensec_security {
 	uint32_t max_update_size;
 	uint8_t dcerpc_auth_level;
 	struct tsocket_address *local_addr, *remote_addr;
+	struct gensec_channel_bindings *channel_bindings;
 	struct gensec_settings *settings;
 
 	/* When we are a server, this may be filled in to provide an
diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c
index bcf98bd5968..4405aca278d 100644
--- a/auth/gensec/gensec_start.c
+++ b/auth/gensec/gensec_start.c
@@ -732,6 +732,7 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx,
 	(*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
 	(*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings);
 	(*gensec_security)->auth_context = talloc_reference(*gensec_security, parent->auth_context);
+	(*gensec_security)->channel_bindings = talloc_reference(*gensec_security, parent->channel_bindings);
 
 	talloc_set_destructor((*gensec_security), gensec_security_destructor);
 	return NT_STATUS_OK;
diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c
index 337aeed9229..d8dc1d2940b 100644
--- a/auth/ntlmssp/ntlmssp_client.c
+++ b/auth/ntlmssp/ntlmssp_client.c
@@ -599,6 +599,8 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
 			SingleHost->Value.AvSingleHost.remaining = data_blob_null;
 		}
 
+		if (!(gensec_security->want_features & GENSEC_FEATURE_CB_OPTIONAL)
+		    || gensec_security->channel_bindings != NULL)
 		{
 			struct AV_PAIR *ChannelBindings = NULL;
 
@@ -607,13 +609,12 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security,
 			count++;
 			*eol = *ChannelBindings;
 
-			/*
-			 * gensec doesn't support channel bindings yet,
-			 * but we want to match Windows on the wire
-			 */
 			ChannelBindings->AvId = MsvChannelBindings;
-			memset(ChannelBindings->Value.ChannelBindings, 0,
-			       sizeof(ChannelBindings->Value.ChannelBindings));
+			nt_status = ntlmssp_hash_channel_bindings(gensec_security,
+					ChannelBindings->Value.ChannelBindings);
+			if (!NT_STATUS_IS_OK(nt_status)) {
+				return nt_status;
+			}
 		}
 
 		service = gensec_get_target_service(gensec_security);
diff --git a/auth/ntlmssp/ntlmssp_private.h b/auth/ntlmssp/ntlmssp_private.h
index 4d84e3347b6..7b939b80ae2 100644
--- a/auth/ntlmssp/ntlmssp_private.h
+++ b/auth/ntlmssp/ntlmssp_private.h
@@ -56,6 +56,8 @@ void debug_ntlmssp_flags(uint32_t neg_flags);
 NTSTATUS ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,
 				  uint32_t neg_flags, const char *name);
 const DATA_BLOB ntlmssp_version_blob(void);
+NTSTATUS ntlmssp_hash_channel_bindings(struct gensec_security *gensec_security,
+				       uint8_t cb_hash[16]);
 
 /* The following definitions come from auth/ntlmssp_server.c  */
 
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index 64b96283eb2..1e49379a8ed 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -386,6 +386,9 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
 	DATA_BLOB version_blob = data_blob_null;
 	const unsigned int mic_len = NTLMSSP_MIC_SIZE;
 	DATA_BLOB mic_blob = data_blob_null;
+	const uint8_t zero_channel_bindings[16] = { 0, };
+	const uint8_t *client_channel_bindings = zero_channel_bindings;
+	uint8_t server_channel_bindings[16] = { 0, };
 	const char *parse_string;
 	bool ok;
 	struct timeval endtime;
@@ -523,6 +526,7 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
 		uint32_t i = 0;
 		uint32_t count = 0;
 		const struct AV_PAIR *flags = NULL;
+		const struct AV_PAIR *cb = NULL;
 		const struct AV_PAIR *eol = NULL;
 		uint32_t av_flags = 0;
 
@@ -598,6 +602,12 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
 			ntlmssp_state->new_spnego = true;
 		}
 
+		cb = ndr_ntlmssp_find_av(&v2_resp.Challenge.AvPairs,
+					 MsvChannelBindings);
+		if (cb != NULL) {
+			client_channel_bindings = cb->Value.ChannelBindings;
+		}
+
 		count = ntlmssp_state->server.av_pair_list.count;
 		if (v2_resp.Challenge.AvPairs.count < count) {
 			return NT_STATUS_INVALID_PARAMETER;
@@ -700,6 +710,43 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security,
 		}
 	}
 
+	if (gensec_security->channel_bindings != NULL) {
+		nt_status = ntlmssp_hash_channel_bindings(gensec_security,
+							  server_channel_bindings);
+		if (!NT_STATUS_IS_OK(nt_status)) {
+			return nt_status;
+		}
+
+		ok = mem_equal_const_time(client_channel_bindings,
+					  server_channel_bindings,
+					  16);
+		if (!ok && gensec_security->want_features & GENSEC_FEATURE_CB_OPTIONAL) {
+			/*
+			 * Unlike kerberos, explicit 16 zeros in
+			 * MsvChannelBindings are not enough to
+			 * pass the optional check.
+			 *
+			 * So we only let it through without explicit
+			 * MsvChannelBindings.
+			 */
+			ok = (client_channel_bindings == zero_channel_bindings);
+		}
+		if (!ok) {
+			DBG_WARNING("Invalid channel bindings for "
+				    "user=[%s] domain=[%s] workstation=[%s]\n",
+				    ntlmssp_state->user,
+				    ntlmssp_state->domain,
+				    ntlmssp_state->client.netbios_name);
+			dump_data(DBGLVL_WARNING,
+				  client_channel_bindings,
+				  16);
+			dump_data(DBGLVL_WARNING,
+				  server_channel_bindings,
+				  16);
+			return NT_STATUS_BAD_BINDINGS;
+		}
+	}
+
 	nttime_to_timeval(&endtime, ntlmssp_state->server.challenge_endtime);
 	expired = timeval_expired(&endtime);
 	if (expired) {
diff --git a/auth/ntlmssp/ntlmssp_util.c b/auth/ntlmssp/ntlmssp_util.c
index 6f3b474fd71..b8dc84e1652 100644
--- a/auth/ntlmssp/ntlmssp_util.c
+++ b/auth/ntlmssp/ntlmssp_util.c
@@ -22,9 +22,15 @@
 */
 
 #include "includes.h"
+#include "auth/gensec/gensec.h"
+#include "auth/gensec/gensec_internal.h"
 #include "../auth/ntlmssp/ntlmssp.h"
 #include "../auth/ntlmssp/ntlmssp_private.h"
 
+#include "lib/crypto/gnutls_helpers.h"
+#include <gnutls/gnutls.h>
+#include <gnutls/crypto.h>
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
 
@@ -218,3 +224,95 @@ const DATA_BLOB ntlmssp_version_blob(void)
 
 	return data_blob_const(version_buffer, ARRAY_SIZE(version_buffer));
 }
+
+NTSTATUS ntlmssp_hash_channel_bindings(struct gensec_security *gensec_security,
+				       uint8_t cb_hash[16])
+{
+	const struct gensec_channel_bindings *cb =
+		gensec_security->channel_bindings;
+	gnutls_hash_hd_t hash_hnd = NULL;
+	uint8_t uint32buf[4];
+	int rc;
+
+	if (cb == NULL) {
+		memset(cb_hash, 0, 16);
+		return NT_STATUS_OK;
+	}
+
+	GNUTLS_FIPS140_SET_LAX_MODE();
+	rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
+	if (rc < 0) {
+		GNUTLS_FIPS140_SET_STRICT_MODE();
+		return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
+	}
+
+	SIVAL(uint32buf, 0, cb->initiator_addrtype);
+	rc = gnutls_hash(hash_hnd, uint32buf, sizeof(uint32buf));
+	if (rc < 0) {
+		gnutls_hash_deinit(hash_hnd, NULL);
+		GNUTLS_FIPS140_SET_STRICT_MODE();
+		return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
+	}
+	SIVAL(uint32buf, 0, cb->initiator_address.length);
+	rc = gnutls_hash(hash_hnd, uint32buf, sizeof(uint32buf));
+	if (rc < 0) {
+		gnutls_hash_deinit(hash_hnd, NULL);
+		GNUTLS_FIPS140_SET_STRICT_MODE();
+		return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
+	}
+	if (cb->initiator_address.length > 0) {
+		rc = gnutls_hash(hash_hnd,
+				 cb->initiator_address.data,
+				 cb->initiator_address.length);
+		if (rc < 0) {
+			gnutls_hash_deinit(hash_hnd, NULL);
+			GNUTLS_FIPS140_SET_STRICT_MODE();
+			return gnutls_error_to_ntstatus(rc, NT_STATUS_HMAC_NOT_SUPPORTED);
+		}
+	}
+	SIVAL(uint32buf, 0, cb->acceptor_addrtype);
+	rc = gnutls_hash(hash_hnd, uint32buf, sizeof(uint32buf));
+	if (rc < 0) {
+		gnutls_hash_deinit(hash_hnd, NULL);
+		GNUTLS_FIPS140_SET_STRICT_MODE();


-- 
Samba Shared Repository



More information about the samba-cvs mailing list