[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