From 2700da00069cd2d1977c291a4f39a2d4733ded7e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 13 Jul 2020 16:15:03 +0200 Subject: [PATCH 001/108] libcli:smb2: Do not leak ptext on error Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- libcli/smb/smb2_signing.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c index cc03607d789..4d430f56df5 100644 --- a/libcli/smb/smb2_signing.c +++ b/libcli/smb/smb2_signing.c @@ -520,6 +520,7 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, ctext = talloc_size(talloc_tos(), ctext_size); if (ctext == NULL) { + TALLOC_FREE(ptext); status = NT_STATUS_NO_MEMORY; goto out; } -- 2.29.2 From efeefe63206b9663bfc1dc5418c294831a96d1ee Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 13 Jul 2020 17:23:37 +0200 Subject: [PATCH 002/108] libcli:smb2: Use talloc NULL context if we don't have a stackframe If we execute this code from python we don't have a talloc stackframe around and segfault with talloc_tos(). To fix the crash we use the NULL context as we take care for freeing the memory as soon as possible. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- libcli/smb/smb2_signing.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/libcli/smb/smb2_signing.c b/libcli/smb/smb2_signing.c index 4d430f56df5..6ece5f2e4d3 100644 --- a/libcli/smb/smb2_signing.c +++ b/libcli/smb/smb2_signing.c @@ -511,14 +511,25 @@ NTSTATUS smb2_signing_encrypt_pdu(struct smb2_signing_key *encryption_key, uint8_t *ctext = NULL; size_t len = 0; int i; + TALLOC_CTX *tmp_ctx = NULL; - ptext = talloc_size(talloc_tos(), ptext_size); + /* + * If we come from python bindings, we don't have a stackframe + * around, so use the NULL context. + * + * This is fine as we make sure we free the memory. + */ + if (talloc_stackframe_exists()) { + tmp_ctx = talloc_tos(); + } + + ptext = talloc_size(tmp_ctx, ptext_size); if (ptext == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } - ctext = talloc_size(talloc_tos(), ctext_size); + ctext = talloc_size(tmp_ctx, ctext_size); if (ctext == NULL) { TALLOC_FREE(ptext); status = NT_STATUS_NO_MEMORY; @@ -710,16 +721,27 @@ NTSTATUS smb2_signing_decrypt_pdu(struct smb2_signing_key *decryption_key, uint8_t *ptext = NULL; size_t len = 0; int i; + TALLOC_CTX *tmp_ctx = NULL; + + /* + * If we come from python bindings, we don't have a stackframe + * around, so use the NULL context. + * + * This is fine as we make sure we free the memory. + */ + if (talloc_stackframe_exists()) { + tmp_ctx = talloc_tos(); + } /* GnuTLS doesn't have a iovec API for decryption yet */ - ptext = talloc_size(talloc_tos(), ptext_size); + ptext = talloc_size(tmp_ctx, ptext_size); if (ptext == NULL) { status = NT_STATUS_NO_MEMORY; goto out; } - ctext = talloc_size(talloc_tos(), ctext_size); + ctext = talloc_size(tmp_ctx, ctext_size); if (ctext == NULL) { TALLOC_FREE(ptext); status = NT_STATUS_NO_MEMORY; -- 2.29.2 From 189ec5ea334188d0473fca9ffe2fe4887c5f804e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 6 Nov 2019 17:37:45 +0100 Subject: [PATCH 003/108] auth:creds: Introduce CRED_SMB_CONF We have several places where we check '> CRED_UNINITIALISED', so we better don't use CRED_UNINITIALISED for values from our smb.conf. Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- auth/credentials/credentials.c | 6 +++--- auth/credentials/credentials.h | 1 + auth/credentials/pycredentials.c | 1 + python/samba/tests/credentials.py | 4 ++-- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index 81f9dbb9eb3..80a31b248ae 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -902,12 +902,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, if (lpcfg_parm_is_cmdline(lp_ctx, "workgroup")) { cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_SPECIFIED); } else { - cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_UNINITIALISED); + cli_credentials_set_domain(cred, lpcfg_workgroup(lp_ctx), CRED_SMB_CONF); } if (lpcfg_parm_is_cmdline(lp_ctx, "netbios name")) { cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SPECIFIED); } else { - cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_UNINITIALISED); + cli_credentials_set_workstation(cred, lpcfg_netbios_name(lp_ctx), CRED_SMB_CONF); } if (realm != NULL && strlen(realm) == 0) { realm = NULL; @@ -915,7 +915,7 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, if (lpcfg_parm_is_cmdline(lp_ctx, "realm")) { cli_credentials_set_realm(cred, realm, CRED_SPECIFIED); } else { - cli_credentials_set_realm(cred, realm, CRED_UNINITIALISED); + cli_credentials_set_realm(cred, realm, CRED_SMB_CONF); } sep = lpcfg_winbind_separator(lp_ctx); diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 9fe6a82b1ea..7154c2a008c 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -42,6 +42,7 @@ struct db_context; /* In order of priority */ enum credentials_obtained { CRED_UNINITIALISED = 0, /* We don't even have a guess yet */ + CRED_SMB_CONF, /* Current value should be used, which comes from smb.conf */ CRED_CALLBACK, /* Callback should be used to obtain value */ CRED_GUESS_ENV, /* Current value should be used, which was guessed */ CRED_GUESS_FILE, /* A guess from a file (or file pointed at in env variable) */ diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index a5d0f9e051c..68edc282741 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -1275,6 +1275,7 @@ MODULE_INIT_FUNC(credentials) return NULL; PyModule_AddObject(m, "UNINITIALISED", PyLong_FromLong(CRED_UNINITIALISED)); + PyModule_AddObject(m, "SMB_CONF", PyLong_FromLong(CRED_SMB_CONF)); PyModule_AddObject(m, "CALLBACK", PyLong_FromLong(CRED_CALLBACK)); PyModule_AddObject(m, "GUESS_ENV", PyLong_FromLong(CRED_GUESS_ENV)); PyModule_AddObject(m, "GUESS_FILE", PyLong_FromLong(CRED_GUESS_FILE)); diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index d2a81506de3..6454ac9ff7c 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -332,7 +332,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): os.environ["USER"] = "env_user" creds.guess(lp) realm = "realm.example.com" - creds.set_realm(realm, credentials.UNINITIALISED) + creds.set_realm(realm, credentials.SMB_CONF) creds.parse_string("user") self.assertEqual(creds.get_username(), "user") self.assertEqual(creds.get_domain(), lp.get("workgroup").upper()) @@ -360,7 +360,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): os.environ["USER"] = "env_user" creds.guess(lp) realm = "realm.example.com" - creds.set_realm(realm, credentials.UNINITIALISED) + creds.set_realm(realm, credentials.SMB_CONF) self.assertEqual(creds.get_username(), "env_user") self.assertEqual(creds.get_domain(), lp.get("workgroup").upper()) self.assertEqual(creds.get_realm(), realm.upper()) -- 2.29.2 From 50499847d67b8c7a9f1f95f94f5c4cc0c3c38ab3 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 10 Oct 2019 14:18:23 +0200 Subject: [PATCH 004/108] param: Add 'server smb encrypt' parameter And this also makes 'smb encrypt' a synonym of that. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- .../smbdotconf/security/serversmbencrypt.xml | 241 ++++++++++++++++++ docs-xml/smbdotconf/security/smbencrypt.xml | 241 +----------------- source3/param/loadparm.c | 2 +- source3/smbd/service.c | 4 +- source3/smbd/smb2_negprot.c | 2 +- source3/smbd/smb2_sesssetup.c | 4 +- source3/smbd/smb2_tcon.c | 4 +- source3/smbd/trans2.c | 2 +- 8 files changed, 257 insertions(+), 243 deletions(-) create mode 100644 docs-xml/smbdotconf/security/serversmbencrypt.xml diff --git a/docs-xml/smbdotconf/security/serversmbencrypt.xml b/docs-xml/smbdotconf/security/serversmbencrypt.xml new file mode 100644 index 00000000000..714aacbf1ca --- /dev/null +++ b/docs-xml/smbdotconf/security/serversmbencrypt.xml @@ -0,0 +1,241 @@ + + + + This parameter controls whether a remote client is allowed or required + to use SMB encryption. It has different effects depending on whether + the connection uses SMB1 or SMB2 and newer: + + + + + + If the connection uses SMB1, then this option controls the use + of a Samba-specific extension to the SMB protocol introduced in + Samba 3.2 that makes use of the Unix extensions. + + + + + + If the connection uses SMB2 or newer, then this option controls + the use of the SMB-level encryption that is supported in SMB + version 3.0 and above and available in Windows 8 and newer. + + + + + + This parameter can be set globally and on a per-share bases. + Possible values are + + off, + if_required, + desired, + and + required. + A special value is default which is + the implicit default setting of if_required. + + + + + Effects for SMB1 + + + The Samba-specific encryption of SMB1 connections is an + extension to the SMB protocol negotiated as part of the UNIX + extensions. SMB encryption uses the GSSAPI (SSPI on Windows) + ability to encrypt and sign every request/response in a SMB + protocol stream. When enabled it provides a secure method of + SMB/CIFS communication, similar to an ssh protected session, but + using SMB/CIFS authentication to negotiate encryption and + signing keys. Currently this is only supported smbclient of by + Samba 3.2 and newer, and hopefully soon Linux CIFSFS and MacOS/X + clients. Windows clients do not support this feature. + + + This may be set on a per-share + basis, but clients may chose to encrypt the entire session, not + just traffic to a specific share. If this is set to mandatory + then all traffic to a share must + be encrypted once the connection has been made to the share. + The server would return "access denied" to all non-encrypted + requests on such a share. Selecting encrypted traffic reduces + throughput as smaller packet sizes must be used (no huge UNIX + style read/writes allowed) as well as the overhead of encrypting + and signing all the data. + + + + If SMB encryption is selected, Windows style SMB signing (see + the option) is no longer + necessary, as the GSSAPI flags use select both signing and + sealing of the data. + + + + When set to auto or default, SMB encryption is offered, but not + enforced. When set to mandatory, SMB encryption is required and + if set to disabled, SMB encryption can not be negotiated. + + + + + + Effects for SMB2 and newer + + + Native SMB transport encryption is available in SMB version 3.0 + or newer. It is only offered by Samba if + server max protocol is set to + SMB3 or newer. + Clients supporting this type of encryption include + Windows 8 and newer, + Windows server 2012 and newer, + and smbclient of Samba 4.1 and newer. + + + + The protocol implementation offers various options: + + + + + + The capability to perform SMB encryption can be + negotiated during protocol negotiation. + + + + + + Data encryption can be enabled globally. In that case, + an encryption-capable connection will have all traffic + in all its sessions encrypted. In particular all share + connections will be encrypted. + + + + + + Data encryption can also be enabled per share if not + enabled globally. For an encryption-capable connection, + all connections to an encryption-enabled share will be + encrypted. + + + + + + Encryption can be enforced. This means that session + setups will be denied on non-encryption-capable + connections if data encryption has been enabled + globally. And tree connections will be denied for + non-encryption capable connections to shares with data + encryption enabled. + + + + + + These features can be controlled with settings of + server smb encrypt as follows: + + + + + + Leaving it as default, explicitly setting + default, or setting it to + if_required globally will enable + negotiation of encryption but will not turn on + data encryption globally or per share. + + + + + + Setting it to desired globally + will enable negotiation and will turn on data encryption + on sessions and share connections for those clients + that support it. + + + + + + Setting it to required globally + will enable negotiation and turn on data encryption + on sessions and share connections. Clients that do + not support encryption will be denied access to the + server. + + + + + + Setting it to off globally will + completely disable the encryption feature for all + connections. Setting server smb encrypt = + required for individual shares (while it's + globally off) will deny access to this shares for all + clients. + + + + + + Setting it to desired on a share + will turn on data encryption for this share for clients + that support encryption if negotiation has been + enabled globally. + + + + + + Setting it to required on a share + will enforce data encryption for this share if + negotiation has been enabled globally. I.e. clients that + do not support encryption will be denied access to the + share. + + + Note that this allows per-share enforcing to be + controlled in Samba differently from Windows: + In Windows, RejectUnencryptedAccess + is a global setting, and if it is set, all shares with + data encryption turned on + are automatically enforcing encryption. In order to + achieve the same effect in Samba, one + has to globally set server smb encrypt to + if_required, and then set all shares + that should be encrypted to + required. + Additionally, it is possible in Samba to have some + shares with encryption required + and some other shares with encryption only + desired, which is not possible in + Windows. + + + + + + Setting it to off or + if_required for a share has + no effect. + + + + + + + + +default + diff --git a/docs-xml/smbdotconf/security/smbencrypt.xml b/docs-xml/smbdotconf/security/smbencrypt.xml index 32a22cb58f5..798e616b765 100644 --- a/docs-xml/smbdotconf/security/smbencrypt.xml +++ b/docs-xml/smbdotconf/security/smbencrypt.xml @@ -1,241 +1,14 @@ + context="S" + type="enum" + enumlist="enum_smb_signing_vals" + function="server_smb_encrypt" + synonym="1" + xmlns:samba="http://www.samba.org/samba/DTD/samba-doc"> - This parameter controls whether a remote client is allowed or required - to use SMB encryption. It has different effects depending on whether - the connection uses SMB1 or SMB2 and newer: + This is a synonym for . - - - - - If the connection uses SMB1, then this option controls the use - of a Samba-specific extension to the SMB protocol introduced in - Samba 3.2 that makes use of the Unix extensions. - - - - - - If the connection uses SMB2 or newer, then this option controls - the use of the SMB-level encryption that is supported in SMB - version 3.0 and above and available in Windows 8 and newer. - - - - - - This parameter can be set globally and on a per-share bases. - Possible values are - off (or disabled), - enabled (or auto, or - if_required), - desired, - and - required - (or mandatory). - A special value is default which is - the implicit default setting of enabled. - - - - - Effects for SMB1 - - - The Samba-specific encryption of SMB1 connections is an - extension to the SMB protocol negotiated as part of the UNIX - extensions. SMB encryption uses the GSSAPI (SSPI on Windows) - ability to encrypt and sign every request/response in a SMB - protocol stream. When enabled it provides a secure method of - SMB/CIFS communication, similar to an ssh protected session, but - using SMB/CIFS authentication to negotiate encryption and - signing keys. Currently this is only supported smbclient of by - Samba 3.2 and newer, and hopefully soon Linux CIFSFS and MacOS/X - clients. Windows clients do not support this feature. - - - This may be set on a per-share - basis, but clients may chose to encrypt the entire session, not - just traffic to a specific share. If this is set to mandatory - then all traffic to a share must - be encrypted once the connection has been made to the share. - The server would return "access denied" to all non-encrypted - requests on such a share. Selecting encrypted traffic reduces - throughput as smaller packet sizes must be used (no huge UNIX - style read/writes allowed) as well as the overhead of encrypting - and signing all the data. - - - - If SMB encryption is selected, Windows style SMB signing (see - the option) is no longer - necessary, as the GSSAPI flags use select both signing and - sealing of the data. - - - - When set to auto or default, SMB encryption is offered, but not - enforced. When set to mandatory, SMB encryption is required and - if set to disabled, SMB encryption can not be negotiated. - - - - - - Effects for SMB2 - - - Native SMB transport encryption is available in SMB version 3.0 - or newer. It is only offered by Samba if - server max protocol is set to - SMB3 or newer. - Clients supporting this type of encryption include - Windows 8 and newer, - Windows server 2012 and newer, - and smbclient of Samba 4.1 and newer. - - - - The protocol implementation offers various options: - - - - - - The capability to perform SMB encryption can be - negotiated during protocol negotiation. - - - - - - Data encryption can be enabled globally. In that case, - an encryption-capable connection will have all traffic - in all its sessions encrypted. In particular all share - connections will be encrypted. - - - - - - Data encryption can also be enabled per share if not - enabled globally. For an encryption-capable connection, - all connections to an encryption-enabled share will be - encrypted. - - - - - - Encryption can be enforced. This means that session - setups will be denied on non-encryption-capable - connections if data encryption has been enabled - globally. And tree connections will be denied for - non-encryption capable connections to shares with data - encryption enabled. - - - - - - These features can be controlled with settings of - smb encrypt as follows: - - - - - - Leaving it as default, explicitly setting - default, or setting it to - enabled globally will enable - negotiation of encryption but will not turn on - data encryption globally or per share. - - - - - - Setting it to desired globally - will enable negotiation and will turn on data encryption - on sessions and share connections for those clients - that support it. - - - - - - Setting it to required globally - will enable negotiation and turn on data encryption - on sessions and share connections. Clients that do - not support encryption will be denied access to the - server. - - - - - - Setting it to off globally will - completely disable the encryption feature for all - connections. Setting smb encrypt = - required for individual shares (while it's - globally off) will deny access to this shares for all - clients. - - - - - - Setting it to desired on a share - will turn on data encryption for this share for clients - that support encryption if negotiation has been - enabled globally. - - - - - - Setting it to required on a share - will enforce data encryption for this share if - negotiation has been enabled globally. I.e. clients that - do not support encryption will be denied access to the - share. - - - Note that this allows per-share enforcing to be - controlled in Samba differently from Windows: - In Windows, RejectUnencryptedAccess - is a global setting, and if it is set, all shares with - data encryption turned on - are automatically enforcing encryption. In order to - achieve the same effect in Samba, one - has to globally set smb encrypt to - enabled, and then set all shares - that should be encrypted to - required. - Additionally, it is possible in Samba to have some - shares with encryption required - and some other shares with encryption only - desired, which is not possible in - Windows. - - - - - - Setting it to off or - enabled for a share has - no effect. - - - - - - default diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index a3abaa2ec67..c0070b716a5 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -241,7 +241,7 @@ static const struct loadparm_service _sDefault = .aio_write_size = 1, .map_readonly = MAP_READONLY_NO, .directory_name_cache_size = 100, - .smb_encrypt = SMB_SIGNING_DEFAULT, + .server_smb_encrypt = SMB_SIGNING_DEFAULT, .kernel_share_modes = true, .durable_handles = true, .check_parent_directory_delete_on_close = false, diff --git a/source3/smbd/service.c b/source3/smbd/service.c index ed38121f292..a263c33b7e2 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -567,9 +567,9 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn, conn->case_preserve = lp_preserve_case(snum); conn->short_case_preserve = lp_short_preserve_case(snum); - conn->encrypt_level = lp_smb_encrypt(snum); + conn->encrypt_level = lp_server_smb_encrypt(snum); if (conn->encrypt_level > SMB_SIGNING_OFF) { - if (lp_smb_encrypt(-1) == SMB_SIGNING_OFF) { + if (lp_server_smb_encrypt(-1) == SMB_SIGNING_OFF) { if (conn->encrypt_level == SMB_SIGNING_REQUIRED) { DBG_ERR("Service [%s] requires encryption, but " "it is disabled globally!\n", diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index 4071f42b5e0..674942b71de 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -335,7 +335,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } if ((protocol >= PROTOCOL_SMB2_24) && - (lp_smb_encrypt(-1) != SMB_SIGNING_OFF) && + (lp_server_smb_encrypt(-1) != SMB_SIGNING_OFF) && (in_capabilities & SMB2_CAP_ENCRYPTION)) { capabilities |= SMB2_CAP_ENCRYPTION; } diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 2b6b3a820d4..8957411e167 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -292,12 +292,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED; } - if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) && + if ((lp_server_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) && (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) { x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED; } - if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) { + if (lp_server_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) { x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED | SMBXSRV_ENCRYPTION_DESIRED; } diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index 76112d04889..0dd3c653b4b 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -302,13 +302,13 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, TALLOC_FREE(proxy); } - if ((lp_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) && + if ((lp_server_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) && (conn->smb2.server.cipher != 0)) { encryption_desired = true; } - if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) { + if (lp_server_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) { encryption_desired = true; encryption_required = true; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 7acde285a90..b745e0906b1 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4484,7 +4484,7 @@ static void call_trans2setfsinfo(connection_struct *conn, return; } - if (lp_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) { + if (lp_server_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) { reply_nterror( req, NT_STATUS_NOT_SUPPORTED); -- 2.29.2 From 74d2e7f5c8892393ebda43009bbd2c781eed275f Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 10:04:19 +0200 Subject: [PATCH 005/108] param: Create and use enum_smb_encryption_vals Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- .../smbdotconf/security/serversmbencrypt.xml | 2 +- docs-xml/smbdotconf/security/smbencrypt.xml | 2 +- lib/param/param_table.c | 23 +++++++++++++++++++ libcli/smb/smb_constants.h | 9 ++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/docs-xml/smbdotconf/security/serversmbencrypt.xml b/docs-xml/smbdotconf/security/serversmbencrypt.xml index 714aacbf1ca..5f38b46419e 100644 --- a/docs-xml/smbdotconf/security/serversmbencrypt.xml +++ b/docs-xml/smbdotconf/security/serversmbencrypt.xml @@ -1,7 +1,7 @@ diff --git a/docs-xml/smbdotconf/security/smbencrypt.xml b/docs-xml/smbdotconf/security/smbencrypt.xml index 798e616b765..60271200c0a 100644 --- a/docs-xml/smbdotconf/security/smbencrypt.xml +++ b/docs-xml/smbdotconf/security/smbencrypt.xml @@ -1,7 +1,7 @@ diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 47b85de1f87..e2f737279dc 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -138,6 +138,29 @@ static const struct enum_list enum_smb_signing_vals[] = { {-1, NULL} }; +static const struct enum_list enum_smb_encryption_vals[] = { + {SMB_ENCRYPTION_DEFAULT, "default"}, + {SMB_ENCRYPTION_OFF, "No"}, + {SMB_ENCRYPTION_OFF, "False"}, + {SMB_ENCRYPTION_OFF, "0"}, + {SMB_ENCRYPTION_OFF, "Off"}, + {SMB_ENCRYPTION_OFF, "disabled"}, + {SMB_ENCRYPTION_IF_REQUIRED, "if_required"}, + {SMB_ENCRYPTION_IF_REQUIRED, "Yes"}, + {SMB_ENCRYPTION_IF_REQUIRED, "True"}, + {SMB_ENCRYPTION_IF_REQUIRED, "1"}, + {SMB_ENCRYPTION_IF_REQUIRED, "On"}, + {SMB_ENCRYPTION_IF_REQUIRED, "enabled"}, + {SMB_ENCRYPTION_IF_REQUIRED, "auto"}, + {SMB_ENCRYPTION_DESIRED, "desired"}, + {SMB_ENCRYPTION_REQUIRED, "required"}, + {SMB_ENCRYPTION_REQUIRED, "mandatory"}, + {SMB_ENCRYPTION_REQUIRED, "force"}, + {SMB_ENCRYPTION_REQUIRED, "forced"}, + {SMB_ENCRYPTION_REQUIRED, "enforced"}, + {-1, NULL} +}; + static const struct enum_list enum_mdns_name_values[] = { {MDNS_NAME_NETBIOS, "netbios"}, {MDNS_NAME_MDNS, "mdns"}, diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index b424b13cde4..2fb1fd7189e 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -106,6 +106,15 @@ enum smb_signing_setting { SMB_SIGNING_REQUIRED = 3, }; +/* This MUST align with 'enum smb_signing_setting' */ +enum smb_encryption_setting { + SMB_ENCRYPTION_DEFAULT = SMB_SIGNING_DEFAULT, + SMB_ENCRYPTION_OFF = SMB_SIGNING_OFF, + SMB_ENCRYPTION_IF_REQUIRED = SMB_SIGNING_IF_REQUIRED, + SMB_ENCRYPTION_DESIRED = SMB_SIGNING_DESIRED, + SMB_ENCRYPTION_REQUIRED = SMB_SIGNING_REQUIRED, +}; + /* types of buffers in core SMB protocol */ #define SMB_DATA_BLOCK 0x1 #define SMB_ASCII4 0x4 -- 2.29.2 From 41d2569830352ad837a7066726870a29657978ac Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 26 May 2020 09:34:54 +0200 Subject: [PATCH 006/108] s3:smbd: Use 'enum smb_encryption_setting' values Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/param/loadparm.c | 2 +- source3/smbd/service.c | 8 ++++---- source3/smbd/smb2_negprot.c | 2 +- source3/smbd/smb2_sesssetup.c | 4 ++-- source3/smbd/smb2_tcon.c | 4 ++-- source3/smbd/trans2.c | 3 ++- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index c0070b716a5..4ad541301b3 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -241,7 +241,7 @@ static const struct loadparm_service _sDefault = .aio_write_size = 1, .map_readonly = MAP_READONLY_NO, .directory_name_cache_size = 100, - .server_smb_encrypt = SMB_SIGNING_DEFAULT, + .server_smb_encrypt = SMB_ENCRYPTION_DEFAULT, .kernel_share_modes = true, .durable_handles = true, .check_parent_directory_delete_on_close = false, diff --git a/source3/smbd/service.c b/source3/smbd/service.c index a263c33b7e2..43803e721c2 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -568,16 +568,16 @@ static NTSTATUS make_connection_snum(struct smbXsrv_connection *xconn, conn->short_case_preserve = lp_short_preserve_case(snum); conn->encrypt_level = lp_server_smb_encrypt(snum); - if (conn->encrypt_level > SMB_SIGNING_OFF) { - if (lp_server_smb_encrypt(-1) == SMB_SIGNING_OFF) { - if (conn->encrypt_level == SMB_SIGNING_REQUIRED) { + if (conn->encrypt_level > SMB_ENCRYPTION_OFF) { + if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_OFF) { + if (conn->encrypt_level == SMB_ENCRYPTION_REQUIRED) { DBG_ERR("Service [%s] requires encryption, but " "it is disabled globally!\n", lp_const_servicename(snum)); status = NT_STATUS_ACCESS_DENIED; goto err_root_exit; } - conn->encrypt_level = SMB_SIGNING_OFF; + conn->encrypt_level = SMB_ENCRYPTION_OFF; } } diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index 674942b71de..99303f1b07b 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -335,7 +335,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) } if ((protocol >= PROTOCOL_SMB2_24) && - (lp_server_smb_encrypt(-1) != SMB_SIGNING_OFF) && + (lp_server_smb_encrypt(-1) != SMB_ENCRYPTION_OFF) && (in_capabilities & SMB2_CAP_ENCRYPTION)) { capabilities |= SMB2_CAP_ENCRYPTION; } diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 8957411e167..907dd92321e 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -292,12 +292,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, x->global->signing_flags = SMBXSRV_SIGNING_REQUIRED; } - if ((lp_server_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) && + if ((lp_server_smb_encrypt(-1) >= SMB_ENCRYPTION_DESIRED) && (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) { x->global->encryption_flags = SMBXSRV_ENCRYPTION_DESIRED; } - if (lp_server_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) { + if (lp_server_smb_encrypt(-1) == SMB_ENCRYPTION_REQUIRED) { x->global->encryption_flags = SMBXSRV_ENCRYPTION_REQUIRED | SMBXSRV_ENCRYPTION_DESIRED; } diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index 0dd3c653b4b..d7e0cf90f47 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -302,13 +302,13 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, TALLOC_FREE(proxy); } - if ((lp_server_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) && + if ((lp_server_smb_encrypt(snum) >= SMB_ENCRYPTION_DESIRED) && (conn->smb2.server.cipher != 0)) { encryption_desired = true; } - if (lp_server_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) { + if (lp_server_smb_encrypt(snum) == SMB_ENCRYPTION_REQUIRED) { encryption_desired = true; encryption_required = true; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index b745e0906b1..2f2fdcb7260 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4484,7 +4484,8 @@ static void call_trans2setfsinfo(connection_struct *conn, return; } - if (lp_server_smb_encrypt(SNUM(conn)) == SMB_SIGNING_OFF) { + if (lp_server_smb_encrypt(SNUM(conn)) == + SMB_ENCRYPTION_OFF) { reply_nterror( req, NT_STATUS_NOT_SUPPORTED); -- 2.29.2 From c1d582d192afb200c4ad3fc6c8109789c3266a75 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 9 Apr 2020 10:38:41 +0200 Subject: [PATCH 007/108] docs-xml: Add 'client smb encrypt' Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- .../smbdotconf/security/clientsmbencrypt.xml | 126 ++++++++++++++++++ lib/param/loadparm.c | 4 + source3/param/loadparm.c | 2 + 3 files changed, 132 insertions(+) create mode 100644 docs-xml/smbdotconf/security/clientsmbencrypt.xml diff --git a/docs-xml/smbdotconf/security/clientsmbencrypt.xml b/docs-xml/smbdotconf/security/clientsmbencrypt.xml new file mode 100644 index 00000000000..05df152e734 --- /dev/null +++ b/docs-xml/smbdotconf/security/clientsmbencrypt.xml @@ -0,0 +1,126 @@ + + + + This parameter controls whether a client should try or is required + to use SMB encryption. It has different effects depending on whether + the connection uses SMB1 or SMB3: + + + + + + If the connection uses SMB1, then this option controls the use + of a Samba-specific extension to the SMB protocol introduced in + Samba 3.2 that makes use of the Unix extensions. + + + + + + If the connection uses SMB2 or newer, then this option controls + the use of the SMB-level encryption that is supported in SMB + version 3.0 and above and available in Windows 8 and newer. + + + + + + This parameter can be set globally. Possible values are + + off, + if_required, + desired, + and + required. + A special value is default which is + the implicit default setting of if_required. + + + + + Effects for SMB1 + + + The Samba-specific encryption of SMB1 connections is an + extension to the SMB protocol negotiated as part of the UNIX + extensions. SMB encryption uses the GSSAPI (SSPI on Windows) + ability to encrypt and sign every request/response in a SMB + protocol stream. When enabled it provides a secure method of + SMB/CIFS communication, similar to an ssh protected session, but + using SMB/CIFS authentication to negotiate encryption and + signing keys. Currently this is only supported smbclient of by + Samba 3.2 and newer. Windows does not support this feature. + + + + When set to default, SMB encryption is probed, but not + enforced. When set to required, SMB encryption is required and + if set to disabled, SMB encryption can not be negotiated. + + + + + + Effects for SMB3 and newer + + + Native SMB transport encryption is available in SMB version 3.0 + or newer. It is only used by Samba if + client max protocol is set to + SMB3 or newer. + + + + These features can be controlled with settings of + client smb encrypt as follows: + + + + + + Leaving it as default, explicitly setting + default, or setting it to + if_required globally will enable + negotiation of encryption but will not turn on + data encryption globally. + + + + + + Setting it to desired globally + will enable negotiation and will turn on data encryption + on sessions and share connections for those servers + that support it. + + + + + + Setting it to required globally + will enable negotiation and turn on data encryption + on sessions and share connections. Clients that do + not support encryption will be denied access to the + server. + + + + + + Setting it to off globally will + completely disable the encryption feature for all + connections. + + + + + + + + +default + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 006caabc092..67f5709b213 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3079,6 +3079,10 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter( lp_ctx, "ldap max search request size", "256000"); + lpcfg_do_global_parameter(lp_ctx, + "client smb encrypt", + "default"); + for (i = 0; parm_table[i].label; i++) { if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { lp_ctx->flags[i] |= FLAG_DEFAULT; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 4ad541301b3..6418a42b6eb 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -960,6 +960,8 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals) Globals.ldap_max_authenticated_request_size = 16777216; Globals.ldap_max_search_request_size = 256000; + Globals.client_smb_encrypt = SMB_ENCRYPTION_DEFAULT; + /* Now put back the settings that were set with lp_set_cmdline() */ apply_lp_set_cmdline(); } -- 2.29.2 From ffe01bcd6390b3ca19c6e327175c262f76683aea Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 22 Jul 2020 17:48:25 +0200 Subject: [PATCH 008/108] lib:param: Add lpcfg_parse_enum_vals() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- lib/param/loadparm.c | 30 ++++++++++++++++++++++++++++++ lib/param/loadparm.h | 2 ++ 2 files changed, 32 insertions(+) diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 67f5709b213..b1410791c60 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3675,3 +3675,33 @@ char *lpcfg_substituted_string(TALLOC_CTX *mem_ctx, raw_value, lp_sub->private_data); } + +/** + * @brief Parse a string value of a given parameter to its integer enum value. + * + * @param[in] param_name The parameter name (e.g. 'client smb encrypt') + * + * @param[in] param_value The parameter value (e.g. 'required'). + * + * @return The integer value of the enum the param_value matches or INT32_MIN + * on error. + */ +int32_t lpcfg_parse_enum_vals(const char *param_name, + const char *param_value) +{ + struct parm_struct *parm = NULL; + int32_t ret = INT32_MIN; + bool ok; + + parm = lpcfg_parm_struct(NULL, param_name); + if (parm == NULL) { + return INT32_MIN; + } + + ok = lp_set_enum_parm(parm, param_value, &ret); + if (!ok) { + return INT32_MIN; + } + + return ret; +} diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h index 323fcf84523..e66ce2324b4 100644 --- a/lib/param/loadparm.h +++ b/lib/param/loadparm.h @@ -316,6 +316,8 @@ bool lp_do_section(const char *pszSectionName, void *userdata); bool store_lp_set_cmdline(const char *pszParmName, const char *pszParmValue); int num_parameters(void); +int32_t lpcfg_parse_enum_vals(const char *param_name, + const char *param_value); struct loadparm_substitution; #ifdef LOADPARM_SUBSTITUTION_INTERNALS -- 2.29.2 From be3b71c7877bda0e5a578b76bfcf98ab9c8e4894 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 9 Oct 2019 09:38:08 +0200 Subject: [PATCH 009/108] libcli:smb: Add smb_signing_setting_translate() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- libcli/smb/smb_util.h | 7 ++++ libcli/smb/test_util_translate.c | 64 ++++++++++++++++++++++++++++++++ libcli/smb/util.c | 20 ++++++++++ libcli/smb/wscript | 5 +++ selftest/tests.py | 2 + 5 files changed, 98 insertions(+) create mode 100644 libcli/smb/test_util_translate.c diff --git a/libcli/smb/smb_util.h b/libcli/smb/smb_util.h index 8861741c92f..15bdbe856d1 100644 --- a/libcli/smb/smb_util.h +++ b/libcli/smb/smb_util.h @@ -24,6 +24,9 @@ #include "smb_constants.h" #include +#ifndef _SMB_UTIL_H +#define _SMB_UTIL_H + const char *smb_protocol_types_string(enum protocol_types protocol); char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib); uint32_t unix_perms_to_wire(mode_t perms); @@ -46,3 +49,7 @@ NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2, const uint8_t *buf, size_t buf_len, const uint8_t *position, size_t *_consumed); + +enum smb_signing_setting smb_signing_setting_translate(const char *str); + +#endif /* _SMB_UTIL_H */ diff --git a/libcli/smb/test_util_translate.c b/libcli/smb/test_util_translate.c new file mode 100644 index 00000000000..4b81984affa --- /dev/null +++ b/libcli/smb/test_util_translate.c @@ -0,0 +1,64 @@ +/* + * Unix SMB/CIFS implementation. + * + * Copyright (C) 2020 Andreas Schneider + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "lib/replace/replace.h" +#include + +#include "libcli/smb/util.c" + +static void test_smb_signing_setting_translate(void **state) +{ + enum smb_signing_setting signing_state; + + signing_state = smb_signing_setting_translate("wurst"); + assert_int_equal(signing_state, SMB_SIGNING_REQUIRED); + + signing_state = smb_signing_setting_translate("off"); + assert_int_equal(signing_state, SMB_SIGNING_OFF); + + signing_state = smb_signing_setting_translate("if_required"); + assert_int_equal(signing_state, SMB_SIGNING_IF_REQUIRED); + + signing_state = smb_signing_setting_translate("mandatory"); + assert_int_equal(signing_state, SMB_SIGNING_REQUIRED); + +} + +int main(int argc, char *argv[]) +{ + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(test_smb_signing_setting_translate), + }; + + if (argc == 2) { + cmocka_set_test_filter(argv[1]); + } + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); + + rc = cmocka_run_group_tests(tests, NULL, NULL); + + return rc; +} diff --git a/libcli/smb/util.c b/libcli/smb/util.c index 6fdf35fbbf3..da0e4db2bf3 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/smb/smb_common.h" #include "system/filesys.h" +#include "lib/param/loadparm.h" const char *smb_protocol_types_string(enum protocol_types protocol) { @@ -428,3 +429,22 @@ NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2, return internal_bytes_pull_str(mem_ctx, _str, ucs2, true, buf, buf_len, position, _consumed); } + +/** + * @brief Translate SMB signing settings as string to an enum. + * + * @param[in] str The string to translate. + * + * @return A corresponding enum @smb_signing_setting tranlated from the string. + */ +enum smb_signing_setting smb_signing_setting_translate(const char *str) +{ + enum smb_signing_setting signing_state = SMB_SIGNING_REQUIRED; + int32_t val = lpcfg_parse_enum_vals("client signing", str); + + if (val != INT32_MIN) { + signing_state = val; + } + + return signing_state; +} diff --git a/libcli/smb/wscript b/libcli/smb/wscript index 86e377f570b..c047fd33278 100644 --- a/libcli/smb/wscript +++ b/libcli/smb/wscript @@ -72,3 +72,8 @@ def build(bld): source='test_smb1cli_session.c', deps='cmocka cli_smb_common', for_selftest=True) + + bld.SAMBA_BINARY('test_util_translate', + source='test_util_translate.c', + deps='cmocka cli_smb_common', + for_selftest=True) diff --git a/selftest/tests.py b/selftest/tests.py index 6918e1306c3..20981754db4 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -376,6 +376,8 @@ plantestsuite("samba.unittests.lib_util_modules", "none", plantestsuite("samba.unittests.smb1cli_session", "none", [os.path.join(bindir(), "default/libcli/smb/test_smb1cli_session")]) +plantestsuite("samba.unittests.smb_util_translate", "none", + [os.path.join(bindir(), "default/libcli/smb/test_util_translate")]) plantestsuite("samba.unittests.talloc_keep_secret", "none", [os.path.join(bindir(), "default/lib/util/test_talloc_keep_secret")]) -- 2.29.2 From 523033ebfca0154cf13fe79796a879797bf61c66 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 26 May 2020 08:39:34 +0200 Subject: [PATCH 010/108] libcli:smb: Add smb_encryption_setting_translate() Add encryption enum and function to avoid confusion when reading the code. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- libcli/smb/smb_util.h | 1 + libcli/smb/test_util_translate.c | 19 +++++++++++++++++++ libcli/smb/util.c | 20 ++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/libcli/smb/smb_util.h b/libcli/smb/smb_util.h index 15bdbe856d1..2a727db8b6f 100644 --- a/libcli/smb/smb_util.h +++ b/libcli/smb/smb_util.h @@ -51,5 +51,6 @@ NTSTATUS smb_bytes_pull_str(TALLOC_CTX *mem_ctx, char **_str, bool ucs2, size_t *_consumed); enum smb_signing_setting smb_signing_setting_translate(const char *str); +enum smb_encryption_setting smb_encryption_setting_translate(const char *str); #endif /* _SMB_UTIL_H */ diff --git a/libcli/smb/test_util_translate.c b/libcli/smb/test_util_translate.c index 4b81984affa..b300af52c09 100644 --- a/libcli/smb/test_util_translate.c +++ b/libcli/smb/test_util_translate.c @@ -46,11 +46,30 @@ static void test_smb_signing_setting_translate(void **state) } +static void test_smb_encryption_setting_translate(void **state) +{ + enum smb_encryption_setting encryption_state; + + encryption_state = smb_encryption_setting_translate("wurst"); + assert_int_equal(encryption_state, SMB_ENCRYPTION_REQUIRED); + + encryption_state = smb_encryption_setting_translate("off"); + assert_int_equal(encryption_state, SMB_ENCRYPTION_OFF); + + encryption_state = smb_encryption_setting_translate("if_required"); + assert_int_equal(encryption_state, SMB_ENCRYPTION_IF_REQUIRED); + + encryption_state = smb_encryption_setting_translate("mandatory"); + assert_int_equal(encryption_state, SMB_ENCRYPTION_REQUIRED); + +} + int main(int argc, char *argv[]) { int rc; const struct CMUnitTest tests[] = { cmocka_unit_test(test_smb_signing_setting_translate), + cmocka_unit_test(test_smb_encryption_setting_translate), }; if (argc == 2) { diff --git a/libcli/smb/util.c b/libcli/smb/util.c index da0e4db2bf3..ac2887ee5c4 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -448,3 +448,23 @@ enum smb_signing_setting smb_signing_setting_translate(const char *str) return signing_state; } + +/** + * @brief Translate SMB encryption settings as string to an enum. + * + * @param[in] str The string to translate. + * + * @return A corresponding enum @smb_encryption_setting tranlated from the + * string. + */ +enum smb_encryption_setting smb_encryption_setting_translate(const char *str) +{ + enum smb_encryption_setting encryption_state = SMB_ENCRYPTION_REQUIRED; + int32_t val = lpcfg_parse_enum_vals("client smb encrypt", str); + + if (val != INT32_MIN) { + encryption_state = val; + } + + return encryption_state; +} -- 2.29.2 From b6f83efae214538df1965df7d2577c5ebd2926a3 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 9 Oct 2019 09:47:59 +0200 Subject: [PATCH 011/108] s3:lib: Use smb_signing_setting_translate for cmdline parsing The function will be removed soon. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/lib/util_cmdline.c | 17 +++-------------- source3/wscript_build | 2 +- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c index 90ee67c4cb7..bc1f1c3ed25 100644 --- a/source3/lib/util_cmdline.c +++ b/source3/lib/util_cmdline.c @@ -28,6 +28,7 @@ #include "librpc/gen_ndr/samr.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" +#include "libcli/smb/smb_util.h" /**************************************************************************n Code to cope with username/password auth options from the commandline. @@ -240,20 +241,8 @@ void set_cmdline_auth_info_password(struct user_auth_info *auth_info, bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info, const char *arg) { - auth_info->signing_state = SMB_SIGNING_DEFAULT; - if (strequal(arg, "off") || strequal(arg, "no") || - strequal(arg, "false")) { - auth_info->signing_state = SMB_SIGNING_OFF; - } else if (strequal(arg, "on") || strequal(arg, "yes") || - strequal(arg, "if_required") || - strequal(arg, "true") || strequal(arg, "auto")) { - auth_info->signing_state = SMB_SIGNING_IF_REQUIRED; - } else if (strequal(arg, "force") || strequal(arg, "required") || - strequal(arg, "forced")) { - auth_info->signing_state = SMB_SIGNING_REQUIRED; - } else { - return false; - } + auth_info->signing_state = smb_signing_setting_translate(arg); + return true; } diff --git a/source3/wscript_build b/source3/wscript_build index 5a07eddac44..6a08afe4a25 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -279,7 +279,7 @@ bld.SAMBA3_LIBRARY('popt_samba3_cmdline', bld.SAMBA3_LIBRARY('util_cmdline', source='lib/util_cmdline.c', - deps='secrets3 samba-credentials', + deps='secrets3 samba-credentials cli_smb_common', private_library=True) bld.SAMBA3_LIBRARY('cmdline_contexts', -- 2.29.2 From f7f4411902cdbfec5358339f4279cca44a9fb181 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 23 Jul 2020 07:47:18 +0200 Subject: [PATCH 012/108] auth:creds: Remove unused credentials autoproto header Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/credentials_krb5.c | 1 - auth/credentials/credentials_secrets.c | 1 - auth/credentials/wscript_build | 1 - source4/auth/kerberos/kerberos_util.c | 1 - source4/auth/tests/kerberos.c | 1 - 5 files changed, 5 deletions(-) diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 20e677e521a..259b35b73b0 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -27,7 +27,6 @@ #include "auth/kerberos/kerberos.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_internal.h" -#include "auth/credentials/credentials_proto.h" #include "auth/credentials/credentials_krb5.h" #include "auth/kerberos/kerberos_credentials.h" #include "auth/kerberos/kerberos_srv_keytab.h" diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c index 54f3ce2d078..52a89d4d5b4 100644 --- a/auth/credentials/credentials_secrets.c +++ b/auth/credentials/credentials_secrets.c @@ -29,7 +29,6 @@ #include "system/filesys.h" #include "auth/credentials/credentials.h" #include "auth/credentials/credentials_internal.h" -#include "auth/credentials/credentials_proto.h" #include "auth/credentials/credentials_krb5.h" #include "auth/kerberos/kerberos_util.h" #include "param/param.h" diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build index f5aba1de248..564a04fe8dd 100644 --- a/auth/credentials/wscript_build +++ b/auth/credentials/wscript_build @@ -2,7 +2,6 @@ bld.SAMBA_LIBRARY('samba-credentials', source='credentials.c', - autoproto='credentials_proto.h', public_headers='credentials.h', pc_files='samba-credentials.pc', deps='LIBCRYPTO samba-errors events LIBCLI_AUTH samba-security CREDENTIALS_SECRETS CREDENTIALS_KRB5', diff --git a/source4/auth/kerberos/kerberos_util.c b/source4/auth/kerberos/kerberos_util.c index ffef24f285c..544d9d853cc 100644 --- a/source4/auth/kerberos/kerberos_util.c +++ b/source4/auth/kerberos/kerberos_util.c @@ -24,7 +24,6 @@ #include "system/kerberos.h" #include "auth/kerberos/kerberos.h" #include "auth/credentials/credentials.h" -#include "auth/credentials/credentials_proto.h" #include "auth/credentials/credentials_krb5.h" #include "auth/kerberos/kerberos_credentials.h" #include "auth/kerberos/kerberos_util.h" diff --git a/source4/auth/tests/kerberos.c b/source4/auth/tests/kerberos.c index 7711eac2afa..d9be3562adb 100644 --- a/source4/auth/tests/kerberos.c +++ b/source4/auth/tests/kerberos.c @@ -10,7 +10,6 @@ #include "system/kerberos.h" #include "auth/kerberos/kerberos.h" #include "auth/credentials/credentials.h" -#include "auth/credentials/credentials_proto.h" #include "auth/credentials/credentials_krb5.h" #include "auth/kerberos/kerberos_credentials.h" #include "auth/kerberos/kerberos_util.h" -- 2.29.2 From ae65707b4b6f0bb640ac6e9f5899d5908b6f5ee4 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 26 May 2020 09:32:44 +0200 Subject: [PATCH 013/108] auth:creds: Add cli_credentials_(get|set)_smb_signing() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/credentials.c | 45 +++++++++++++++++++++++++ auth/credentials/credentials.h | 7 ++++ auth/credentials/credentials_internal.h | 4 +++ 3 files changed, 56 insertions(+) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index 80a31b248ae..365a6def7ea 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -44,6 +44,8 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->winbind_separator = '\\'; + cred->signing_state = SMB_SIGNING_DEFAULT; + return cred; } @@ -922,6 +924,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, if (sep != NULL && sep[0] != '\0') { cred->winbind_separator = *lpcfg_winbind_separator(lp_ctx); } + + if (cred->signing_state_obtained <= CRED_SMB_CONF) { + /* Will be set to default for invalid smb.conf values */ + cred->signing_state = lpcfg_client_signing(lp_ctx); + cred->signing_state_obtained = CRED_SMB_CONF; + } } /** @@ -1304,6 +1312,43 @@ _PUBLIC_ bool cli_credentials_parse_password_fd(struct cli_credentials *credenti return true; } +/** + * @brief Set the SMB signing state to request for a SMB connection. + * + * @param[in] creds The credentials structure to update. + * + * @param[in] signing_state The signing state to set. + * + * @param obtained This way the described signing state was specified. + * + * @return true if we could set the signing state, false otherwise. + */ +_PUBLIC_ bool cli_credentials_set_smb_signing(struct cli_credentials *creds, + enum smb_signing_setting signing_state, + enum credentials_obtained obtained) +{ + if (obtained >= creds->signing_state_obtained) { + creds->signing_state_obtained = obtained; + creds->signing_state = signing_state; + return true; + } + + return false; +} + +/** + * @brief Obtain the SMB signing state from a credentials structure. + * + * @param[in] creds The credential structure to obtain the SMB signing state + * from. + * + * @return The SMB singing state. + */ +_PUBLIC_ enum smb_signing_setting +cli_credentials_get_smb_signing(struct cli_credentials *creds) +{ + return creds->signing_state; +} /** * Encrypt a data blob using the session key and the negotiated encryption diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 7154c2a008c..422391ad585 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -38,6 +38,7 @@ struct gssapi_creds_container; struct smb_krb5_context; struct keytab_container; struct db_context; +enum smb_signing_setting; /* In order of priority */ enum credentials_obtained { @@ -290,6 +291,12 @@ void *_cli_credentials_callback_data(struct cli_credentials *cred); #define cli_credentials_callback_data_void(_cred) \ _cli_credentials_callback_data(_cred) +bool cli_credentials_set_smb_signing(struct cli_credentials *cred, + enum smb_signing_setting signing_state, + enum credentials_obtained obtained); +enum smb_signing_setting +cli_credentials_get_smb_signing(struct cli_credentials *cred); + /** * Return attached NETLOGON credentials */ diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index 68f1f25dce1..9cde0000b5f 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -24,6 +24,7 @@ #include "../lib/util/data_blob.h" #include "librpc/gen_ndr/misc.h" +#include "libcli/smb/smb_constants.h" struct cli_credentials { enum credentials_obtained workstation_obtained; @@ -36,6 +37,7 @@ struct cli_credentials { enum credentials_obtained principal_obtained; enum credentials_obtained keytab_obtained; enum credentials_obtained server_gss_creds_obtained; + enum credentials_obtained signing_state_obtained; /* Threshold values (essentially a MAX() over a number of the * above) for the ccache and GSS credentials, to ensure we @@ -117,6 +119,8 @@ struct cli_credentials { char winbind_separator; bool password_will_be_nt_hash; + + enum smb_signing_setting signing_state; }; #endif /* __CREDENTIALS_INTERNAL_H__ */ -- 2.29.2 From 7408b2af20c3d3b3bf1a59850e9f4659d9379eed Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 3 Jun 2020 11:56:01 +0200 Subject: [PATCH 014/108] auth:creds: Add python bindings for (get|set)_smb_signing Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/pycredentials.c | 63 +++++++++++++++++++++++++++++++ python/samba/tests/credentials.py | 6 +++ 2 files changed, 69 insertions(+) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 68edc282741..846c418419f 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -34,6 +34,7 @@ #include "auth/credentials/credentials_internal.h" #include "system/kerberos.h" #include "auth/kerberos/kerberos.h" +#include "libcli/smb/smb_constants.h" void initcredentials(void); @@ -929,6 +930,52 @@ static PyObject *py_creds_encrypt_netr_crypt_password(PyObject *self, Py_RETURN_NONE; } +static PyObject *py_creds_get_smb_signing(PyObject *self, PyObject *unused) +{ + enum smb_signing_setting signing_state; + struct cli_credentials *creds = NULL; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + + signing_state = cli_credentials_get_smb_signing(creds); + return PyLong_FromLong(signing_state); +} + +static PyObject *py_creds_set_smb_signing(PyObject *self, PyObject *args) +{ + enum smb_signing_setting signing_state; + struct cli_credentials *creds = NULL; + enum credentials_obtained obt = CRED_SPECIFIED; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) { + return NULL; + } + + switch (signing_state) { + case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_OFF: + case SMB_SIGNING_IF_REQUIRED: + case SMB_SIGNING_DESIRED: + case SMB_SIGNING_REQUIRED: + break; + default: + PyErr_Format(PyExc_TypeError, "Invalid signing state value"); + return NULL; + } + + cli_credentials_set_smb_signing(creds, signing_state, obt); + Py_RETURN_NONE; +} + static PyMethodDef py_creds_methods[] = { { .ml_name = "get_username", @@ -1209,6 +1256,16 @@ static PyMethodDef py_creds_methods[] = { "Encrypt the supplied password using the session key and\n" "the negotiated encryption algorithm in place\n" "i.e. it overwrites the original data"}, + { + .ml_name = "get_smb_signing", + .ml_meth = py_creds_get_smb_signing, + .ml_flags = METH_NOARGS, + }, + { + .ml_name = "set_smb_signing", + .ml_meth = py_creds_set_smb_signing, + .ml_flags = METH_VARARGS, + }, { .ml_name = NULL } }; @@ -1295,6 +1352,12 @@ MODULE_INIT_FUNC(credentials) PyModule_AddObject(m, "CLI_CRED_NTLM_AUTH", PyLong_FromLong(CLI_CRED_NTLM_AUTH)); PyModule_AddObject(m, "CLI_CRED_CLEAR_AUTH", PyLong_FromLong(CLI_CRED_CLEAR_AUTH)); + PyModule_AddObject(m, "SMB_SIGNING_DEFAULT", PyLong_FromLong(SMB_SIGNING_DEFAULT)); + PyModule_AddObject(m, "SMB_SIGNING_OFF", PyLong_FromLong(SMB_SIGNING_OFF)); + PyModule_AddObject(m, "SMB_SIGNING_IF_REQUIRED", PyLong_FromLong(SMB_SIGNING_IF_REQUIRED)); + PyModule_AddObject(m, "SMB_SIGNING_DESIRED", PyLong_FromLong(SMB_SIGNING_DESIRED)); + PyModule_AddObject(m, "SMB_SIGNING_REQUIRED", PyLong_FromLong(SMB_SIGNING_REQUIRED)); + Py_INCREF(&PyCredentials); PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials); Py_INCREF(&PyCredentialCacheContainer); diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index 6454ac9ff7c..e5f8122fa21 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -456,3 +456,9 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_principal(), "user@samba.org") self.assertEqual(creds.is_anonymous(), False) self.assertEqual(creds.authentication_requested(), True) + + def test_smb_signing(self): + creds = credentials.Credentials() + self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_DEFAULT) + creds.set_smb_signing(credentials.SMB_SIGNING_REQUIRED) + self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_REQUIRED) -- 2.29.2 From b5753b24a1a8897c55189869c623977bb78430b0 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 16:31:35 +0200 Subject: [PATCH 015/108] auth:creds: Add cli_credentials_(get|set)_smb_ipc_signing() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/credentials.c | 51 +++++++++++++++++++++++++ auth/credentials/credentials.h | 6 +++ auth/credentials/credentials_internal.h | 3 ++ 3 files changed, 60 insertions(+) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index 365a6def7ea..dc5d51f1424 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -46,6 +46,12 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->signing_state = SMB_SIGNING_DEFAULT; + /* + * The default value of lpcfg_client_ipc_signing() is REQUIRED, so use + * the same value here. + */ + cred->ipc_signing_state = SMB_SIGNING_REQUIRED; + return cred; } @@ -930,6 +936,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, cred->signing_state = lpcfg_client_signing(lp_ctx); cred->signing_state_obtained = CRED_SMB_CONF; } + + if (cred->ipc_signing_state_obtained <= CRED_SMB_CONF) { + /* Will be set to required for invalid smb.conf values */ + cred->ipc_signing_state = lpcfg_client_ipc_signing(lp_ctx); + cred->ipc_signing_state_obtained = CRED_SMB_CONF; + } } /** @@ -1350,6 +1362,45 @@ cli_credentials_get_smb_signing(struct cli_credentials *creds) return creds->signing_state; } +/** + * @brief Set the SMB IPC signing state to request for a SMB connection. + * + * @param[in] creds The credentials structure to update. + * + * @param[in] signing_state The signing state to set. + * + * @param obtained This way the described signing state was specified. + * + * @return true if we could set the signing state, false otherwise. + */ +_PUBLIC_ bool +cli_credentials_set_smb_ipc_signing(struct cli_credentials *creds, + enum smb_signing_setting ipc_signing_state, + enum credentials_obtained obtained) +{ + if (obtained >= creds->ipc_signing_state_obtained) { + creds->ipc_signing_state_obtained = obtained; + creds->ipc_signing_state = ipc_signing_state; + return true; + } + + return false; +} + +/** + * @brief Obtain the SMB IPC signing state from a credentials structure. + * + * @param[in] creds The credential structure to obtain the SMB IPC signing + * state from. + * + * @return The SMB singing state. + */ +_PUBLIC_ enum smb_signing_setting +cli_credentials_get_smb_ipc_signing(struct cli_credentials *creds) +{ + return creds->ipc_signing_state; +} + /** * Encrypt a data blob using the session key and the negotiated encryption * algorithm diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 422391ad585..25bec916278 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -297,6 +297,12 @@ bool cli_credentials_set_smb_signing(struct cli_credentials *cred, enum smb_signing_setting cli_credentials_get_smb_signing(struct cli_credentials *cred); +bool cli_credentials_set_smb_ipc_signing(struct cli_credentials *cred, + enum smb_signing_setting ipc_signing_state, + enum credentials_obtained obtained); +enum smb_signing_setting +cli_credentials_get_smb_ipc_signing(struct cli_credentials *cred); + /** * Return attached NETLOGON credentials */ diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index 9cde0000b5f..54e8271471f 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -38,6 +38,7 @@ struct cli_credentials { enum credentials_obtained keytab_obtained; enum credentials_obtained server_gss_creds_obtained; enum credentials_obtained signing_state_obtained; + enum credentials_obtained ipc_signing_state_obtained; /* Threshold values (essentially a MAX() over a number of the * above) for the ccache and GSS credentials, to ensure we @@ -121,6 +122,8 @@ struct cli_credentials { bool password_will_be_nt_hash; enum smb_signing_setting signing_state; + + enum smb_signing_setting ipc_signing_state; }; #endif /* __CREDENTIALS_INTERNAL_H__ */ -- 2.29.2 From 1e7031e438992e37cb9324250d21e82c5f5324c6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 3 Jun 2020 12:32:46 +0200 Subject: [PATCH 016/108] auth:creds: Add python bindings for (get|set)_smb_ipc_signing Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/pycredentials.c | 56 +++++++++++++++++++++++++++++++ python/samba/tests/credentials.py | 6 ++++ 2 files changed, 62 insertions(+) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 846c418419f..1a83c506088 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -976,6 +976,52 @@ static PyObject *py_creds_set_smb_signing(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *py_creds_get_smb_ipc_signing(PyObject *self, PyObject *unused) +{ + enum smb_signing_setting signing_state; + struct cli_credentials *creds = NULL; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + + signing_state = cli_credentials_get_smb_ipc_signing(creds); + return PyLong_FromLong(signing_state); +} + +static PyObject *py_creds_set_smb_ipc_signing(PyObject *self, PyObject *args) +{ + enum smb_signing_setting signing_state; + struct cli_credentials *creds = NULL; + enum credentials_obtained obt = CRED_SPECIFIED; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + if (!PyArg_ParseTuple(args, "i|i", &signing_state, &obt)) { + return NULL; + } + + switch (signing_state) { + case SMB_SIGNING_DEFAULT: + case SMB_SIGNING_OFF: + case SMB_SIGNING_IF_REQUIRED: + case SMB_SIGNING_DESIRED: + case SMB_SIGNING_REQUIRED: + break; + default: + PyErr_Format(PyExc_TypeError, "Invalid signing state value"); + return NULL; + } + + cli_credentials_set_smb_ipc_signing(creds, signing_state, obt); + Py_RETURN_NONE; +} + static PyMethodDef py_creds_methods[] = { { .ml_name = "get_username", @@ -1266,6 +1312,16 @@ static PyMethodDef py_creds_methods[] = { .ml_meth = py_creds_set_smb_signing, .ml_flags = METH_VARARGS, }, + { + .ml_name = "get_smb_ipc_signing", + .ml_meth = py_creds_get_smb_ipc_signing, + .ml_flags = METH_NOARGS, + }, + { + .ml_name = "set_smb_ipc_signing", + .ml_meth = py_creds_set_smb_ipc_signing, + .ml_flags = METH_VARARGS, + }, { .ml_name = NULL } }; diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index e5f8122fa21..8edf13ce6ff 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -462,3 +462,9 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_DEFAULT) creds.set_smb_signing(credentials.SMB_SIGNING_REQUIRED) self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_REQUIRED) + + def test_smb_ipc_signing(self): + creds = credentials.Credentials() + self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED) + creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF) + self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF) -- 2.29.2 From 8843b4072f5f1d27dea9742518cedbad543e137a Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 16:10:52 +0200 Subject: [PATCH 017/108] auth:creds: Add cli_credentials_(get|set)_smb_encryption() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/credentials.c | 45 +++++++++++++++++++++++++ auth/credentials/credentials.h | 7 ++++ auth/credentials/credentials_internal.h | 3 ++ 3 files changed, 55 insertions(+) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index dc5d51f1424..9168b92d3ec 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -51,6 +51,7 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) * the same value here. */ cred->ipc_signing_state = SMB_SIGNING_REQUIRED; + cred->encryption_state = SMB_ENCRYPTION_DEFAULT; return cred; } @@ -942,6 +943,12 @@ _PUBLIC_ void cli_credentials_set_conf(struct cli_credentials *cred, cred->ipc_signing_state = lpcfg_client_ipc_signing(lp_ctx); cred->ipc_signing_state_obtained = CRED_SMB_CONF; } + + if (cred->encryption_state_obtained <= CRED_SMB_CONF) { + /* Will be set to default for invalid smb.conf values */ + cred->encryption_state = lpcfg_client_smb_encrypt(lp_ctx); + cred->encryption_state_obtained = CRED_SMB_CONF; + } } /** @@ -1401,6 +1408,44 @@ cli_credentials_get_smb_ipc_signing(struct cli_credentials *creds) return creds->ipc_signing_state; } +/** + * @brief Set the SMB encryption state to request for a SMB connection. + * + * @param[in] creds The credentials structure to update. + * + * @param[in] encryption_state The encryption state to set. + * + * @param obtained This way the described encryption state was specified. + * + * @return true if we could set the encryption state, false otherwise. + */ +_PUBLIC_ bool cli_credentials_set_smb_encryption(struct cli_credentials *creds, + enum smb_encryption_setting encryption_state, + enum credentials_obtained obtained) +{ + if (obtained >= creds->encryption_state_obtained) { + creds->encryption_state_obtained = obtained; + creds->encryption_state = encryption_state; + return true; + } + + return false; +} + +/** + * @brief Obtain the SMB encryption state from a credentials structure. + * + * @param[in] creds The credential structure to obtain the SMB encryption state + * from. + * + * @return The SMB singing state. + */ +_PUBLIC_ enum smb_encryption_setting +cli_credentials_get_smb_encryption(struct cli_credentials *creds) +{ + return creds->encryption_state; +} + /** * Encrypt a data blob using the session key and the negotiated encryption * algorithm diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 25bec916278..7d0cf53194b 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -39,6 +39,7 @@ struct smb_krb5_context; struct keytab_container; struct db_context; enum smb_signing_setting; +enum smb_encryption_setting; /* In order of priority */ enum credentials_obtained { @@ -303,6 +304,12 @@ bool cli_credentials_set_smb_ipc_signing(struct cli_credentials *cred, enum smb_signing_setting cli_credentials_get_smb_ipc_signing(struct cli_credentials *cred); +bool cli_credentials_set_smb_encryption(struct cli_credentials *cred, + enum smb_encryption_setting encryption_state, + enum credentials_obtained obtained); +enum smb_encryption_setting +cli_credentials_get_smb_encryption(struct cli_credentials *cred); + /** * Return attached NETLOGON credentials */ diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index 54e8271471f..3b86b742448 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -39,6 +39,7 @@ struct cli_credentials { enum credentials_obtained server_gss_creds_obtained; enum credentials_obtained signing_state_obtained; enum credentials_obtained ipc_signing_state_obtained; + enum credentials_obtained encryption_state_obtained; /* Threshold values (essentially a MAX() over a number of the * above) for the ccache and GSS credentials, to ensure we @@ -124,6 +125,8 @@ struct cli_credentials { enum smb_signing_setting signing_state; enum smb_signing_setting ipc_signing_state; + + enum smb_encryption_setting encryption_state; }; #endif /* __CREDENTIALS_INTERNAL_H__ */ -- 2.29.2 From fa8fb414c21d7c823eb35130ecf05bd13cec3370 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 3 Jun 2020 12:38:30 +0200 Subject: [PATCH 018/108] auth:creds: Add python bindings for (get|set)_smb_encryption Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/pycredentials.c | 62 +++++++++++++++++++++++++++++++ python/samba/tests/credentials.py | 6 +++ 2 files changed, 68 insertions(+) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 1a83c506088..628aae6500b 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -1022,6 +1022,52 @@ static PyObject *py_creds_set_smb_ipc_signing(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *py_creds_get_smb_encryption(PyObject *self, PyObject *unused) +{ + enum smb_encryption_setting encryption_state; + struct cli_credentials *creds = NULL; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + + encryption_state = cli_credentials_get_smb_encryption(creds); + return PyLong_FromLong(encryption_state); +} + +static PyObject *py_creds_set_smb_encryption(PyObject *self, PyObject *args) +{ + enum smb_encryption_setting encryption_state; + struct cli_credentials *creds = NULL; + enum credentials_obtained obt = CRED_SPECIFIED; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + if (!PyArg_ParseTuple(args, "i|i", &encryption_state, &obt)) { + return NULL; + } + + switch (encryption_state) { + case SMB_ENCRYPTION_DEFAULT: + case SMB_ENCRYPTION_OFF: + case SMB_ENCRYPTION_IF_REQUIRED: + case SMB_ENCRYPTION_DESIRED: + case SMB_ENCRYPTION_REQUIRED: + break; + default: + PyErr_Format(PyExc_TypeError, "Invalid encryption state value"); + return NULL; + } + + cli_credentials_set_smb_encryption(creds, encryption_state, obt); + Py_RETURN_NONE; +} + static PyMethodDef py_creds_methods[] = { { .ml_name = "get_username", @@ -1322,6 +1368,16 @@ static PyMethodDef py_creds_methods[] = { .ml_meth = py_creds_set_smb_ipc_signing, .ml_flags = METH_VARARGS, }, + { + .ml_name = "get_smb_encryption", + .ml_meth = py_creds_get_smb_encryption, + .ml_flags = METH_NOARGS, + }, + { + .ml_name = "set_smb_encryption", + .ml_meth = py_creds_set_smb_encryption, + .ml_flags = METH_VARARGS, + }, { .ml_name = NULL } }; @@ -1414,6 +1470,12 @@ MODULE_INIT_FUNC(credentials) PyModule_AddObject(m, "SMB_SIGNING_DESIRED", PyLong_FromLong(SMB_SIGNING_DESIRED)); PyModule_AddObject(m, "SMB_SIGNING_REQUIRED", PyLong_FromLong(SMB_SIGNING_REQUIRED)); + PyModule_AddObject(m, "SMB_ENCRYPTION_DEFAULT", PyLong_FromLong(SMB_ENCRYPTION_DEFAULT)); + PyModule_AddObject(m, "SMB_ENCRYPTION_OFF", PyLong_FromLong(SMB_ENCRYPTION_OFF)); + PyModule_AddObject(m, "SMB_ENCRYPTION_IF_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_IF_REQUIRED)); + PyModule_AddObject(m, "SMB_ENCRYPTION_DESIRED", PyLong_FromLong(SMB_ENCRYPTION_DESIRED)); + PyModule_AddObject(m, "SMB_ENCRYPTION_REQUIRED", PyLong_FromLong(SMB_ENCRYPTION_REQUIRED)); + Py_INCREF(&PyCredentials); PyModule_AddObject(m, "Credentials", (PyObject *)&PyCredentials); Py_INCREF(&PyCredentialCacheContainer); diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index 8edf13ce6ff..e0a6248d37a 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -468,3 +468,9 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED) creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF) self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF) + + def test_smb_encryption(self): + creds = credentials.Credentials() + self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_DEFAULT) + creds.set_smb_encryption(credentials.SMB_ENCRYPTION_REQUIRED) + self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_REQUIRED) -- 2.29.2 From 9029cd9abb9bbd668f6616821a99e79f31617ccf Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 4 Jun 2020 11:19:53 +0200 Subject: [PATCH 019/108] auth:creds: Add python bindings for cli_credentials_set_conf() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/pycredentials.c | 41 +++++++++++++++++++++++++++++++ python/samba/tests/credentials.py | 33 +++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 628aae6500b..17c90573f09 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -621,6 +621,42 @@ static PyObject *py_creds_set_forced_sasl_mech(PyObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *py_creds_set_conf(PyObject *self, PyObject *args) +{ + PyObject *py_lp_ctx = Py_None; + struct loadparm_context *lp_ctx; + TALLOC_CTX *mem_ctx; + struct cli_credentials *creds; + + creds = PyCredentials_AsCliCredentials(self); + if (creds == NULL) { + PyErr_Format(PyExc_TypeError, "Credentials expected"); + return NULL; + } + + if (!PyArg_ParseTuple(args, "|O", &py_lp_ctx)) { + return NULL; + } + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + lp_ctx = lpcfg_from_py_object(mem_ctx, py_lp_ctx); + if (lp_ctx == NULL) { + talloc_free(mem_ctx); + return NULL; + } + + cli_credentials_set_conf(creds, lp_ctx); + + talloc_free(mem_ctx); + + Py_RETURN_NONE; +} + static PyObject *py_creds_guess(PyObject *self, PyObject *args) { PyObject *py_lp_ctx = Py_None; @@ -1279,6 +1315,11 @@ static PyMethodDef py_creds_methods[] = { .ml_meth = py_creds_set_krb_forwardable, .ml_flags = METH_VARARGS, }, + { + .ml_name = "set_conf", + .ml_meth = py_creds_set_conf, + .ml_flags = METH_VARARGS, + }, { .ml_name = "guess", .ml_meth = py_creds_guess, diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index e0a6248d37a..6187bded0b6 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -463,14 +463,47 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): creds.set_smb_signing(credentials.SMB_SIGNING_REQUIRED) self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_REQUIRED) + def test_smb_signing_set_conf(self): + lp = samba.tests.env_loadparm() + + creds = credentials.Credentials() + creds.set_conf(lp) + self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_DEFAULT) + creds.set_smb_signing(credentials.SMB_SIGNING_OFF) + self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_OFF) + creds.set_conf(lp) + self.assertEqual(creds.get_smb_signing(), credentials.SMB_SIGNING_OFF) + def test_smb_ipc_signing(self): creds = credentials.Credentials() self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED) creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF) self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF) + def test_smb_ipc_signing_set_conf(self): + lp = samba.tests.env_loadparm() + + creds = credentials.Credentials() + creds.set_conf(lp) + self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_REQUIRED) + creds.set_smb_ipc_signing(credentials.SMB_SIGNING_OFF) + self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF) + creds.set_conf(lp) + self.assertEqual(creds.get_smb_ipc_signing(), credentials.SMB_SIGNING_OFF) + def test_smb_encryption(self): creds = credentials.Credentials() self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_DEFAULT) creds.set_smb_encryption(credentials.SMB_ENCRYPTION_REQUIRED) self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_REQUIRED) + + def test_smb_encryption_set_conf(self): + lp = samba.tests.env_loadparm() + + creds = credentials.Credentials() + creds.set_conf(lp) + self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_DEFAULT) + creds.set_smb_encryption(credentials.SMB_ENCRYPTION_OFF) + self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_OFF) + creds.set_conf(lp) + self.assertEqual(creds.get_smb_encryption(), credentials.SMB_ENCRYPTION_OFF) -- 2.29.2 From 3567e45ea254c8b8fd171174833e9a153f88a2ca Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 23 Jul 2020 08:14:23 +0200 Subject: [PATCH 020/108] auth:creds: Bump library version We added new functions so bump the version. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- auth/credentials/wscript_build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build index 564a04fe8dd..1e3302e3e48 100644 --- a/auth/credentials/wscript_build +++ b/auth/credentials/wscript_build @@ -5,7 +5,7 @@ bld.SAMBA_LIBRARY('samba-credentials', public_headers='credentials.h', pc_files='samba-credentials.pc', deps='LIBCRYPTO samba-errors events LIBCLI_AUTH samba-security CREDENTIALS_SECRETS CREDENTIALS_KRB5', - vnum='0.0.1' + vnum='0.1.0' ) bld.SAMBA_SUBSYSTEM('CREDENTIALS_KRB5', -- 2.29.2 From e4b2962b34affec4cb9a4367faea53fe27c494e7 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 27 May 2020 11:10:30 +0200 Subject: [PATCH 021/108] s3:lib: Use cli_credential_(get|set)_smb_signing() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/lib/util_cmdline.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c index bc1f1c3ed25..6038ec11515 100644 --- a/source3/lib/util_cmdline.c +++ b/source3/lib/util_cmdline.c @@ -40,7 +40,6 @@ struct user_auth_info { struct loadparm_context *lp_ctx; bool got_username; bool got_pass; - int signing_state; bool smb_encrypt; bool use_machine_account; bool use_pw_nt_hash; @@ -70,7 +69,6 @@ struct user_auth_info *user_auth_info_init(TALLOC_CTX *mem_ctx) cli_credentials_set_conf(result->creds, result->lp_ctx); - result->signing_state = SMB_SIGNING_DEFAULT; return result; } @@ -241,15 +239,23 @@ void set_cmdline_auth_info_password(struct user_auth_info *auth_info, bool set_cmdline_auth_info_signing_state(struct user_auth_info *auth_info, const char *arg) { - auth_info->signing_state = smb_signing_setting_translate(arg); + enum smb_signing_setting signing_state = + smb_signing_setting_translate(arg); + bool ok; - return true; + ok = cli_credentials_set_smb_signing(auth_info->creds, + signing_state, + CRED_SPECIFIED); + + return ok; } void set_cmdline_auth_info_signing_state_raw(struct user_auth_info *auth_info, int signing_state) { - auth_info->signing_state = signing_state; + cli_credentials_set_smb_signing(auth_info->creds, + signing_state, + CRED_SPECIFIED); } int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info) @@ -257,7 +263,7 @@ int get_cmdline_auth_info_signing_state(const struct user_auth_info *auth_info) if (auth_info->smb_encrypt) { return SMB_SIGNING_REQUIRED; } - return auth_info->signing_state; + return cli_credentials_get_smb_signing(auth_info->creds); } void set_cmdline_auth_info_use_ccache(struct user_auth_info *auth_info, bool b) -- 2.29.2 From 1cabf0cd51019ae8d6d37c27b0b5aacc989d5818 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:45:34 +0200 Subject: [PATCH 022/108] s3:lib: Set smb encryption also via cli creds API Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/lib/util_cmdline.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c index 6038ec11515..9c9e2f0ac0f 100644 --- a/source3/lib/util_cmdline.c +++ b/source3/lib/util_cmdline.c @@ -377,6 +377,9 @@ void set_cmdline_auth_info_use_krb5_ticket(struct user_auth_info *auth_info) /* This should only be used by lib/popt_common.c JRA */ void set_cmdline_auth_info_smb_encrypt(struct user_auth_info *auth_info) { + cli_credentials_set_smb_encryption(auth_info->creds, + SMB_ENCRYPTION_REQUIRED, + CRED_SPECIFIED); auth_info->smb_encrypt = true; } -- 2.29.2 From 60af05cd7dd38dbb936df530d9255b7e829f5283 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 13 Aug 2020 10:40:23 +0200 Subject: [PATCH 023/108] python: Remove unused sign argument from smb_connection() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- python/samba/netcmd/gpo.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py index 1e2c2918ebe..ad60cda0690 100644 --- a/python/samba/netcmd/gpo.py +++ b/python/samba/netcmd/gpo.py @@ -382,13 +382,13 @@ def create_directory_hier(conn, remotedir): if not conn.chkpath(path): conn.mkdir(path) -def smb_connection(dc_hostname, service, lp, creds, sign=False): +def smb_connection(dc_hostname, service, lp, creds): # SMB connect to DC try: # the SMB bindings rely on having a s3 loadparm s3_lp = s3param.get_context() s3_lp.load(lp.configfile) - conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=sign) + conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=True) except Exception: raise CommandError("Error connecting to '%s' using SMB" % dc_hostname) return conn @@ -998,7 +998,7 @@ class cmd_fetch(GPOCommand): # SMB connect to DC conn = smb_connection(dc_hostname, service, lp=self.lp, - creds=self.creds, sign=True) + creds=self.creds) # Copy GPT tmpdir, gpodir = self.construct_tmpdir(tmpdir, gpo) @@ -1629,8 +1629,7 @@ class cmd_admxload(Command): conn = smb_connection(dc_hostname, 'sysvol', lp=self.lp, - creds=self.creds, - sign=True) + creds=self.creds) smb_dir = '\\'.join([self.lp.get('realm').lower(), 'Policies', 'PolicyDefinitions']) -- 2.29.2 From 061d5a2ddfe247494ca1bbd601e2eb63d0b26fe8 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 3 Jun 2020 14:02:37 +0200 Subject: [PATCH 024/108] python: Set smb signing via the creds API Pair-Programmed-With: Stefan Metzmacher Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- python/samba/gpclass.py | 7 +++++++ python/samba/netcmd/domain_backup.py | 10 +++++++++- python/samba/netcmd/gpo.py | 6 ++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py index cc574e12a42..1781a55a618 100644 --- a/python/samba/gpclass.py +++ b/python/samba/gpclass.py @@ -38,6 +38,7 @@ from tempfile import NamedTemporaryFile from samba.dcerpc import preg from samba.dcerpc import misc from samba.ndr import ndr_pack, ndr_unpack +from samba.credentials import SMB_SIGNING_REQUIRED try: from enum import Enum @@ -421,7 +422,13 @@ def check_refresh_gpo_list(dc_hostname, lp, creds, gpos): # the SMB bindings rely on having a s3 loadparm s3_lp = s3param.get_context() s3_lp.load(lp.configfile) + + # Force signing for the connection + saved_signing_state = creds.get_smb_signing() + creds.set_smb_signing(SMB_SIGNING_REQUIRED) conn = libsmb.Conn(dc_hostname, 'sysvol', lp=s3_lp, creds=creds, sign=True) + # Reset signing state + creds.set_smb_signing(saved_signing_state) cache_path = lp.cache_path('gpo_cache') for gpo in gpos: if not gpo.file_sys_path: diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py index a3dc7fb454f..a9e0ba5bc67 100644 --- a/python/samba/netcmd/domain_backup.py +++ b/python/samba/netcmd/domain_backup.py @@ -54,6 +54,7 @@ from subprocess import CalledProcessError from samba import sites from samba.dsdb import _dsdb_load_udv_v2 from samba.ndr import ndr_pack +from samba.credentials import SMB_SIGNING_REQUIRED # work out a SID (based on a free RID) to use when the domain gets restored. @@ -115,7 +116,14 @@ def smb_sysvol_conn(server, lp, creds): # the SMB bindings rely on having a s3 loadparm s3_lp = s3param.get_context() s3_lp.load(lp.configfile) - return libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds, sign=True) + + # Force signing for the connection + saved_signing_state = creds.get_smb_signing() + creds.set_smb_signing(SMB_SIGNING_REQUIRED) + conn = libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds, sign=True) + # Reset signing state + creds.set_smb_signing(saved_signing_state) + return conn def get_timestamp(): diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py index ad60cda0690..0f2f6520fc3 100644 --- a/python/samba/netcmd/gpo.py +++ b/python/samba/netcmd/gpo.py @@ -62,6 +62,7 @@ from samba.gp_parse.gp_csv import GPAuditCsvParser from samba.gp_parse.gp_inf import GptTmplInfParser from samba.gp_parse.gp_aas import GPAasParser from samba import param +from samba.credentials import SMB_SIGNING_REQUIRED def attr_default(msg, attrname, default): @@ -384,6 +385,9 @@ def create_directory_hier(conn, remotedir): def smb_connection(dc_hostname, service, lp, creds): # SMB connect to DC + # Force signing for the smb connection + saved_signing_state = creds.get_smb_signing() + creds.set_smb_signing(SMB_SIGNING_REQUIRED) try: # the SMB bindings rely on having a s3 loadparm s3_lp = s3param.get_context() @@ -391,6 +395,8 @@ def smb_connection(dc_hostname, service, lp, creds): conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=True) except Exception: raise CommandError("Error connecting to '%s' using SMB" % dc_hostname) + # Reset signing state + creds.set_smb_signing(saved_signing_state) return conn -- 2.29.2 From d6e0f9079047c1832c981a0bf357e5e9415168d4 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 17:22:12 +0200 Subject: [PATCH 025/108] s3:libsmb: Introduce CLI_FULL_CONNECTION_IPC Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- examples/winexe/winexe.c | 2 +- source3/include/client.h | 1 + source3/libnet/libnet_join.c | 6 +++--- source3/libsmb/cliconnect.c | 3 ++- source3/rpc_server/spoolss/srv_spoolss_nt.c | 4 +++- source3/rpcclient/cmd_spoolss.c | 2 +- source3/rpcclient/rpcclient.c | 2 +- source3/utils/mdfind.c | 2 +- source3/utils/net_ads.c | 3 ++- source3/utils/net_util.c | 9 +++++++-- source3/utils/netlookup.c | 4 +++- 11 files changed, 25 insertions(+), 13 deletions(-) diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c index fc6b15f8e52..bb9c27e2e6d 100644 --- a/examples/winexe/winexe.c +++ b/examples/winexe/winexe.c @@ -1919,7 +1919,7 @@ int main(int argc, const char *argv[]) "IPC$", "?????", options.credentials, - 0, + CLI_FULL_CONNECTION_IPC, 0); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/include/client.h b/source3/include/client.h index 6a3b1b02ff3..19a738900b7 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -121,5 +121,6 @@ struct file_info { #define CLI_FULL_CONNECTION_FORCE_ASCII 0x0100 #define CLI_FULL_CONNECTION_FORCE_SMB1 0x0400 #define CLI_FULL_CONNECTION_DISABLE_SMB1 0x0800 +#define CLI_FULL_CONNECTION_IPC 0x1000 #endif /* _CLIENT_H */ diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 34938603606..392e3eff74f 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -1068,7 +1068,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc, bool use_ccache = false; bool pw_nt_hash = false; struct cli_credentials *creds = NULL; - int flags = 0; + int flags = CLI_FULL_CONNECTION_IPC; NTSTATUS status; if (use_kerberos && pass) { @@ -1684,7 +1684,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, struct netlogon_creds_CredentialState *creds = NULL; uint32_t netlogon_flags = 0; NTSTATUS status; - int flags = 0; + int flags = CLI_FULL_CONNECTION_IPC; if (!dc_name) { TALLOC_FREE(frame); @@ -1734,7 +1734,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, NULL, 0, "IPC$", "IPC", anon_creds, - 0, + flags, SMB_SIGNING_OFF); } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1fb1f0127b9..f20146378e3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2788,7 +2788,7 @@ static struct tevent_req *cli_start_connection_send( } state->ev = ev; - if (signing_state == SMB_SIGNING_IPC_DEFAULT) { + if (flags & CLI_FULL_CONNECTION_IPC) { state->min_protocol = lp_client_ipc_min_protocol(); state->max_protocol = lp_client_ipc_max_protocol(); } else { @@ -3673,6 +3673,7 @@ struct cli_state *get_ipc_connect(char *server, uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK; flags |= CLI_FULL_CONNECTION_FORCE_SMB1; + flags |= CLI_FULL_CONNECTION_IPC; nt_status = cli_full_connection_creds(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", get_cmdline_auth_info_creds(user_info), diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index 10c1b1d54f2..f578f1c4131 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -2482,7 +2482,9 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct c /* setup the connection */ ret = cli_full_connection_creds( pp_cli, lp_netbios_name(), remote_machine, &rm_addr, 0, "IPC$", "IPC", - anon_creds, 0, SMB_SIGNING_OFF); + anon_creds, + CLI_FULL_CONNECTION_IPC, + SMB_SIGNING_OFF); TALLOC_FREE(anon_creds); if ( !NT_STATUS_IS_OK( ret ) ) { DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n", diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index a7e0c673a65..7198a451ab7 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -3537,7 +3537,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, "IPC$", "IPC", get_cmdline_auth_info_creds( popt_get_cmdline_auth_info()), - 0, /* flags */ + CLI_FULL_CONNECTION_IPC, get_cmdline_auth_info_signing_state( popt_get_cmdline_auth_info())); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 67a1066fc15..c86474d08f1 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1019,7 +1019,7 @@ out_free: static int opt_port = 0; int result = 0; TALLOC_CTX *frame = talloc_stackframe(); - uint32_t flags = 0; + uint32_t flags = CLI_FULL_CONNECTION_IPC; struct dcerpc_binding *binding = NULL; enum dcerpc_transport_t transport; uint32_t bflags = 0; diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c index 2f952c29b4f..a3c879e75fb 100644 --- a/source3/utils/mdfind.c +++ b/source3/utils/mdfind.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) const char *mds_query = NULL; struct cli_state *cli = NULL; char *basepath = NULL; - uint32_t flags = 0; + uint32_t flags = CLI_FULL_CONNECTION_IPC; int signing_state = SMB_SIGNING_IPC_DEFAULT; uint64_t *cnids = NULL; size_t ncnids; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index e5db844c2f2..28ef6dc9974 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -2437,7 +2437,8 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * nt_status = cli_full_connection_creds(&cli, lp_netbios_name(), servername, &server_ss, 0, "IPC$", "IPC", - creds, 0, + creds, + CLI_FULL_CONNECTION_IPC, SMB_SIGNING_IPC_DEFAULT); if (NT_STATUS_IS_ERR(nt_status)) { diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index c566ecc9000..d01b2d8c771 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -110,6 +110,7 @@ NTSTATUS connect_to_service(struct net_context *c, NTSTATUS nt_status; enum smb_signing_setting signing_setting = SMB_SIGNING_DEFAULT; struct cli_credentials *creds = NULL; + int flags = 0; creds = net_context_creds(c, c); if (creds == NULL) { @@ -119,12 +120,14 @@ NTSTATUS connect_to_service(struct net_context *c, if (strequal(service_type, "IPC")) { signing_setting = SMB_SIGNING_IPC_DEFAULT; + flags |= CLI_FULL_CONNECTION_IPC; } nt_status = cli_full_connection_creds(cli_ctx, NULL, server_name, server_ss, c->opt_port, service_name, service_type, - creds, 0, + creds, + flags, signing_setting); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("Could not connect to server %s\n"), @@ -195,7 +198,9 @@ NTSTATUS connect_to_ipc_anonymous(struct net_context *c, nt_status = cli_full_connection_creds(cli_ctx, c->opt_requester_name, server_name, server_ss, c->opt_port, "IPC$", "IPC", - anon_creds, 0, SMB_SIGNING_OFF); + anon_creds, + CLI_FULL_CONNECTION_IPC, + SMB_SIGNING_OFF); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; diff --git a/source3/utils/netlookup.c b/source3/utils/netlookup.c index 6cea2ee306c..2241beb331f 100644 --- a/source3/utils/netlookup.c +++ b/source3/utils/netlookup.c @@ -98,7 +98,9 @@ static struct con_struct *create_cs(struct net_context *c, nt_status = cli_full_connection_creds(&cs->cli, lp_netbios_name(), lp_netbios_name(), &loopback_ss, 0, "IPC$", "IPC", - anon_creds, 0, SMB_SIGNING_OFF); + anon_creds, + CLI_FULL_CONNECTION_IPC, + SMB_SIGNING_OFF); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status))); -- 2.29.2 From 1a928ac9a29329588633058ef226098f118c3f87 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 17:29:25 +0200 Subject: [PATCH 026/108] s3:pylibsmb: Add ipc=True support for CLI_FULL_CONNECTION_IPC Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/libsmb/pylibsmb.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c index 3fcc3424a57..3579a040830 100644 --- a/source3/libsmb/pylibsmb.c +++ b/source3/libsmb/pylibsmb.c @@ -445,6 +445,8 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, int signing_state = SMB_SIGNING_DEFAULT; PyObject *py_force_smb1 = Py_False; bool force_smb1 = false; + PyObject *py_ipc = Py_False; + bool use_ipc = false; struct tevent_req *req; bool ret; int flags = 0; @@ -452,6 +454,7 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, static const char *kwlist[] = { "host", "share", "lp", "creds", "multi_threaded", "sign", "force_smb1", + "ipc", NULL }; @@ -462,12 +465,13 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, } ret = ParseTupleAndKeywords( - args, kwds, "ssO|O!OOO", kwlist, + args, kwds, "ssO|O!OOOO", kwlist, &host, &share, &py_lp, py_type_Credentials, &creds, &py_multi_threaded, &py_sign, - &py_force_smb1); + &py_force_smb1, + &py_ipc); Py_DECREF(py_type_Credentials); @@ -493,6 +497,11 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, flags = CLI_FULL_CONNECTION_FORCE_SMB1; } + use_ipc = PyObject_IsTrue(py_ipc); + if (use_ipc) { + flags |= CLI_FULL_CONNECTION_IPC; + } + if (multi_threaded) { #ifdef HAVE_PTHREAD ret = py_cli_state_setup_mt_ev(self); -- 2.29.2 From c06aed4a9d30a50c36787c57e091b34610d10a61 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 24 Jul 2020 09:47:11 +0200 Subject: [PATCH 027/108] python:tests: Mark libsmb connection as an IPC connection Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- python/samba/tests/dcerpc/raw_testcase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index ba7440df13b..2c028d381db 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -43,7 +43,7 @@ class smb_pipe_socket(object): lp3 = s3param.get_context() lp3.load(lp.configfile) self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3, - creds=creds, sign=True) + creds=creds, ipc=True, sign=True) self.smbfid = self.smbconn.create(pipename, DesiredAccess=0x12019f, ShareAccess=0x7, -- 2.29.2 From 94218e70119c343d747808f62c4f8acccabbf7a6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 17 Aug 2020 12:52:39 +0200 Subject: [PATCH 028/108] python:tests: Set smb ipc signing via the creds API Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- python/samba/tests/dcerpc/raw_testcase.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index 2c028d381db..d6f5de7440a 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -36,14 +36,18 @@ from samba.ntstatus import ( from samba import NTSTATUSError from samba.samba3 import param as s3param from samba.samba3 import libsmb_samba_internal as libsmb +from samba.credentials import SMB_SIGNING_REQUIRED class smb_pipe_socket(object): def __init__(self, target_hostname, pipename, creds, impersonation_level, lp): lp3 = s3param.get_context() lp3.load(lp.configfile) + saved_signing_state = creds.get_smb_ipc_signing() + creds.set_smb_ipc_signing(SMB_SIGNING_REQUIRED) self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3, creds=creds, ipc=True, sign=True) + creds.set_smb_ipc_signing(saved_signing_state) self.smbfid = self.smbconn.create(pipename, DesiredAccess=0x12019f, ShareAccess=0x7, -- 2.29.2 From 44a039e9373f5274a33b6eccfcb82c0a5e538818 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 17:59:19 +0200 Subject: [PATCH 029/108] s3:libsmb: Use 'enum smb_signing_setting' in cliconnect.c Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/libsmb/cliconnect.c | 14 +++++++------- source3/libsmb/proto.h | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f20146378e3..bb20aa59385 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2631,7 +2631,7 @@ static NTSTATUS cli_connect_sock_recv(struct tevent_req *req, struct cli_connect_nb_state { const char *desthost; - int signing_state; + enum smb_signing_setting signing_state; int flags; struct cli_state *cli; }; @@ -2642,7 +2642,7 @@ static struct tevent_req *cli_connect_nb_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *host, const struct sockaddr_storage *dest_ss, uint16_t port, int name_type, const char *myname, - int signing_state, int flags) + enum smb_signing_setting signing_state, int flags) { struct tevent_req *req, *subreq; struct cli_connect_nb_state *state; @@ -2727,7 +2727,7 @@ static NTSTATUS cli_connect_nb_recv(struct tevent_req *req, NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss, uint16_t port, int name_type, const char *myname, - int signing_state, int flags, struct cli_state **pcli) + enum smb_signing_setting signing_state, int flags, struct cli_state **pcli) { struct tevent_context *ev; struct tevent_req *req; @@ -2776,7 +2776,7 @@ static struct tevent_req *cli_start_connection_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *my_name, const char *dest_host, const struct sockaddr_storage *dest_ss, int port, - int signing_state, int flags) + enum smb_signing_setting signing_state, int flags) { struct tevent_req *req, *subreq; struct cli_start_connection_state *state; @@ -2881,7 +2881,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, const struct sockaddr_storage *dest_ss, int port, - int signing_state, int flags) + enum smb_signing_setting signing_state, int flags) { struct tevent_context *ev; struct tevent_req *req; @@ -3361,7 +3361,7 @@ struct tevent_req *cli_full_connection_creds_send( const struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, struct cli_credentials *creds, - int flags, int signing_state) + int flags, enum smb_signing_setting signing_state) { struct tevent_req *req, *subreq; struct cli_full_connection_creds_state *state; @@ -3520,7 +3520,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, const char *service, const char *service_type, struct cli_credentials *creds, int flags, - int signing_state) + enum smb_signing_setting signing_state) { struct tevent_context *ev; struct tevent_req *req; diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index d214cdabca4..995187e21b4 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -86,12 +86,12 @@ NTSTATUS cli_tree_connect(struct cli_state *cli, const char *share, NTSTATUS cli_tdis(struct cli_state *cli); NTSTATUS cli_connect_nb(const char *host, const struct sockaddr_storage *dest_ss, uint16_t port, int name_type, const char *myname, - int signing_state, int flags, struct cli_state **pcli); + enum smb_signing_setting signing_state, int flags, struct cli_state **pcli); NTSTATUS cli_start_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, const struct sockaddr_storage *dest_ss, int port, - int signing_state, int flags); + enum smb_signing_setting signing_state, int flags); NTSTATUS cli_smb1_setup_encryption(struct cli_state *cli, struct cli_credentials *creds); struct tevent_req *cli_full_connection_creds_send( @@ -100,7 +100,7 @@ struct tevent_req *cli_full_connection_creds_send( const struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, struct cli_credentials *creds, - int flags, int signing_state); + int flags, enum smb_signing_setting signing_state); NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req, struct cli_state **output_cli); NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, @@ -110,7 +110,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, const char *service, const char *service_type, struct cli_credentials *creds, int flags, - int signing_state); + enum smb_signing_setting signing_state); NTSTATUS cli_raw_tcon(struct cli_state *cli, const char *service, const char *pass, const char *dev, uint16_t *max_xmit, uint16_t *tid); @@ -177,7 +177,7 @@ extern struct GUID cli_state_client_guid; struct cli_state *cli_state_create(TALLOC_CTX *mem_ctx, int fd, const char *remote_name, - int signing_state, + enum smb_signing_setting signing_state, int flags); void cli_nt_pipes_close(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); -- 2.29.2 From 797c0e55c8521a6788a98ecd405579e2d2d09b46 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 18:11:31 +0200 Subject: [PATCH 030/108] s3:client: Turn off smb signing for message op Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- python/samba/gpclass.py | 2 +- python/samba/netcmd/domain_backup.py | 2 +- python/samba/netcmd/gpo.py | 2 +- python/samba/tests/dcerpc/raw_testcase.py | 2 +- source3/client/client.c | 5 ++++- source3/libsmb/pylibsmb.c | 20 +++++++++----------- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py index 1781a55a618..2c00f5349a0 100644 --- a/python/samba/gpclass.py +++ b/python/samba/gpclass.py @@ -426,7 +426,7 @@ def check_refresh_gpo_list(dc_hostname, lp, creds, gpos): # Force signing for the connection saved_signing_state = creds.get_smb_signing() creds.set_smb_signing(SMB_SIGNING_REQUIRED) - conn = libsmb.Conn(dc_hostname, 'sysvol', lp=s3_lp, creds=creds, sign=True) + conn = libsmb.Conn(dc_hostname, 'sysvol', lp=s3_lp, creds=creds) # Reset signing state creds.set_smb_signing(saved_signing_state) cache_path = lp.cache_path('gpo_cache') diff --git a/python/samba/netcmd/domain_backup.py b/python/samba/netcmd/domain_backup.py index a9e0ba5bc67..2977b071ec3 100644 --- a/python/samba/netcmd/domain_backup.py +++ b/python/samba/netcmd/domain_backup.py @@ -120,7 +120,7 @@ def smb_sysvol_conn(server, lp, creds): # Force signing for the connection saved_signing_state = creds.get_smb_signing() creds.set_smb_signing(SMB_SIGNING_REQUIRED) - conn = libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds, sign=True) + conn = libsmb.Conn(server, "sysvol", lp=s3_lp, creds=creds) # Reset signing state creds.set_smb_signing(saved_signing_state) return conn diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py index 0f2f6520fc3..bbaa0c17881 100644 --- a/python/samba/netcmd/gpo.py +++ b/python/samba/netcmd/gpo.py @@ -392,7 +392,7 @@ def smb_connection(dc_hostname, service, lp, creds): # the SMB bindings rely on having a s3 loadparm s3_lp = s3param.get_context() s3_lp.load(lp.configfile) - conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=True) + conn = libsmb.Conn(dc_hostname, service, lp=s3_lp, creds=creds) except Exception: raise CommandError("Error connecting to '%s' using SMB" % dc_hostname) # Reset signing state diff --git a/python/samba/tests/dcerpc/raw_testcase.py b/python/samba/tests/dcerpc/raw_testcase.py index d6f5de7440a..34785e2a2a7 100644 --- a/python/samba/tests/dcerpc/raw_testcase.py +++ b/python/samba/tests/dcerpc/raw_testcase.py @@ -46,7 +46,7 @@ class smb_pipe_socket(object): saved_signing_state = creds.get_smb_ipc_signing() creds.set_smb_ipc_signing(SMB_SIGNING_REQUIRED) self.smbconn = libsmb.Conn(target_hostname, 'IPC$', lp3, - creds=creds, ipc=True, sign=True) + creds=creds, ipc=True) creds.set_smb_ipc_signing(saved_signing_state) self.smbfid = self.smbconn.create(pipename, DesiredAccess=0x12019f, diff --git a/source3/client/client.c b/source3/client/client.c index 8c7ceb644aa..56309efcea7 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -6164,7 +6164,10 @@ static int do_message_op(struct user_auth_info *a_info) status = cli_connect_nb(desthost, have_ip ? &dest_ss : NULL, port ? port : NBT_SMB_PORT, name_type, - lp_netbios_name(), SMB_SIGNING_DEFAULT, 0, &cli); + lp_netbios_name(), + SMB_SIGNING_OFF, + 0, + &cli); if (!NT_STATUS_IS_OK(status)) { d_printf("Connection to %s failed. Error %s\n", desthost, nt_errstr(status)); return 1; diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c index 3579a040830..f8a4d56cf53 100644 --- a/source3/libsmb/pylibsmb.c +++ b/source3/libsmb/pylibsmb.c @@ -440,9 +440,7 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, PyObject *py_lp = Py_None; PyObject *py_multi_threaded = Py_False; bool multi_threaded = false; - PyObject *py_sign = Py_False; - bool sign = false; - int signing_state = SMB_SIGNING_DEFAULT; + enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT; PyObject *py_force_smb1 = Py_False; bool force_smb1 = false; PyObject *py_ipc = Py_False; @@ -453,7 +451,7 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, static const char *kwlist[] = { "host", "share", "lp", "creds", - "multi_threaded", "sign", "force_smb1", + "multi_threaded", "force_smb1", "ipc", NULL }; @@ -465,11 +463,10 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, } ret = ParseTupleAndKeywords( - args, kwds, "ssO|O!OOOO", kwlist, + args, kwds, "ssO|O!OOO", kwlist, &host, &share, &py_lp, py_type_Credentials, &creds, &py_multi_threaded, - &py_sign, &py_force_smb1, &py_ipc); @@ -480,13 +477,8 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, } multi_threaded = PyObject_IsTrue(py_multi_threaded); - sign = PyObject_IsTrue(py_sign); force_smb1 = PyObject_IsTrue(py_force_smb1); - if (sign) { - signing_state = SMB_SIGNING_REQUIRED; - } - if (force_smb1) { /* * As most of the cli_*_send() function @@ -532,6 +524,12 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, cli_creds = PyCredentials_AsCliCredentials(creds); } + if (use_ipc) { + signing_state = cli_credentials_get_smb_ipc_signing(cli_creds); + } else { + signing_state = cli_credentials_get_smb_signing(cli_creds); + } + req = cli_full_connection_creds_send( NULL, self->ev, "myname", host, NULL, 0, share, "?????", cli_creds, flags, signing_state); -- 2.29.2 From ae84010726a6a428a1b1ad2ddddbf7dd9fd54d6f Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 28 May 2020 18:20:02 +0200 Subject: [PATCH 031/108] s3:libsmb: Remove signing_state from cli_full_connection_creds_send() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/libsmb/cliconnect.c | 11 +++++++++-- source3/libsmb/proto.h | 2 +- source3/libsmb/pylibsmb.c | 9 +-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index bb20aa59385..0ff9c283e39 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3361,10 +3361,11 @@ struct tevent_req *cli_full_connection_creds_send( const struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, struct cli_credentials *creds, - int flags, enum smb_signing_setting signing_state) + int flags) { struct tevent_req *req, *subreq; struct cli_full_connection_creds_state *state; + enum smb_signing_setting signing_state; req = tevent_req_create(mem_ctx, &state, struct cli_full_connection_creds_state); @@ -3379,6 +3380,12 @@ struct tevent_req *cli_full_connection_creds_send( state->creds = creds; state->flags = flags; + if (flags & CLI_FULL_CONNECTION_IPC) { + signing_state = cli_credentials_get_smb_ipc_signing(creds); + } else { + signing_state = cli_credentials_get_smb_signing(creds); + } + subreq = cli_start_connection_send( state, ev, my_name, dest_host, dest_ss, port, signing_state, flags); @@ -3532,7 +3539,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, } req = cli_full_connection_creds_send( ev, ev, my_name, dest_host, dest_ss, port, service, - service_type, creds, flags, signing_state); + service_type, creds, flags); if (req == NULL) { goto fail; } diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 995187e21b4..bef04d32638 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -100,7 +100,7 @@ struct tevent_req *cli_full_connection_creds_send( const struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, struct cli_credentials *creds, - int flags, enum smb_signing_setting signing_state); + int flags); NTSTATUS cli_full_connection_creds_recv(struct tevent_req *req, struct cli_state **output_cli); NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, diff --git a/source3/libsmb/pylibsmb.c b/source3/libsmb/pylibsmb.c index f8a4d56cf53..c7a2d73afcb 100644 --- a/source3/libsmb/pylibsmb.c +++ b/source3/libsmb/pylibsmb.c @@ -440,7 +440,6 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, PyObject *py_lp = Py_None; PyObject *py_multi_threaded = Py_False; bool multi_threaded = false; - enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT; PyObject *py_force_smb1 = Py_False; bool force_smb1 = false; PyObject *py_ipc = Py_False; @@ -524,15 +523,9 @@ static int py_cli_state_init(struct py_cli_state *self, PyObject *args, cli_creds = PyCredentials_AsCliCredentials(creds); } - if (use_ipc) { - signing_state = cli_credentials_get_smb_ipc_signing(cli_creds); - } else { - signing_state = cli_credentials_get_smb_signing(cli_creds); - } - req = cli_full_connection_creds_send( NULL, self->ev, "myname", host, NULL, 0, share, "?????", - cli_creds, flags, signing_state); + cli_creds, flags); if (!py_tevent_req_wait_exc(self, req)) { return -1; } -- 2.29.2 From 23dd3d7fd8e120be59bd0b45ea5bccb6812730d6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 4 Jun 2020 14:59:14 +0200 Subject: [PATCH 032/108] s3:libsmb: Remove signing_state from cli_full_connection_creds() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- examples/fuse/smb2mount.c | 3 +-- examples/winexe/winexe.c | 4 +--- source3/libnet/libnet_join.c | 9 +++------ source3/libsmb/cliconnect.c | 6 ++---- source3/libsmb/libsmb_server.c | 8 +------- source3/libsmb/proto.h | 3 +-- source3/rpc_server/spoolss/srv_spoolss_nt.c | 3 +-- source3/rpcclient/cmd_spoolss.c | 5 +---- source3/rpcclient/rpcclient.c | 3 +-- source3/torture/locktest2.c | 11 +++++++++-- source3/torture/torture.c | 6 ++---- source3/utils/mdfind.c | 3 +-- source3/utils/net_ads.c | 3 +-- source3/utils/net_util.c | 8 ++------ source3/utils/netlookup.c | 3 +-- source3/utils/smbcacls.c | 3 +-- source3/utils/smbcquotas.c | 4 +--- 17 files changed, 30 insertions(+), 55 deletions(-) diff --git a/examples/fuse/smb2mount.c b/examples/fuse/smb2mount.c index ea1d9a11e0b..6206c3a9701 100644 --- a/examples/fuse/smb2mount.c +++ b/examples/fuse/smb2mount.c @@ -37,8 +37,7 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info, NULL, port, share, "?????", get_cmdline_auth_info_creds(auth_info), - flags, - get_cmdline_auth_info_signing_state(auth_info)); + flags); if (!NT_STATUS_IS_OK(nt_status)) { DBG_ERR("cli_full_connection failed! (%s)\n", nt_errstr(nt_status)); diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c index bb9c27e2e6d..03e7ec85198 100644 --- a/examples/winexe/winexe.c +++ b/examples/winexe/winexe.c @@ -360,7 +360,6 @@ static NTSTATUS winexe_svc_upload( "ADMIN$", "?????", credentials, - 0, 0); if (!NT_STATUS_IS_OK(status)) { DBG_WARNING("cli_full_connection_creds failed: %s\n", @@ -1919,8 +1918,7 @@ int main(int argc, const char *argv[]) "IPC$", "?????", options.credentials, - CLI_FULL_CONNECTION_IPC, - 0); + CLI_FULL_CONNECTION_IPC); if (!NT_STATUS_IS_OK(status)) { DBG_WARNING("cli_full_connection_creds failed: %s\n", diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 392e3eff74f..f3bf27e6c00 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -1095,8 +1095,7 @@ static NTSTATUS libnet_join_connect_dc_ipc(const char *dc, NULL, 0, "IPC$", "IPC", creds, - flags, - SMB_SIGNING_IPC_DEFAULT); + flags); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(frame); return status; @@ -1716,8 +1715,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, NULL, 0, "IPC$", "IPC", cli_creds, - flags, - SMB_SIGNING_IPC_DEFAULT); + flags); if (!NT_STATUS_IS_OK(status)) { struct cli_credentials *anon_creds = NULL; @@ -1734,8 +1732,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, NULL, 0, "IPC$", "IPC", anon_creds, - flags, - SMB_SIGNING_OFF); + flags); } if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0ff9c283e39..b24743d789b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3526,8 +3526,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, const struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, struct cli_credentials *creds, - int flags, - enum smb_signing_setting signing_state) + int flags) { struct tevent_context *ev; struct tevent_req *req; @@ -3684,8 +3683,7 @@ struct cli_state *get_ipc_connect(char *server, nt_status = cli_full_connection_creds(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", get_cmdline_auth_info_creds(user_info), - flags, - SMB_SIGNING_DEFAULT); + flags); if (NT_STATUS_IS_OK(nt_status)) { return cli; diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 3d1cd602f6c..33dc8419deb 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -785,7 +785,6 @@ SMBC_attr_server(TALLOC_CTX *ctx, pp_workgroup, pp_username, pp_password); if (!ipc_srv) { struct cli_credentials *creds = NULL; - int signing_state = SMB_SIGNING_DEFAULT; /* We didn't find a cached connection. Get the password */ if (!*pp_password || (*pp_password)[0] == '\0') { @@ -812,16 +811,11 @@ SMBC_attr_server(TALLOC_CTX *ctx, return NULL; } - if (context->internal->smb_encryption_level != SMBC_ENCRYPTLEVEL_NONE) { - signing_state = SMB_SIGNING_REQUIRED; - } - nt_status = cli_full_connection_creds(&ipc_cli, lp_netbios_name(), server, NULL, 0, "IPC$", "?????", creds, - flags, - signing_state); + flags); if (! NT_STATUS_IS_OK(nt_status)) { TALLOC_FREE(creds); DEBUG(1,("cli_full_connection failed! (%s)\n", diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index bef04d32638..850cf12c8a6 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -109,8 +109,7 @@ NTSTATUS cli_full_connection_creds(struct cli_state **output_cli, const struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, struct cli_credentials *creds, - int flags, - enum smb_signing_setting signing_state); + int flags); NTSTATUS cli_raw_tcon(struct cli_state *cli, const char *service, const char *pass, const char *dev, uint16_t *max_xmit, uint16_t *tid); diff --git a/source3/rpc_server/spoolss/srv_spoolss_nt.c b/source3/rpc_server/spoolss/srv_spoolss_nt.c index f578f1c4131..906fab2adb5 100644 --- a/source3/rpc_server/spoolss/srv_spoolss_nt.c +++ b/source3/rpc_server/spoolss/srv_spoolss_nt.c @@ -2483,8 +2483,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct c ret = cli_full_connection_creds( pp_cli, lp_netbios_name(), remote_machine, &rm_addr, 0, "IPC$", "IPC", anon_creds, - CLI_FULL_CONNECTION_IPC, - SMB_SIGNING_OFF); + CLI_FULL_CONNECTION_IPC); TALLOC_FREE(anon_creds); if ( !NT_STATUS_IS_OK( ret ) ) { DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n", diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 7198a451ab7..02889a0a666 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -3537,10 +3537,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, "IPC$", "IPC", get_cmdline_auth_info_creds( popt_get_cmdline_auth_info()), - CLI_FULL_CONNECTION_IPC, - get_cmdline_auth_info_signing_state( - popt_get_cmdline_auth_info())); - + CLI_FULL_CONNECTION_IPC); if ( !NT_STATUS_IS_OK(nt_status) ) return WERR_GEN_FAILURE; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index c86474d08f1..2ead6cc7ba5 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1206,8 +1206,7 @@ out_free: "IPC$", "IPC", get_cmdline_auth_info_creds( popt_get_cmdline_auth_info()), - flags, - SMB_SIGNING_IPC_DEFAULT); + flags); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("Cannot connect to server. Error was %s\n", nt_errstr(nt_status))); diff --git a/source3/torture/locktest2.c b/source3/torture/locktest2.c index 84c335f959f..92ddb7629b9 100644 --- a/source3/torture/locktest2.c +++ b/source3/torture/locktest2.c @@ -217,8 +217,15 @@ static struct cli_state *connect_one(char *share) slprintf(myname,sizeof(myname), "lock-%lu-%u", (unsigned long)getpid(), count++); - nt_status = cli_full_connection_creds(&c, myname, server_n, NULL, 0, share, "?????", - creds, 0, SMB_SIGNING_DEFAULT); + nt_status = cli_full_connection_creds(&c, + myname, + server_n, + NULL, + 0, + share, + "?????", + creds, + 0); TALLOC_FREE(creds); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("cli_full_connection failed with error %s\n", nt_errstr(nt_status))); diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 2a3133373e9..a4edeefd628 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -345,8 +345,7 @@ static bool torture_open_connection_share(struct cli_state **c, sharename, "?????", torture_creds, - flags, - signing_state); + flags); if (!NT_STATUS_IS_OK(status)) { printf("failed to open share connection: //%s/%s port:%d - %s\n", hostname, sharename, port_to_use, nt_errstr(status)); @@ -1523,8 +1522,7 @@ static bool run_tcon_devtype_test(int dummy) NULL, /* service */ NULL, /* service_type */ torture_creds, - flags, - signing_state); + flags); if (!NT_STATUS_IS_OK(status)) { printf("could not open connection\n"); diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c index a3c879e75fb..2ac4fde7daf 100644 --- a/source3/utils/mdfind.c +++ b/source3/utils/mdfind.c @@ -153,8 +153,7 @@ int main(int argc, char **argv) "IPC$", "IPC", creds, - flags, - SMB_SIGNING_IPC_DEFAULT); + flags); if (!NT_STATUS_IS_OK(status)) { DBG_ERR("Cannot connect to server: %s\n", nt_errstr(status)); goto fail; diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 28ef6dc9974..7f5b9c3a440 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -2438,8 +2438,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * &server_ss, 0, "IPC$", "IPC", creds, - CLI_FULL_CONNECTION_IPC, - SMB_SIGNING_IPC_DEFAULT); + CLI_FULL_CONNECTION_IPC); if (NT_STATUS_IS_ERR(nt_status)) { d_fprintf(stderr, _("Unable to open a connection to %s to " diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index d01b2d8c771..b139fb2d0da 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -108,7 +108,6 @@ NTSTATUS connect_to_service(struct net_context *c, const char *service_type) { NTSTATUS nt_status; - enum smb_signing_setting signing_setting = SMB_SIGNING_DEFAULT; struct cli_credentials *creds = NULL; int flags = 0; @@ -119,7 +118,6 @@ NTSTATUS connect_to_service(struct net_context *c, } if (strequal(service_type, "IPC")) { - signing_setting = SMB_SIGNING_IPC_DEFAULT; flags |= CLI_FULL_CONNECTION_IPC; } @@ -127,8 +125,7 @@ NTSTATUS connect_to_service(struct net_context *c, server_ss, c->opt_port, service_name, service_type, creds, - flags, - signing_setting); + flags); if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("Could not connect to server %s\n"), server_name); @@ -199,8 +196,7 @@ NTSTATUS connect_to_ipc_anonymous(struct net_context *c, server_name, server_ss, c->opt_port, "IPC$", "IPC", anon_creds, - CLI_FULL_CONNECTION_IPC, - SMB_SIGNING_OFF); + CLI_FULL_CONNECTION_IPC); if (NT_STATUS_IS_OK(nt_status)) { return nt_status; diff --git a/source3/utils/netlookup.c b/source3/utils/netlookup.c index 2241beb331f..aaf78b0977a 100644 --- a/source3/utils/netlookup.c +++ b/source3/utils/netlookup.c @@ -99,8 +99,7 @@ static struct con_struct *create_cs(struct net_context *c, &loopback_ss, 0, "IPC$", "IPC", anon_creds, - CLI_FULL_CONNECTION_IPC, - SMB_SIGNING_OFF); + CLI_FULL_CONNECTION_IPC); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(2,("create_cs: Connect failed. Error was %s\n", nt_errstr(nt_status))); diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index f3209c31877..5983ebbd0a5 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -778,8 +778,7 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info, NULL, 0, share, "?????", get_cmdline_auth_info_creds(auth_info), - flags, - get_cmdline_auth_info_signing_state(auth_info)); + flags); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); return NULL; diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c index 954d6eba804..fea066ce468 100644 --- a/source3/utils/smbcquotas.c +++ b/source3/utils/smbcquotas.c @@ -527,9 +527,7 @@ static struct cli_state *connect_one(const char *share) share, "?????", get_cmdline_auth_info_creds( popt_get_cmdline_auth_info()), - flags, - get_cmdline_auth_info_signing_state( - popt_get_cmdline_auth_info())); + flags); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); return NULL; -- 2.29.2 From fba11e893292fbbb03a85617c69326815dfdc996 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Jun 2020 08:04:24 +0200 Subject: [PATCH 033/108] s3:libsmb: Add encryption support to cli_full_connection_creds*() Pair-Programmed-With: Andreas Schneider Signed-off-by: Andreas Schneider Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- source3/libsmb/cliconnect.c | 166 ++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b24743d789b..abfd18bfaf1 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -3352,6 +3352,10 @@ static int cli_full_connection_creds_state_destructor( static void cli_full_connection_creds_conn_done(struct tevent_req *subreq); static void cli_full_connection_creds_sess_start(struct tevent_req *req); static void cli_full_connection_creds_sess_done(struct tevent_req *subreq); +static void cli_full_connection_creds_enc_start(struct tevent_req *req); +static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq); +static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq); +static void cli_full_connection_creds_enc_done(struct tevent_req *subreq); static void cli_full_connection_creds_tcon_start(struct tevent_req *req); static void cli_full_connection_creds_tcon_done(struct tevent_req *subreq); @@ -3366,6 +3370,8 @@ struct tevent_req *cli_full_connection_creds_send( struct tevent_req *req, *subreq; struct cli_full_connection_creds_state *state; enum smb_signing_setting signing_state; + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(creds); req = tevent_req_create(mem_ctx, &state, struct cli_full_connection_creds_state); @@ -3386,6 +3392,16 @@ struct tevent_req *cli_full_connection_creds_send( signing_state = cli_credentials_get_smb_signing(creds); } + if (encryption_state == SMB_ENCRYPTION_REQUIRED) { + if (flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK) { + encryption_state = SMB_ENCRYPTION_DESIRED; + } + } + + if (encryption_state >= SMB_ENCRYPTION_DESIRED) { + signing_state = SMB_SIGNING_REQUIRED; + } + subreq = cli_start_connection_send( state, ev, my_name, dest_host, dest_ss, port, signing_state, flags); @@ -3460,6 +3476,156 @@ static void cli_full_connection_creds_sess_done(struct tevent_req *subreq) return; } + cli_full_connection_creds_enc_start(req); +} + +static void cli_full_connection_creds_enc_start(struct tevent_req *req) +{ + struct cli_full_connection_creds_state *state = tevent_req_data( + req, struct cli_full_connection_creds_state); + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(state->creds); + struct tevent_req *subreq = NULL; + NTSTATUS status; + + if (encryption_state < SMB_ENCRYPTION_DESIRED) { + cli_full_connection_creds_tcon_start(req); + return; + } + + if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { + status = smb2cli_session_encryption_on(state->cli->smb2.session); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + if (encryption_state < SMB_ENCRYPTION_REQUIRED) { + cli_full_connection_creds_tcon_start(req); + return; + } + d_printf("Encryption required and " + "server doesn't support " + "SMB3 encryption - failing connect\n"); + tevent_req_nterror(req, status); + return; + } else if (!NT_STATUS_IS_OK(status)) { + d_printf("Encryption required and " + "setup failed with error %s.\n", + nt_errstr(status)); + tevent_req_nterror(req, status); + return; + } + + cli_full_connection_creds_tcon_start(req); + return; + } + + if (!SERVER_HAS_UNIX_CIFS(state->cli)) { + if (encryption_state < SMB_ENCRYPTION_REQUIRED) { + cli_full_connection_creds_tcon_start(req); + return; + } + + status = NT_STATUS_NOT_SUPPORTED; + d_printf("Encryption required and " + "server doesn't support " + "SMB1 Unix Extensions - failing connect\n"); + tevent_req_nterror(req, status); + return; + } + + /* + * We do a tcon on IPC$ just to setup the encryption, + * the real tcon will be encrypted then. + */ + subreq = cli_tree_connect_send(state, state->ev, state->cli, + "IPC$", "IPC", NULL); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_full_connection_creds_enc_tcon, req); +} + +static void cli_full_connection_creds_enc_tcon(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_full_connection_creds_state *state = tevent_req_data( + req, struct cli_full_connection_creds_state); + NTSTATUS status; + + status = cli_tree_connect_recv(subreq); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + subreq = cli_unix_extensions_version_send(state, state->ev, state->cli); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, cli_full_connection_creds_enc_ver, req); +} + +static void cli_full_connection_creds_enc_ver(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_full_connection_creds_state *state = tevent_req_data( + req, struct cli_full_connection_creds_state); + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(state->creds); + uint16_t major, minor; + uint32_t caplow, caphigh; + NTSTATUS status; + + status = cli_unix_extensions_version_recv(subreq, + &major, &minor, + &caplow, + &caphigh); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + if (encryption_state < SMB_ENCRYPTION_REQUIRED) { + cli_full_connection_creds_tcon_start(req); + return; + } + DEBUG(10, ("%s: cli_unix_extensions_version " + "returned %s\n", __func__, nt_errstr(status))); + tevent_req_nterror(req, NT_STATUS_UNKNOWN_REVISION); + return; + } + + if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) { + if (encryption_state < SMB_ENCRYPTION_REQUIRED) { + cli_full_connection_creds_tcon_start(req); + return; + } + DEBUG(10, ("%s: CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP " + "not supported\n", __func__)); + tevent_req_nterror(req, NT_STATUS_UNSUPPORTED_COMPRESSION); + return; + } + + subreq = cli_smb1_setup_encryption_send(state, state->ev, + state->cli, + state->creds); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, + cli_full_connection_creds_enc_done, + req); +} + +static void cli_full_connection_creds_enc_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; + + status = cli_smb1_setup_encryption_recv(subreq); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + cli_full_connection_creds_tcon_start(req); } -- 2.29.2 From b6e55cb03a821baf2ed7e7e1e4a4ff8ced9aa549 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 11:26:00 +0200 Subject: [PATCH 034/108] python: Add a test for SMB encryption Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- python/samba/tests/libsmb.py | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/python/samba/tests/libsmb.py b/python/samba/tests/libsmb.py index e8f8e7fe94d..81d4e482644 100644 --- a/python/samba/tests/libsmb.py +++ b/python/samba/tests/libsmb.py @@ -21,10 +21,12 @@ from samba.samba3 import libsmb_samba_internal as libsmb from samba.dcerpc import security from samba.samba3 import param as s3param from samba import credentials +from samba.credentials import SMB_ENCRYPTION_REQUIRED import samba.tests import threading import sys import os +import random class LibsmbTestCase(samba.tests.TestCase): @@ -77,6 +79,41 @@ class LibsmbTestCase(samba.tests.TestCase): if t.exc: raise t.exc[0](t.exc[1]) + def test_SMB3EncryptionRequired(self): + test_dir = 'testing_%d' % random.randint(0, 0xFFFF) + + lp = s3param.get_context() + lp.load(os.getenv("SMB_CONF_PATH")) + + creds = credentials.Credentials() + creds.guess(lp) + creds.set_username(os.getenv("USERNAME")) + creds.set_password(os.getenv("PASSWORD")) + creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + + c = libsmb.Conn(os.getenv("SERVER_IP"), "tmp", + lp, creds) + + c.mkdir(test_dir) + c.rmdir(test_dir) + + def test_SMB1EncryptionRequired(self): + test_dir = 'testing_%d' % random.randint(0, 0xFFFF) + + lp = s3param.get_context() + lp.load(os.getenv("SMB_CONF_PATH")) + + creds = credentials.Credentials() + creds.guess(lp) + creds.set_username(os.getenv("USERNAME")) + creds.set_password(os.getenv("PASSWORD")) + creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + + c = libsmb.Conn(os.getenv("SERVER_IP"), "tmp", + lp, creds, force_smb1=True) + + c.mkdir(test_dir) + c.rmdir(test_dir) if __name__ == "__main__": import unittest -- 2.29.2 From 16113fa8ed57b2ec8d75e8ff0e653a264f28b75a Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:31:02 +0200 Subject: [PATCH 035/108] s3:net: Use cli_credentials_set_smb_encryption() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/utils/net_util.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index b139fb2d0da..5829d891075 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -148,16 +148,6 @@ NTSTATUS connect_to_service(struct net_context *c, return nt_status; } - if (c->smb_encrypt) { - nt_status = cli_cm_force_encryption_creds(*cli_ctx, - creds, - service_name); - if (!NT_STATUS_IS_OK(nt_status)) { - cli_shutdown(*cli_ctx); - *cli_ctx = NULL; - } - } - return nt_status; } @@ -577,6 +567,12 @@ struct cli_credentials *net_context_creds(struct net_context *c, CRED_SPECIFIED); } + if (c->smb_encrypt) { + cli_credentials_set_smb_encryption(creds, + SMB_ENCRYPTION_REQUIRED, + CRED_SPECIFIED); + } + return creds; } -- 2.29.2 From fc775b9734466e9454db559b08704c308c5b310d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:40:13 +0200 Subject: [PATCH 036/108] s3:libsmb: Use cli_credentials_set_smb_encryption() This also adds a SMBC_ENCRYPTLEVEL_DEFAULT to 'enum smbc_smb_encrypt_level' in order to use the smb.conf default value. Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/include/libsmbclient.h | 1 + source3/libsmb/ABI/smbclient-0.7.0.sigs | 188 ++++++++++++++++++++++++ source3/libsmb/libsmb_context.c | 4 +- source3/libsmb/libsmb_server.c | 72 +++------ source3/libsmb/wscript | 2 +- 5 files changed, 216 insertions(+), 51 deletions(-) create mode 100644 source3/libsmb/ABI/smbclient-0.7.0.sigs diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index c47e7c2a872..84c98089251 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -225,6 +225,7 @@ typedef enum smbc_share_mode */ typedef enum smbc_smb_encrypt_level { + SMBC_ENCRYPTLEVEL_DEFAULT = -1, SMBC_ENCRYPTLEVEL_NONE = 0, SMBC_ENCRYPTLEVEL_REQUEST = 1, SMBC_ENCRYPTLEVEL_REQUIRE = 2 diff --git a/source3/libsmb/ABI/smbclient-0.7.0.sigs b/source3/libsmb/ABI/smbclient-0.7.0.sigs new file mode 100644 index 00000000000..ee758e21b50 --- /dev/null +++ b/source3/libsmb/ABI/smbclient-0.7.0.sigs @@ -0,0 +1,188 @@ +smbc_chmod: int (const char *, mode_t) +smbc_close: int (int) +smbc_closedir: int (int) +smbc_creat: int (const char *, mode_t) +smbc_fgetxattr: int (int, const char *, const void *, size_t) +smbc_flistxattr: int (int, char *, size_t) +smbc_free_context: int (SMBCCTX *, int) +smbc_fremovexattr: int (int, const char *) +smbc_fsetxattr: int (int, const char *, const void *, size_t, int) +smbc_fstat: int (int, struct stat *) +smbc_fstatvfs: int (int, struct statvfs *) +smbc_ftruncate: int (int, off_t) +smbc_getDebug: int (SMBCCTX *) +smbc_getFunctionAddCachedServer: smbc_add_cached_srv_fn (SMBCCTX *) +smbc_getFunctionAuthData: smbc_get_auth_data_fn (SMBCCTX *) +smbc_getFunctionAuthDataWithContext: smbc_get_auth_data_with_context_fn (SMBCCTX *) +smbc_getFunctionCheckServer: smbc_check_server_fn (SMBCCTX *) +smbc_getFunctionChmod: smbc_chmod_fn (SMBCCTX *) +smbc_getFunctionClose: smbc_close_fn (SMBCCTX *) +smbc_getFunctionClosedir: smbc_closedir_fn (SMBCCTX *) +smbc_getFunctionCreat: smbc_creat_fn (SMBCCTX *) +smbc_getFunctionFstat: smbc_fstat_fn (SMBCCTX *) +smbc_getFunctionFstatVFS: smbc_fstatvfs_fn (SMBCCTX *) +smbc_getFunctionFstatdir: smbc_fstatdir_fn (SMBCCTX *) +smbc_getFunctionFtruncate: smbc_ftruncate_fn (SMBCCTX *) +smbc_getFunctionGetCachedServer: smbc_get_cached_srv_fn (SMBCCTX *) +smbc_getFunctionGetdents: smbc_getdents_fn (SMBCCTX *) +smbc_getFunctionGetxattr: smbc_getxattr_fn (SMBCCTX *) +smbc_getFunctionListPrintJobs: smbc_list_print_jobs_fn (SMBCCTX *) +smbc_getFunctionListxattr: smbc_listxattr_fn (SMBCCTX *) +smbc_getFunctionLseek: smbc_lseek_fn (SMBCCTX *) +smbc_getFunctionLseekdir: smbc_lseekdir_fn (SMBCCTX *) +smbc_getFunctionMkdir: smbc_mkdir_fn (SMBCCTX *) +smbc_getFunctionNotify: smbc_notify_fn (SMBCCTX *) +smbc_getFunctionOpen: smbc_open_fn (SMBCCTX *) +smbc_getFunctionOpenPrintJob: smbc_open_print_job_fn (SMBCCTX *) +smbc_getFunctionOpendir: smbc_opendir_fn (SMBCCTX *) +smbc_getFunctionPrintFile: smbc_print_file_fn (SMBCCTX *) +smbc_getFunctionPurgeCachedServers: smbc_purge_cached_fn (SMBCCTX *) +smbc_getFunctionRead: smbc_read_fn (SMBCCTX *) +smbc_getFunctionReaddir: smbc_readdir_fn (SMBCCTX *) +smbc_getFunctionReaddirPlus: smbc_readdirplus_fn (SMBCCTX *) +smbc_getFunctionReaddirPlus2: smbc_readdirplus2_fn (SMBCCTX *) +smbc_getFunctionRemoveCachedServer: smbc_remove_cached_srv_fn (SMBCCTX *) +smbc_getFunctionRemoveUnusedServer: smbc_remove_unused_server_fn (SMBCCTX *) +smbc_getFunctionRemovexattr: smbc_removexattr_fn (SMBCCTX *) +smbc_getFunctionRename: smbc_rename_fn (SMBCCTX *) +smbc_getFunctionRmdir: smbc_rmdir_fn (SMBCCTX *) +smbc_getFunctionSetxattr: smbc_setxattr_fn (SMBCCTX *) +smbc_getFunctionSplice: smbc_splice_fn (SMBCCTX *) +smbc_getFunctionStat: smbc_stat_fn (SMBCCTX *) +smbc_getFunctionStatVFS: smbc_statvfs_fn (SMBCCTX *) +smbc_getFunctionTelldir: smbc_telldir_fn (SMBCCTX *) +smbc_getFunctionUnlink: smbc_unlink_fn (SMBCCTX *) +smbc_getFunctionUnlinkPrintJob: smbc_unlink_print_job_fn (SMBCCTX *) +smbc_getFunctionUtimes: smbc_utimes_fn (SMBCCTX *) +smbc_getFunctionWrite: smbc_write_fn (SMBCCTX *) +smbc_getNetbiosName: const char *(SMBCCTX *) +smbc_getOptionBrowseMaxLmbCount: int (SMBCCTX *) +smbc_getOptionCaseSensitive: smbc_bool (SMBCCTX *) +smbc_getOptionDebugToStderr: smbc_bool (SMBCCTX *) +smbc_getOptionFallbackAfterKerberos: smbc_bool (SMBCCTX *) +smbc_getOptionFullTimeNames: smbc_bool (SMBCCTX *) +smbc_getOptionNoAutoAnonymousLogin: smbc_bool (SMBCCTX *) +smbc_getOptionOneSharePerServer: smbc_bool (SMBCCTX *) +smbc_getOptionOpenShareMode: smbc_share_mode (SMBCCTX *) +smbc_getOptionSmbEncryptionLevel: smbc_smb_encrypt_level (SMBCCTX *) +smbc_getOptionUrlEncodeReaddirEntries: smbc_bool (SMBCCTX *) +smbc_getOptionUseCCache: smbc_bool (SMBCCTX *) +smbc_getOptionUseKerberos: smbc_bool (SMBCCTX *) +smbc_getOptionUseNTHash: smbc_bool (SMBCCTX *) +smbc_getOptionUserData: void *(SMBCCTX *) +smbc_getPort: uint16_t (SMBCCTX *) +smbc_getServerCacheData: struct smbc_server_cache *(SMBCCTX *) +smbc_getTimeout: int (SMBCCTX *) +smbc_getUser: const char *(SMBCCTX *) +smbc_getWorkgroup: const char *(SMBCCTX *) +smbc_getdents: int (unsigned int, struct smbc_dirent *, int) +smbc_getxattr: int (const char *, const char *, const void *, size_t) +smbc_init: int (smbc_get_auth_data_fn, int) +smbc_init_context: SMBCCTX *(SMBCCTX *) +smbc_lgetxattr: int (const char *, const char *, const void *, size_t) +smbc_list_print_jobs: int (const char *, smbc_list_print_job_fn) +smbc_listxattr: int (const char *, char *, size_t) +smbc_llistxattr: int (const char *, char *, size_t) +smbc_lremovexattr: int (const char *, const char *) +smbc_lseek: off_t (int, off_t, int) +smbc_lseekdir: int (int, off_t) +smbc_lsetxattr: int (const char *, const char *, const void *, size_t, int) +smbc_mkdir: int (const char *, mode_t) +smbc_new_context: SMBCCTX *(void) +smbc_notify: int (int, smbc_bool, uint32_t, unsigned int, smbc_notify_callback_fn, void *) +smbc_open: int (const char *, int, mode_t) +smbc_open_print_job: int (const char *) +smbc_opendir: int (const char *) +smbc_option_get: void *(SMBCCTX *, char *) +smbc_option_set: void (SMBCCTX *, char *, ...) +smbc_print_file: int (const char *, const char *) +smbc_read: ssize_t (int, void *, size_t) +smbc_readdir: struct smbc_dirent *(unsigned int) +smbc_readdirplus: const struct libsmb_file_info *(unsigned int) +smbc_readdirplus2: const struct libsmb_file_info *(unsigned int, struct stat *) +smbc_removexattr: int (const char *, const char *) +smbc_rename: int (const char *, const char *) +smbc_rmdir: int (const char *) +smbc_setConfiguration: int (SMBCCTX *, const char *) +smbc_setDebug: void (SMBCCTX *, int) +smbc_setFunctionAddCachedServer: void (SMBCCTX *, smbc_add_cached_srv_fn) +smbc_setFunctionAuthData: void (SMBCCTX *, smbc_get_auth_data_fn) +smbc_setFunctionAuthDataWithContext: void (SMBCCTX *, smbc_get_auth_data_with_context_fn) +smbc_setFunctionCheckServer: void (SMBCCTX *, smbc_check_server_fn) +smbc_setFunctionChmod: void (SMBCCTX *, smbc_chmod_fn) +smbc_setFunctionClose: void (SMBCCTX *, smbc_close_fn) +smbc_setFunctionClosedir: void (SMBCCTX *, smbc_closedir_fn) +smbc_setFunctionCreat: void (SMBCCTX *, smbc_creat_fn) +smbc_setFunctionFstat: void (SMBCCTX *, smbc_fstat_fn) +smbc_setFunctionFstatVFS: void (SMBCCTX *, smbc_fstatvfs_fn) +smbc_setFunctionFstatdir: void (SMBCCTX *, smbc_fstatdir_fn) +smbc_setFunctionFtruncate: void (SMBCCTX *, smbc_ftruncate_fn) +smbc_setFunctionGetCachedServer: void (SMBCCTX *, smbc_get_cached_srv_fn) +smbc_setFunctionGetdents: void (SMBCCTX *, smbc_getdents_fn) +smbc_setFunctionGetxattr: void (SMBCCTX *, smbc_getxattr_fn) +smbc_setFunctionListPrintJobs: void (SMBCCTX *, smbc_list_print_jobs_fn) +smbc_setFunctionListxattr: void (SMBCCTX *, smbc_listxattr_fn) +smbc_setFunctionLseek: void (SMBCCTX *, smbc_lseek_fn) +smbc_setFunctionLseekdir: void (SMBCCTX *, smbc_lseekdir_fn) +smbc_setFunctionMkdir: void (SMBCCTX *, smbc_mkdir_fn) +smbc_setFunctionNotify: void (SMBCCTX *, smbc_notify_fn) +smbc_setFunctionOpen: void (SMBCCTX *, smbc_open_fn) +smbc_setFunctionOpenPrintJob: void (SMBCCTX *, smbc_open_print_job_fn) +smbc_setFunctionOpendir: void (SMBCCTX *, smbc_opendir_fn) +smbc_setFunctionPrintFile: void (SMBCCTX *, smbc_print_file_fn) +smbc_setFunctionPurgeCachedServers: void (SMBCCTX *, smbc_purge_cached_fn) +smbc_setFunctionRead: void (SMBCCTX *, smbc_read_fn) +smbc_setFunctionReaddir: void (SMBCCTX *, smbc_readdir_fn) +smbc_setFunctionReaddirPlus: void (SMBCCTX *, smbc_readdirplus_fn) +smbc_setFunctionReaddirPlus2: void (SMBCCTX *, smbc_readdirplus2_fn) +smbc_setFunctionRemoveCachedServer: void (SMBCCTX *, smbc_remove_cached_srv_fn) +smbc_setFunctionRemoveUnusedServer: void (SMBCCTX *, smbc_remove_unused_server_fn) +smbc_setFunctionRemovexattr: void (SMBCCTX *, smbc_removexattr_fn) +smbc_setFunctionRename: void (SMBCCTX *, smbc_rename_fn) +smbc_setFunctionRmdir: void (SMBCCTX *, smbc_rmdir_fn) +smbc_setFunctionSetxattr: void (SMBCCTX *, smbc_setxattr_fn) +smbc_setFunctionSplice: void (SMBCCTX *, smbc_splice_fn) +smbc_setFunctionStat: void (SMBCCTX *, smbc_stat_fn) +smbc_setFunctionStatVFS: void (SMBCCTX *, smbc_statvfs_fn) +smbc_setFunctionTelldir: void (SMBCCTX *, smbc_telldir_fn) +smbc_setFunctionUnlink: void (SMBCCTX *, smbc_unlink_fn) +smbc_setFunctionUnlinkPrintJob: void (SMBCCTX *, smbc_unlink_print_job_fn) +smbc_setFunctionUtimes: void (SMBCCTX *, smbc_utimes_fn) +smbc_setFunctionWrite: void (SMBCCTX *, smbc_write_fn) +smbc_setLogCallback: void (SMBCCTX *, void *, smbc_debug_callback_fn) +smbc_setNetbiosName: void (SMBCCTX *, const char *) +smbc_setOptionBrowseMaxLmbCount: void (SMBCCTX *, int) +smbc_setOptionCaseSensitive: void (SMBCCTX *, smbc_bool) +smbc_setOptionDebugToStderr: void (SMBCCTX *, smbc_bool) +smbc_setOptionFallbackAfterKerberos: void (SMBCCTX *, smbc_bool) +smbc_setOptionFullTimeNames: void (SMBCCTX *, smbc_bool) +smbc_setOptionNoAutoAnonymousLogin: void (SMBCCTX *, smbc_bool) +smbc_setOptionOneSharePerServer: void (SMBCCTX *, smbc_bool) +smbc_setOptionOpenShareMode: void (SMBCCTX *, smbc_share_mode) +smbc_setOptionProtocols: smbc_bool (SMBCCTX *, const char *, const char *) +smbc_setOptionSmbEncryptionLevel: void (SMBCCTX *, smbc_smb_encrypt_level) +smbc_setOptionUrlEncodeReaddirEntries: void (SMBCCTX *, smbc_bool) +smbc_setOptionUseCCache: void (SMBCCTX *, smbc_bool) +smbc_setOptionUseKerberos: void (SMBCCTX *, smbc_bool) +smbc_setOptionUseNTHash: void (SMBCCTX *, smbc_bool) +smbc_setOptionUserData: void (SMBCCTX *, void *) +smbc_setPort: void (SMBCCTX *, uint16_t) +smbc_setServerCacheData: void (SMBCCTX *, struct smbc_server_cache *) +smbc_setTimeout: void (SMBCCTX *, int) +smbc_setUser: void (SMBCCTX *, const char *) +smbc_setWorkgroup: void (SMBCCTX *, const char *) +smbc_set_context: SMBCCTX *(SMBCCTX *) +smbc_set_credentials: void (const char *, const char *, const char *, smbc_bool, const char *) +smbc_set_credentials_with_fallback: void (SMBCCTX *, const char *, const char *, const char *) +smbc_setxattr: int (const char *, const char *, const void *, size_t, int) +smbc_stat: int (const char *, struct stat *) +smbc_statvfs: int (char *, struct statvfs *) +smbc_telldir: off_t (int) +smbc_unlink: int (const char *) +smbc_unlink_print_job: int (const char *, int) +smbc_urldecode: int (char *, char *, size_t) +smbc_urlencode: int (char *, char *, int) +smbc_utime: int (const char *, struct utimbuf *) +smbc_utimes: int (const char *, struct timeval *) +smbc_version: const char *(void) +smbc_write: ssize_t (int, const void *, size_t) diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index eaa0cdeca93..ea741f41c7d 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -171,7 +171,7 @@ smbc_new_context(void) smbc_setOptionFullTimeNames(context, False); smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); - smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE); + smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_DEFAULT); smbc_setOptionUseCCache(context, True); smbc_setOptionCaseSensitive(context, False); smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ @@ -474,6 +474,8 @@ smbc_option_get(SMBCCTX *context, } else if (strcmp(option_name, "smb_encrypt_level") == 0) { switch(smbc_getOptionSmbEncryptionLevel(context)) { + case SMBC_ENCRYPTLEVEL_DEFAULT: + return discard_const_p(void, "default"); case 0: return discard_const_p(void, "none"); case 1: diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 33dc8419deb..eb58d7c6ac9 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -284,6 +284,29 @@ static struct cli_credentials *SMBC_auth_credentials(TALLOC_CTX *mem_ctx, return NULL; } + switch (context->internal->smb_encryption_level) { + case SMBC_ENCRYPTLEVEL_DEFAULT: + /* Use the config option */ + break; + case SMBC_ENCRYPTLEVEL_NONE: + cli_credentials_set_smb_encryption(creds, + SMB_ENCRYPTION_OFF, + CRED_SPECIFIED); + break; + case SMBC_ENCRYPTLEVEL_REQUEST: + cli_credentials_set_smb_encryption(creds, + SMB_ENCRYPTION_DESIRED, + CRED_SPECIFIED); + break; + case SMBC_ENCRYPTLEVEL_REQUIRE: + default: + cli_credentials_set_smb_encryption(creds, + SMB_ENCRYPTION_REQUIRED, + CRED_SPECIFIED); + break; + } + + return creds; } @@ -625,30 +648,6 @@ SMBC_server_internal(TALLOC_CTX *ctx, smbXcli_tcon_set_fs_attributes(tcon, fs_attrs); } - if (context->internal->smb_encryption_level) { - /* Attempt encryption. */ - status = cli_cm_force_encryption_creds(c, - creds, - share); - if (!NT_STATUS_IS_OK(status)) { - - /* - * context->smb_encryption_level == 1 - * means don't fail if encryption can't be negotiated, - * == 2 means fail if encryption can't be negotiated. - */ - - DEBUG(4,(" SMB encrypt failed\n")); - - if (context->internal->smb_encryption_level == 2) { - cli_shutdown(c); - errno = EPERM; - return NULL; - } - } - DEBUG(4,(" SMB encrypt ok\n")); - } - /* * Ok, we have got a nice connection * Let's allocate a server structure. @@ -825,31 +824,6 @@ SMBC_attr_server(TALLOC_CTX *ctx, } talloc_steal(ipc_cli, creds); - if (context->internal->smb_encryption_level) { - /* Attempt encryption. */ - nt_status = cli_cm_force_encryption_creds(ipc_cli, - creds, - "IPC$"); - if (!NT_STATUS_IS_OK(nt_status)) { - - /* - * context->smb_encryption_level == - * 1 means don't fail if encryption can't be - * negotiated, == 2 means fail if encryption - * can't be negotiated. - */ - - DEBUG(4,(" SMB encrypt failed on IPC$\n")); - - if (context->internal->smb_encryption_level == 2) { - cli_shutdown(ipc_cli); - errno = EPERM; - return NULL; - } - } - DEBUG(4,(" SMB encrypt ok on IPC$\n")); - } - ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; diff --git a/source3/libsmb/wscript b/source3/libsmb/wscript index ec4a516b2ee..61503d0a98b 100644 --- a/source3/libsmb/wscript +++ b/source3/libsmb/wscript @@ -26,5 +26,5 @@ def build(bld): public_headers='../include/libsmbclient.h', abi_directory='ABI', abi_match='smbc_*', - vnum='0.6.0', + vnum='0.7.0', pc_files='smbclient.pc') -- 2.29.2 From 4f3adf58dded81470d654b36a6b41f44c97a0c1a Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:43:33 +0200 Subject: [PATCH 037/108] s3:client: Remove unused smb encryption code Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/client/smbspool.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index f56dc323b6e..16a8d44c069 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -584,16 +584,6 @@ smb_complete_connection(struct cli_state **output_cli, return nt_status; } -#if 0 - /* Need to work out how to specify this on the URL. */ - if (smb_encrypt) { - if (!cli_cm_force_encryption_creds(cli, creds, share)) { - fprintf(stderr, "ERROR: encryption setup failed\n"); - cli_shutdown(cli); - return NULL; - } - } -#endif *output_cli = cli; return NT_STATUS_OK; -- 2.29.2 From 98fd48ab6736cbc5321da554cbdade876747c8b2 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:47:05 +0200 Subject: [PATCH 038/108] s3:utils: Remove obsolete force encryption from smbacls Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/utils/smbcacls.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 5983ebbd0a5..8fd9fcc5780 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -784,16 +784,6 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info, return NULL; } - if (get_cmdline_auth_info_smb_encrypt(auth_info)) { - nt_status = cli_cm_force_encryption_creds(c, - get_cmdline_auth_info_creds(auth_info), - share); - if (!NT_STATUS_IS_OK(nt_status)) { - cli_shutdown(c); - c = NULL; - } - } - return c; } -- 2.29.2 From 60c9bdb31c4b558cb14a6861ecdb64a019c1a360 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:48:18 +0200 Subject: [PATCH 039/108] s3:utils: Remove obsolete force encryption from mdfind Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/utils/mdfind.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/source3/utils/mdfind.c b/source3/utils/mdfind.c index 2ac4fde7daf..ef2657e4fa5 100644 --- a/source3/utils/mdfind.c +++ b/source3/utils/mdfind.c @@ -159,13 +159,6 @@ int main(int argc, char **argv) goto fail; } - if (get_cmdline_auth_info_smb_encrypt(auth)) { - status = cli_cm_force_encryption_creds(cli, creds, "IPC$"); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - } - status = cli_rpc_pipe_open_noauth_transport(cli, NCACN_NP, &ndr_table_mdssvc, -- 2.29.2 From ad636063188db7e3307140edf7d5fdf40d79c0e4 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:49:28 +0200 Subject: [PATCH 040/108] s3:utils: Remove obsolete force encryption from smbcquotas Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/utils/smbcquotas.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/source3/utils/smbcquotas.c b/source3/utils/smbcquotas.c index fea066ce468..4ceac7b3ab0 100644 --- a/source3/utils/smbcquotas.c +++ b/source3/utils/smbcquotas.c @@ -533,17 +533,6 @@ static struct cli_state *connect_one(const char *share) return NULL; } - if (get_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info())) { - nt_status = cli_cm_force_encryption_creds(c, - get_cmdline_auth_info_creds( - popt_get_cmdline_auth_info()), - share); - if (!NT_STATUS_IS_OK(nt_status)) { - cli_shutdown(c); - return NULL; - } - } - return c; } -- 2.29.2 From 4b64497f1473661d86b032f2ae82c2c845cf8c8d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 10 Jun 2020 12:51:18 +0200 Subject: [PATCH 041/108] s3:rpcclient: Remove obsolete force encryption from rpcclient Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/rpcclient/rpcclient.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 2ead6cc7ba5..575a42ebf70 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -1214,17 +1214,6 @@ out_free: goto done; } - if (get_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info())) { - nt_status = cli_cm_force_encryption_creds(cli, - get_cmdline_auth_info_creds( - popt_get_cmdline_auth_info()), - "IPC$"); - if (!NT_STATUS_IS_OK(nt_status)) { - result = 1; - goto done; - } - } - #if 0 /* COMMENT OUT FOR TESTING */ memset(cmdline_auth_info.password,'X',sizeof(cmdline_auth_info.password)); #endif -- 2.29.2 From 10c912597ca6a00e62e2756c8b6a83a35fbc2da5 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 6 Jul 2020 10:58:36 +0200 Subject: [PATCH 042/108] examples: Remove obsolete force encryption from smb2mount Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- examples/fuse/smb2mount.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/examples/fuse/smb2mount.c b/examples/fuse/smb2mount.c index 6206c3a9701..c64be573462 100644 --- a/examples/fuse/smb2mount.c +++ b/examples/fuse/smb2mount.c @@ -44,17 +44,6 @@ static struct cli_state *connect_one(const struct user_auth_info *auth_info, return NULL; } - if (get_cmdline_auth_info_smb_encrypt(auth_info)) { - nt_status = cli_cm_force_encryption_creds( - c, - get_cmdline_auth_info_creds(auth_info), - share); - if (!NT_STATUS_IS_OK(nt_status)) { - cli_shutdown(c); - c = NULL; - } - } - return c; } -- 2.29.2 From acc244f893ee415fc572c701af6c9894acbefa93 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 6 Jul 2020 11:05:59 +0200 Subject: [PATCH 043/108] s3:libsmb: Make cli_cm_force_encryption_creds() static Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source3/libsmb/clidfs.c | 6 +++--- source3/libsmb/proto.h | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 4495a027830..aff998f6187 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -43,9 +43,9 @@ Ensure a connection is encrypted. ********************************************************************/ -NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c, - struct cli_credentials *creds, - const char *sharename) +static NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c, + struct cli_credentials *creds, + const char *sharename) { uint16_t major, minor; uint32_t caplow, caphigh; diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 850cf12c8a6..eeabcaa7463 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -123,9 +123,6 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, /* The following definitions come from libsmb/clidfs.c */ -NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c, - struct cli_credentials *creds, - const char *sharename); NTSTATUS cli_cm_open(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, -- 2.29.2 From 3c37b922596ec55b67942b901dd57abeb30197e8 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 13 Aug 2020 16:16:55 +0200 Subject: [PATCH 044/108] s4:libcli: Return NTSTATUS errors for smb_composite_connect_send() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source4/libcli/smb_composite/connect.c | 40 +++++++++++++++++++------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 582d43ef173..ad50ae0ac81 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -420,15 +420,25 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec struct connect_state *state; c = talloc_zero(mem_ctx, struct composite_context); - if (c == NULL) goto failed; - - c->event_ctx = event_ctx; - if (c->event_ctx == NULL) goto failed; + if (c == NULL) { + goto nomem; + } state = talloc_zero(c, struct connect_state); - if (state == NULL) goto failed; + if (state == NULL) { + goto nomem; + } + + c->event_ctx = event_ctx; + if (c->event_ctx == NULL) { + composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); + return c; + } - if (io->in.gensec_settings == NULL) goto failed; + if (io->in.gensec_settings == NULL) { + composite_error(c, NT_STATUS_INVALID_PARAMETER_MIX); + return c; + } state->io = io; c->state = COMPOSITE_STATE_IN_PROGRESS; @@ -449,12 +459,14 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec &io->in.options, &state->transport); if (!NT_STATUS_IS_OK(status)) { - goto failed; + composite_error(c, status); + return c; } status = connect_send_session(c, io); if (!NT_STATUS_IS_OK(status)) { - goto failed; + composite_error(c, status); + return c; } return c; @@ -468,15 +480,18 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec io->in.socket_options, &state->calling, &state->called); - if (state->creq == NULL) goto failed; + if (state->creq == NULL) { + composite_error(c, NT_STATUS_NO_MEMORY); + return c; + } state->stage = CONNECT_SOCKET; state->creq->async.private_data = c; state->creq->async.fn = composite_handler; return c; -failed: - talloc_free(c); +nomem: + TALLOC_FREE(c); return NULL; } @@ -506,5 +521,8 @@ NTSTATUS smb_composite_connect(struct smb_composite_connect *io, TALLOC_CTX *mem struct tevent_context *ev) { struct composite_context *c = smb_composite_connect_send(io, mem_ctx, resolve_ctx, ev); + if (c == NULL) { + return NT_STATUS_NO_MEMORY; + } return smb_composite_connect_recv(c, mem_ctx); } -- 2.29.2 From 5b37563928d8f82d90359aeb62b89203895bb480 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 7 Jul 2020 12:54:26 +0200 Subject: [PATCH 045/108] s4:libcli: Return if encryption is requested for SMB1 Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source4/libcli/smb_composite/sesssetup.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 6ee4929e8d7..51e121bdce6 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -620,10 +620,17 @@ struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *se struct composite_context *c; struct sesssetup_state *state; NTSTATUS status; + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(io->in.credentials); c = composite_create(session, session->transport->ev); if (c == NULL) return NULL; + if (encryption_state > SMB_ENCRYPTION_DESIRED) { + composite_error(c, NT_STATUS_PROTOCOL_NOT_SUPPORTED); + return c; + } + state = talloc_zero(c, struct sesssetup_state); if (composite_nomem(state, c)) return c; c->private_data = state; -- 2.29.2 From 2d46ced85e374a823ecafde16743456eede6ce9e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 7 Jul 2020 12:29:39 +0200 Subject: [PATCH 046/108] s3:libcli: Split out smb2_connect_tcon_start() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source4/libcli/smb2/connect.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 6fc3993a4e8..95ff05eac8f 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -237,6 +237,7 @@ static void smb2_connect_session_start(struct tevent_req *req) tevent_req_set_callback(subreq, smb2_connect_session_done, req); } +static void smb2_connect_tcon_start(struct tevent_req *req); static void smb2_connect_tcon_done(struct tevent_req *subreq); static void smb2_connect_session_done(struct tevent_req *subreq) @@ -248,7 +249,6 @@ static void smb2_connect_session_done(struct tevent_req *subreq) tevent_req_data(req, struct smb2_connect_state); NTSTATUS status; - uint32_t timeout_msec; status = smb2_session_setup_spnego_recv(subreq); TALLOC_FREE(subreq); @@ -289,6 +289,17 @@ static void smb2_connect_session_done(struct tevent_req *subreq) return; } + smb2_connect_tcon_start(req); +} + +static void smb2_connect_tcon_start(struct tevent_req *req) +{ + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + struct tevent_req *subreq = NULL; + uint32_t timeout_msec; + timeout_msec = state->transport->options.request_timeout * 1000; subreq = smb2cli_tcon_send(state, state->ev, -- 2.29.2 From 5ee85438a34c78b1ec626002192a7118fb01fdb7 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 7 Jul 2020 12:44:26 +0200 Subject: [PATCH 047/108] s4:libcli: Add smb2_connect_enc_start() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source4/libcli/smb2/connect.c | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 95ff05eac8f..3a3ecdf20e8 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -237,6 +237,7 @@ static void smb2_connect_session_start(struct tevent_req *req) tevent_req_set_callback(subreq, smb2_connect_session_done, req); } +static void smb2_connect_enc_start(struct tevent_req *req); static void smb2_connect_tcon_start(struct tevent_req *req); static void smb2_connect_tcon_done(struct tevent_req *subreq); @@ -289,6 +290,43 @@ static void smb2_connect_session_done(struct tevent_req *subreq) return; } + smb2_connect_enc_start(req); +} + +static void smb2_connect_enc_start(struct tevent_req *req) +{ + struct smb2_connect_state *state = + tevent_req_data(req, + struct smb2_connect_state); + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(state->credentials); + NTSTATUS status; + + if (encryption_state < SMB_ENCRYPTION_DESIRED) { + smb2_connect_tcon_start(req); + return; + } + + status = smb2cli_session_encryption_on(state->session->smbXcli); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + if (encryption_state < SMB_ENCRYPTION_REQUIRED) { + smb2_connect_tcon_start(req); + return; + } + + DBG_ERR("Encryption required and server doesn't support " + "SMB3 encryption - failing connect\n"); + tevent_req_nterror(req, status); + return; + } + + DBG_ERR("Encryption required and setup failed with error %s.\n", + nt_errstr(status)); + tevent_req_nterror(req, NT_STATUS_PROTOCOL_NOT_SUPPORTED); + return; + } + smb2_connect_tcon_start(req); } -- 2.29.2 From 7620d79d4aef09bf893ef1823cb3c8a12bdd6977 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 24 Jul 2020 10:18:52 +0200 Subject: [PATCH 048/108] s4:libcli: Require signing for SMB encryption Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher --- source4/libcli/smb2/connect.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index 3a3ecdf20e8..9540704491e 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -31,6 +31,7 @@ #include "param/param.h" #include "auth/credentials/credentials.h" #include "../libcli/smb/smbXcli_base.h" +#include "smb2_constants.h" struct smb2_connect_state { struct tevent_context *ev; @@ -76,6 +77,8 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx, struct smb2_connect_state *state; struct composite_context *creq; static const char *default_ports[] = { "445", "139", NULL }; + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(credentials); req = tevent_req_create(mem_ctx, &state, struct smb2_connect_state); @@ -99,6 +102,10 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx, state->ports = default_ports; } + if (encryption_state >= SMB_ENCRYPTION_DESIRED) { + state->options.signing = SMB_SIGNING_REQUIRED; + } + make_nbt_name_client(&state->calling, cli_credentials_get_workstation(credentials)); @@ -116,7 +123,7 @@ struct tevent_req *smb2_connect_send(TALLOC_CTX *mem_ctx, status = smb2_transport_raw_init(state, ev, existing_conn, - options, + &state->options, &state->transport); if (tevent_req_nterror(req, status)) { return tevent_req_post(req, ev); -- 2.29.2 From 28403a2791fda77fe9fb73202964a3cea1eb732c Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 7 Jul 2020 14:27:07 +0200 Subject: [PATCH 049/108] python:tests: Add test for SMB encrypted DCERPC connection Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Wed Aug 19 17:46:28 UTC 2020 on sn-devel-184 --- python/samba/tests/dcerpc/binding.py | 82 ++++++++++++++++++++++++++++ selftest/tests.py | 1 + 2 files changed, 83 insertions(+) create mode 100644 python/samba/tests/dcerpc/binding.py diff --git a/python/samba/tests/dcerpc/binding.py b/python/samba/tests/dcerpc/binding.py new file mode 100644 index 00000000000..8e0d6a5ef0a --- /dev/null +++ b/python/samba/tests/dcerpc/binding.py @@ -0,0 +1,82 @@ +# +# Unix SMB/CIFS implementation. +# Copyright (c) 2020 Andreas Schneider +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +"""Tests for samba.dcerpc., credentials and binding strings""" + +import samba.tests +from samba.tests import RpcInterfaceTestCase, TestCase +from samba.dcerpc import lsa +import samba.dcerpc.security as security +from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED +from samba import NTSTATUSError + +class RpcBindingTests(RpcInterfaceTestCase): + def setUp(self): + super(RpcBindingTests, self).setUp() + + def get_user_creds(self): + c = Credentials() + c.guess() + domain = samba.tests.env_get_var_value('DOMAIN') + username = samba.tests.env_get_var_value('USERNAME') + password = samba.tests.env_get_var_value('PASSWORD') + c.set_domain(domain) + c.set_username(username) + c.set_password(password) + return c + + def test_smb3_dcerpc_encryption(self): + creds = self.get_user_creds() + creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + + lp = self.get_loadparm() + lp.set('client ipc max protocol', 'SMB3') + lp.set('client ipc min protocol', 'SMB3') + + binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER'))) + lsa_conn = lsa.lsarpc(binding_string, lp, creds) + + objectAttr = lsa.ObjectAttribute() + objectAttr.sec_qos = lsa.QosInfo() + + pol_handle = lsa_conn.OpenPolicy2('', + objectAttr, + security.SEC_FLAG_MAXIMUM_ALLOWED) + self.assertIsNotNone(pol_handle) + + def test_smb2_dcerpc_encryption(self): + creds = self.get_user_creds() + creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + + lp = self.get_loadparm() + lp.set('client ipc max protocol', 'SMB2') + lp.set('client ipc min protocol', 'SMB2') + + binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER'))) + self.assertRaises(NTSTATUSError, lsa.lsarpc, binding_string, lp, creds) + + def test_smb1_dcerpc_encryption(self): + creds = self.get_user_creds() + creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + + lp = self.get_loadparm() + lp.set('client ipc max protocol', 'NT1') + lp.set('client ipc min protocol', 'NT1') + + binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER'))) + self.assertRaises(NTSTATUSError, lsa.lsarpc, binding_string, lp, creds) diff --git a/selftest/tests.py b/selftest/tests.py index 20981754db4..adcb5b53189 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -92,6 +92,7 @@ planpythontestsuite( extra_path=[os.path.join(samba4srcdir, "..", "buildtools"), os.path.join(samba4srcdir, "..", "third_party", "waf")]) planpythontestsuite("fileserver", "samba.tests.smbd_fuzztest") +planpythontestsuite("nt4_dc_smb1", "samba.tests.dcerpc.binding") def cmdline(script, *args): -- 2.29.2 From 77523b06608555f58f31267a95ae54fd8bc3f495 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Sep 2020 10:47:54 +0200 Subject: [PATCH 050/108] auth:gensec: Add gensec_security_sasl_names() Pair-Programmed-With: Andreas Schneider Signed-off-by: Andreas Schneider Signed-off-by: Stefan Metzmacher (cherry picked from commit b34e8dc8982b625d946e2ac8794ee41311bc41c2) --- auth/gensec/gensec.h | 2 + auth/gensec/gensec_start.c | 87 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index d424067d02c..fe26fff171a 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -308,6 +308,8 @@ const struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, const char *sasl_name); +const char **gensec_security_sasl_names(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx); int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value); bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value); diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index d2d62d6652e..4eb45643714 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -299,6 +299,93 @@ const struct gensec_security_ops *gensec_security_by_name(struct gensec_security return NULL; } +static const char **gensec_security_sasl_names_from_ops( + struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, + const struct gensec_security_ops * const *ops) +{ + const char **sasl_names = NULL; + size_t i, sasl_names_count = 0; + + if (ops == NULL) { + return NULL; + } + + sasl_names = talloc_array(mem_ctx, const char *, 1); + if (sasl_names == NULL) { + return NULL; + } + + for (i = 0; ops[i] != NULL; i++) { + enum gensec_role role = GENSEC_SERVER; + const char **tmp = NULL; + + if (ops[i]->sasl_name == NULL) { + continue; + } + + if (gensec_security != NULL) { + if (!gensec_security_ops_enabled(ops[i], + gensec_security)) { + continue; + } + + role = gensec_security->gensec_role; + } + + switch (role) { + case GENSEC_CLIENT: + if (ops[i]->client_start == NULL) { + continue; + } + break; + case GENSEC_SERVER: + if (ops[i]->server_start == NULL) { + continue; + } + break; + } + + tmp = talloc_realloc(mem_ctx, + sasl_names, + const char *, + sasl_names_count + 2); + if (tmp == NULL) { + TALLOC_FREE(sasl_names); + return NULL; + } + sasl_names = tmp; + + sasl_names[sasl_names_count] = ops[i]->sasl_name; + sasl_names_count++; + } + sasl_names[sasl_names_count] = NULL; + + return sasl_names; +} + +/** + * @brief Get the sasl names from the gensec security context. + * + * @param[in] gensec_security The gensec security context. + * + * @param[in] mem_ctx The memory context to allocate memory on. + * + * @return An allocated array with sasl names, NULL on error. + */ +_PUBLIC_ +const char **gensec_security_sasl_names(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx) +{ + const struct gensec_security_ops **ops = NULL; + + ops = gensec_security_mechs(gensec_security, mem_ctx); + + return gensec_security_sasl_names_from_ops(gensec_security, + mem_ctx, + ops); +} + /** * Return a unique list of security subsystems from those specified in * the list of SASL names. -- 2.29.2 From 84fb67e29e2e220b6e74067cab4ee986c53d6a0e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Sep 2020 10:48:27 +0200 Subject: [PATCH 051/108] s4:ldap_server: Use samba_server_gensec_start() in ldapsrv_backend_Init() Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 5e3363e0b82193700f91a9bae5080aae0b744e5c) --- source4/dsdb/samdb/ldb_modules/rootdse.c | 4 +- source4/ldap_server/ldap_backend.c | 49 +++++++++++------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 55340fa4f1e..4be9550747c 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -230,7 +230,7 @@ static int rootdse_add_dynamic(struct rootdse_context *ac, struct ldb_message *m struct ldb_context *ldb; struct rootdse_private_data *priv = talloc_get_type(ldb_module_get_private(ac->module), struct rootdse_private_data); const char * const *attrs = ac->req->op.search.attrs; - char **server_sasl; + const char **server_sasl = NULL; const struct dsdb_schema *schema; int *val; struct ldb_control *edn_control; @@ -341,7 +341,7 @@ static int rootdse_add_dynamic(struct rootdse_context *ac, struct ldb_message *m } server_sasl = talloc_get_type(ldb_get_opaque(ldb, "supportedSASLMechanisms"), - char *); + const char *); if (server_sasl && do_attribute(attrs, "supportedSASLMechanisms")) { for (i = 0; server_sasl && server_sasl[i]; i++) { char *sasl_name = talloc_strdup(msg, server_sasl[i]); diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index 2839082daef..915d9b94f9b 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -33,6 +33,7 @@ #include "ldb_wrap.h" #include "lib/tsocket/tsocket.h" #include "libcli/ldap/ldap_proto.h" +#include "source4/auth/auth.h" static int map_ldb_error(TALLOC_CTX *mem_ctx, int ldb_err, const char *add_err_string, const char **errstring) @@ -199,37 +200,33 @@ int ldapsrv_backend_Init(struct ldapsrv_connection *conn, } if (conn->server_credentials) { - char **sasl_mechs = NULL; - const struct gensec_security_ops * const *backends = gensec_security_all(); - const struct gensec_security_ops **ops - = gensec_use_kerberos_mechs(conn, backends, conn->server_credentials); - unsigned int i, j = 0; - for (i = 0; ops && ops[i]; i++) { - if (!lpcfg_parm_bool(conn->lp_ctx, NULL, "gensec", ops[i]->name, ops[i]->enabled)) - continue; - - if (ops[i]->sasl_name && ops[i]->server_start) { - char *sasl_name = talloc_strdup(conn, ops[i]->sasl_name); - - if (!sasl_name) { - return LDB_ERR_OPERATIONS_ERROR; - } - sasl_mechs = talloc_realloc(conn, sasl_mechs, char *, j + 2); - if (!sasl_mechs) { - return LDB_ERR_OPERATIONS_ERROR; - } - sasl_mechs[j] = sasl_name; - talloc_steal(sasl_mechs, sasl_name); - sasl_mechs[j+1] = NULL; - j++; - } + struct gensec_security *gensec_security = NULL; + const char **sasl_mechs = NULL; + NTSTATUS status; + + status = samba_server_gensec_start(conn, + conn->connection->event.ctx, + conn->connection->msg_ctx, + conn->lp_ctx, + conn->server_credentials, + "ldap", + &gensec_security); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("samba_server_gensec_start failed: %s\n", + nt_errstr(status)); + return LDB_ERR_OPERATIONS_ERROR; } - talloc_unlink(conn, ops); /* ldb can have a different lifetime to conn, so we need to ensure that sasl_mechs lives as long as the ldb does */ - talloc_steal(conn->ldb, sasl_mechs); + sasl_mechs = gensec_security_sasl_names(gensec_security, + conn->ldb); + TALLOC_FREE(gensec_security); + if (sasl_mechs == NULL) { + DBG_ERR("Failed to get sasl mechs!\n"); + return LDB_ERR_OPERATIONS_ERROR; + } ldb_set_opaque(conn->ldb, "supportedSASLMechanisms", sasl_mechs); } -- 2.29.2 From 79d9d8b597afc5f637039b29dd13a363c8cb9b54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Sep 2020 14:39:15 +0200 Subject: [PATCH 052/108] auth:gensec: Make gensec_use_kerberos_mechs() a static function Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit 2186d4131ad4c7961d0c830bf9d48f3d06d27924) --- auth/gensec/gensec.h | 3 --- auth/gensec/gensec_start.c | 7 ++++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/auth/gensec/gensec.h b/auth/gensec/gensec.h index fe26fff171a..8bece3c3458 100644 --- a/auth/gensec/gensec.h +++ b/auth/gensec/gensec.h @@ -302,9 +302,6 @@ NTSTATUS gensec_wrap(struct gensec_security *gensec_security, const struct gensec_security_ops * const *gensec_security_all(void); bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct gensec_security *security); -const struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx, - const struct gensec_security_ops * const *old_gensec_list, - struct cli_credentials *creds); NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, const char *sasl_name); diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index 4eb45643714..ebcab76999a 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -83,9 +83,10 @@ bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct g * more compplex. */ -_PUBLIC_ const struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx, - const struct gensec_security_ops * const *old_gensec_list, - struct cli_credentials *creds) +static const struct gensec_security_ops **gensec_use_kerberos_mechs( + TALLOC_CTX *mem_ctx, + const struct gensec_security_ops * const *old_gensec_list, + struct cli_credentials *creds) { const struct gensec_security_ops **new_gensec_list; int i, j, num_mechs_in; -- 2.29.2 From 434d9895989832e7f338c565c43ff2f7fa9c514e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Sep 2020 14:41:43 +0200 Subject: [PATCH 053/108] auth:gensec: Pass use_kerberos and keep_schannel to gensec_use_kerberos_mechs() Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider (cherry picked from commit a33a40bbc848e5691869cf264009d23a03128f31) --- auth/gensec/gensec_start.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index ebcab76999a..8d1b41fec74 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -86,19 +86,11 @@ bool gensec_security_ops_enabled(const struct gensec_security_ops *ops, struct g static const struct gensec_security_ops **gensec_use_kerberos_mechs( TALLOC_CTX *mem_ctx, const struct gensec_security_ops * const *old_gensec_list, - struct cli_credentials *creds) + enum credentials_use_kerberos use_kerberos, + bool keep_schannel) { const struct gensec_security_ops **new_gensec_list; int i, j, num_mechs_in; - enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS; - bool keep_schannel = false; - - if (creds) { - use_kerberos = cli_credentials_get_kerberos_state(creds); - if (cli_credentials_get_netlogon_creds(creds) != NULL) { - keep_schannel = true; - } - } for (num_mechs_in=0; old_gensec_list && old_gensec_list[num_mechs_in]; num_mechs_in++) { /* noop */ @@ -163,18 +155,28 @@ _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs( struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx) { - struct cli_credentials *creds = NULL; const struct gensec_security_ops * const *backends = gensec_security_all(); + enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS; + bool keep_schannel = false; if (gensec_security != NULL) { + struct cli_credentials *creds = NULL; + creds = gensec_get_credentials(gensec_security); + if (creds != NULL) { + use_kerberos = cli_credentials_get_kerberos_state(creds); + if (cli_credentials_get_netlogon_creds(creds) != NULL) { + keep_schannel = true; + } + } if (gensec_security->settings->backends) { backends = gensec_security->settings->backends; } } - return gensec_use_kerberos_mechs(mem_ctx, backends, creds); + return gensec_use_kerberos_mechs(mem_ctx, backends, + use_kerberos, keep_schannel); } -- 2.29.2 From 0da017218009cce876c3e251beec5ea6958717f4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 4 Sep 2020 17:00:45 +0200 Subject: [PATCH 054/108] auth:gensec: If Kerberos is required, keep schannel for machine account auth Signed-off-by: Stefan Metzmacher Signed-off-by: Andreas Schneider (cherry picked from commit 515cffb1f20eacb041ff7b3d43f8a122a82ddfbd) --- auth/gensec/gensec_start.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index 8d1b41fec74..3f42d611140 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -168,6 +168,15 @@ _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs( if (cli_credentials_get_netlogon_creds(creds) != NULL) { keep_schannel = true; } + + /* + * Even if Kerberos is set to REQUIRED, keep the + * schannel auth mechanism that machine accounts are + * able to authenticate via netlogon. + */ + if (gensec_security->gensec_role == GENSEC_SERVER) { + keep_schannel = true; + } } if (gensec_security->settings->backends) { -- 2.29.2 From 9242884180b1f6bb202f7c5249f8d37a2453141e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 4 Sep 2020 12:21:21 +0200 Subject: [PATCH 055/108] auth:creds: Add cli_credentials_init_server() Signed-off-by: Andreas Schneider Reviewed-by: Stefan Metzmacher (cherry picked from commit 2c00bea2aefdcc69608dffdafa7ce581d31f9354) --- auth/credentials/credentials.c | 25 +++++++++++++++++++++++++ auth/credentials/credentials.h | 2 ++ 2 files changed, 27 insertions(+) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index 9168b92d3ec..77c35dd104b 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -56,6 +56,31 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) return cred; } +_PUBLIC_ +struct cli_credentials *cli_credentials_init_server(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx) +{ + struct cli_credentials *server_creds = NULL; + NTSTATUS status; + + server_creds = cli_credentials_init(mem_ctx); + if (server_creds == NULL) { + return NULL; + } + + cli_credentials_set_conf(server_creds, lp_ctx); + + status = cli_credentials_set_machine_account(server_creds, lp_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("Failed to obtain server credentials: %s\n", + nt_errstr(status))); + TALLOC_FREE(server_creds); + return NULL; + } + + return server_creds; +} + _PUBLIC_ void cli_credentials_set_callback_data(struct cli_credentials *cred, void *callback_data) { diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 7d0cf53194b..438bcdce232 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -76,6 +76,8 @@ bool cli_credentials_set_workstation(struct cli_credentials *cred, enum credentials_obtained obtained); bool cli_credentials_is_anonymous(struct cli_credentials *cred); struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx); +struct cli_credentials *cli_credentials_init_server(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx); void cli_credentials_set_anonymous(struct cli_credentials *cred); bool cli_credentials_wrong_password(struct cli_credentials *cred); const char *cli_credentials_get_password(struct cli_credentials *cred); -- 2.29.2 From 2da8321de6ef2e81378bdb3221a7e9d398eebcc5 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 4 Sep 2020 12:21:36 +0200 Subject: [PATCH 056/108] s4:rpc_server: Use cli_credentials_init_server() Signed-off-by: Andreas Schneider (cherry picked from commit 6c94ebf77fdb7383be2042f5e20ba2ef598cd4a4) --- source4/rpc_server/dcerpc_server.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 084857a44bf..e64148ef788 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -673,25 +673,14 @@ NTSTATUS dcesrv_gensec_prepare(TALLOC_CTX *mem_ctx, struct cli_credentials *server_creds = NULL; struct imessaging_context *imsg_ctx = dcesrv_imessaging_context(call->conn); - NTSTATUS status; - server_creds = cli_credentials_init(call->auth_state); - if (!server_creds) { + server_creds = cli_credentials_init_server(call->auth_state, + call->conn->dce_ctx->lp_ctx); + if (server_creds == NULL) { DEBUG(1, ("Failed to init server credentials\n")); return NT_STATUS_NO_MEMORY; } - cli_credentials_set_conf(server_creds, call->conn->dce_ctx->lp_ctx); - - status = cli_credentials_set_machine_account(server_creds, - call->conn->dce_ctx->lp_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("Failed to obtain server credentials: %s\n", - nt_errstr(status))); - talloc_free(server_creds); - return status; - } - return samba_server_gensec_start(mem_ctx, call->event_ctx, imsg_ctx, -- 2.29.2 From 5a641937dc9b842a70754950f157ef8a559a49c8 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 7 Sep 2020 09:19:43 +0200 Subject: [PATCH 057/108] s4:smb_server: Use cli_credentials_init_server() for negprot Signed-off-by: Andreas Schneider Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Mon Sep 7 13:22:26 UTC 2020 on sn-devel-184 (cherry picked from commit 0b742ec6a0558397d5cf01b99a401f8e2bc0e2e0) --- source4/smb_server/smb/negprot.c | 28 ++++++++++++++-------------- source4/smb_server/smb2/negprot.c | 25 +++++++++++++------------ 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index a6177a72019..04b69dd9883 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -374,22 +374,22 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) DATA_BLOB blob = data_blob_null; const char *oid; NTSTATUS nt_status; - - server_credentials - = cli_credentials_init(req); - if (!server_credentials) { - smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n"); - return; - } - - cli_credentials_set_conf(server_credentials, req->smb_conn->lp_ctx); - nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); + + server_credentials = + cli_credentials_init_server(req, req->smb_conn->lp_ctx); + if (server_credentials == NULL) { + DBG_DEBUG("Failed to obtain server credentials, " + "perhaps a standalone server?\n"); /* - * We keep the server_credentials as anonymous - * this is required for the spoolss.notify test + * Create anon server credentials for for the + * spoolss.notify test. */ + server_credentials = cli_credentials_init_anon(req); + if (server_credentials == NULL) { + smbsrv_terminate_connection(req->smb_conn, + "Failed to init server credentials\n"); + return; + } } nt_status = samba_server_gensec_start(req, diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 4aaaf46793b..c433eb194bd 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -39,20 +39,21 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB * NTSTATUS nt_status; struct cli_credentials *server_credentials; - server_credentials = cli_credentials_init(req); - if (!server_credentials) { - smbsrv_terminate_connection(req->smb_conn, "Failed to init server credentials\n"); - return NT_STATUS_NO_MEMORY; - } - - cli_credentials_set_conf(server_credentials, req->smb_conn->lp_ctx); - nt_status = cli_credentials_set_machine_account(server_credentials, req->smb_conn->lp_ctx); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(10, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(nt_status))); + server_credentials = + cli_credentials_init_server(req, req->smb_conn->lp_ctx); + if (server_credentials == NULL) { + DBG_DEBUG("Failed to obtain server credentials, " + "perhaps a standalone server?\n"); /* - * We keep the server_credentials as anonymous - * this is required for the spoolss.notify test + * Create anon server credentials for for the + * spoolss.notify test. */ + server_credentials = cli_credentials_init_anon(req); + if (server_credentials == NULL) { + smbsrv_terminate_connection(req->smb_conn, + "Failed to init server credentials\n"); + return NT_STATUS_NO_MEMORY; + } } req->smb_conn->negotiate.server_credentials = talloc_steal(req->smb_conn, server_credentials); -- 2.29.2 From 1f73660655160daa18acf5943dfd7cc323e801bd Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 8 Sep 2020 10:15:22 +0200 Subject: [PATCH 058/108] selftest: Rename 'smb encrypt' to 'server smb encrypt' This makes it more clear what we want. 'smb encrypt' is a synonym for 'server smb encrypt'. Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit c75e8ff47b4d79b37240f9461ddae10a4f03c892) --- selftest/target/Samba3.pm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index e141f102ef1..c070086ca49 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1178,7 +1178,7 @@ sub setup_simpleserver ntlm auth = yes vfs objects = xattr_tdb streams_depot change notify = no - smb encrypt = off + server smb encrypt = off [vfs_aio_pthread] path = $prefix_abs/share @@ -1245,7 +1245,7 @@ sub setup_simpleserver [enc_desired] path = $prefix_abs/share vfs objects = - smb encrypt = desired + server smb encrypt = desired [hidenewfiles] path = $prefix_abs/share @@ -2351,7 +2351,7 @@ sub provision($$) [tmpenc] path = $shrdir comment = encrypt smb username is [%U] - smb encrypt = required + server smb encrypt = required vfs objects = dirsort [tmpguest] path = $shrdir -- 2.29.2 From a939facd076f75564d1a9e3c4afbb953a67bb6fe Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 8 Sep 2020 12:30:08 +0200 Subject: [PATCH 059/108] selftest: Move enc_desired to provision to have it in 'fileserver' too Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 1b67943f938ae774360dc3db73db940f9982243b) --- selftest/target/Samba3.pm | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index c070086ca49..fa3ca8962a5 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -1242,11 +1242,6 @@ sub setup_simpleserver hide files = /hidefile/ hide dot files = yes -[enc_desired] - path = $prefix_abs/share - vfs objects = - server smb encrypt = desired - [hidenewfiles] path = $prefix_abs/share hide new files timeout = 5 @@ -2833,7 +2828,13 @@ sub provision($$) [delete_readonly] path = $prefix_abs/share delete readonly = yes + +[enc_desired] + path = $prefix_abs/share + vfs objects = + server smb encrypt = desired "; + close(CONF); my $net = Samba::bindir_path($self, "net"); -- 2.29.2 From 297f6cd53a59a5f7e1bd8e57a791977de64e3f8c Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 8 Sep 2020 10:15:20 +0200 Subject: [PATCH 060/108] s3:tests: Add smbclient tests for 'client smb encrypt' Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit e7577ab6cbc83b496ac091c3e425c7c7fea29cdb) --- selftest/knownfail.d/smbclient-encryption | 2 + selftest/target/Samba3.pm | 5 ++ .../script/tests/test_smbclient_encryption.sh | 72 +++++++++++++++++++ source3/selftest/tests.py | 6 ++ 4 files changed, 85 insertions(+) create mode 100644 selftest/knownfail.d/smbclient-encryption create mode 100755 source3/script/tests/test_smbclient_encryption.sh diff --git a/selftest/knownfail.d/smbclient-encryption b/selftest/knownfail.d/smbclient-encryption new file mode 100644 index 00000000000..972096bdc8b --- /dev/null +++ b/selftest/knownfail.d/smbclient-encryption @@ -0,0 +1,2 @@ +^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.enc_desired..simpleserver +^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.tmp..simpleserver diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index fa3ca8962a5..ffc19c7d5a2 100755 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -2833,6 +2833,11 @@ sub provision($$) path = $prefix_abs/share vfs objects = server smb encrypt = desired + +[enc_off] + path = $prefix_abs/share + vfs objects = + server smb encrypt = off "; close(CONF); diff --git a/source3/script/tests/test_smbclient_encryption.sh b/source3/script/tests/test_smbclient_encryption.sh new file mode 100755 index 00000000000..9a717cdac4f --- /dev/null +++ b/source3/script/tests/test_smbclient_encryption.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +if [ $# -lt 5 ]; then +cat < Date: Thu, 27 Aug 2020 15:19:27 +0200 Subject: [PATCH 061/108] s3:client: Remove global smb_encrypt Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 1189b20cb7ea09cfed5c246cf977442a51ef72cb) --- source3/client/client.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 56309efcea7..60d4fb3c5ee 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -96,9 +96,6 @@ static unsigned int put_total_time_ms = 0; /* totals globals */ static double dir_total; -/* encrypted state. */ -static bool smb_encrypt; - /* root cli_state connection */ struct cli_state *cli; @@ -2758,7 +2755,7 @@ static int cmd_posix_encrypt(void) d_printf("posix_encrypt failed with error %s\n", nt_errstr(status)); } else { d_printf("encryption on\n"); - smb_encrypt = true; + set_cmdline_auth_info_smb_encrypt(popt_get_cmdline_auth_info()); } return 0; @@ -5283,6 +5280,9 @@ int cmd_iosize(void) TALLOC_CTX *ctx = talloc_tos(); char *buf; int iosize; + bool smb_encrypt = + get_cmdline_auth_info_smb_encrypt( + popt_get_cmdline_auth_info()); if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { @@ -5546,6 +5546,9 @@ static int process_command_string(const char *cmd_in) TALLOC_CTX *ctx = talloc_tos(); char *cmd = talloc_strdup(ctx, cmd_in); int rc = 0; + bool smb_encrypt = + get_cmdline_auth_info_smb_encrypt( + popt_get_cmdline_auth_info()); if (!cmd) { return 1; @@ -5999,6 +6002,9 @@ static int process(const char *base_directory) { int rc = 0; NTSTATUS status; + bool smb_encrypt = + get_cmdline_auth_info_smb_encrypt( + popt_get_cmdline_auth_info()); status = cli_cm_open(talloc_tos(), NULL, desthost, @@ -6037,6 +6043,9 @@ static int process(const char *base_directory) static int do_host_query(const char *query_host) { NTSTATUS status; + bool smb_encrypt = + get_cmdline_auth_info_smb_encrypt( + popt_get_cmdline_auth_info()); status = cli_cm_open(talloc_tos(), NULL, query_host, @@ -6114,6 +6123,9 @@ static int do_tar_op(const char *base_directory) { struct tar *tar_ctx = tar_get_ctx(); int ret = 0; + bool smb_encrypt = + get_cmdline_auth_info_smb_encrypt( + popt_get_cmdline_auth_info()); /* do we already have a connection? */ if (!cli) { @@ -6459,9 +6471,6 @@ int main(int argc,char *argv[]) case 'q': quiet=true; break; - case 'e': - smb_encrypt=true; - break; case 'B': return(do_smb_browse()); @@ -6531,8 +6540,6 @@ int main(int argc,char *argv[]) /* Ensure we have a password (or equivalent). */ popt_common_credentials_post(); - smb_encrypt = get_cmdline_auth_info_smb_encrypt( - popt_get_cmdline_auth_info()); max_protocol = lp_client_max_protocol(); -- 2.29.2 From 743cf3240680fd7b868dd789fd743ab9ecd66ace Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 15:24:27 +0200 Subject: [PATCH 062/108] s3:libsmb: Remove force_encrypt from cli_cm_open() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit a9fbc8dae878ddfa54153e91cc1128c307816b76) --- source3/client/client.c | 21 ++++----------------- source3/lib/netapi/cm.c | 1 - source3/libsmb/clidfs.c | 4 ++-- source3/libsmb/proto.h | 1 - 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 60d4fb3c5ee..3a610086511 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -5546,9 +5546,6 @@ static int process_command_string(const char *cmd_in) TALLOC_CTX *ctx = talloc_tos(); char *cmd = talloc_strdup(ctx, cmd_in); int rc = 0; - bool smb_encrypt = - get_cmdline_auth_info_smb_encrypt( - popt_get_cmdline_auth_info()); if (!cmd) { return 1; @@ -5561,7 +5558,6 @@ static int process_command_string(const char *cmd_in) status = cli_cm_open(talloc_tos(), NULL, desthost, service, popt_get_cmdline_auth_info(), - smb_encrypt, max_protocol, have_ip ? &dest_ss : NULL, port, name_type, @@ -6002,14 +5998,11 @@ static int process(const char *base_directory) { int rc = 0; NTSTATUS status; - bool smb_encrypt = - get_cmdline_auth_info_smb_encrypt( - popt_get_cmdline_auth_info()); status = cli_cm_open(talloc_tos(), NULL, desthost, service, popt_get_cmdline_auth_info(), - smb_encrypt, max_protocol, + max_protocol, have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6043,14 +6036,11 @@ static int process(const char *base_directory) static int do_host_query(const char *query_host) { NTSTATUS status; - bool smb_encrypt = - get_cmdline_auth_info_smb_encrypt( - popt_get_cmdline_auth_info()); status = cli_cm_open(talloc_tos(), NULL, query_host, "IPC$", popt_get_cmdline_auth_info(), - smb_encrypt, max_protocol, + max_protocol, have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6097,7 +6087,7 @@ static int do_host_query(const char *query_host) status = cli_cm_open(talloc_tos(), NULL, query_host, "IPC$", popt_get_cmdline_auth_info(), - smb_encrypt, max_proto, + max_proto, have_ip ? &dest_ss : NULL, NBT_SMB_PORT, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6123,9 +6113,6 @@ static int do_tar_op(const char *base_directory) { struct tar *tar_ctx = tar_get_ctx(); int ret = 0; - bool smb_encrypt = - get_cmdline_auth_info_smb_encrypt( - popt_get_cmdline_auth_info()); /* do we already have a connection? */ if (!cli) { @@ -6134,7 +6121,7 @@ static int do_tar_op(const char *base_directory) status = cli_cm_open(talloc_tos(), NULL, desthost, service, popt_get_cmdline_auth_info(), - smb_encrypt, max_protocol, + max_protocol, have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 1b8f2a4e97a..0fd31ef3d5a 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -110,7 +110,6 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, status = cli_cm_open(ctx, NULL, server_name, "IPC$", auth_info, - false, lp_client_ipc_max_protocol(), NULL, 0, 0x20, &cli_ipc); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index aff998f6187..4825b8f3fae 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -383,7 +383,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, const char *server, const char *share, const struct user_auth_info *auth_info, - bool force_encrypt, int max_protocol, const struct sockaddr_storage *dest_ss, int port, @@ -393,6 +392,8 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, /* Try to reuse an existing connection in this list. */ struct cli_state *c = cli_cm_find(referring_cli, server, share); NTSTATUS status; + bool force_encrypt = + get_cmdline_auth_info_smb_encrypt(auth_info); if (c) { *pcli = c; @@ -962,7 +963,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, smbXcli_conn_remote_name(rootcli->conn), "IPC$", dfs_auth_info, - cli_state_is_encryption_on(rootcli), smbXcli_conn_protocol(rootcli->conn), NULL, /* dest_ss not needed, we reuse the transport */ 0, diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index eeabcaa7463..bb3e9e6874e 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -128,7 +128,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, const char *server, const char *share, const struct user_auth_info *auth_info, - bool force_encrypt, int max_protocol, const struct sockaddr_storage *dest_ss, int port, -- 2.29.2 From 5e0333d93ae6008c37b03deac682ca2d00030913 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 15:26:39 +0200 Subject: [PATCH 063/108] s3:libsmb: Remove force_encrypt from cli_cm_connect() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit d27e237cf37fb254646d94827935d9c302c379ff) --- source3/libsmb/clidfs.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 4825b8f3fae..b0032005398 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -287,7 +287,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, const char *server, const char *share, const struct user_auth_info *auth_info, - bool force_encrypt, int max_protocol, const struct sockaddr_storage *dest_ss, int port, @@ -296,6 +295,8 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, { struct cli_state *cli = NULL; NTSTATUS status; + bool force_encrypt = + get_cmdline_auth_info_smb_encrypt(auth_info); status = do_connect(ctx, server, share, auth_info, @@ -392,8 +393,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, /* Try to reuse an existing connection in this list. */ struct cli_state *c = cli_cm_find(referring_cli, server, share); NTSTATUS status; - bool force_encrypt = - get_cmdline_auth_info_smb_encrypt(auth_info); if (c) { *pcli = c; @@ -414,7 +413,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, server, share, auth_info, - force_encrypt, max_protocol, dest_ss, port, @@ -1020,7 +1018,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, dfs_refs[count].server, dfs_refs[count].share, dfs_auth_info, - cli_state_is_encryption_on(rootcli), smbXcli_conn_protocol(rootcli->conn), NULL, /* dest_ss */ 0, /* port */ -- 2.29.2 From 7e74d7ac8b329aadb5c99a3852d19f4eadde533c Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 15:28:28 +0200 Subject: [PATCH 064/108] s3:libsmb: Remove force_encrypt from clidfs do_connect() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 615a9a68166bdeb0ab7dbacf395c6125ec70f288) --- source3/libsmb/clidfs.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index b0032005398..5503506de97 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -107,7 +107,6 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, const char *server, const char *share, const struct user_auth_info *auth_info, - bool force_encrypt, int max_protocol, const struct sockaddr_storage *dest_ss, int port, @@ -123,6 +122,8 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, enum protocol_types protocol = PROTOCOL_NONE; int signing_state = get_cmdline_auth_info_signing_state(auth_info); struct cli_credentials *creds = NULL; + bool force_encrypt = + get_cmdline_auth_info_smb_encrypt(auth_info); if (force_encrypt) { signing_state = SMB_SIGNING_REQUIRED; @@ -233,7 +234,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, cli_shutdown(c); return do_connect(ctx, newserver, newshare, auth_info, - force_encrypt, max_protocol, + max_protocol, NULL, port, name_type, pcli); } @@ -295,12 +296,10 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, { struct cli_state *cli = NULL; NTSTATUS status; - bool force_encrypt = - get_cmdline_auth_info_smb_encrypt(auth_info); status = do_connect(ctx, server, share, auth_info, - force_encrypt, max_protocol, + max_protocol, dest_ss, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { -- 2.29.2 From 487deacc65d64eff31211426be7865637bbff3cc Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 15:52:11 +0200 Subject: [PATCH 065/108] s3:libsmb: Remove force_encrypt from cli_check_msdfs_proxy() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 4ddec1ca257fff418847c5d1e83a3fb7cb5ade1a) --- source3/libsmb/clidfs.c | 17 ++++++++++++----- source3/libsmb/libsmb_server.c | 4 ---- source3/libsmb/proto.h | 1 - 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 5503506de97..736c565a7a8 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -230,7 +230,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, if (smbXcli_conn_dfs_supported(c->conn) && cli_check_msdfs_proxy(ctx, c, sharename, &newserver, &newshare, - force_encrypt, creds)) { + creds)) { cli_shutdown(c); return do_connect(ctx, newserver, newshare, auth_info, @@ -1176,7 +1176,6 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, const char *sharename, char **pp_newserver, char **pp_newshare, - bool force_encrypt, struct cli_credentials *creds) { struct client_dfs_referral *refs = NULL; @@ -1188,6 +1187,8 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, char *newextrapath = NULL; NTSTATUS status; const char *remote_name; + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(creds); if (!cli || !sharename) { return false; @@ -1223,11 +1224,17 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, return false; } - if (force_encrypt) { + if (encryption_state >= SMB_ENCRYPTION_DESIRED) { status = cli_cm_force_encryption_creds(cli, creds, "IPC$"); if (!NT_STATUS_IS_OK(status)) { - cli_state_restore_tcon(cli, orig_tcon); - return false; + switch (encryption_state) { + case SMB_ENCRYPTION_DESIRED: + break; + case SMB_ENCRYPTION_REQUIRED: + default: + cli_state_restore_tcon(cli, orig_tcon); + return false; + } } } diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index eb58d7c6ac9..5a1055ba773 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -587,10 +587,6 @@ SMBC_server_internal(TALLOC_CTX *ctx, if (smbXcli_conn_dfs_supported(c->conn) && cli_check_msdfs_proxy(ctx, c, share, &newserver, &newshare, - /* FIXME: cli_check_msdfs_proxy() does - not support smbc_smb_encrypt_level type */ - context->internal->smb_encryption_level ? - true : false, creds)) { cli_shutdown(c); srv = SMBC_server_internal(ctx, context, connect_if_not_found, diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index bb3e9e6874e..f2b0a8c5ff8 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -161,7 +161,6 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, const char *sharename, char **pp_newserver, char **pp_newshare, - bool force_encrypt, struct cli_credentials *creds); /* The following definitions come from libsmb/clientgen.c */ -- 2.29.2 From feac38a965b280a8b9b4374597f57ae60db5e6bb Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 18 Aug 2020 17:15:09 +0200 Subject: [PATCH 066/108] s3:libsmb: Pass cli_credentials to clidfs do_connect() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 276563de06f2071ec2ed9a8b73f92215ab621bba) --- selftest/knownfail.d/smbclient-encryption | 2 -- source3/libsmb/clidfs.c | 34 +++++++++++++---------- 2 files changed, 20 insertions(+), 16 deletions(-) delete mode 100644 selftest/knownfail.d/smbclient-encryption diff --git a/selftest/knownfail.d/smbclient-encryption b/selftest/knownfail.d/smbclient-encryption deleted file mode 100644 index 972096bdc8b..00000000000 --- a/selftest/knownfail.d/smbclient-encryption +++ /dev/null @@ -1,2 +0,0 @@ -^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.enc_desired..simpleserver -^samba3.blackbox.smbclient.encryption.smbclient.smb3.client.encrypt.required...LOCALSHARE4.tmp..simpleserver diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 736c565a7a8..d536e0597af 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -106,7 +106,7 @@ static NTSTATUS cli_cm_force_encryption_creds(struct cli_state *c, static NTSTATUS do_connect(TALLOC_CTX *ctx, const char *server, const char *share, - const struct user_auth_info *auth_info, + struct cli_credentials *creds, int max_protocol, const struct sockaddr_storage *dest_ss, int port, @@ -120,12 +120,12 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, NTSTATUS status; int flags = 0; enum protocol_types protocol = PROTOCOL_NONE; - int signing_state = get_cmdline_auth_info_signing_state(auth_info); - struct cli_credentials *creds = NULL; - bool force_encrypt = - get_cmdline_auth_info_smb_encrypt(auth_info); + enum smb_signing_setting signing_state = + cli_credentials_get_smb_signing(creds); + enum smb_encryption_setting encryption_state = + cli_credentials_get_smb_encryption(creds); - if (force_encrypt) { + if (encryption_state >= SMB_ENCRYPTION_DESIRED) { signing_state = SMB_SIGNING_REQUIRED; } @@ -192,13 +192,12 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, smb2cli_conn_set_max_credits(c->conn, DEFAULT_SMB2_MAX_CREDITS); } - creds = get_cmdline_auth_info_creds(auth_info); - status = cli_session_setup_creds(c, creds); if (!NT_STATUS_IS_OK(status)) { /* If a password was not supplied then * try again with a null username. */ - if (force_encrypt || smbXcli_conn_signing_mandatory(c->conn) || + if (encryption_state == SMB_ENCRYPTION_REQUIRED || + smbXcli_conn_signing_mandatory(c->conn) || cli_credentials_authentication_requested(creds) || cli_credentials_is_anonymous(creds) || !NT_STATUS_IS_OK(status = cli_session_setup_anon(c))) @@ -233,7 +232,7 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, creds)) { cli_shutdown(c); return do_connect(ctx, newserver, - newshare, auth_info, + newshare, creds, max_protocol, NULL, port, name_type, pcli); } @@ -247,13 +246,19 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, return status; } - if (force_encrypt) { + if (encryption_state >= SMB_ENCRYPTION_DESIRED) { status = cli_cm_force_encryption_creds(c, creds, sharename); if (!NT_STATUS_IS_OK(status)) { - cli_shutdown(c); - return status; + switch (encryption_state) { + case SMB_ENCRYPTION_DESIRED: + break; + case SMB_ENCRYPTION_REQUIRED: + default: + cli_shutdown(c); + return status; + } } } @@ -295,10 +300,11 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, struct cli_state **pcli) { struct cli_state *cli = NULL; + struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info); NTSTATUS status; status = do_connect(ctx, server, share, - auth_info, + creds, max_protocol, dest_ss, port, name_type, &cli); -- 2.29.2 From 46278f0a81f35add7bdb3276c64c9465586c0adf Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 18 Aug 2020 17:18:16 +0200 Subject: [PATCH 067/108] s3:libsmb: Pass cli_credentials to cli_cm_connect() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit c8349111243fec81a2b95484e56a6d6bebaba80e) --- source3/libsmb/clidfs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index d536e0597af..a2c6f5fe5ec 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -292,7 +292,7 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, - const struct user_auth_info *auth_info, + struct cli_credentials *creds, int max_protocol, const struct sockaddr_storage *dest_ss, int port, @@ -300,7 +300,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, struct cli_state **pcli) { struct cli_state *cli = NULL; - struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info); NTSTATUS status; status = do_connect(ctx, server, share, @@ -397,6 +396,7 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, { /* Try to reuse an existing connection in this list. */ struct cli_state *c = cli_cm_find(referring_cli, server, share); + struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info); NTSTATUS status; if (c) { @@ -417,7 +417,7 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, referring_cli, server, share, - auth_info, + creds, max_protocol, dest_ss, port, @@ -886,6 +886,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, struct smbXcli_tcon *root_tcon = NULL; struct smbXcli_tcon *target_tcon = NULL; struct cli_dfs_path_split *dfs_refs = NULL; + struct cli_credentials *creds = get_cmdline_auth_info_creds(dfs_auth_info); if ( !rootcli || !path || !targetcli ) { return NT_STATUS_INVALID_PARAMETER; @@ -1022,7 +1023,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, status = cli_cm_connect(ctx, rootcli, dfs_refs[count].server, dfs_refs[count].share, - dfs_auth_info, + creds, smbXcli_conn_protocol(rootcli->conn), NULL, /* dest_ss */ 0, /* port */ -- 2.29.2 From aa2e76ce788a224ea5b52550bf60103db7cf5d0d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 18 Aug 2020 17:26:54 +0200 Subject: [PATCH 068/108] s3:libsmb: Pass cli_credentials to cli_cm_open() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit df1623abd7267916696e2e60c146ef8fa6c9dfc9) --- source3/client/client.c | 23 ++++++++++++++++++----- source3/lib/netapi/cm.c | 4 +++- source3/libsmb/clidfs.c | 25 ++++++++++++------------- source3/libsmb/proto.h | 18 +++++++++--------- 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 3a610086511..c54b5065b44 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -5546,6 +5546,8 @@ static int process_command_string(const char *cmd_in) TALLOC_CTX *ctx = talloc_tos(); char *cmd = talloc_strdup(ctx, cmd_in); int rc = 0; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); if (!cmd) { return 1; @@ -5557,7 +5559,8 @@ static int process_command_string(const char *cmd_in) status = cli_cm_open(talloc_tos(), NULL, desthost, - service, popt_get_cmdline_auth_info(), + service, + creds, max_protocol, have_ip ? &dest_ss : NULL, port, name_type, @@ -5998,10 +6001,13 @@ static int process(const char *base_directory) { int rc = 0; NTSTATUS status; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); status = cli_cm_open(talloc_tos(), NULL, desthost, - service, popt_get_cmdline_auth_info(), + service, + creds, max_protocol, have_ip ? &dest_ss : NULL, port, name_type, &cli); @@ -6036,10 +6042,13 @@ static int process(const char *base_directory) static int do_host_query(const char *query_host) { NTSTATUS status; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); status = cli_cm_open(talloc_tos(), NULL, query_host, - "IPC$", popt_get_cmdline_auth_info(), + "IPC$", + creds, max_protocol, have_ip ? &dest_ss : NULL, port, name_type, &cli); @@ -6086,7 +6095,8 @@ static int do_host_query(const char *query_host) d_printf("Reconnecting with SMB1 for workgroup listing.\n"); status = cli_cm_open(talloc_tos(), NULL, query_host, - "IPC$", popt_get_cmdline_auth_info(), + "IPC$", + creds, max_proto, have_ip ? &dest_ss : NULL, NBT_SMB_PORT, name_type, &cli); @@ -6113,6 +6123,8 @@ static int do_tar_op(const char *base_directory) { struct tar *tar_ctx = tar_get_ctx(); int ret = 0; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); /* do we already have a connection? */ if (!cli) { @@ -6120,7 +6132,8 @@ static int do_tar_op(const char *base_directory) status = cli_cm_open(talloc_tos(), NULL, desthost, - service, popt_get_cmdline_auth_info(), + service, + creds, max_protocol, have_ip ? &dest_ss : NULL, port, name_type, &cli); diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 0fd31ef3d5a..943f7498e8c 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -71,6 +71,7 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, struct cli_state *cli_ipc = NULL; struct client_ipc_connection *p; NTSTATUS status; + struct cli_credentials *creds = NULL; if (!ctx || !pp || !server_name) { return WERR_INVALID_PARAMETER; @@ -106,10 +107,11 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, if (ctx->use_ccache) { set_cmdline_auth_info_use_ccache(auth_info, true); } + creds = get_cmdline_auth_info_creds(auth_info); status = cli_cm_open(ctx, NULL, server_name, "IPC$", - auth_info, + creds, lp_client_ipc_max_protocol(), NULL, 0, 0x20, &cli_ipc); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index a2c6f5fe5ec..ef75fb36a45 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -384,19 +384,18 @@ static struct cli_state *cli_cm_find(struct cli_state *cli, ****************************************************************************/ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, - struct cli_state *referring_cli, - const char *server, - const char *share, - const struct user_auth_info *auth_info, - int max_protocol, - const struct sockaddr_storage *dest_ss, - int port, - int name_type, - struct cli_state **pcli) + struct cli_state *referring_cli, + const char *server, + const char *share, + struct cli_credentials *creds, + int max_protocol, + const struct sockaddr_storage *dest_ss, + int port, + int name_type, + struct cli_state **pcli) { /* Try to reuse an existing connection in this list. */ struct cli_state *c = cli_cm_find(referring_cli, server, share); - struct cli_credentials *creds = get_cmdline_auth_info_creds(auth_info); NTSTATUS status; if (c) { @@ -404,11 +403,11 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, return NT_STATUS_OK; } - if (auth_info == NULL) { + if (creds == NULL) { /* Can't do a new connection * without auth info. */ d_printf("cli_cm_open() Unable to open connection [\\%s\\%s] " - "without auth info\n", + "without client credentials\n", server, share ); return NT_STATUS_INVALID_PARAMETER; } @@ -966,7 +965,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, rootcli, smbXcli_conn_remote_name(rootcli->conn), "IPC$", - dfs_auth_info, + creds, smbXcli_conn_protocol(rootcli->conn), NULL, /* dest_ss not needed, we reuse the transport */ 0, diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index f2b0a8c5ff8..0b8cf2a6036 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -124,15 +124,15 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, /* The following definitions come from libsmb/clidfs.c */ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, - struct cli_state *referring_cli, - const char *server, - const char *share, - const struct user_auth_info *auth_info, - int max_protocol, - const struct sockaddr_storage *dest_ss, - int port, - int name_type, - struct cli_state **pcli); + struct cli_state *referring_cli, + const char *server, + const char *share, + struct cli_credentials *creds, + int max_protocol, + const struct sockaddr_storage *dest_ss, + int port, + int name_type, + struct cli_state **pcli); void cli_cm_display(struct cli_state *c); struct client_dfs_referral; NTSTATUS cli_dfs_get_referral_ex(TALLOC_CTX *ctx, -- 2.29.2 From c9a6141048f058168d2b1679c3a4bf087d367ee5 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 18 Aug 2020 17:42:25 +0200 Subject: [PATCH 069/108] s3:libsmb: Pass cli_credentials to cli_resolve_path(), using helper variables. Signed-off-by: Andreas Schneider Signed-off-by: Jeremy Allison (cherry picked from commit 5245ab3c4dacc88d5cbe3bb1e3e339e4fb77a4db) --- source3/client/client.c | 148 +++++++++++++++++++++++++++------- source3/libsmb/clidfs.c | 5 +- source3/libsmb/libsmb_dir.c | 43 ++++++++-- source3/libsmb/libsmb_file.c | 13 ++- source3/libsmb/libsmb_stat.c | 6 +- source3/libsmb/libsmb_xattr.c | 13 ++- source3/libsmb/proto.h | 2 +- source3/utils/smbcacls.c | 5 +- 8 files changed, 188 insertions(+), 47 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index c54b5065b44..13e48f80a01 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -298,9 +298,14 @@ static int do_dskattr(void) struct cli_state *targetcli = NULL; char *targetpath = NULL; TALLOC_CTX *ctx = talloc_tos(); + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), cli, + status = cli_resolve_path(ctx, + "", + creds, + cli, client_get_cur_dir(), &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { @@ -390,6 +395,8 @@ static int do_cd(const char *new_dir) uint32_t attributes; int ret = 1; TALLOC_CTX *ctx = talloc_stackframe(); + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; newdir = talloc_strdup(ctx, new_dir); @@ -432,7 +439,8 @@ static int do_cd(const char *new_dir) new_cd = client_clean_name(ctx, new_cd); client_set_cur_dir(new_cd); - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, new_cd, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("cd %s: %s\n", new_cd, nt_errstr(status)); @@ -809,6 +817,8 @@ NTSTATUS do_list(const char *mask, TALLOC_CTX *ctx = talloc_tos(); struct cli_state *targetcli = NULL; char *targetpath = NULL; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS ret_status = NT_STATUS_OK; NTSTATUS status = NT_STATUS_OK; @@ -832,7 +842,7 @@ NTSTATUS do_list(const char *mask, /* check for dfs */ status = cli_resolve_path(ctx, "", - popt_get_cmdline_auth_info(), + creds, cli, head, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("do_list: [%s] %s\n", head, @@ -1042,6 +1052,8 @@ static int do_get(const char *rname, const char *lname_in, bool reget) struct cli_state *targetcli = NULL; char *targetname = NULL; char *lname = NULL; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; lname = talloc_strdup(ctx, lname_in); @@ -1056,7 +1068,8 @@ static int do_get(const char *rname, const char *lname_in, bool reget) } } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, rname, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("Failed to open %s: %s\n", rname, nt_errstr(status)); @@ -1413,9 +1426,12 @@ static bool do_mkdir(const char *name) TALLOC_CTX *ctx = talloc_tos(); struct cli_state *targetcli; char *targetname = NULL; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, name, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("mkdir %s: %s\n", name, nt_errstr(status)); @@ -1474,6 +1490,8 @@ static int cmd_mkdir(void) TALLOC_CTX *ctx = talloc_tos(); char *mask = NULL; char *buf = NULL; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; mask = talloc_strdup(ctx, client_get_cur_dir()); @@ -1510,7 +1528,8 @@ static int cmd_mkdir(void) } status = cli_resolve_path(ctx, "", - popt_get_cmdline_auth_info(), cli, mask, + creds, + cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { return 1; @@ -1824,9 +1843,12 @@ static int do_put(const char *rname, const char *lname, bool reput) struct cli_state *targetcli; char *targetname = NULL; struct push_state state; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, rname, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("Failed to open %s: %s\n", rname, nt_errstr(status)); @@ -2601,6 +2623,8 @@ static int cmd_wdel(void) uint32_t attribute; struct cli_state *targetcli; char *targetname = NULL; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -2626,7 +2650,8 @@ static int cmd_wdel(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("cmd_wdel %s: %s\n", mask, nt_errstr(status)); @@ -2652,6 +2677,8 @@ static int cmd_open(void) char *targetname = NULL; struct cli_state *targetcli; uint16_t fnum = (uint16_t)-1; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -2671,7 +2698,8 @@ static int cmd_open(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("open %s: %s\n", mask, nt_errstr(status)); @@ -2773,6 +2801,8 @@ static int cmd_posix_open(void) struct cli_state *targetcli; mode_t mode; uint16_t fnum; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -2797,7 +2827,8 @@ static int cmd_posix_open(void) } mode = (mode_t)strtol(buf, (char **)NULL, 8); - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("posix_open %s: %s\n", mask, nt_errstr(status)); @@ -2832,6 +2863,8 @@ static int cmd_posix_mkdir(void) char *targetname = NULL; struct cli_state *targetcli; mode_t mode; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -2856,7 +2889,8 @@ static int cmd_posix_mkdir(void) } mode = (mode_t)strtol(buf, (char **)NULL, 8); - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("posix_mkdir %s: %s\n", mask, nt_errstr(status)); @@ -2880,6 +2914,8 @@ static int cmd_posix_unlink(void) char *buf = NULL; char *targetname = NULL; struct cli_state *targetcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -2898,7 +2934,8 @@ static int cmd_posix_unlink(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("posix_unlink %s: %s\n", mask, nt_errstr(status)); @@ -2923,6 +2960,8 @@ static int cmd_posix_rmdir(void) char *buf = NULL; char *targetname = NULL; struct cli_state *targetcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -2941,7 +2980,8 @@ static int cmd_posix_rmdir(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("posix_rmdir %s: %s\n", mask, nt_errstr(status)); @@ -3230,6 +3270,8 @@ static int cmd_rmdir(void) char *buf = NULL; char *targetname = NULL; struct cli_state *targetcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -3248,7 +3290,8 @@ static int cmd_rmdir(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, mask, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("rmdir %s: %s\n", mask, nt_errstr(status)); @@ -3277,6 +3320,8 @@ static int cmd_link(void) char *buf2 = NULL; char *targetname = NULL; struct cli_state *targetcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || @@ -3307,7 +3352,8 @@ static int cmd_link(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, oldname, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("link %s: %s\n", oldname, nt_errstr(status)); @@ -3340,6 +3386,8 @@ static int cmd_readlink(void) char *targetname = NULL; char *linkname = NULL; struct cli_state *targetcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { @@ -3358,7 +3406,8 @@ static int cmd_readlink(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, name, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("readlink %s: %s\n", name, nt_errstr(status)); @@ -3397,6 +3446,8 @@ static int cmd_symlink(void) char *buf = NULL; char *buf2 = NULL; struct cli_state *newcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || @@ -3419,7 +3470,8 @@ static int cmd_symlink(void) } /* New name must be present in share namespace. */ status = cli_resolve_path(ctx, "", - popt_get_cmdline_auth_info(), cli, newname, + creds, + cli, newname, &newcli, &newname); if (!NT_STATUS_IS_OK(status)) { d_printf("link %s: %s\n", newname, @@ -3455,6 +3507,8 @@ static int cmd_chmod(void) char *targetname = NULL; struct cli_state *targetcli; mode_t mode; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || @@ -3476,7 +3530,8 @@ static int cmd_chmod(void) mode = (mode_t)strtol(buf, NULL, 8); - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("chmod %s: %s\n", src, nt_errstr(status)); @@ -3620,6 +3675,8 @@ static int cmd_getfacl(void) size_t num_dir_acls = 0; size_t expected_buflen; uint16_t i; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) { @@ -3638,7 +3695,8 @@ static int cmd_getfacl(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("stat %s: %s\n", src, nt_errstr(status)); @@ -3803,6 +3861,8 @@ static int cmd_geteas(void) NTSTATUS status; size_t i, num_eas; struct ea_struct *eas; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) { d_printf("geteas filename\n"); @@ -3820,7 +3880,8 @@ static int cmd_geteas(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("stat %s: %s\n", src, nt_errstr(status)); @@ -3859,6 +3920,8 @@ static int cmd_setea(void) char *eavalue = NULL; char *targetname = NULL; struct cli_state *targetcli; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr, &name, NULL) @@ -3881,7 +3944,8 @@ static int cmd_setea(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("stat %s: %s\n", src, nt_errstr(status)); @@ -3913,6 +3977,8 @@ static int cmd_stat(void) SMB_STRUCT_STAT sbuf; struct tm *lt; time_t tmp_time; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&name,NULL)) { @@ -3931,7 +3997,8 @@ static int cmd_stat(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("stat %s: %s\n", src, nt_errstr(status)); @@ -4020,6 +4087,8 @@ static int cmd_chown(void) char *buf, *buf2, *buf3; struct cli_state *targetcli; char *targetname = NULL; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || @@ -4043,7 +4112,8 @@ static int cmd_chown(void) if (src == NULL) { return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("chown %s: %s\n", src, nt_errstr(status)); @@ -4077,6 +4147,8 @@ static int cmd_rename(void) struct cli_state *targetcli; char *targetsrc; char *targetdest; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; bool replace = false; @@ -4115,14 +4187,16 @@ static int cmd_rename(void) replace = true; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetsrc); if (!NT_STATUS_IS_OK(status)) { d_printf("rename %s: %s\n", src, nt_errstr(status)); return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, dest, &targetcli, &targetdest); if (!NT_STATUS_IS_OK(status)) { d_printf("rename %s: %s\n", dest, nt_errstr(status)); @@ -4179,6 +4253,8 @@ static int cmd_scopy(void) off_t written = 0; struct scopy_timing st; int rc = 0; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || @@ -4211,14 +4287,16 @@ static int cmd_scopy(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetsrc); if (!NT_STATUS_IS_OK(status)) { d_printf("scopy %s: %s\n", src, nt_errstr(status)); return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, dest, &targetcli, &targetdest); if (!NT_STATUS_IS_OK(status)) { d_printf("scopy %s: %s\n", dest, nt_errstr(status)); @@ -4317,6 +4395,8 @@ static int cmd_hardlink(void) char *buf, *buf2; struct cli_state *targetcli; char *targetname; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL) || @@ -4349,7 +4429,8 @@ static int cmd_hardlink(void) return 1; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, src, &targetcli, &targetname); if (!NT_STATUS_IS_OK(status)) { d_printf("hardlink %s: %s\n", src, nt_errstr(status)); @@ -5023,9 +5104,13 @@ static int cmd_show_connect( void ) TALLOC_CTX *ctx = talloc_tos(); struct cli_state *targetcli; char *targetpath; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), cli, + status = cli_resolve_path(ctx, "", + creds, + cli, client_get_cur_dir(), &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { @@ -5685,6 +5770,8 @@ static char **remote_completion(const char *text, int len) struct cli_state *targetcli = NULL; int i; struct completion_remote info = { NULL, NULL, 1, 0, NULL, 0 }; + struct cli_credentials *creds = + get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()); NTSTATUS status; /* can't have non-static initialisation on Sun CC, so do it @@ -5745,7 +5832,8 @@ static char **remote_completion(const char *text, int len) goto cleanup; } - status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), + status = cli_resolve_path(ctx, "", + creds, cli, dirmask, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { goto cleanup; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index ef75fb36a45..e6695159a96 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -859,7 +859,7 @@ struct cli_dfs_path_split { NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, const char *mountpt, - const struct user_auth_info *dfs_auth_info, + struct cli_credentials *creds, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, @@ -885,7 +885,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, struct smbXcli_tcon *root_tcon = NULL; struct smbXcli_tcon *target_tcon = NULL; struct cli_dfs_path_split *dfs_refs = NULL; - struct cli_credentials *creds = get_cmdline_auth_info_creds(dfs_auth_info); if ( !rootcli || !path || !targetcli ) { return NT_STATUS_INVALID_PARAMETER; @@ -1130,7 +1129,7 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) { status = cli_resolve_path(ctx, newmount, - dfs_auth_info, + creds, *targetcli, *pp_targetpath, &newcli, diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 12abb734c2d..0326f27125b 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -911,6 +911,7 @@ SMBC_opendir_ctx(SMBCCTX *context, */ char *targetpath; struct cli_state *targetcli; + struct cli_credentials *creds = NULL; NTSTATUS status; /* We connect to the server and list the directory */ @@ -943,8 +944,12 @@ SMBC_opendir_ctx(SMBCCTX *context, return NULL; } + creds = get_cmdline_auth_info_creds( + context->internal->auth_info); + status = cli_resolve_path( - frame, "", context->internal->auth_info, + frame, "", + creds, srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); @@ -1543,6 +1548,7 @@ SMBC_mkdir_ctx(SMBCCTX *context, char *targetpath = NULL; uint16_t port = 0; struct cli_state *targetcli = NULL; + struct cli_credentials *creds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -1595,8 +1601,11 @@ SMBC_mkdir_ctx(SMBCCTX *context, } + creds = get_cmdline_auth_info_creds(context->internal->auth_info); + /*d_printf(">>>mkdir: resolving %s\n", path);*/ - status = cli_resolve_path(frame, "", context->internal->auth_info, + status = cli_resolve_path(frame, "", + creds, srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); @@ -1654,6 +1663,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, char *targetpath = NULL; uint16_t port = 0; struct cli_state *targetcli = NULL; + struct cli_credentials *creds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -1706,8 +1716,11 @@ SMBC_rmdir_ctx(SMBCCTX *context, } + creds = get_cmdline_auth_info_creds(context->internal->auth_info), + /*d_printf(">>>rmdir: resolving %s\n", path);*/ - status = cli_resolve_path(frame, "", context->internal->auth_info, + status = cli_resolve_path(frame, "", + creds, srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); @@ -1959,6 +1972,7 @@ SMBC_chmod_ctx(SMBCCTX *context, char *path = NULL; uint32_t attr; uint16_t port = 0; + struct cli_credentials *creds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -2010,8 +2024,11 @@ SMBC_chmod_ctx(SMBCCTX *context, return -1; /* errno set by SMBC_server */ } + creds = get_cmdline_auth_info_creds(context->internal->auth_info); + /*d_printf(">>>unlink: resolving %s\n", path);*/ - status = cli_resolve_path(frame, "", context->internal->auth_info, + status = cli_resolve_path(frame, "", + creds, srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); @@ -2152,6 +2169,7 @@ SMBC_unlink_ctx(SMBCCTX *context, uint16_t port = 0; struct cli_state *targetcli = NULL; SMBCSRV *srv = NULL; + struct cli_credentials *creds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -2204,8 +2222,11 @@ SMBC_unlink_ctx(SMBCCTX *context, } + creds = get_cmdline_auth_info_creds(context->internal->auth_info); + /*d_printf(">>>unlink: resolving %s\n", path);*/ - status = cli_resolve_path(frame, "", context->internal->auth_info, + status = cli_resolve_path(frame, "", + creds, srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); @@ -2282,6 +2303,8 @@ SMBC_rename_ctx(SMBCCTX *ocontext, SMBCSRV *srv = NULL; uint16_t port1 = 0; uint16_t port2 = 0; + struct cli_credentials *ocreds = NULL; + struct cli_credentials *ncreds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -2375,7 +2398,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext, password1); /*d_printf(">>>rename: resolving %s\n", path1);*/ - status = cli_resolve_path(frame, "", ocontext->internal->auth_info, + ocreds = get_cmdline_auth_info_creds(ocontext->internal->auth_info); + + status = cli_resolve_path(frame, "", + ocreds, srv->cli, path1, &targetcli1, &targetpath1); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path1); @@ -2392,7 +2418,10 @@ SMBC_rename_ctx(SMBCCTX *ocontext, /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ - status = cli_resolve_path(frame, "", ncontext->internal->auth_info, + ncreds = get_cmdline_auth_info_creds(ncontext->internal->auth_info); + + status = cli_resolve_path(frame, "", + ncreds, srv->cli, path2, &targetcli2, &targetpath2); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path2); diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 0791df36690..a44925e0e0e 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -103,6 +103,8 @@ SMBC_open_ctx(SMBCCTX *context, if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { status = NT_STATUS_OBJECT_PATH_INVALID; } else { + struct cli_credentials *creds = NULL; + file = SMB_MALLOC_P(SMBCFILE); if (!file) { errno = ENOMEM; @@ -112,9 +114,12 @@ SMBC_open_ctx(SMBCCTX *context, ZERO_STRUCTP(file); + creds = get_cmdline_auth_info_creds( + context->internal->auth_info); /*d_printf(">>>open: resolving %s\n", path);*/ status = cli_resolve_path( - frame, "", context->internal->auth_info, + frame, "", + creds, srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { d_printf("Could not resolve %s\n", path); @@ -461,6 +466,7 @@ SMBC_getatr(SMBCCTX * context, struct timespec change_time_ts = {0}; time_t write_time = 0; SMB_INO_T ino = 0; + struct cli_credentials *creds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -490,7 +496,10 @@ SMBC_getatr(SMBCCTX * context, } DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); - status = cli_resolve_path(frame, "", context->internal->auth_info, + creds = get_cmdline_auth_info_creds(context->internal->auth_info); + + status = cli_resolve_path(frame, "", + creds, srv->cli, fixedpath, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 790934bd565..1260928d0ff 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -242,6 +242,7 @@ SMBC_fstat_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; SMB_INO_T ino = 0; uint16_t port = 0; + struct cli_credentials *creds = NULL; TALLOC_CTX *frame = talloc_stackframe(); NTSTATUS status; @@ -279,8 +280,11 @@ SMBC_fstat_ctx(SMBCCTX *context, return -1; } + creds = get_cmdline_auth_info_creds(context->internal->auth_info); + /*d_printf(">>>fstat: resolving %s\n", path);*/ - status = cli_resolve_path(frame, "", context->internal->auth_info, + status = cli_resolve_path(frame, "", + creds, file->srv->cli, path, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index d1b6548eb90..8b74d0a39e3 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -860,13 +860,18 @@ cacl_get(SMBCCTX *context, if (ipc_cli && (all || some_nt || all_nt_acls)) { char *targetpath = NULL; struct cli_state *targetcli = NULL; + struct cli_credentials *creds = NULL; NTSTATUS status; /* Point to the portion after "system.nt_sec_desc." */ name += 19; /* if (all) this will be invalid but unused */ + creds = get_cmdline_auth_info_creds( + context->internal->auth_info); + status = cli_resolve_path( - ctx, "", context->internal->auth_info, + ctx, "", + creds, cli, filename, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("cacl_get Could not resolve %s\n", @@ -1511,6 +1516,7 @@ cacl_set(SMBCCTX *context, bool numeric = True; char *targetpath = NULL; struct cli_state *targetcli = NULL; + struct cli_credentials *creds = NULL; NTSTATUS status; /* the_acl will be null for REMOVE_ALL operations */ @@ -1540,7 +1546,10 @@ cacl_set(SMBCCTX *context, return -1; } - status = cli_resolve_path(ctx, "", context->internal->auth_info, + creds = get_cmdline_auth_info_creds(context->internal->auth_info); + + status = cli_resolve_path(ctx, "", + creds, cli, filename, &targetcli, &targetpath); if (!NT_STATUS_IS_OK(status)) { DEBUG(5,("cacl_set: Could not resolve %s\n", filename)); diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 0b8cf2a6036..517738dbcd7 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -150,7 +150,7 @@ NTSTATUS cli_dfs_get_referral(TALLOC_CTX *ctx, size_t *consumed); NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, const char *mountpt, - const struct user_auth_info *dfs_auth_info, + struct cli_credentials *creds, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 8fd9fcc5780..4989ec633c3 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -806,6 +806,7 @@ int main(int argc, char *argv[]) than going via LSA calls to resolve them */ int numeric = 0; struct cli_state *targetcli = NULL; + struct cli_credentials *creds = NULL; char *targetfile = NULL; NTSTATUS status; @@ -1069,9 +1070,11 @@ int main(int argc, char *argv[]) } } + creds = get_cmdline_auth_info_creds(popt_get_cmdline_auth_info()), + status = cli_resolve_path(frame, "", - popt_get_cmdline_auth_info(), + creds, cli, filename, &targetcli, -- 2.29.2 From 915516d0e2f817a6e0169b6c2578c17cd8d9d1fc Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 16:40:49 +0200 Subject: [PATCH 070/108] s3:client: Remove global max_protocol Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit d07f28645f37c1f976017d5b89864791a18d1943) --- source3/client/client.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 13e48f80a01..902cdec8b64 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -61,7 +61,6 @@ static int io_bufsize = 0; /* we use the default size */ static int io_timeout = (CLIENT_TIMEOUT/1000); /* Per operation timeout (in seconds). */ static int name_type = 0x20; -static int max_protocol = -1; static int process_tok(char *tok); static int cmd_help(void); @@ -5646,7 +5645,7 @@ static int process_command_string(const char *cmd_in) desthost, service, creds, - max_protocol, + lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); @@ -6096,7 +6095,7 @@ static int process(const char *base_directory) desthost, service, creds, - max_protocol, + lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6137,7 +6136,7 @@ static int do_host_query(const char *query_host) query_host, "IPC$", creds, - max_protocol, + lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6172,7 +6171,7 @@ static int do_host_query(const char *query_host) if (port != NBT_SMB_PORT || smbXcli_conn_protocol(cli->conn) > PROTOCOL_NT1) { - int max_proto = MIN(max_protocol, PROTOCOL_NT1); + int max_proto = MIN(lp_client_max_protocol(), PROTOCOL_NT1); /* * Workgroups simply don't make sense over anything @@ -6222,7 +6221,7 @@ static int do_tar_op(const char *base_directory) desthost, service, creds, - max_protocol, + lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6629,8 +6628,6 @@ int main(int argc,char *argv[]) /* Ensure we have a password (or equivalent). */ popt_common_credentials_post(); - max_protocol = lp_client_max_protocol(); - if (tar_to_process(tar_ctx)) { if (cmdstr) process_command_string(cmdstr); -- 2.29.2 From ac116f4a319a28453416fa30e66d8aa9a608ecc9 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 16:43:46 +0200 Subject: [PATCH 071/108] s3:libsmb: Remove max_protocol from cli_cm_open() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 4aac9daf095e7c2de6a27697a13385ee87a4b634) --- source3/client/client.c | 7 ------- source3/lib/netapi/cm.c | 1 - source3/libsmb/clidfs.c | 4 +--- source3/libsmb/proto.h | 1 - 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/source3/client/client.c b/source3/client/client.c index 902cdec8b64..82764c5ca16 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -5645,7 +5645,6 @@ static int process_command_string(const char *cmd_in) desthost, service, creds, - lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); @@ -6095,7 +6094,6 @@ static int process(const char *base_directory) desthost, service, creds, - lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6136,7 +6134,6 @@ static int do_host_query(const char *query_host) query_host, "IPC$", creds, - lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6171,8 +6168,6 @@ static int do_host_query(const char *query_host) if (port != NBT_SMB_PORT || smbXcli_conn_protocol(cli->conn) > PROTOCOL_NT1) { - int max_proto = MIN(lp_client_max_protocol(), PROTOCOL_NT1); - /* * Workgroups simply don't make sense over anything * else but port 139 and SMB1. @@ -6184,7 +6179,6 @@ static int do_host_query(const char *query_host) query_host, "IPC$", creds, - max_proto, have_ip ? &dest_ss : NULL, NBT_SMB_PORT, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -6221,7 +6215,6 @@ static int do_tar_op(const char *base_directory) desthost, service, creds, - lp_client_max_protocol(), have_ip ? &dest_ss : NULL, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index 943f7498e8c..3f4e188b396 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -112,7 +112,6 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, status = cli_cm_open(ctx, NULL, server_name, "IPC$", creds, - lp_client_ipc_max_protocol(), NULL, 0, 0x20, &cli_ipc); if (!NT_STATUS_IS_OK(status)) { cli_ipc = NULL; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e6695159a96..fb1a0c72e6d 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -388,7 +388,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, const char *server, const char *share, struct cli_credentials *creds, - int max_protocol, const struct sockaddr_storage *dest_ss, int port, int name_type, @@ -417,7 +416,7 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, server, share, creds, - max_protocol, + lp_client_max_protocol(), dest_ss, port, name_type, @@ -965,7 +964,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, smbXcli_conn_remote_name(rootcli->conn), "IPC$", creds, - smbXcli_conn_protocol(rootcli->conn), NULL, /* dest_ss not needed, we reuse the transport */ 0, 0x20, diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index 517738dbcd7..8aaaff2cb1e 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -128,7 +128,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, const char *server, const char *share, struct cli_credentials *creds, - int max_protocol, const struct sockaddr_storage *dest_ss, int port, int name_type, -- 2.29.2 From 70e2b7c9bd556f5d8762e86960864f71be357d60 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 16:45:12 +0200 Subject: [PATCH 072/108] s3:libcmb: Remove max_protocol from cli_cm_connect() Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 2159582610ecc932047b85a77ec321b3d3ac806f) --- source3/libsmb/clidfs.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index fb1a0c72e6d..023dd4d2757 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -293,7 +293,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, const char *server, const char *share, struct cli_credentials *creds, - int max_protocol, const struct sockaddr_storage *dest_ss, int port, int name_type, @@ -304,7 +303,7 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, status = do_connect(ctx, server, share, creds, - max_protocol, + lp_client_max_protocol(), dest_ss, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { @@ -416,7 +415,6 @@ NTSTATUS cli_cm_open(TALLOC_CTX *ctx, server, share, creds, - lp_client_max_protocol(), dest_ss, port, name_type, @@ -1020,7 +1018,6 @@ NTSTATUS cli_resolve_path(TALLOC_CTX *ctx, dfs_refs[count].server, dfs_refs[count].share, creds, - smbXcli_conn_protocol(rootcli->conn), NULL, /* dest_ss */ 0, /* port */ 0x20, -- 2.29.2 From 68bb1153c9b2f3566f7558adb144f99d0dbbae64 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 27 Aug 2020 16:46:29 +0200 Subject: [PATCH 073/108] s3:libsmb: Remove max_protocol from clidfs do_connect() The if check for max_protocol == 0 is part of lp_client_max_protocol(). Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit 50b59b4c28bc816094a4ca97f64450860e2495b2) --- source3/libsmb/clidfs.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 023dd4d2757..ee5becf76a6 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -107,7 +107,6 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, const char *server, const char *share, struct cli_credentials *creds, - int max_protocol, const struct sockaddr_storage *dest_ss, int port, int name_type, @@ -167,14 +166,11 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, return status; } - if (max_protocol == 0) { - max_protocol = PROTOCOL_LATEST; - } DEBUG(4,(" session request ok\n")); status = smbXcli_negprot(c->conn, c->timeout, lp_client_min_protocol(), - max_protocol); + lp_client_max_protocol()); if (!NT_STATUS_IS_OK(status)) { d_printf("protocol negotiation failed: %s\n", @@ -233,7 +229,6 @@ static NTSTATUS do_connect(TALLOC_CTX *ctx, cli_shutdown(c); return do_connect(ctx, newserver, newshare, creds, - max_protocol, NULL, port, name_type, pcli); } @@ -303,7 +298,6 @@ static NTSTATUS cli_cm_connect(TALLOC_CTX *ctx, status = do_connect(ctx, server, share, creds, - lp_client_max_protocol(), dest_ss, port, name_type, &cli); if (!NT_STATUS_IS_OK(status)) { -- 2.29.2 From e11dbff10f7e05de3e0886bb89f97d80f421a7cf Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 10 Aug 2020 15:47:35 +0200 Subject: [PATCH 074/108] s3:include: Move loadparm prototypes to own header file Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison (cherry picked from commit d4d8218b9618dd289f54b41f13d7015f1b3994fd) --- source3/include/includes.h | 3 + source3/include/proto.h | 167 ------------------------------- source3/param/loadparm.h | 200 +++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 167 deletions(-) create mode 100644 source3/param/loadparm.h diff --git a/source3/include/includes.h b/source3/include/includes.h index 8fa65cc3122..c94f919ed59 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -293,6 +293,9 @@ typedef char fstring[FSTRING_LEN]; #endif #include "lib/param/loadparm.h" +#include "source3/param/loadparm.h" +/* Automatically generated by generate_param.py. */ +#include "source3/param/param_proto.h" /* String routines */ diff --git a/source3/include/proto.h b/source3/include/proto.h index 12aa392abae..b9a6cb7f116 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -739,173 +739,6 @@ NTSTATUS trust_pw_change(struct netlogon_creds_cli_context *context, const char *dcname, bool force); -/* The following definitions come from param/loadparm.c */ - -const struct loadparm_substitution *loadparm_s3_global_substitution(void); - -char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx, - const struct loadparm_substitution *lp_sub, - int snum, - const char *type, - const char *option, - const char *def); - -#include "source3/param/param_proto.h" - -char *lp_servicename(TALLOC_CTX *ctx, const struct loadparm_substitution *, int); -const char *lp_const_servicename(int); -bool lp_autoloaded(int); -const char *lp_dnsdomain(void); -int lp_winbind_max_domain_connections(void); -bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high); -bool lp_idmap_default_range(uint32_t *low, uint32_t *high); -const char *lp_idmap_backend(const char *domain_name); -const char *lp_idmap_default_backend (void); -int lp_security(void); -int lp_client_max_protocol(void); -int lp_client_ipc_min_protocol(void); -int lp_client_ipc_max_protocol(void); -int lp_client_ipc_signing(void); -int lp_smb2_max_credits(void); -int lp_cups_encrypt(void); -bool lp_widelinks(int ); -int lp_rpc_low_port(void); -int lp_rpc_high_port(void); -bool lp_lanman_auth(void); -enum samba_weak_crypto lp_weak_crypto(void); - -int lp_wi_scan_global_parametrics( - const char *regex, size_t max_matches, - bool (*cb)(const char *string, regmatch_t matches[], - void *private_data), - void *private_data); - -const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def); -struct loadparm_service; -const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, - const char *option, const char *def); -const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def); -int lp_parm_int(int snum, const char *type, const char *option, int def); -unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def); -unsigned long long lp_parm_ulonglong(int snum, const char *type, - const char *option, - unsigned long long def); -bool lp_parm_bool(int snum, const char *type, const char *option, bool def); -struct enum_list; -int lp_parm_enum(int snum, const char *type, const char *option, - const struct enum_list *_enum, int def); -char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src); -bool lp_add_home(const char *pszHomename, int iDefaultService, - const char *user, const char *pszHomedir); -int lp_add_service(const char *pszService, int iDefaultService); -bool lp_add_printer(const char *pszPrintername, int iDefaultService); -bool lp_parameter_is_valid(const char *pszParmName); -bool lp_parameter_is_global(const char *pszParmName); -bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm, - bool *inverse); -bool lp_canonicalize_parameter_with_value(const char *parm_name, - const char *val, - const char **canon_parm, - const char **canon_val); -void show_parameter_list(void); -bool lp_invert_boolean(const char *str, const char **inverse_str); -bool lp_canonicalize_boolean(const char *str, const char**canon_str); -bool process_registry_service(const char *service_name); -bool process_registry_shares(void); -bool lp_config_backend_is_registry(void); -bool lp_config_backend_is_file(void); -bool lp_file_list_changed(void); -const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx); -const char *lp_ldap_user_suffix(TALLOC_CTX *ctx); -const char *lp_ldap_group_suffix(TALLOC_CTX *ctx); -const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx); -struct parm_struct; -/* Return a pointer to a service by name. */ -struct loadparm_service *lp_service(const char *pszServiceName); -struct loadparm_service *lp_servicebynum(int snum); -struct loadparm_service *lp_default_loadparm_service(void); -void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm); -void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm); -bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue); -bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue); -bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal); -bool lp_snum_ok(int iService); -void lp_add_one_printer(const char *name, const char *comment, - const char *location, void *pdata); -bool lp_loaded(void); -void lp_killunused(struct smbd_server_connection *sconn, - bool (*snumused) (struct smbd_server_connection *, int)); -void lp_kill_all_services(void); -void lp_killservice(int iServiceIn); -const char* server_role_str(uint32_t role); -enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, - SMB_STRUCT_STAT *psbuf, - const char *servicename, - int snum, - char **lines, - int numlines, - char **pp_sharepath, - char **pp_comment, - char **pp_cp_share_name, - struct security_descriptor **ppsd, - bool *pallow_guest); -int load_usershare_service(const char *servicename); -int load_usershare_shares(struct smbd_server_connection *sconn, - bool (*snumused) (struct smbd_server_connection *, int)); -void gfree_loadparm(void); -bool lp_load_initial_only(const char *pszFname); -bool lp_load_global(const char *file_name); -bool lp_load_with_shares(const char *file_name); -bool lp_load_client(const char *file_name); -bool lp_load_global_no_reinit(const char *file_name); -bool lp_load_no_reinit(const char *file_name); -bool lp_load_client_no_reinit(const char *file_name); -bool lp_load_with_registry_shares(const char *pszFname); -int lp_numservices(void); -void lp_dump(FILE *f, bool show_defaults, int maxtoprint); -void lp_dump_one(FILE * f, bool show_defaults, int snum); -int lp_servicenumber(const char *pszServiceName); -const char *volume_label(TALLOC_CTX *ctx, int snum); -bool lp_domain_master(void); -bool lp_preferred_master(void); -void lp_remove_service(int snum); -void lp_copy_service(int snum, const char *new_name); -int lp_default_server_announce(void); -const char *lp_printername(TALLOC_CTX *ctx, - const struct loadparm_substitution *lp_sub, - int snum); -void lp_set_logfile(const char *name); -int lp_maxprintjobs(int snum); -const char *lp_printcapname(void); -bool lp_disable_spoolss( void ); -void lp_set_spoolss_state( uint32_t state ); -uint32_t lp_get_spoolss_state( void ); -struct smb_signing_state; -void set_use_sendfile(int snum, bool val); -void lp_set_mangling_method(const char *new_method); -bool lp_posix_pathnames(void); -void lp_set_posix_pathnames(void); -enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp); -void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val); -int lp_min_receive_file_size(void); -void widelinks_warning(int snum); -const char *lp_ncalrpc_dir(void); -void _lp_set_server_role(int server_role); - -/* The following definitions come from param/loadparm_ctx.c */ - -const struct loadparm_s3_helpers *loadparm_s3_helpers(void); - -/* The following definitions come from param/loadparm_server_role.c */ - -int lp_server_role(void); -void set_server_role(void); - -/* The following definitions come from param/util.c */ - -uint32_t get_int_param( const char* param ); -char* get_string_param( const char* param ); - /* The following definitions come from lib/server_contexts.c */ struct tevent_context *global_event_context(void); void global_event_context_free(void); diff --git a/source3/param/loadparm.h b/source3/param/loadparm.h new file mode 100644 index 00000000000..7686877ccf1 --- /dev/null +++ b/source3/param/loadparm.h @@ -0,0 +1,200 @@ +/* + * + * Unix SMB/CIFS implementation. + * + * Type definitions for loadparm + * + * Copyright (c) 2020 Andreas Schneider + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _S3_LOADPARM_H +#define _S3_LOADPARM_H + +#include +#include + +/* Forward declarations */ +typedef struct stat_ex SMB_STRUCT_STAT; +typedef struct files_struct files_struct; +struct smbd_server_connection; +struct security_descriptor; + +/* The following definitions come from param/loadparm.c */ + +const struct loadparm_substitution *loadparm_s3_global_substitution(void); + +char *lp_parm_substituted_string(TALLOC_CTX *mem_ctx, + const struct loadparm_substitution *lp_sub, + int snum, + const char *type, + const char *option, + const char *def); + +char *lp_servicename(TALLOC_CTX *ctx, const struct loadparm_substitution *, int); +const char *lp_const_servicename(int); +bool lp_autoloaded(int); +const char *lp_dnsdomain(void); +int lp_winbind_max_domain_connections(void); +bool lp_idmap_range(const char *domain_name, uint32_t *low, uint32_t *high); +bool lp_idmap_default_range(uint32_t *low, uint32_t *high); +const char *lp_idmap_backend(const char *domain_name); +const char *lp_idmap_default_backend (void); +int lp_security(void); +int lp_client_max_protocol(void); +int lp_client_ipc_min_protocol(void); +int lp_client_ipc_max_protocol(void); +int lp_client_ipc_signing(void); +int lp_smb2_max_credits(void); +int lp_cups_encrypt(void); +bool lp_widelinks(int ); +int lp_rpc_low_port(void); +int lp_rpc_high_port(void); +bool lp_lanman_auth(void); +enum samba_weak_crypto lp_weak_crypto(void); + +int lp_wi_scan_global_parametrics( + const char *regex, size_t max_matches, + bool (*cb)(const char *string, regmatch_t matches[], + void *private_data), + void *private_data); + +const char *lp_parm_const_string(int snum, const char *type, const char *option, const char *def); +struct loadparm_service; +const char *lp_parm_const_string_service(struct loadparm_service *service, const char *type, + const char *option, const char *def); +const char **lp_parm_string_list(int snum, const char *type, const char *option, const char **def); +int lp_parm_int(int snum, const char *type, const char *option, int def); +unsigned long lp_parm_ulong(int snum, const char *type, const char *option, unsigned long def); +unsigned long long lp_parm_ulonglong(int snum, const char *type, + const char *option, + unsigned long long def); +bool lp_parm_bool(int snum, const char *type, const char *option, bool def); +struct enum_list; +int lp_parm_enum(int snum, const char *type, const char *option, + const struct enum_list *_enum, int def); +char *canonicalize_servicename(TALLOC_CTX *ctx, const char *src); +bool lp_add_home(const char *pszHomename, int iDefaultService, + const char *user, const char *pszHomedir); +int lp_add_service(const char *pszService, int iDefaultService); +bool lp_add_printer(const char *pszPrintername, int iDefaultService); +bool lp_parameter_is_valid(const char *pszParmName); +bool lp_parameter_is_global(const char *pszParmName); +bool lp_canonicalize_parameter(const char *parm_name, const char **canon_parm, + bool *inverse); +bool lp_canonicalize_parameter_with_value(const char *parm_name, + const char *val, + const char **canon_parm, + const char **canon_val); +void show_parameter_list(void); +bool lp_invert_boolean(const char *str, const char **inverse_str); +bool lp_canonicalize_boolean(const char *str, const char**canon_str); +bool process_registry_service(const char *service_name); +bool process_registry_shares(void); +bool lp_config_backend_is_registry(void); +bool lp_config_backend_is_file(void); +bool lp_file_list_changed(void); +const char *lp_ldap_machine_suffix(TALLOC_CTX *ctx); +const char *lp_ldap_user_suffix(TALLOC_CTX *ctx); +const char *lp_ldap_group_suffix(TALLOC_CTX *ctx); +const char *lp_ldap_idmap_suffix(TALLOC_CTX *ctx); +struct parm_struct; +/* Return a pointer to a service by name. */ +struct loadparm_service *lp_service(const char *pszServiceName); +struct loadparm_service *lp_servicebynum(int snum); +struct loadparm_service *lp_default_loadparm_service(void); +void *lp_parm_ptr(struct loadparm_service *service, struct parm_struct *parm); +void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm); +bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue); +bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue); +bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal); +bool lp_snum_ok(int iService); +void lp_add_one_printer(const char *name, const char *comment, + const char *location, void *pdata); +bool lp_loaded(void); +void lp_killunused(struct smbd_server_connection *sconn, + bool (*snumused) (struct smbd_server_connection *, int)); +void lp_kill_all_services(void); +void lp_killservice(int iServiceIn); +const char* server_role_str(uint32_t role); +enum usershare_err parse_usershare_file(TALLOC_CTX *ctx, + SMB_STRUCT_STAT *psbuf, + const char *servicename, + int snum, + char **lines, + int numlines, + char **pp_sharepath, + char **pp_comment, + char **pp_cp_share_name, + struct security_descriptor **ppsd, + bool *pallow_guest); +int load_usershare_service(const char *servicename); +int load_usershare_shares(struct smbd_server_connection *sconn, + bool (*snumused) (struct smbd_server_connection *, int)); +void gfree_loadparm(void); +bool lp_load_initial_only(const char *pszFname); +bool lp_load_global(const char *file_name); +bool lp_load_with_shares(const char *file_name); +bool lp_load_client(const char *file_name); +bool lp_load_global_no_reinit(const char *file_name); +bool lp_load_no_reinit(const char *file_name); +bool lp_load_client_no_reinit(const char *file_name); +bool lp_load_with_registry_shares(const char *pszFname); +int lp_numservices(void); +void lp_dump(FILE *f, bool show_defaults, int maxtoprint); +void lp_dump_one(FILE * f, bool show_defaults, int snum); +int lp_servicenumber(const char *pszServiceName); +const char *volume_label(TALLOC_CTX *ctx, int snum); +bool lp_domain_master(void); +bool lp_preferred_master(void); +void lp_remove_service(int snum); +void lp_copy_service(int snum, const char *new_name); +int lp_default_server_announce(void); +const char *lp_printername(TALLOC_CTX *ctx, + const struct loadparm_substitution *lp_sub, + int snum); +void lp_set_logfile(const char *name); +int lp_maxprintjobs(int snum); +const char *lp_printcapname(void); +bool lp_disable_spoolss( void ); +void lp_set_spoolss_state( uint32_t state ); +uint32_t lp_get_spoolss_state( void ); +struct smb_signing_state; +void set_use_sendfile(int snum, bool val); +void lp_set_mangling_method(const char *new_method); +bool lp_posix_pathnames(void); +void lp_set_posix_pathnames(void); +enum brl_flavour lp_posix_cifsu_locktype(files_struct *fsp); +void lp_set_posix_default_cifsx_readwrite_locktype(enum brl_flavour val); +int lp_min_receive_file_size(void); +void widelinks_warning(int snum); +const char *lp_ncalrpc_dir(void); +void _lp_set_server_role(int server_role); +uint32_t lp_get_async_dns_timeout(void); + +/* The following definitions come from param/loadparm_ctx.c */ + +const struct loadparm_s3_helpers *loadparm_s3_helpers(void); + +/* The following definitions come from param/loadparm_server_role.c */ + +int lp_server_role(void); +void set_server_role(void); + +/* The following definitions come from param/util.c */ + +uint32_t get_int_param( const char* param ); +char *get_string_param( const char* param ); + +#endif /* _S3_LOADPARM_H */ -- 2.29.2 From aac95c28508e0afbd252579e8bdac8d24f3e5de0 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 11 Aug 2020 10:41:07 +0200 Subject: [PATCH 075/108] s3:lib: Move interface prototypes to own header file Signed-off-by: Andreas Schneider Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Oct 9 20:36:13 UTC 2020 on sn-devel-184 (cherry picked from commit 925cc9aafbe17cb2cbd89f468fac70f96ae89475) --- source3/include/proto.h | 21 +------------------ source3/lib/interface.h | 46 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 source3/lib/interface.h diff --git a/source3/include/proto.h b/source3/include/proto.h index b9a6cb7f116..1bbd8e9d526 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -84,26 +84,7 @@ NTSTATUS vfs_at_fspcwd(TALLOC_CTX *mem_ctx, struct connection_struct *conn, struct files_struct **_fsp); -/* The following definitions come from lib/interface.c */ - -bool ismyaddr(const struct sockaddr *ip); -bool ismyip_v4(struct in_addr ip); -bool is_local_net(const struct sockaddr *from); -void setup_linklocal_scope_id(struct sockaddr *pss); -bool is_local_net_v4(struct in_addr from); -int iface_count(void); -int iface_count_v4_nl(void); -const struct in_addr *first_ipv4_iface(void); -struct interface *get_interface(int n); -const struct sockaddr_storage *iface_n_sockaddr_storage(int n); -const struct in_addr *iface_n_ip_v4(int n); -const struct in_addr *iface_n_bcast_v4(int n); -const struct sockaddr_storage *iface_n_bcast(int n); -const struct sockaddr_storage *iface_ip(const struct sockaddr *ip); -bool iface_local(const struct sockaddr *ip); -void load_interfaces(void); -void gfree_interfaces(void); -bool interfaces_changed(void); +#include "source3/lib/interface.h" /* The following definitions come from lib/ldap_debug_handler.c */ diff --git a/source3/lib/interface.h b/source3/lib/interface.h new file mode 100644 index 00000000000..f45435b4a81 --- /dev/null +++ b/source3/lib/interface.h @@ -0,0 +1,46 @@ +/* + * + * Unix SMB/CIFS implementation. + * + * Type definitions for interfaces + * + * Copyright (c) 2020 Andreas Schneider + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _INTERFACE_H +#define _INTERFACE_H + +#include + +bool ismyaddr(const struct sockaddr *ip); +bool ismyip_v4(struct in_addr ip); +bool is_local_net(const struct sockaddr *from); +void setup_linklocal_scope_id(struct sockaddr *pss); +bool is_local_net_v4(struct in_addr from); +int iface_count(void); +int iface_count_v4_nl(void); +const struct in_addr *first_ipv4_iface(void); +struct interface *get_interface(int n); +const struct sockaddr_storage *iface_n_sockaddr_storage(int n); +const struct in_addr *iface_n_ip_v4(int n); +const struct in_addr *iface_n_bcast_v4(int n); +const struct sockaddr_storage *iface_n_bcast(int n); +const struct sockaddr_storage *iface_ip(const struct sockaddr *ip); +bool iface_local(const struct sockaddr *ip); +void load_interfaces(void); +void gfree_interfaces(void); +bool interfaces_changed(void); + +#endif /* _INTERFACE_H */ -- 2.29.2 From 8b9b3b04734a2caaf45cf4a4106e20489937dd63 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 7 Feb 2020 16:48:16 +0100 Subject: [PATCH 076/108] idl: Add SID_SAMBA_SMB3 Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 56879ec5876625346df89110f62d52e3fd5b8934) --- librpc/idl/security.idl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index a92e8f1518e..06bf7449a70 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -282,6 +282,9 @@ interface security const string SID_SAMBA_UNIX_USER_OWNER = "S-1-22-1"; const string SID_SAMBA_UNIX_GROUP_OWNER = "S-1-22-2"; + /* Information passing via security token */ + const string SID_SAMBA_SMB3 = "S-1-22-1397571891"; + /* SECURITY_NT_SERVICE */ const string NAME_NT_SERVICE = "NT SERVICE"; -- 2.29.2 From ea7d7d025cb198d787d219d169e0cf01f8ecb8be Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 7 Feb 2020 16:48:29 +0100 Subject: [PATCH 077/108] s3:smbd: Add SMB3 connection information to session info Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 905c2b9722a64ee57f3fbcff51e6bb591c6e3edc) --- source3/include/vfs.h | 1 + source3/smbd/pipes.c | 82 +++++++++++++++++++++++++++++++++++++- source3/smbd/smb2_server.c | 5 +++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/source3/include/vfs.h b/source3/include/vfs.h index d527f850628..c0d60636c31 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -411,6 +411,7 @@ typedef struct files_struct { bool use_ofd_locks : 1; bool closing : 1; bool lock_failure_seen : 1; + bool encryption_required : 1; } fsp_flags; struct tevent_timer *update_write_time_event; diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2dd38bb7ab3..d51a3de9497 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -30,13 +30,16 @@ #include "smbd/globals.h" #include "libcli/security/security.h" #include "rpc_server/srv_pipe_hnd.h" +#include "auth/auth_util.h" NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, struct files_struct **pfsp) { + struct smbXsrv_connection *xconn = smb_req->xconn; struct connection_struct *conn = smb_req->conn; struct files_struct *fsp; struct smb_filename *smb_fname = NULL; + struct auth_session_info *session_info = conn->session_info; NTSTATUS status; status = file_new(smb_req, conn, &fsp); @@ -68,10 +71,87 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, return status; } + if (smb_req->smb2req != NULL && smb_req->smb2req->was_encrypted) { + struct security_token *security_token = NULL; + uint16_t dialect = xconn->smb2.server.dialect; + uint16_t srv_smb_encrypt = 0x0002; + uint16_t cipher = xconn->smb2.server.cipher; + char smb3_sid_str[SID_MAX_SIZE]; + struct dom_sid smb3_dom_sid; + struct dom_sid smb3_sid; + uint32_t i; + bool ok; + int rc; + + session_info = copy_session_info(fsp, conn->session_info); + if (session_info == NULL) { + DBG_ERR("Failed to copy session info\n"); + file_free(smb_req, fsp); + return NT_STATUS_NO_MEMORY; + } + security_token = session_info->security_token; + + ok = dom_sid_parse(SID_SAMBA_SMB3, &smb3_dom_sid); + if (!ok) { + file_free(smb_req, fsp); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* + * Security check: + * + * Make sure we don't have a SMB3 SID in the security token! + */ + for (i = 0; i < security_token->num_sids; i++) { + int cmp; + + cmp = dom_sid_compare_domain(&security_token->sids[i], + &smb3_dom_sid); + if (cmp == 0) { + DBG_ERR("ERROR: An SMB3 SID has already been " + "detected in the security token!\n"); + file_free(smb_req, fsp); + return NT_STATUS_ACCESS_DENIED; + } + } + + rc = snprintf(smb3_sid_str, + sizeof(smb3_sid_str), + "%s-%u-%u-%u", + SID_SAMBA_SMB3, + dialect, + srv_smb_encrypt, + cipher); + if (rc < 0) { + DBG_ERR("Buffer too small\n"); + file_free(smb_req, fsp); + return NT_STATUS_BUFFER_TOO_SMALL; + } + + ok = dom_sid_parse(smb3_sid_str, &smb3_sid); + if (!ok) { + DBG_ERR("Failed to parse SMB3 SID\n"); + file_free(smb_req, fsp); + return NT_STATUS_INVALID_PARAMETER; + } + + status = add_sid_to_array_unique(security_token, + &smb3_sid, + &security_token->sids, + &security_token->num_sids); + if (!NT_STATUS_IS_OK(status)) { + DBG_ERR("Failed to add SMB3 SID to security token\n"); + file_free(smb_req, fsp); + return status; + } + + fsp->fsp_flags.encryption_required = true; + } + status = np_open(fsp, name, conn->sconn->remote_address, conn->sconn->local_address, - conn->session_info, + session_info, conn->sconn->ev_ctx, conn->sconn->msg_ctx, conn->sconn->dce_ctx, diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index cf9de185c1f..cd24b7d2ed5 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -3232,6 +3232,11 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, NT_STATUS_FILE_CLOSED); } + } else { + if (fsp->fsp_flags.encryption_required && !req->was_encrypted) { + return smbd_smb2_request_error(req, + NT_STATUS_ACCESS_DENIED); + } } } -- 2.29.2 From fd5b1158697117be089d7feb199076a5413239c6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 12 Mar 2020 14:11:56 +0100 Subject: [PATCH 078/108] librpc: Add dcerpc helper dcerpc_is_transport_encrypted() Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 8bbe5c8c94aaf75d715f558c363e5b2de49f7bf9) --- librpc/rpc/dcerpc_helper.c | 137 +++++++++++++++++++++++++++++++++++++ librpc/rpc/dcerpc_helper.h | 26 +++++++ librpc/wscript_build | 9 +++ 3 files changed, 172 insertions(+) create mode 100644 librpc/rpc/dcerpc_helper.c create mode 100644 librpc/rpc/dcerpc_helper.h diff --git a/librpc/rpc/dcerpc_helper.c b/librpc/rpc/dcerpc_helper.c new file mode 100644 index 00000000000..c5443764628 --- /dev/null +++ b/librpc/rpc/dcerpc_helper.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2020 Andreas Schneider + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "includes.h" +#include "librpc/gen_ndr/security.h" +#include "librpc/gen_ndr/auth.h" +#include "lib/crypto/gnutls_helpers.h" +#include "libcli/security/dom_sid.h" +#include "libcli/smb/smb2_constants.h" + +#include "dcerpc_helper.h" + +static bool smb3_sid_parse(const struct dom_sid *sid, + uint16_t *pdialect, + uint16_t *pencrypt, + uint16_t *pcipher) +{ + uint16_t dialect; + uint16_t encrypt; + uint16_t cipher; + + if (sid->sub_auths[0] != 1397571891) { + return false; + } + + dialect = sid->sub_auths[1]; + if (dialect > 0x03ff) { + return false; + } + + encrypt = sid->sub_auths[2]; + if (encrypt > 0x0002) { + return false; + } + + cipher = sid->sub_auths[3]; + if (cipher > SMB2_ENCRYPTION_AES128_GCM) { + return false; + } + + if (pdialect != NULL) { + *pdialect = dialect; + } + + if (pencrypt != NULL) { + *pencrypt = encrypt; + } + + if (pcipher != NULL) { + *pcipher = cipher; + } + + return true; +} + +bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info) +{ + struct security_token *token = session_info->security_token; + struct dom_sid smb3_dom_sid; + const struct dom_sid *smb3_sid = NULL; + uint16_t dialect = 0; + uint16_t encrypt = 0; + uint16_t cipher = 0; + uint32_t i; + bool ok; + + ok = dom_sid_parse(SID_SAMBA_SMB3, &smb3_dom_sid); + if (!ok) { + return false; + } + + for (i = 0; i < token->num_sids; i++) { + int cmp; + + /* There is only one SMB3 SID allowed! */ + cmp = dom_sid_compare_domain(&token->sids[i], &smb3_dom_sid); + if (cmp == 0) { + if (smb3_sid == NULL) { + smb3_sid = &token->sids[i]; + } else { + DBG_ERR("ERROR: The SMB3 SID has been detected " + "multiple times\n"); + return false; + } + } + } + + if (smb3_sid == NULL) { + return false; + } + + ok = smb3_sid_parse(smb3_sid, &dialect, &encrypt, &cipher); + if (!ok) { + DBG_ERR("Failed to parse SMB3 SID!\n"); + return false; + } + + DBG_DEBUG("SMB SID - dialect: %#04x, encrypt: %#04x, cipher: %#04x\n", + dialect, + encrypt, + cipher); + + if (dialect < SMB3_DIALECT_REVISION_300) { + DBG_DEBUG("Invalid SMB3 dialect!\n"); + return false; + } + + if (encrypt != DCERPC_SMB_ENCRYPTION_REQUIRED) { + DBG_DEBUG("Invalid SMB3 encryption!\n"); + return false; + } + + switch (cipher) { + case SMB2_ENCRYPTION_AES128_CCM: + case SMB2_ENCRYPTION_AES128_GCM: + break; + default: + DBG_DEBUG("Invalid SMB3 cipher!\n"); + return false; + } + + return true; +} diff --git a/librpc/rpc/dcerpc_helper.h b/librpc/rpc/dcerpc_helper.h new file mode 100644 index 00000000000..c0f09ee494e --- /dev/null +++ b/librpc/rpc/dcerpc_helper.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2020 Andreas Schneider + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _DCERPC_HELPER_H +#define _DCERPC_HELPER_H + +#define DCERPC_SMB_ENCRYPTION_OFF 0x0000 +#define DCERPC_SMB_ENCRYPTION_REQUIRED 0x0002 + +bool dcerpc_is_transport_encrypted(struct auth_session_info *session_info); + +#endif /* _DCERPC_HELPER_H */ diff --git a/librpc/wscript_build b/librpc/wscript_build index 27b180fa63d..109a1834841 100644 --- a/librpc/wscript_build +++ b/librpc/wscript_build @@ -669,6 +669,15 @@ bld.SAMBA_LIBRARY('dcerpc-server-core', autoproto='rpc/dcesrv_core_proto.h', vnum='0.0.1') +bld.SAMBA_SUBSYSTEM('DCERPC_HELPER', + source='rpc/dcerpc_helper.c', + public_deps=''' + samba-hostconfig + samba-security + gnutls + GNUTLS_HELPERS + ''') + bld.SAMBA_SUBSYSTEM('NDR_WINBIND', source='gen_ndr/ndr_winbind.c', public_deps='ndr NDR_LSA' -- 2.29.2 From 671201a82e2590951f9ac7ff92a17662971bf1c6 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 28 Aug 2020 16:31:17 +0200 Subject: [PATCH 079/108] s3:smbd: Use defines to set 'srv_smb_encrypt' Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 5f1a73be6311c68a21a550c0de5078baeb78f4ee) --- source3/smbd/pipes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index d51a3de9497..785cbb23b5f 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -31,6 +31,7 @@ #include "libcli/security/security.h" #include "rpc_server/srv_pipe_hnd.h" #include "auth/auth_util.h" +#include "librpc/rpc/dcerpc_helper.h" NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, struct files_struct **pfsp) @@ -74,7 +75,7 @@ NTSTATUS open_np_file(struct smb_request *smb_req, const char *name, if (smb_req->smb2req != NULL && smb_req->smb2req->was_encrypted) { struct security_token *security_token = NULL; uint16_t dialect = xconn->smb2.server.dialect; - uint16_t srv_smb_encrypt = 0x0002; + uint16_t srv_smb_encrypt = DCERPC_SMB_ENCRYPTION_REQUIRED; uint16_t cipher = xconn->smb2.server.cipher; char smb3_sid_str[SID_MAX_SIZE]; struct dom_sid smb3_dom_sid; -- 2.29.2 From 5d542e9aef4c97cf5747d6580971c64fc81d4853 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 12 Nov 2019 16:56:45 +0100 Subject: [PATCH 080/108] s3:rpc_server: Allow to use RC4 for setting passwords Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit c6a21e1897985f267bcfc681179cea95165c3c57) --- source3/rpc_server/samr/srv_samr_chgpasswd.c | 3 + source3/rpc_server/samr/srv_samr_nt.c | 78 +++++++++++++++++++- source3/rpc_server/wscript_build | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c index cb9837ecf01..e326745169e 100644 --- a/source3/rpc_server/samr/srv_samr_chgpasswd.c +++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c @@ -769,11 +769,13 @@ static NTSTATUS check_oem_password(const char *user, .size = 16, }; + GNUTLS_FIPS140_SET_LAX_MODE(); rc = gnutls_cipher_init(&cipher_hnd, GNUTLS_CIPHER_ARCFOUR_128, &enc_key, NULL); if (rc < 0) { + GNUTLS_FIPS140_SET_STRICT_MODE(); return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); } @@ -781,6 +783,7 @@ static NTSTATUS check_oem_password(const char *user, password_encrypted, 516); gnutls_cipher_deinit(cipher_hnd); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (rc < 0) { return gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); } diff --git a/source3/rpc_server/samr/srv_samr_nt.c b/source3/rpc_server/samr/srv_samr_nt.c index 5ffc3331185..77cb18b6a88 100644 --- a/source3/rpc_server/samr/srv_samr_nt.c +++ b/source3/rpc_server/samr/srv_samr_nt.c @@ -46,6 +46,8 @@ #include "rpc_server/srv_access_check.h" #include "../lib/tsocket/tsocket.h" #include "lib/util/base64.h" +#include "param/param.h" +#include "librpc/rpc/dcerpc_helper.h" #include "lib/crypto/gnutls_helpers.h" #include @@ -1887,6 +1889,7 @@ NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p, char *user_name = NULL; char *rhost; const char *wks = NULL; + bool encrypted; DEBUG(5,("_samr_ChangePasswordUser2: %d\n", __LINE__)); @@ -1915,6 +1918,12 @@ NTSTATUS _samr_ChangePasswordUser2(struct pipes_struct *p, return NT_STATUS_NO_MEMORY; } + encrypted = dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + return NT_STATUS_ACCESS_DENIED; + } + /* * UNIX username case mangling not required, pass_oem_change * is case insensitive. @@ -1948,6 +1957,7 @@ NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p, char *user_name = NULL; const char *wks = NULL; char *rhost; + bool encrypted; DEBUG(5,("_samr_OemChangePasswordUser2: %d\n", __LINE__)); @@ -1985,6 +1995,12 @@ NTSTATUS _samr_OemChangePasswordUser2(struct pipes_struct *p, return NT_STATUS_NO_MEMORY; } + encrypted = dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + return NT_STATUS_ACCESS_DENIED; + } + status = pass_oem_change(user_name, rhost, r->in.password->data, @@ -5200,8 +5216,13 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, char *rhost; DATA_BLOB session_key; struct dom_sid_buf buf; + struct loadparm_context *lp_ctx = NULL; + bool encrypted; - DEBUG(5,("_samr_SetUserInfo: %d\n", __LINE__)); + lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers()); + if (lp_ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } /* This is tricky. A WinXP domain join sets (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES) @@ -5390,13 +5411,27 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, break; case 23: + encrypted = + dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + status = NT_STATUS_ACCESS_DENIED; + break; + } + status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { break; } + /* + * This can be allowed as it requires a session key + * which we only have if we have a SMB session. + */ + GNUTLS_FIPS140_SET_LAX_MODE(); status = arc4_decrypt_data(session_key, info->info23.password.data, 516); + GNUTLS_FIPS140_SET_STRICT_MODE(); if(!NT_STATUS_IS_OK(status)) { break; } @@ -5412,14 +5447,27 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, break; case 24: + encrypted = + dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + status = NT_STATUS_ACCESS_DENIED; + break; + } status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { break; } + /* + * This can be allowed as it requires a session key + * which we only have if we have a SMB session. + */ + GNUTLS_FIPS140_SET_LAX_MODE(); status = arc4_decrypt_data(session_key, info->info24.password.data, 516); + GNUTLS_FIPS140_SET_STRICT_MODE(); if(!NT_STATUS_IS_OK(status)) { break; } @@ -5434,12 +5482,26 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, break; case 25: + encrypted = + dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + status = NT_STATUS_ACCESS_DENIED; + break; + } + status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { break; } + /* + * This can be allowed as it requires a session key + * which we only have if we have a SMB session. + */ + GNUTLS_FIPS140_SET_LAX_MODE(); status = decode_rc4_passwd_buffer(&session_key, &info->info25.password); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (!NT_STATUS_IS_OK(status)) { break; } @@ -5454,12 +5516,26 @@ NTSTATUS _samr_SetUserInfo(struct pipes_struct *p, break; case 26: + encrypted = + dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + status = NT_STATUS_ACCESS_DENIED; + break; + } + status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES); if(!NT_STATUS_IS_OK(status)) { break; } + /* + * This can be allowed as it requires a session key + * which we only have if we have a SMB session. + */ + GNUTLS_FIPS140_SET_LAX_MODE(); status = decode_rc4_passwd_buffer(&session_key, &info->info26.password); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (!NT_STATUS_IS_OK(status)) { break; } diff --git a/source3/rpc_server/wscript_build b/source3/rpc_server/wscript_build index 2af02ad6fa8..eb91ac09384 100644 --- a/source3/rpc_server/wscript_build +++ b/source3/rpc_server/wscript_build @@ -85,7 +85,7 @@ bld.SAMBA3_SUBSYSTEM('RPC_SAMR', source='''samr/srv_samr_nt.c samr/srv_samr_util.c samr/srv_samr_chgpasswd.c''', - deps='PLAINTEXT_AUTH SRV_ACCESS_CHECK') + deps='PLAINTEXT_AUTH SRV_ACCESS_CHECK DCERPC_HELPER') bld.SAMBA3_SUBSYSTEM('RPC_SPOOLSS', source='''spoolss/srv_spoolss_nt.c -- 2.29.2 From bd94d3d3a4919616b40cd7306374bee5f244bb71 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 15 Nov 2019 13:49:40 +0100 Subject: [PATCH 081/108] s4:rpc_server: Allow to use RC4 for setting passwords Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit a9c532c6d3e85fbe49b7040254cfc66ab54074bc) --- source4/rpc_server/samr/samr_password.c | 30 +++++++++++++++++++++++++ source4/rpc_server/wscript_build | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 52a644176e2..83b104fbd0e 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -31,6 +31,8 @@ #include "../lib/util/util_ldb.h" #include "rpc_server/samr/proto.h" #include "auth/auth_sam.h" +#include "lib/param/loadparm.h" +#include "librpc/rpc/dcerpc_helper.h" #include "lib/crypto/gnutls_helpers.h" #include @@ -129,6 +131,8 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, struct dom_sid *user_objectSid = NULL; gnutls_cipher_hd_t cipher_hnd = NULL; gnutls_datum_t lm_session_key; + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + bool encrypted; int rc; if (pwbuf == NULL) { @@ -144,6 +148,12 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, return NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; } + encrypted = dcerpc_is_transport_encrypted(session_info); + if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + return NT_STATUS_ACCESS_DENIED; + } + /* Connect to a SAMDB with system privileges for fetching the old pw * hashes. */ sam_ctx = samdb_connect(mem_ctx, @@ -188,11 +198,13 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, .size = sizeof(lm_pwd->hash), }; + GNUTLS_FIPS140_SET_LAX_MODE(); rc = gnutls_cipher_init(&cipher_hnd, GNUTLS_CIPHER_ARCFOUR_128, &lm_session_key, NULL); if (rc < 0) { + GNUTLS_FIPS140_SET_STRICT_MODE(); status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto failed; } @@ -201,6 +213,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, pwbuf->data, 516); gnutls_cipher_deinit(cipher_hnd); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (rc < 0) { status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto failed; @@ -607,7 +620,17 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, DATA_BLOB session_key = data_blob(NULL, 0); gnutls_cipher_hd_t cipher_hnd = NULL; gnutls_datum_t _session_key; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; int rc; + bool encrypted; + + encrypted = dcerpc_is_transport_encrypted(session_info); + if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + return NT_STATUS_ACCESS_DENIED; + } nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { @@ -621,11 +644,17 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, .size = session_key.length, }; + /* + * This is safe to support as we only have a session key + * over a SMB connection which we force to be encrypted. + */ + GNUTLS_FIPS140_SET_LAX_MODE(); rc = gnutls_cipher_init(&cipher_hnd, GNUTLS_CIPHER_ARCFOUR_128, &_session_key, NULL); if (rc < 0) { + GNUTLS_FIPS140_SET_STRICT_MODE(); nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; } @@ -634,6 +663,7 @@ NTSTATUS samr_set_password(struct dcesrv_call_state *dce_call, pwbuf->data, 516); gnutls_cipher_deinit(cipher_hnd); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (rc < 0) { nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; diff --git a/source4/rpc_server/wscript_build b/source4/rpc_server/wscript_build index de55ad6239a..c9c1978f223 100644 --- a/source4/rpc_server/wscript_build +++ b/source4/rpc_server/wscript_build @@ -87,7 +87,7 @@ bld.SAMBA_MODULE('dcesrv_samr', autoproto='samr/proto.h', subsystem='dcerpc_server', init_function='dcerpc_server_samr_init', - deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS' + deps='samdb DCERPC_COMMON ndr-standard auth4_sam GNUTLS_HELPERS DCERPC_HELPER' ) -- 2.29.2 From d458644e8800fbb312749ac6e496c0b89429d229 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:45:49 +0200 Subject: [PATCH 082/108] lib:crypto: Add py binding for set_relax/strict fips mode Signed-off-by: Isaac Boukris Reviewed-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 32d4c75d6cbf9153068a0487347097707afb356a) --- lib/crypto/py_crypto.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lib/crypto/py_crypto.c b/lib/crypto/py_crypto.c index 32b946eee8f..ad18d3ada0f 100644 --- a/lib/crypto/py_crypto.c +++ b/lib/crypto/py_crypto.c @@ -24,6 +24,7 @@ #include #include +#include "lib/crypto/gnutls_helpers.h" static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) { @@ -85,12 +86,27 @@ static PyObject *py_crypto_arcfour_crypt_blob(PyObject *module, PyObject *args) return result; } +static PyObject *py_crypto_set_relax_mode(PyObject *module) +{ + GNUTLS_FIPS140_SET_LAX_MODE(); + + Py_RETURN_NONE; +} + +static PyObject *py_crypto_set_strict_mode(PyObject *module) +{ + GNUTLS_FIPS140_SET_STRICT_MODE(); + + Py_RETURN_NONE; +} static const char py_crypto_arcfour_crypt_blob_doc[] = "arcfour_crypt_blob(data, key)\n" "Encrypt the data with RC4 algorithm using the key"; static PyMethodDef py_crypto_methods[] = { { "arcfour_crypt_blob", (PyCFunction)py_crypto_arcfour_crypt_blob, METH_VARARGS, py_crypto_arcfour_crypt_blob_doc }, + { "set_relax_mode", (PyCFunction)py_crypto_set_relax_mode, METH_NOARGS, "Set fips to relax mode" }, + { "set_strict_mode", (PyCFunction)py_crypto_set_strict_mode, METH_NOARGS, "Set fips to strict mode" }, {0}, }; -- 2.29.2 From 5f742a16dc55bd76443e7b6f5a6910604102c41b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 28 Oct 2020 17:05:36 +0100 Subject: [PATCH 083/108] s4:param: Add 'weak crypto' getter to pyparam Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 7d54e4b49c235dc571f47d15e6b0a6fa63340773) --- source4/param/pyparam.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/source4/param/pyparam.c b/source4/param/pyparam.c index 4023fac4dd6..e15592b5743 100644 --- a/source4/param/pyparam.c +++ b/source4/param/pyparam.c @@ -463,6 +463,23 @@ static PyObject *py_lp_ctx_config_file(PyObject *self, void *closure) return PyUnicode_FromString(configfile); } +static PyObject *py_lp_ctx_weak_crypto(PyObject *self, void *closure) +{ + enum samba_weak_crypto weak_crypto = + lpcfg_weak_crypto(PyLoadparmContext_AsLoadparmContext(self)); + + switch(weak_crypto) { + case SAMBA_WEAK_CRYPTO_UNKNOWN: + Py_RETURN_NONE; + case SAMBA_WEAK_CRYPTO_ALLOWED: + return PyUnicode_FromString("allowed"); + case SAMBA_WEAK_CRYPTO_DISALLOWED: + return PyUnicode_FromString("disallowed"); + } + + Py_RETURN_NONE; +} + static PyGetSetDef py_lp_ctx_getset[] = { { .name = discard_const_p(char, "default_service"), @@ -473,6 +490,11 @@ static PyGetSetDef py_lp_ctx_getset[] = { .get = (getter)py_lp_ctx_config_file, .doc = discard_const_p(char, "Name of last config file that was loaded.") }, + { + .name = discard_const_p(char, "weak_crypto"), + .get = (getter)py_lp_ctx_weak_crypto, + .doc = discard_const_p(char, "If weak crypto is allowed.") + }, { .name = NULL } }; -- 2.29.2 From 0851add217d1c5f3c5038fa68b2704fc7f3a073f Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 21 Oct 2020 10:09:22 +0200 Subject: [PATCH 084/108] python:tests: Add SAMR password change tests for fips Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 9a3ba502d8193b25799ef92917efafd52de2e8c2) --- .../tests/dcerpc/samr_change_password.py | 188 ++++++++++++++++++ selftest/tests.py | 2 + 2 files changed, 190 insertions(+) create mode 100644 python/samba/tests/dcerpc/samr_change_password.py diff --git a/python/samba/tests/dcerpc/samr_change_password.py b/python/samba/tests/dcerpc/samr_change_password.py new file mode 100644 index 00000000000..109eeea98cc --- /dev/null +++ b/python/samba/tests/dcerpc/samr_change_password.py @@ -0,0 +1,188 @@ +# Unix SMB/CIFS implementation. +# +# Copyright © 2020 Andreas Schneider +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +"""Tests for samba.dcerpc.samr.password""" + +import os +import ctypes +import samba.tests + +from samba import crypto, generate_random_password, generate_random_bytes, ntstatus +from samba.auth import system_session +from samba.credentials import Credentials +from samba.credentials import SMB_ENCRYPTION_REQUIRED +from samba.dcerpc import samr, security, lsa +from samba.samdb import SamDB +from samba.tests import RpcInterfaceTestCase + + +class SamrPasswordTests(RpcInterfaceTestCase): + def setUp(self): + super(SamrPasswordTests, self).setUp() + self.open_samdb() + + self.create_user_account(10000) + + self.remote_server = samba.tests.env_get_var_value('SERVER') + self.remote_domain = samba.tests.env_get_var_value('DOMAIN') + self.remote_user = samba.tests.env_get_var_value('USERNAME') + self.remote_password = samba.tests.env_get_var_value('PASSWORD') + self.remote_binding_string = "ncacn_np:%s[krb5]" % (self.remote_server) + + self.remote_creds = Credentials() + self.remote_creds.guess(self.lp) + self.remote_creds.set_username(self.remote_user) + self.remote_creds.set_password(self.remote_password) + + def tearDown(self): + super(SamrPasswordTests, self).tearDown() + + samr.Close(self.user_handle) + samr.Close(self.domain_handle) + samr.Close(self.handle) + + samba.tests.delete_force(self.samdb, self.user_dn) + + # + # Open the samba database + # + def open_samdb(self): + self.lp = samba.tests.env_loadparm() + + self.local_creds = Credentials() + self.local_creds.guess(self.lp) + self.session = system_session() + self.samdb = SamDB(session_info=self.session, + credentials=self.local_creds, + lp=self.lp) + + # + # Open a SAMR Domain handle + # + def open_domain_handle(self): + self.handle = self.conn.Connect2(None, + security.SEC_FLAG_MAXIMUM_ALLOWED) + + self.domain_sid = self.conn.LookupDomain(self.handle, + lsa.String(self.remote_domain)) + + self.domain_handle = self.conn.OpenDomain(self.handle, + security.SEC_FLAG_MAXIMUM_ALLOWED, + self.domain_sid) + + def open_user_handle(self): + name = lsa.String(self.user_name) + + rids = self.conn.LookupNames(self.domain_handle, [name]) + + self.user_handle = self.conn.OpenUser(self.domain_handle, + security.SEC_FLAG_MAXIMUM_ALLOWED, + rids[0].ids[0]) + # + # Create a test user account + # + def create_user_account(self, user_id): + self.user_name = ("SAMR_USER_%d" % user_id) + self.user_pass = generate_random_password(32, 32) + self.user_dn = "cn=%s,cn=users,%s" % (self.user_name, self.samdb.domain_dn()) + + samba.tests.delete_force(self.samdb, self.user_dn) + + self.samdb.newuser(self.user_name, + self.user_pass, + description="Password for " + self.user_name + " is " + self.user_pass, + givenname=self.user_name, + surname=self.user_name) + + + def init_samr_CryptPassword(self, password, session_key): + + def encode_pw_buffer(password): + data = bytearray([0] * 516) + + p = samba.string_to_byte_array(password.encode('utf-16-le')) + plen = len(p) + + b = generate_random_bytes(512 - plen) + + i = 512 - plen + data[0:i] = b + data[i:i+plen] = p + data[512:516] = plen.to_bytes(4, byteorder='little') + + return bytes(data) + + # This is a test, so always allow to encrypt using RC4 + try: + crypto.set_relax_mode() + encrypted_blob = samba.arcfour_encrypt(session_key, encode_pw_buffer(password)) + finally: + crypto.set_strict_mode() + + out_blob = samr.CryptPassword() + out_blob.data = list(encrypted_blob) + + return out_blob + + + def test_setUserInfo2_Password(self, password='P@ssw0rd'): + self.conn = samr.samr(self.remote_binding_string, + self.get_loadparm(), + self.remote_creds) + self.open_domain_handle() + self.open_user_handle() + + password='P@ssw0rd' + + level = 24 + info = samr.UserInfo24() + + info.password_expired = 0 + info.password = self.init_samr_CryptPassword(password, self.conn.session_key) + + # If the server is in FIPS mode, it should reject the password change! + try: + self.conn.SetUserInfo2(self.user_handle, level, info) + except samba.NTSTATUSError as e: + code = ctypes.c_uint32(e.args[0]).value + print(code) + if ((code == ntstatus.NT_STATUS_ACCESS_DENIED) and + (self.lp.weak_crypto == 'disallowed')): + pass + else: + raise + + + def test_setUserInfo2_Password_Encrypted(self, password='P@ssw0rd'): + self.remote_creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + + self.conn = samr.samr(self.remote_binding_string, + self.get_loadparm(), + self.remote_creds) + self.open_domain_handle() + self.open_user_handle() + + password='P@ssw0rd' + + level = 24 + info = samr.UserInfo24() + + info.password_expired = 0 + info.password = self.init_samr_CryptPassword(password, self.conn.session_key) + + self.conn.SetUserInfo2(self.user_handle, level, info) diff --git a/selftest/tests.py b/selftest/tests.py index adcb5b53189..86cab3f8046 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -93,6 +93,8 @@ planpythontestsuite( os.path.join(samba4srcdir, "..", "third_party", "waf")]) planpythontestsuite("fileserver", "samba.tests.smbd_fuzztest") planpythontestsuite("nt4_dc_smb1", "samba.tests.dcerpc.binding") +for env in [ 'ad_dc:local', 'ad_dc_fips:local' ]: + planpythontestsuite(env, "samba.tests.dcerpc.samr_change_password") def cmdline(script, *args): -- 2.29.2 From d9d570cd7dcd4d8a4fef6b098e7163d6dfe0a85b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 21 Oct 2020 10:09:22 +0200 Subject: [PATCH 085/108] python:tests: Add SAMR password change tests for fips Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Thu Oct 29 15:41:37 UTC 2020 on sn-devel-184 (cherry picked from commit ebd687335b9accfdbae7dbc65c9882ab4d5c0986) --- selftest/target/Samba4.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 649e923ff9a..1ebdf2a5484 100755 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -1040,7 +1040,7 @@ servicePrincipalName: http/testupnspn.$ctx->{dnsname} $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" "; $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" "; $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool") - . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'"; + . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account' -d10"; unless (system($samba_tool_cmd) == 0) { warn("Unable to add '$testallowed_account' user to 'Allowed RODC Password Replication Group': \n$samba_tool_cmd\n"); return undef; -- 2.29.2 From f23b2e38a9169b074ca12a24cc91a12bfc582ad9 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 20 Aug 2020 09:40:41 +0200 Subject: [PATCH 086/108] auth:creds: Rename CRED_USE_KERBEROS values Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 1298280a22ef7494fb85a6a5953bae15d22fa204) --- auth/credentials/credentials.c | 8 +++++--- auth/credentials/credentials.h | 9 ++++++--- auth/credentials/credentials_krb5.c | 4 ++-- auth/credentials/credentials_ntlm.c | 2 +- auth/credentials/credentials_secrets.c | 5 +++-- auth/credentials/pycredentials.c | 6 +++--- auth/credentials/tests/simple.c | 2 +- auth/credentials/wscript_build | 2 +- auth/gensec/gensec_start.c | 8 ++++---- examples/winexe/winexe.c | 4 ++-- source3/auth/auth_generic.c | 4 ++-- source3/lib/util_cmdline.c | 18 +++++++++--------- source3/libads/sasl.c | 8 ++++---- source3/libnet/libnet_join.c | 2 +- source3/libsmb/cliconnect.c | 16 ++++++++-------- source3/passdb/passdb.c | 6 +++--- source3/passdb/pdb_samba_dsdb.c | 4 ++-- source3/rpc_client/cli_pipe.c | 2 +- source3/rpcclient/rpcclient.c | 8 ++++---- source3/utils/net_ads.c | 2 +- source3/utils/net_util.c | 6 +++--- source3/utils/ntlm_auth.c | 4 ++-- source3/winbindd/winbindd_cm.c | 2 +- source4/auth/gensec/gensec_gssapi.c | 2 +- source4/auth/session.c | 2 +- source4/lib/cmdline/popt_credentials.c | 4 ++-- source4/torture/ldap/session_expiry.c | 2 +- source4/torture/raw/session.c | 4 ++-- source4/torture/rpc/schannel.c | 4 ++-- source4/torture/smb2/session.c | 12 ++++++------ 30 files changed, 84 insertions(+), 78 deletions(-) diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index 77c35dd104b..1bdd6f15a09 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -44,6 +44,8 @@ _PUBLIC_ struct cli_credentials *cli_credentials_init(TALLOC_CTX *mem_ctx) cred->winbind_separator = '\\'; + cred->use_kerberos = CRED_USE_KERBEROS_DESIRED; + cred->signing_state = SMB_SIGNING_DEFAULT; /* @@ -360,7 +362,7 @@ _PUBLIC_ bool cli_credentials_authentication_requested(struct cli_credentials *c return true; } - if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) { + if (cli_credentials_get_kerberos_state(cred) == CRED_USE_KERBEROS_REQUIRED) { return true; } @@ -1018,7 +1020,7 @@ _PUBLIC_ void cli_credentials_guess(struct cli_credentials *cred, } if (lp_ctx != NULL && - cli_credentials_get_kerberos_state(cred) != CRED_DONT_USE_KERBEROS) { + cli_credentials_get_kerberos_state(cred) != CRED_USE_KERBEROS_DISABLED) { cli_credentials_set_ccache(cred, lp_ctx, NULL, CRED_GUESS_FILE, &error_string); } @@ -1097,7 +1099,7 @@ _PUBLIC_ void cli_credentials_set_anonymous(struct cli_credentials *cred) cli_credentials_set_principal(cred, NULL, CRED_SPECIFIED); cli_credentials_set_realm(cred, NULL, CRED_SPECIFIED); cli_credentials_set_workstation(cred, "", CRED_UNINITIALISED); - cli_credentials_set_kerberos_state(cred, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(cred, CRED_USE_KERBEROS_DISABLED); } /** diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 438bcdce232..f468b8558dd 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -53,9 +53,12 @@ enum credentials_obtained { }; enum credentials_use_kerberos { - CRED_AUTO_USE_KERBEROS = 0, /* Default, we try kerberos if available */ - CRED_DONT_USE_KERBEROS, /* Sometimes trying kerberos just does 'bad things', so don't */ - CRED_MUST_USE_KERBEROS /* Sometimes administrators are parinoid, so always do kerberos */ + /** Sometimes trying kerberos just does 'bad things', so don't */ + CRED_USE_KERBEROS_DISABLED = 0, + /** Default, we try kerberos if available */ + CRED_USE_KERBEROS_DESIRED, + /** Sometimes administrators are paranoid, so always do kerberos */ + CRED_USE_KERBEROS_REQUIRED, }; enum credentials_krb_forwardable { diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index 259b35b73b0..36f6b59a72b 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -871,7 +871,7 @@ _PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache, error_string); if (ret) { - if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) { + if (cli_credentials_get_kerberos_state(cred) == CRED_USE_KERBEROS_REQUIRED) { DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", *error_string)); } else { DEBUG(4, ("Failed to get kerberos credentials: %s\n", *error_string)); @@ -1431,7 +1431,7 @@ _PUBLIC_ void cli_credentials_set_impersonate_principal(struct cli_credentials * cred->impersonate_principal = talloc_strdup(cred, principal); talloc_free(cred->self_service); cred->self_service = talloc_strdup(cred, self_service); - cli_credentials_set_kerberos_state(cred, CRED_MUST_USE_KERBEROS); + cli_credentials_set_kerberos_state(cred, CRED_USE_KERBEROS_REQUIRED); } /* diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index f1b22a6c9e2..1bec60e5dce 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -53,7 +53,7 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred const struct samr_Password *nt_hash = NULL; int rc; - if (cred->use_kerberos == CRED_MUST_USE_KERBEROS) { + if (cred->use_kerberos == CRED_USE_KERBEROS_REQUIRED) { TALLOC_FREE(frame); return NT_STATUS_INVALID_PARAMETER_MIX; } diff --git a/auth/credentials/credentials_secrets.c b/auth/credentials/credentials_secrets.c index 52a89d4d5b4..58067a5bece 100644 --- a/auth/credentials/credentials_secrets.c +++ b/auth/credentials/credentials_secrets.c @@ -370,7 +370,8 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credenti } if (secrets_tdb_password_more_recent) { - enum credentials_use_kerberos use_kerberos = CRED_DONT_USE_KERBEROS; + enum credentials_use_kerberos use_kerberos = + CRED_USE_KERBEROS_DISABLED; char *machine_account = talloc_asprintf(tmp_ctx, "%s$", lpcfg_netbios_name(lp_ctx)); cli_credentials_set_password(cred, secrets_tdb_password, CRED_SPECIFIED); cli_credentials_set_old_password(cred, secrets_tdb_old_password, CRED_SPECIFIED); @@ -386,7 +387,7 @@ _PUBLIC_ NTSTATUS cli_credentials_set_machine_account_db_ctx(struct cli_credenti FALL_THROUGH; case ROLE_ACTIVE_DIRECTORY_DC: - use_kerberos = CRED_AUTO_USE_KERBEROS; + use_kerberos = CRED_USE_KERBEROS_DESIRED; break; } } diff --git a/auth/credentials/pycredentials.c b/auth/credentials/pycredentials.c index 17c90573f09..95dde276ef7 100644 --- a/auth/credentials/pycredentials.c +++ b/auth/credentials/pycredentials.c @@ -1492,9 +1492,9 @@ MODULE_INIT_FUNC(credentials) PyModule_AddObject(m, "CALLBACK_RESULT", PyLong_FromLong(CRED_CALLBACK_RESULT)); PyModule_AddObject(m, "SPECIFIED", PyLong_FromLong(CRED_SPECIFIED)); - PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyLong_FromLong(CRED_AUTO_USE_KERBEROS)); - PyModule_AddObject(m, "DONT_USE_KERBEROS", PyLong_FromLong(CRED_DONT_USE_KERBEROS)); - PyModule_AddObject(m, "MUST_USE_KERBEROS", PyLong_FromLong(CRED_MUST_USE_KERBEROS)); + PyModule_AddObject(m, "AUTO_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_DESIRED)); + PyModule_AddObject(m, "DONT_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_DISABLED)); + PyModule_AddObject(m, "MUST_USE_KERBEROS", PyLong_FromLong(CRED_USE_KERBEROS_REQUIRED)); PyModule_AddObject(m, "AUTO_KRB_FORWARDABLE", PyLong_FromLong(CRED_AUTO_KRB_FORWARDABLE)); PyModule_AddObject(m, "NO_KRB_FORWARDABLE", PyLong_FromLong(CRED_NO_KRB_FORWARDABLE)); diff --git a/auth/credentials/tests/simple.c b/auth/credentials/tests/simple.c index 7f122bed3bc..b39d7a2251b 100644 --- a/auth/credentials/tests/simple.c +++ b/auth/credentials/tests/simple.c @@ -73,7 +73,7 @@ static bool test_guess(struct torture_context *tctx) const char *passwd_fd = getenv("PASSWD_FD"); const char *passwd_file = getenv("PASSWD_FILE"); - cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS); + cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_REQUIRED); unsetenv("USER"); unsetenv("PASSWD_FD"); diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build index 1e3302e3e48..ad16b7d8008 100644 --- a/auth/credentials/wscript_build +++ b/auth/credentials/wscript_build @@ -5,7 +5,7 @@ bld.SAMBA_LIBRARY('samba-credentials', public_headers='credentials.h', pc_files='samba-credentials.pc', deps='LIBCRYPTO samba-errors events LIBCLI_AUTH samba-security CREDENTIALS_SECRETS CREDENTIALS_KRB5', - vnum='0.1.0' + vnum='1.0.0' ) bld.SAMBA_SUBSYSTEM('CREDENTIALS_KRB5', diff --git a/auth/gensec/gensec_start.c b/auth/gensec/gensec_start.c index 3f42d611140..56306efed13 100644 --- a/auth/gensec/gensec_start.c +++ b/auth/gensec/gensec_start.c @@ -117,18 +117,18 @@ static const struct gensec_security_ops **gensec_use_kerberos_mechs( } switch (use_kerberos) { - case CRED_AUTO_USE_KERBEROS: + case CRED_USE_KERBEROS_DESIRED: keep = true; break; - case CRED_DONT_USE_KERBEROS: + case CRED_USE_KERBEROS_DISABLED: if (old_gensec_list[i]->kerberos == false) { keep = true; } break; - case CRED_MUST_USE_KERBEROS: + case CRED_USE_KERBEROS_REQUIRED: if (old_gensec_list[i]->kerberos == true) { keep = true; } @@ -156,7 +156,7 @@ _PUBLIC_ const struct gensec_security_ops **gensec_security_mechs( TALLOC_CTX *mem_ctx) { const struct gensec_security_ops * const *backends = gensec_security_all(); - enum credentials_use_kerberos use_kerberos = CRED_AUTO_USE_KERBEROS; + enum credentials_use_kerberos use_kerberos = CRED_USE_KERBEROS_DESIRED; bool keep_schannel = false; if (gensec_security != NULL) { diff --git a/examples/winexe/winexe.c b/examples/winexe/winexe.c index 03e7ec85198..95386211c0a 100644 --- a/examples/winexe/winexe.c +++ b/examples/winexe/winexe.c @@ -283,8 +283,8 @@ static void parse_args(int argc, const char *argv[], if (opt_kerberos) { cli_credentials_set_kerberos_state(cred, strcmp(opt_kerberos, "yes") - ? CRED_MUST_USE_KERBEROS - : CRED_DONT_USE_KERBEROS); + ? CRED_USE_KERBEROS_REQUIRED + : CRED_USE_KERBEROS_DISABLED); } if (options->runas == NULL && options->runas_file != NULL) { diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c index 0e9500ac08d..f314acd9559 100644 --- a/source3/auth/auth_generic.c +++ b/source3/auth/auth_generic.c @@ -356,9 +356,9 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx, cli_credentials_set_conf(server_credentials, lp_ctx); if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) { - cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS); + cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DESIRED); } else { - cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DISABLED); } nt_status = gensec_server_start(tmp_ctx, gensec_settings, diff --git a/source3/lib/util_cmdline.c b/source3/lib/util_cmdline.c index 9c9e2f0ac0f..d2af34ee19b 100644 --- a/source3/lib/util_cmdline.c +++ b/source3/lib/util_cmdline.c @@ -307,9 +307,9 @@ void set_cmdline_auth_info_use_kerberos(struct user_auth_info *auth_info, enum credentials_use_kerberos krb5_state; if (b) { - krb5_state = CRED_MUST_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_REQUIRED; } else { - krb5_state = CRED_DONT_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_DISABLED; } cli_credentials_set_kerberos_state(auth_info->creds, krb5_state); @@ -321,7 +321,7 @@ bool get_cmdline_auth_info_use_kerberos(const struct user_auth_info *auth_info) krb5_state = cli_credentials_get_kerberos_state(auth_info->creds); - if (krb5_state == CRED_MUST_USE_KERBEROS) { + if (krb5_state == CRED_USE_KERBEROS_REQUIRED) { return true; } @@ -336,17 +336,17 @@ void set_cmdline_auth_info_fallback_after_kerberos(struct user_auth_info *auth_i krb5_state = cli_credentials_get_kerberos_state(auth_info->creds); switch (krb5_state) { - case CRED_MUST_USE_KERBEROS: + case CRED_USE_KERBEROS_REQUIRED: if (b) { - krb5_state = CRED_AUTO_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_DESIRED; } break; - case CRED_AUTO_USE_KERBEROS: + case CRED_USE_KERBEROS_DESIRED: if (!b) { - krb5_state = CRED_MUST_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_REQUIRED; } break; - case CRED_DONT_USE_KERBEROS: + case CRED_USE_KERBEROS_DISABLED: /* nothing to do */ break; } @@ -360,7 +360,7 @@ bool get_cmdline_auth_info_fallback_after_kerberos(const struct user_auth_info * krb5_state = cli_credentials_get_kerberos_state(auth_info->creds); - if (krb5_state == CRED_AUTO_USE_KERBEROS) { + if (krb5_state == CRED_USE_KERBEROS_DESIRED) { return true; } diff --git a/source3/libads/sasl.c b/source3/libads/sasl.c index 87beeafe3ed..90ffa040ec0 100644 --- a/source3/libads/sasl.c +++ b/source3/libads/sasl.c @@ -158,7 +158,7 @@ static ADS_STATUS ads_sasl_spnego_gensec_bind(ADS_STRUCT *ads, use_spnego_principal = false; } - if (krb5_state == CRED_DONT_USE_KERBEROS) { + if (krb5_state == CRED_USE_KERBEROS_DISABLED) { use_spnego_principal = false; } @@ -565,7 +565,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) { status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_MUST_USE_KERBEROS, + CRED_USE_KERBEROS_REQUIRED, p.service, p.hostname, blob); if (ADS_ERR_OK(status)) { @@ -581,7 +581,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) if (ADS_ERR_OK(status)) { status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_MUST_USE_KERBEROS, + CRED_USE_KERBEROS_REQUIRED, p.service, p.hostname, blob); if (!ADS_ERR_OK(status)) { @@ -616,7 +616,7 @@ static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads) library for HMAC_MD4 encryption */ mech = "NTLMSSP"; status = ads_sasl_spnego_gensec_bind(ads, "GSS-SPNEGO", - CRED_DONT_USE_KERBEROS, + CRED_USE_KERBEROS_DISABLED, p.service, p.hostname, data_blob_null); done: diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index f3bf27e6c00..bd3aeec9434 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -1707,7 +1707,7 @@ NTSTATUS libnet_join_ok(struct messaging_context *msg_ctx, if (use_kerberos) { cli_credentials_set_kerberos_state(cli_creds, - CRED_MUST_USE_KERBEROS); + CRED_USE_KERBEROS_REQUIRED); } status = cli_full_connection_creds(&cli, NULL, diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index abfd18bfaf1..f7b4741de89 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -124,13 +124,13 @@ struct cli_credentials *cli_session_creds_init(TALLOC_CTX *mem_ctx, if (use_kerberos && fallback_after_kerberos) { cli_credentials_set_kerberos_state(creds, - CRED_AUTO_USE_KERBEROS); + CRED_USE_KERBEROS_DESIRED); } else if (use_kerberos) { cli_credentials_set_kerberos_state(creds, - CRED_MUST_USE_KERBEROS); + CRED_USE_KERBEROS_REQUIRED); } else { cli_credentials_set_kerberos_state(creds, - CRED_DONT_USE_KERBEROS); + CRED_USE_KERBEROS_DISABLED); } if (use_ccache) { @@ -255,7 +255,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, krb5_state = cli_credentials_get_kerberos_state(creds); - if (krb5_state != CRED_DONT_USE_KERBEROS) { + if (krb5_state != CRED_USE_KERBEROS_DISABLED) { try_kerberos = true; } @@ -275,7 +275,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, try_kerberos = false; } - if (krb5_state == CRED_MUST_USE_KERBEROS && !try_kerberos) { + if (krb5_state == CRED_USE_KERBEROS_REQUIRED && !try_kerberos) { DEBUG(0, ("Kerberos auth with '%s' (%s\\%s) to access " "'%s' not possible\n", user_principal, user_domain, user_account, @@ -286,7 +286,7 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, if (pass == NULL || strlen(pass) == 0) { need_kinit = false; - } else if (krb5_state == CRED_MUST_USE_KERBEROS) { + } else if (krb5_state == CRED_USE_KERBEROS_REQUIRED) { need_kinit = try_kerberos; } else { need_kinit = try_kerberos; @@ -321,14 +321,14 @@ NTSTATUS cli_session_creds_prepare_krb5(struct cli_state *cli, if (ret != 0) { int dbglvl = DBGLVL_NOTICE; - if (krb5_state == CRED_MUST_USE_KERBEROS) { + if (krb5_state == CRED_USE_KERBEROS_REQUIRED) { dbglvl = DBGLVL_ERR; } DEBUG(dbglvl, ("Kinit for %s to access %s failed: %s\n", user_principal, target_hostname, error_message(ret))); - if (krb5_state == CRED_MUST_USE_KERBEROS) { + if (krb5_state == CRED_USE_KERBEROS_REQUIRED) { TALLOC_FREE(frame); return krb5_to_nt_status(ret); } diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 8ed1bafcea3..b12c845d9d2 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -2630,7 +2630,7 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain, /* * It's not possible to use NTLMSSP with a domain trust account. */ - cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS); + cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_REQUIRED); } else { /* * We can't use kerberos against an NT4 domain. @@ -2638,7 +2638,7 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain, * We should have a mode that also disallows NTLMSSP here, * as only NETLOGON SCHANNEL is possible. */ - cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_DISABLED); } ok = cli_credentials_set_username(creds, account_name, CRED_SPECIFIED); @@ -2656,7 +2656,7 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain, /* * We currently can't do kerberos just with an NTHASH. */ - cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_DISABLED); goto done; } diff --git a/source3/passdb/pdb_samba_dsdb.c b/source3/passdb/pdb_samba_dsdb.c index 276bda88efc..93e8f5bebe6 100644 --- a/source3/passdb/pdb_samba_dsdb.c +++ b/source3/passdb/pdb_samba_dsdb.c @@ -2599,13 +2599,13 @@ static NTSTATUS pdb_samba_dsdb_get_trusteddom_creds(struct pdb_methods *m, * Force kerberos if this is an active directory domain */ cli_credentials_set_kerberos_state(creds, - CRED_MUST_USE_KERBEROS); + CRED_USE_KERBEROS_REQUIRED); } else { /* * TODO: we should allow krb5 with the raw nt hash. */ cli_credentials_set_kerberos_state(creds, - CRED_DONT_USE_KERBEROS); + CRED_USE_KERBEROS_DISABLED); } *_creds = talloc_move(mem_ctx, &creds); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8227ef0b0bd..ba6c86cc227 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2637,7 +2637,7 @@ NTSTATUS rpccli_ncalrpc_bind_data(TALLOC_CTX *mem_ctx, NAME_NT_AUTHORITY, /* domain */ "SYSTEM", NULL, /* password */ - CRED_DONT_USE_KERBEROS, + CRED_USE_KERBEROS_DISABLED, NULL, /* netlogon_creds_CredentialState */ presult); } diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 575a42ebf70..a38f69f5592 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -810,19 +810,19 @@ static NTSTATUS do_cmd(struct cli_state *cli, case DCERPC_AUTH_TYPE_SPNEGO: switch (pipe_default_auth_spnego_type) { case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: - krb5_state = CRED_DONT_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_DISABLED; break; case PIPE_AUTH_TYPE_SPNEGO_KRB5: - krb5_state = CRED_MUST_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_REQUIRED; break; case PIPE_AUTH_TYPE_SPNEGO_NONE: - krb5_state = CRED_AUTO_USE_KERBEROS; + krb5_state = CRED_USE_KERBEROS_DESIRED; break; } FALL_THROUGH; case DCERPC_AUTH_TYPE_NTLMSSP: case DCERPC_AUTH_TYPE_KRB5: - if (krb5_state != CRED_AUTO_USE_KERBEROS) { + if (krb5_state != CRED_USE_KERBEROS_DESIRED) { cli_credentials_set_kerberos_state(creds, krb5_state); } diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 7f5b9c3a440..1a0e8a5c9dd 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -2432,7 +2432,7 @@ static int net_ads_printer_publish(struct net_context *c, int argc, const char * talloc_destroy(mem_ctx); return -1; } - cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS); + cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_REQUIRED); nt_status = cli_full_connection_creds(&cli, lp_netbios_name(), servername, &server_ss, 0, diff --git a/source3/utils/net_util.c b/source3/utils/net_util.c index 5829d891075..6c5321db0fd 100644 --- a/source3/utils/net_util.c +++ b/source3/utils/net_util.c @@ -493,13 +493,13 @@ struct cli_credentials *net_context_creds(struct net_context *c, if (c->opt_kerberos && c->opt_user_specified) { cli_credentials_set_kerberos_state(creds, - CRED_AUTO_USE_KERBEROS); + CRED_USE_KERBEROS_DESIRED); } else if (c->opt_kerberos) { cli_credentials_set_kerberos_state(creds, - CRED_MUST_USE_KERBEROS); + CRED_USE_KERBEROS_REQUIRED); } else { cli_credentials_set_kerberos_state(creds, - CRED_DONT_USE_KERBEROS); + CRED_USE_KERBEROS_DISABLED); } if (c->opt_ccache) { diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 7f8d2688978..bfaeff5188d 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1364,9 +1364,9 @@ static NTSTATUS ntlm_auth_prepare_gensec_server(TALLOC_CTX *mem_ctx, cli_credentials_set_conf(server_credentials, lp_ctx); if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC || lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) { - cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS); + cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DESIRED); } else { - cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(server_credentials, CRED_USE_KERBEROS_DISABLED); } nt_status = gensec_server_start(tmp_ctx, gensec_settings, diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 5fb22d7e9c8..466a0095ef2 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -706,7 +706,7 @@ static NTSTATUS cm_get_ipc_credentials(TALLOC_CTX *mem_ctx, } cli_credentials_set_conf(creds, lp_ctx); - cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(creds, CRED_USE_KERBEROS_DISABLED); ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED); if (!ok) { diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index d66abf32a7f..b668d4ed258 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -1556,7 +1556,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi } /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */ - cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS); + cli_credentials_set_kerberos_state(session_info->credentials, CRED_USE_KERBEROS_REQUIRED); /* It has been taken from this place... */ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; diff --git a/source4/auth/session.c b/source4/auth/session.c index c5fc226a7d7..8e44dcd24f1 100644 --- a/source4/auth/session.c +++ b/source4/auth/session.c @@ -295,7 +295,7 @@ struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx, /* This credential handle isn't useful for password * authentication, so ensure nobody tries to do that */ cli_credentials_set_kerberos_state(creds, - CRED_MUST_USE_KERBEROS); + CRED_USE_KERBEROS_REQUIRED); } #endif diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c index 5dd61f6339c..7d8963da99e 100644 --- a/source4/lib/cmdline/popt_credentials.c +++ b/source4/lib/cmdline/popt_credentials.c @@ -120,8 +120,8 @@ static void popt_common_credentials_callback(poptContext con, cli_credentials_set_kerberos_state( popt_get_cmdline_credentials(), use_kerberos - ? CRED_MUST_USE_KERBEROS - : CRED_DONT_USE_KERBEROS); + ? CRED_USE_KERBEROS_REQUIRED + : CRED_USE_KERBEROS_DISABLED); break; } diff --git a/source4/torture/ldap/session_expiry.c b/source4/torture/ldap/session_expiry.c index 35dda439b17..e5e38450745 100644 --- a/source4/torture/ldap/session_expiry.c +++ b/source4/torture/ldap/session_expiry.c @@ -55,7 +55,7 @@ bool torture_ldap_session_expiry(struct torture_context *torture) torture, url!=NULL, ret, fail, "talloc_asprintf failed"); cli_credentials_set_kerberos_state( - credentials, CRED_MUST_USE_KERBEROS); + credentials, CRED_USE_KERBEROS_REQUIRED); ok = lpcfg_set_option( torture->lp_ctx, "gensec_gssapi:requested_life_time=4"); diff --git a/source4/torture/raw/session.c b/source4/torture/raw/session.c index 0c460ae3069..e246d25e9fb 100644 --- a/source4/torture/raw/session.c +++ b/source4/torture/raw/session.c @@ -245,12 +245,12 @@ static bool test_session_expire1(struct torture_context *tctx) use_kerberos = cli_credentials_get_kerberos_state( popt_get_cmdline_credentials()); - if (use_kerberos != CRED_MUST_USE_KERBEROS) { + if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) { torture_warning(tctx, "smb2.session.expire1 requires -k yes!"); torture_skip(tctx, "smb2.session.expire1 requires -k yes!"); } - torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS, + torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED, "please use -k yes"); lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4"); diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index fff0b1aacbd..a5755041040 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -965,8 +965,8 @@ bool torture_rpc_schannel_bench1(struct torture_context *torture) torture_assert(torture, s->join_ctx2 != NULL, "Failed to join domain with acct_flags=ACB_WSTRUST"); - cli_credentials_set_kerberos_state(s->wks_creds1, CRED_DONT_USE_KERBEROS); - cli_credentials_set_kerberos_state(s->wks_creds2, CRED_DONT_USE_KERBEROS); + cli_credentials_set_kerberos_state(s->wks_creds1, CRED_USE_KERBEROS_DISABLED); + cli_credentials_set_kerberos_state(s->wks_creds2, CRED_USE_KERBEROS_DISABLED); for (i=0; i < s->nprocs; i++) { struct cli_credentials *wks = s->wks_creds1; diff --git a/source4/torture/smb2/session.c b/source4/torture/smb2/session.c index 07c6faebb15..701dfc10a07 100644 --- a/source4/torture/smb2/session.c +++ b/source4/torture/smb2/session.c @@ -956,7 +956,7 @@ bool test_session_reauth6(struct torture_context *tctx, struct smb2_tree *tree) krb_state = cli_credentials_get_kerberos_state( popt_get_cmdline_credentials()); - if (krb_state == CRED_MUST_USE_KERBEROS) { + if (krb_state == CRED_USE_KERBEROS_REQUIRED) { torture_skip(tctx, "Can't test failing session setup with kerberos."); } @@ -1064,12 +1064,12 @@ static bool test_session_expire1i(struct torture_context *tctx, size_t i; use_kerberos = cli_credentials_get_kerberos_state(credentials); - if (use_kerberos != CRED_MUST_USE_KERBEROS) { + if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) { torture_warning(tctx, "smb2.session.expire1 requires -k yes!"); torture_skip(tctx, "smb2.session.expire1 requires -k yes!"); } - torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS, + torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED, "please use -k yes"); cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); @@ -1250,12 +1250,12 @@ static bool test_session_expire2i(struct torture_context *tctx, struct smb2_notify ntf2; use_kerberos = cli_credentials_get_kerberos_state(credentials); - if (use_kerberos != CRED_MUST_USE_KERBEROS) { + if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) { torture_warning(tctx, "smb2.session.expire2 requires -k yes!"); torture_skip(tctx, "smb2.session.expire2 requires -k yes!"); } - torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS, + torture_assert_int_equal(tctx, use_kerberos, CRED_USE_KERBEROS_REQUIRED, "please use -k yes"); cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); @@ -1612,7 +1612,7 @@ static bool test_session_expire_disconnect(struct torture_context *tctx) bool connected; use_kerberos = cli_credentials_get_kerberos_state(credentials); - if (use_kerberos != CRED_MUST_USE_KERBEROS) { + if (use_kerberos != CRED_USE_KERBEROS_REQUIRED) { torture_warning(tctx, "smb2.session.expire1 requires -k yes!"); torture_skip(tctx, "smb2.session.expire1 requires -k yes!"); } -- 2.29.2 From 7f21cee87046f219f0b3cc9874e816f8b7812278 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 1 Sep 2020 12:32:28 +0200 Subject: [PATCH 087/108] auth:creds:tests: Migrate test to a cmocka unit test Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 1a92994a9513f5e73d30604a1dc217ddeb1ac8d5) --- auth/credentials/tests/test_creds.c | 221 ++++++++++++++++++++++++++++ auth/credentials/wscript_build | 6 + selftest/tests.py | 2 + source4/torture/local/local.c | 1 - source4/torture/local/wscript_build | 2 +- 5 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 auth/credentials/tests/test_creds.c diff --git a/auth/credentials/tests/test_creds.c b/auth/credentials/tests/test_creds.c new file mode 100644 index 00000000000..d2d3d30d73d --- /dev/null +++ b/auth/credentials/tests/test_creds.c @@ -0,0 +1,221 @@ +/* + * Unix SMB/CIFS implementation. + * + * Copyright (C) 2018-2019 Andreas Schneider + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "lib/replace/replace.h" +#include "auth/credentials/credentials.c" + +static int setup_talloc_context(void **state) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + *state = frame; + return 0; +} + +static int teardown_talloc_context(void **state) +{ + TALLOC_CTX *frame = *state; + TALLOC_FREE(frame); + return 0; +} + +static void torture_creds_init(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct cli_credentials *creds = NULL; + const char *username = NULL; + const char *domain = NULL; + const char *password = NULL; + bool ok; + + creds = cli_credentials_init(mem_ctx); + assert_non_null(creds); + assert_null(creds->username); + assert_int_equal(creds->username_obtained, CRED_UNINITIALISED); + + domain = cli_credentials_get_domain(creds); + assert_null(domain); + ok = cli_credentials_set_domain(creds, "WURST", CRED_SPECIFIED); + assert_true(ok); + assert_int_equal(creds->domain_obtained, CRED_SPECIFIED); + domain = cli_credentials_get_domain(creds); + assert_string_equal(domain, "WURST"); + + username = cli_credentials_get_username(creds); + assert_null(username); + ok = cli_credentials_set_username(creds, "brot", CRED_SPECIFIED); + assert_true(ok); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + username = cli_credentials_get_username(creds); + assert_string_equal(username, "brot"); + + password = cli_credentials_get_password(creds); + assert_null(password); + ok = cli_credentials_set_password(creds, "SECRET", CRED_SPECIFIED); + assert_true(ok); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); + password = cli_credentials_get_password(creds); + assert_string_equal(password, "SECRET"); +} + +static void torture_creds_init_anonymous(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct cli_credentials *creds = NULL; + + creds = cli_credentials_init_anon(mem_ctx); + assert_non_null(creds); + + assert_string_equal(creds->domain, ""); + assert_int_equal(creds->domain_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->username, ""); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + + assert_null(creds->password); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); +} + +static void torture_creds_guess(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct cli_credentials *creds = NULL; + const char *env_user = getenv("USER"); + + creds = cli_credentials_init(mem_ctx); + assert_non_null(creds); + + setenv("PASSWD", "SECRET", 1); + cli_credentials_guess(creds, NULL); + + assert_string_equal(creds->username, env_user); + assert_int_equal(creds->username_obtained, CRED_GUESS_ENV); + + assert_string_equal(creds->password, "SECRET"); + assert_int_equal(creds->password_obtained, CRED_GUESS_ENV); + unsetenv("PASSWD"); +} + +static void torture_creds_anon_guess(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct cli_credentials *creds = NULL; + + creds = cli_credentials_init_anon(mem_ctx); + assert_non_null(creds); + + setenv("PASSWD", "SECRET", 1); + cli_credentials_guess(creds, NULL); + + assert_string_equal(creds->username, ""); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + + assert_null(creds->password); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); + unsetenv("PASSWD"); +} + +static void torture_creds_parse_string(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct cli_credentials *creds = NULL; + + creds = cli_credentials_init(mem_ctx); + assert_non_null(creds); + + /* Anonymous */ + cli_credentials_parse_string(creds, "%", CRED_SPECIFIED); + + assert_string_equal(creds->domain, ""); + assert_int_equal(creds->domain_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->username, ""); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + + assert_null(creds->password); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); + + /* Username + password */ + cli_credentials_parse_string(creds, "wurst%BROT", CRED_SPECIFIED); + + assert_string_equal(creds->domain, ""); + assert_int_equal(creds->domain_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->username, "wurst"); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->password, "BROT"); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); + + /* Domain + username + password */ + cli_credentials_parse_string(creds, "XXL\\wurst%BROT", CRED_SPECIFIED); + + assert_string_equal(creds->domain, "XXL"); + assert_int_equal(creds->domain_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->username, "wurst"); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->password, "BROT"); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); + + /* Principal */ + cli_credentials_parse_string(creds, "wurst@brot.realm", CRED_SPECIFIED); + + assert_string_equal(creds->domain, ""); + assert_int_equal(creds->domain_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->username, "wurst@brot.realm"); + assert_int_equal(creds->username_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->principal, "wurst@brot.realm"); + assert_int_equal(creds->principal_obtained, CRED_SPECIFIED); + + assert_string_equal(creds->password, "BROT"); + assert_int_equal(creds->password_obtained, CRED_SPECIFIED); +} + +int main(int argc, char *argv[]) +{ + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_creds_init), + cmocka_unit_test(torture_creds_init_anonymous), + cmocka_unit_test(torture_creds_guess), + cmocka_unit_test(torture_creds_anon_guess), + cmocka_unit_test(torture_creds_parse_string), + }; + + if (argc == 2) { + cmocka_set_test_filter(argv[1]); + } + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); + + rc = cmocka_run_group_tests(tests, + setup_talloc_context, + teardown_talloc_context); + + return rc; +} diff --git a/auth/credentials/wscript_build b/auth/credentials/wscript_build index ad16b7d8008..46111164b36 100644 --- a/auth/credentials/wscript_build +++ b/auth/credentials/wscript_build @@ -31,3 +31,9 @@ bld.SAMBA_PYTHON('pycredentials', public_deps='samba-credentials cmdline-credentials %s %s CREDENTIALS_KRB5 CREDENTIALS_SECRETS' % (pytalloc_util, pyparam_util), realname='samba/credentials.so' ) + +bld.SAMBA_BINARY('test_creds', + source='tests/test_creds.c', + deps='cmocka samba-credentials', + local_include=False, + for_selftest=True) diff --git a/selftest/tests.py b/selftest/tests.py index 86cab3f8046..4a968cdbe8a 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -418,3 +418,5 @@ plantestsuite("samba.unittests.test_oLschema2ldif", "none", if with_elasticsearch_backend: plantestsuite("samba.unittests.mdsparser_es", "none", [os.path.join(bindir(), "default/source3/test_mdsparser_es")] + [configuration]) +plantestsuite("samba.unittests.credentials", "none", + [os.path.join(bindir(), "default/auth/credentials/test_creds")]) diff --git a/source4/torture/local/local.c b/source4/torture/local/local.c index a3186788524..d19b55e9502 100644 --- a/source4/torture/local/local.c +++ b/source4/torture/local/local.c @@ -70,7 +70,6 @@ torture_local_tevent_req, torture_local_torture, torture_local_dbspeed, - torture_local_credentials, torture_ldb, torture_dsdb_dn, torture_dsdb_syntax, diff --git a/source4/torture/local/wscript_build b/source4/torture/local/wscript_build index 38b6c8f4b6e..f0ab0357986 100644 --- a/source4/torture/local/wscript_build +++ b/source4/torture/local/wscript_build @@ -16,7 +16,7 @@ TORTURE_LOCAL_SOURCE = '''../../../lib/util/charset/tests/iconv.c ../../libcli/security/tests/sddl.c ../../../lib/tdr/testsuite.c ../../../lib/tevent/testsuite.c ../../param/tests/share.c ../../../lib/tevent/test_req.c - ../../param/tests/loadparm.c ../../../auth/credentials/tests/simple.c local.c + ../../param/tests/loadparm.c local.c dbspeed.c torture.c ../ldb/ldb.c ../../dsdb/common/tests/dsdb_dn.c ../../dsdb/schema/tests/schema_syntax.c ../../../lib/util/tests/anonymous_shared.c -- 2.29.2 From 286d1baff05b7c1a899ad9d73a41ed4d5b69e0d5 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:09:05 +0200 Subject: [PATCH 088/108] Add smb2cli_session_get_encryption_cipher() When 'session->smb2->should_encrypt' is true, the client MUST encrypt all transport messages (see also MS-SMB2 3.2.4.1.8). Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit f0f8de9d4a4e05445e427f00bb10eb34e1110a97) --- libcli/smb/smbXcli_base.c | 13 +++++++++++++ libcli/smb/smbXcli_base.h | 1 + 2 files changed, 14 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 7d2da4b9ebc..471319a32f1 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -6436,6 +6436,19 @@ NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session) return NT_STATUS_OK; } +uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session) +{ + if (session->conn->protocol < PROTOCOL_SMB2_24) { + return 0; + } + + if (!session->smb2->should_encrypt) { + return 0; + } + + return session->conn->smb2.server.cipher; +} + struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx) { struct smbXcli_tcon *tcon; diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 2afc7165cd9..db5f5d58799 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -518,6 +518,7 @@ NTSTATUS smb2cli_session_set_channel_key(struct smbXcli_session *session, const DATA_BLOB channel_key, const struct iovec *recv_iov); NTSTATUS smb2cli_session_encryption_on(struct smbXcli_session *session); +uint16_t smb2cli_session_get_encryption_cipher(struct smbXcli_session *session); struct smbXcli_tcon *smbXcli_tcon_create(TALLOC_CTX *mem_ctx); struct smbXcli_tcon *smbXcli_tcon_copy(TALLOC_CTX *mem_ctx, -- 2.29.2 From 34242b72abc65a100f6d19e98369b926ffdd17b9 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:18:21 +0200 Subject: [PATCH 089/108] Add dcerpc_transport_encrypted() Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit 339bfcd67af2675d10287946d8f5dabba1022d57) --- source4/librpc/rpc/dcerpc.h | 2 ++ source4/librpc/rpc/dcerpc_smb.c | 11 +++++++++++ source4/librpc/rpc/dcerpc_util.c | 13 +++++++++++++ 3 files changed, 26 insertions(+) diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 6b0b841d64d..57124f10778 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -87,6 +87,7 @@ struct dcecli_connection { struct dcerpc_transport { enum dcerpc_transport_t transport; void *private_data; + bool encrypted; struct tstream_context *stream; /** to serialize write events */ @@ -181,6 +182,7 @@ NTSTATUS dcerpc_bind_auth_none(struct dcerpc_pipe *p, const struct ndr_interface_table *table); NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, DATA_BLOB *session_key); +bool dcerpc_transport_encrypted(struct dcerpc_pipe *p); struct composite_context; NTSTATUS dcerpc_secondary_connection_recv(struct composite_context *c, struct dcerpc_pipe **p2); diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index b20b154a1cb..101ed64f0cd 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -145,6 +145,7 @@ static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq) struct dcerpc_pipe_open_smb_state); struct composite_context *ctx = state->ctx; struct dcecli_connection *c = state->c; + uint16_t enc_cipher; ctx->status = tstream_smbXcli_np_open_recv(subreq, state->smb, @@ -173,6 +174,16 @@ static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq) /* Over-ride the default session key with the SMB session key */ c->security_state.session_key = smb_session_key; + enc_cipher = smb2cli_session_get_encryption_cipher(state->smb->session); + switch (enc_cipher) { + case SMB2_ENCRYPTION_AES128_CCM: + case SMB2_ENCRYPTION_AES128_GCM: + c->transport.encrypted = true; + break; + default: + c->transport.encrypted = false; + } + c->transport.private_data = talloc_move(c, &state->smb); composite_done(ctx); diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index bd79a072bc8..6ea27a8d9a3 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -743,6 +743,19 @@ _PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, return NT_STATUS_OK; } +_PUBLIC_ bool dcerpc_transport_encrypted(struct dcerpc_pipe *p) +{ + if (p == NULL) { + return false; + } + + if (p->conn == NULL) { + return false; + } + + return p->conn->transport.encrypted; +} + /* create a secondary context from a primary connection -- 2.29.2 From 3aea4bbd34849aedca16a4a6baf0bdf914ddde81 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:35:01 +0200 Subject: [PATCH 090/108] Add py binding for dcerpc_transport_encrypted Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit eba91f0dfa8e3267689b4076302e257f4cecd63b) --- source4/librpc/rpc/pyrpc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/source4/librpc/rpc/pyrpc.c b/source4/librpc/rpc/pyrpc.c index be914ed5f14..309a6d72e26 100644 --- a/source4/librpc/rpc/pyrpc.c +++ b/source4/librpc/rpc/pyrpc.c @@ -293,11 +293,25 @@ static PyObject *py_iface_request(PyObject *self, PyObject *args, PyObject *kwar return ret; } +static PyObject *py_iface_transport_encrypted(PyObject *self) +{ + dcerpc_InterfaceObject *iface = (dcerpc_InterfaceObject *)self; + + if (dcerpc_transport_encrypted(iface->pipe)) { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + static PyMethodDef dcerpc_interface_methods[] = { { "request", PY_DISCARD_FUNC_SIG(PyCFunction, py_iface_request), METH_VARARGS|METH_KEYWORDS, "S.request(opnum, data, object=None) -> data\n" "Make a raw request" }, + { "transport_encrypted", PY_DISCARD_FUNC_SIG(PyCFunction, py_iface_transport_encrypted), + METH_NOARGS, + "Check if the DCE transport is encrypted" }, { NULL, NULL, 0, NULL }, }; -- 2.29.2 From 0f6af3877dd1f84f2813e491fa3508f5378400cd Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:44:08 +0200 Subject: [PATCH 091/108] selftest: add a test for py dce transport_encrypted Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit a77551bea969ce73a3dc27384d94b4126bef04f7) --- python/samba/tests/dcerpc/binding.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/python/samba/tests/dcerpc/binding.py b/python/samba/tests/dcerpc/binding.py index 8e0d6a5ef0a..24e4ac77d89 100644 --- a/python/samba/tests/dcerpc/binding.py +++ b/python/samba/tests/dcerpc/binding.py @@ -22,7 +22,7 @@ import samba.tests from samba.tests import RpcInterfaceTestCase, TestCase from samba.dcerpc import lsa import samba.dcerpc.security as security -from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED +from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED, SMB_ENCRYPTION_OFF from samba import NTSTATUSError class RpcBindingTests(RpcInterfaceTestCase): @@ -40,6 +40,26 @@ class RpcBindingTests(RpcInterfaceTestCase): c.set_password(password) return c + def test_smb3_dcerpc_no_encryption(self): + creds = self.get_user_creds() + creds.set_smb_encryption(SMB_ENCRYPTION_OFF) + + lp = self.get_loadparm() + lp.set('client ipc max protocol', 'SMB3') + lp.set('client ipc min protocol', 'SMB3') + + binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER'))) + lsa_conn = lsa.lsarpc(binding_string, lp, creds) + self.assertFalse(lsa_conn.transport_encrypted()) + + objectAttr = lsa.ObjectAttribute() + objectAttr.sec_qos = lsa.QosInfo() + + pol_handle = lsa_conn.OpenPolicy2('', + objectAttr, + security.SEC_FLAG_MAXIMUM_ALLOWED) + self.assertIsNotNone(pol_handle) + def test_smb3_dcerpc_encryption(self): creds = self.get_user_creds() creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) @@ -50,6 +70,7 @@ class RpcBindingTests(RpcInterfaceTestCase): binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER'))) lsa_conn = lsa.lsarpc(binding_string, lp, creds) + self.assertTrue(lsa_conn.transport_encrypted()) objectAttr = lsa.ObjectAttribute() objectAttr.sec_qos = lsa.QosInfo() -- 2.29.2 From 204dbcb972e85497960fffa68b8309f7d28b1c00 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:47:12 +0200 Subject: [PATCH 092/108] Add CreateTrustedDomainRelax wrapper for fips mode Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit c2644032b49b4160517a7c73634cebc54a76f827) --- python/samba/trust_utils.py | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 python/samba/trust_utils.py diff --git a/python/samba/trust_utils.py b/python/samba/trust_utils.py new file mode 100644 index 00000000000..b4df0fa5bb8 --- /dev/null +++ b/python/samba/trust_utils.py @@ -0,0 +1,62 @@ +# trust utils +# +# Copyright Isaac Boukris 2020 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from samba.dcerpc import lsa, drsblobs +from samba.ndr import ndr_pack +from samba import arcfour_encrypt, string_to_byte_array +import random +from samba import crypto + +def CreateTrustedDomainRelax(lsaconn, policy, trust_info, mask, in_blob, out_blob): + + def generate_AuthInfoInternal(session_key, incoming=None, outgoing=None): + confounder = [0] * 512 + for i in range(len(confounder)): + confounder[i] = random.randint(0, 255) + + trustpass = drsblobs.trustDomainPasswords() + + trustpass.confounder = confounder + trustpass.outgoing = outgoing + trustpass.incoming = incoming + + trustpass_blob = ndr_pack(trustpass) + + encrypted_trustpass = arcfour_encrypt(session_key, trustpass_blob) + + auth_blob = lsa.DATA_BUF2() + auth_blob.size = len(encrypted_trustpass) + auth_blob.data = string_to_byte_array(encrypted_trustpass) + + auth_info = lsa.TrustDomainInfoAuthInfoInternal() + auth_info.auth_blob = auth_blob + + return auth_info + + session_key = lsaconn.session_key + + try: + if lsaconn.transport_encrypted(): + crypto.set_relax_mode() + auth_info = generate_AuthInfoInternal(session_key, + incoming=in_blob, + outgoing=out_blob) + finally: + crypto.set_strict_mode() + + return lsaconn.CreateTrustedDomainEx2(policy, trust_info, auth_info, mask) -- 2.29.2 From 7240d19414330b3cebc0b9633b60b3e07a41110a Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 20 Aug 2020 12:49:17 +0200 Subject: [PATCH 093/108] Use the new CreateTrustedDomainRelax() Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit baf4e2930ee13b47c23c63c7e945fdc4444f0c69) --- python/samba/netcmd/domain.py | 57 ++++++++--------------------------- 1 file changed, 13 insertions(+), 44 deletions(-) diff --git a/python/samba/netcmd/domain.py b/python/samba/netcmd/domain.py index 1d12c362911..93a3258d28d 100644 --- a/python/samba/netcmd/domain.py +++ b/python/samba/netcmd/domain.py @@ -102,6 +102,7 @@ from samba.netcmd.domain_backup import cmd_domain_backup from samba.compat import binary_type from samba.compat import get_string +from samba.trust_utils import CreateTrustedDomainRelax string_version_to_constant = { "2008_R2": DS_DOMAIN_FUNCTION_2008_R2, @@ -2528,54 +2529,20 @@ class cmd_domain_trust_create(DomainTrustCommand): return blob - def generate_AuthInfoInternal(session_key, incoming=None, outgoing=None): - confounder = [0] * 512 - for i in range(len(confounder)): - confounder[i] = random.randint(0, 255) - - trustpass = drsblobs.trustDomainPasswords() - - trustpass.confounder = confounder - trustpass.outgoing = outgoing - trustpass.incoming = incoming - - trustpass_blob = ndr_pack(trustpass) - - encrypted_trustpass = arcfour_encrypt(session_key, trustpass_blob) - - auth_blob = lsa.DATA_BUF2() - auth_blob.size = len(encrypted_trustpass) - auth_blob.data = string_to_byte_array(encrypted_trustpass) - - auth_info = lsa.TrustDomainInfoAuthInfoInternal() - auth_info.auth_blob = auth_blob - - return auth_info - update_time = samba.current_unix_time() incoming_blob = generate_AuthInOutBlob(incoming_secret, update_time) outgoing_blob = generate_AuthInOutBlob(outgoing_secret, update_time) - local_tdo_handle = None - remote_tdo_handle = None - - local_auth_info = generate_AuthInfoInternal(local_lsa.session_key, - incoming=incoming_blob, - outgoing=outgoing_blob) - if remote_trust_info: - remote_auth_info = generate_AuthInfoInternal(remote_lsa.session_key, - incoming=outgoing_blob, - outgoing=incoming_blob) - try: if remote_trust_info: self.outf.write("Creating remote TDO.\n") current_request = {"location": "remote", "name": "CreateTrustedDomainEx2"} - remote_tdo_handle = \ - remote_lsa.CreateTrustedDomainEx2(remote_policy, - remote_trust_info, - remote_auth_info, - lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS) + remote_tdo_handle = CreateTrustedDomainRelax(remote_lsa, + remote_policy, + remote_trust_info, + lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS, + outgoing_blob, + incoming_blob) self.outf.write("Remote TDO created.\n") if enc_types: self.outf.write("Setting supported encryption types on remote TDO.\n") @@ -2586,10 +2553,12 @@ class cmd_domain_trust_create(DomainTrustCommand): self.outf.write("Creating local TDO.\n") current_request = {"location": "local", "name": "CreateTrustedDomainEx2"} - local_tdo_handle = local_lsa.CreateTrustedDomainEx2(local_policy, - local_trust_info, - local_auth_info, - lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS) + local_tdo_handle = CreateTrustedDomainRelax(local_lsa, + local_policy, + local_trust_info, + lsa.LSA_TRUSTED_DOMAIN_ALL_ACCESS, + incoming_blob, + outgoing_blob) self.outf.write("Local TDO created\n") if enc_types: self.outf.write("Setting supported encryption types on local TDO.\n") -- 2.29.2 From 6d8e8f07766fd6b43baff3b9495b927b28c142e6 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Tue, 1 Sep 2020 20:14:29 +0300 Subject: [PATCH 094/108] selftest: add a test for the CreateTrustedDomainRelax wrapper Originally copied from 'source4/scripting/devel/createtrust' (had to drop the TRUST_AUTH_TYPE_VERSION part though, as it fails against samba DC). Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy (cherry picked from commit cfaad16ff632df83a881fe5d8ec498bab102c9c9) --- python/samba/tests/dcerpc/createtrustrelax.py | 131 ++++++++++++++++++ selftest/knownfail.d/createtrustrelax_server | 1 + source4/selftest/tests.py | 4 + 3 files changed, 136 insertions(+) create mode 100644 python/samba/tests/dcerpc/createtrustrelax.py create mode 100644 selftest/knownfail.d/createtrustrelax_server diff --git a/python/samba/tests/dcerpc/createtrustrelax.py b/python/samba/tests/dcerpc/createtrustrelax.py new file mode 100644 index 00000000000..48beb0f9680 --- /dev/null +++ b/python/samba/tests/dcerpc/createtrustrelax.py @@ -0,0 +1,131 @@ +# Unix SMB/CIFS implementation. +# +# Copyright (C) Andrew Bartlett 2011 +# Copyright (C) Isaac Boukris 2020 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +"""Tests for the CreateTrustedDomainRelax wrapper""" + +import os +import samba +from samba.tests import TestCase +from samba.dcerpc import lsa, security, drsblobs +from samba.credentials import Credentials, SMB_ENCRYPTION_REQUIRED, SMB_ENCRYPTION_OFF +from samba.trust_utils import CreateTrustedDomainRelax + +class CreateTrustedDomainRelaxTest(TestCase): + def setUp(self): + super(CreateTrustedDomainRelaxTest, self).setUp() + + def get_user_creds(self): + c = Credentials() + c.guess() + domain = samba.tests.env_get_var_value('DOMAIN') + username = samba.tests.env_get_var_value('USERNAME') + password = samba.tests.env_get_var_value('PASSWORD') + c.set_domain(domain) + c.set_username(username) + c.set_password(password) + return c + + def _create_trust_relax(self, smbencrypt=True): + creds = self.get_user_creds() + + if smbencrypt: + creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED) + else: + creds.set_smb_encryption(SMB_ENCRYPTION_OFF) + + lp = self.get_loadparm() + + binding_string = ("ncacn_np:%s" % (samba.tests.env_get_var_value('SERVER'))) + lsa_conn = lsa.lsarpc(binding_string, lp, creds) + + if smbencrypt: + self.assertTrue(lsa_conn.transport_encrypted()) + else: + self.assertFalse(lsa_conn.transport_encrypted()) + + objectAttr = lsa.ObjectAttribute() + objectAttr.sec_qos = lsa.QosInfo() + + pol_handle = lsa_conn.OpenPolicy2('', + objectAttr, + security.SEC_FLAG_MAXIMUM_ALLOWED) + self.assertIsNotNone(pol_handle) + + name = lsa.String() + name.string = "tests.samba.example.com" + try: + info = lsa_conn.QueryTrustedDomainInfoByName(pol_handle, name, + lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO) + + lsa_conn.DeleteTrustedDomain(pol_handle, info.info_ex.sid) + except RuntimeError: + pass + + info = lsa.TrustDomainInfoInfoEx() + info.domain_name.string = name.string + info.netbios_name.string = "createtrustrelax" + info.sid = security.dom_sid("S-1-5-21-538490383-3740119673-95748416") + info.trust_direction = lsa.LSA_TRUST_DIRECTION_INBOUND | lsa.LSA_TRUST_DIRECTION_OUTBOUND + info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL + info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE + + password_blob = samba.string_to_byte_array("password".encode('utf-16-le')) + + clear_value = drsblobs.AuthInfoClear() + clear_value.size = len(password_blob) + clear_value.password = password_blob + + clear_authentication_information = drsblobs.AuthenticationInformation() + clear_authentication_information.LastUpdateTime = 0 + clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR + clear_authentication_information.AuthInfo = clear_value + + authentication_information_array = drsblobs.AuthenticationInformationArray() + authentication_information_array.count = 1 + authentication_information_array.array = [clear_authentication_information] + + outgoing = drsblobs.trustAuthInOutBlob() + outgoing.count = 1 + outgoing.current = authentication_information_array + + trustdom_handle = None + try: + trustdom_handle = CreateTrustedDomainRelax(lsa_conn, + pol_handle, + info, + security.SEC_STD_DELETE, + outgoing, + outgoing) + except samba.NTSTATUSError as nt: + raise AssertionError(nt) + except OSError as e: + if smbencrypt: + raise AssertionError(e) + + if smbencrypt: + self.assertIsNotNone(trustdom_handle) + lsa_conn.DeleteTrustedDomain(pol_handle, info.sid) + else: + self.assertIsNone(trustdom_handle) + + def test_create_trust_relax_encrypt(self): + self._create_trust_relax(True) + + def test_create_trust_relax_no_enc(self): + self._create_trust_relax(False) diff --git a/selftest/knownfail.d/createtrustrelax_server b/selftest/knownfail.d/createtrustrelax_server new file mode 100644 index 00000000000..80effda8343 --- /dev/null +++ b/selftest/knownfail.d/createtrustrelax_server @@ -0,0 +1 @@ +^samba.tests.dcerpc.createtrustrelax.samba.tests.dcerpc.createtrustrelax.CreateTrustedDomainRelaxTest.test_create_trust_relax_encrypt\(ad_dc_fips\) diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index 3a903a7eee0..96f51b68cfc 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -704,6 +704,10 @@ def planoldpythontestsuite(env, module, name=None, extra_path=[], environ={}, ex name = module plantestsuite_loadlist(name, env, args) +if have_gnutls_crypto_policies: + planoldpythontestsuite("ad_dc", "samba.tests.dcerpc.createtrustrelax", environ={'GNUTLS_FORCE_FIPS_MODE':'1'}) + planoldpythontestsuite("ad_dc_fips", "samba.tests.dcerpc.createtrustrelax", environ={'GNUTLS_FORCE_FIPS_MODE':'1'}) + # Run complex search expressions test once for each database backend. # Right now ad_dc has mdb and ad_dc_ntvfs has tdb mdb_testenv = "ad_dc" -- 2.29.2 From e4290d0a47d020a726051e67d18f6a5378001bb3 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Thu, 5 Nov 2020 15:38:19 +0200 Subject: [PATCH 095/108] Remove source4/scripting/devel/createtrust script We now have the 'samba-tool domain trust' command. Signed-off-by: Isaac Boukris Reviewed-by: Stefan Metzmacher Reviewed-by: Alexander Bokovoy Autobuild-User(master): Isaac Boukris Autobuild-Date(master): Fri Nov 6 11:25:02 UTC 2020 on sn-devel-184 (cherry picked from commit 604153525afc892f57a1df710c41ffca275b0dd3) --- source4/scripting/devel/createtrust | 125 ---------------------------- 1 file changed, 125 deletions(-) delete mode 100755 source4/scripting/devel/createtrust diff --git a/source4/scripting/devel/createtrust b/source4/scripting/devel/createtrust deleted file mode 100755 index 26b0d0dcb68..00000000000 --- a/source4/scripting/devel/createtrust +++ /dev/null @@ -1,125 +0,0 @@ -#!/usr/bin/env python3 - -# create a domain trust - -import sys -from optparse import OptionParser - -sys.path.insert(0, "bin/python") - -import samba -import samba.getopt as options -from samba.dcerpc import lsa, security, drsblobs -from samba.ndr import ndr_pack -from samba import arcfour_encrypt, string_to_byte_array -import random - -########### main code ########### -if __name__ == "__main__": - parser = OptionParser("createtrust [options] server") - sambaopts = options.SambaOptions(parser) - credopts = options.CredentialsOptionsDouble(parser) - parser.add_option_group(credopts) - - (opts, args) = parser.parse_args() - - lp = sambaopts.get_loadparm() - creds = credopts.get_credentials(lp) - - if len(args) != 1: - parser.error("You must supply a server") - - if not creds.authentication_requested(): - parser.error("You must supply credentials") - - server = args[0] - - binding_str = "ncacn_np:%s[print]" % server - - lsaconn = lsa.lsarpc(binding_str, lp, creds) - - objectAttr = lsa.ObjectAttribute() - objectAttr.sec_qos = lsa.QosInfo() - - pol_handle = lsaconn.OpenPolicy2(''.decode('utf-8'), - objectAttr, security.SEC_FLAG_MAXIMUM_ALLOWED) - - name = lsa.String() - name.string = "sub2.win2k3.obed.home.abartlet.net" - try: - info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO) - - lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid) - except RuntimeError: - pass - - info = lsa.TrustDomainInfoInfoEx() - info.domain_name.string = "sub2.win2k3.obed.home.abartlet.net" - info.netbios_name.string = "sub2" - info.sid = security.dom_sid("S-1-5-21-538090388-3760119675-95745416") - info.trust_direction = lsa.LSA_TRUST_DIRECTION_INBOUND | lsa.LSA_TRUST_DIRECTION_OUTBOUND - info.trust_type = lsa.LSA_TRUST_TYPE_UPLEVEL - info.trust_attributes = lsa.LSA_TRUST_ATTRIBUTE_WITHIN_FOREST - - password_blob = string_to_byte_array("password".encode('utf-16-le')) - - clear_value = drsblobs.AuthInfoClear() - clear_value.size = len(password_blob) - clear_value.password = password_blob - - clear_authentication_information = drsblobs.AuthenticationInformation() - clear_authentication_information.LastUpdateTime = 0 - clear_authentication_information.AuthType = lsa.TRUST_AUTH_TYPE_CLEAR - clear_authentication_information.AuthInfo = clear_value - - version_value = drsblobs.AuthInfoVersion() - version_value.version = 1 - - version = drsblobs.AuthenticationInformation() - version.LastUpdateTime = 0 - version.AuthType = lsa.TRUST_AUTH_TYPE_VERSION - version.AuthInfo = version_value - - authentication_information_array = drsblobs.AuthenticationInformationArray() - authentication_information_array.count = 2 - authentication_information_array.array = [clear_authentication_information, version] - - outgoing = drsblobs.trustAuthInOutBlob() - outgoing.count = 1 - outgoing.current = authentication_information_array - - trustpass = drsblobs.trustDomainPasswords() - confounder = [3] * 512 - - for i in range(512): - confounder[i] = random.randint(0, 255) - - trustpass.confounder = confounder - -# print "confounder: ", trustpass.confounder - - trustpass.outgoing = outgoing - trustpass.incoming = outgoing - - trustpass_blob = ndr_pack(trustpass) - -# print "trustpass_blob: ", list(trustpass_blob) - - encrypted_trustpass = arcfour_encrypt(lsaconn.session_key, trustpass_blob) - -# print "encrypted_trustpass: ", list(encrypted_trustpass) - - auth_blob = lsa.DATA_BUF2() - auth_blob.size = len(encrypted_trustpass) - auth_blob.data = string_to_byte_array(encrypted_trustpass) - - auth_info = lsa.TrustDomainInfoAuthInfoInternal() - auth_info.auth_blob = auth_blob - - -# print "auth_info.auth_blob.data: ", auth_info.auth_blob.data - - trustdom_handle = lsaconn.CreateTrustedDomainEx2(pol_handle, - info, - auth_info, - security.SEC_STD_DELETE) -- 2.29.2 From 840be1b927ac2600f548d9c1e504f77de6c84f96 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 6 Nov 2020 14:30:26 +0100 Subject: [PATCH 096/108] s3:rpc_server: Use gnutls_cipher_decrypt() in get_trustdom_auth_blob() It doesn't matter for RC4, but just to be correct. Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit 6c11e5f42ba3248c97d85c989d422b256d2465a9) --- source3/rpc_server/lsa/srv_lsa_nt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c index 198387424e6..e749caf2551 100644 --- a/source3/rpc_server/lsa/srv_lsa_nt.c +++ b/source3/rpc_server/lsa/srv_lsa_nt.c @@ -1726,7 +1726,7 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p, goto out; } - rc = gnutls_cipher_encrypt(cipher_hnd, + rc = gnutls_cipher_decrypt(cipher_hnd, auth_blob->data, auth_blob->length); gnutls_cipher_deinit(cipher_hnd); -- 2.29.2 From e7b7b3f4aec8fb6d37375934f0f193fea6649f18 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 6 Nov 2020 14:33:38 +0100 Subject: [PATCH 097/108] s4:rpc_server: Use gnutls_cipher_decrypt() in get_trustdom_auth_blob() It doesn't matter for RC4, but just to be correct. Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy (cherry picked from commit c93ccebdfedd60c1d19f1b1436ac30062259952a) --- source4/rpc_server/lsa/dcesrv_lsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 8333cb149b6..4bb8aaa9592 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -889,7 +889,7 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, goto out; } - rc = gnutls_cipher_encrypt(cipher_hnd, + rc = gnutls_cipher_decrypt(cipher_hnd, auth_blob->data, auth_blob->length); gnutls_cipher_deinit(cipher_hnd); -- 2.29.2 From 3c57cdaa7013bc01ac6b3d65dade151526cacc5b Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 20 Aug 2020 13:40:21 +0200 Subject: [PATCH 098/108] s3:rpc_server: Allow to use RC4 for creating trusts Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy Reviewed-by: Stefan Metzmacher (cherry picked from commit 4425f2c113a4dc33a8dc609d84a92018d61b4d2e) --- source3/rpc_server/lsa/srv_lsa_nt.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c index e749caf2551..d6d606ddeca 100644 --- a/source3/rpc_server/lsa/srv_lsa_nt.c +++ b/source3/rpc_server/lsa/srv_lsa_nt.c @@ -51,6 +51,8 @@ #include "../libcli/lsarpc/util_lsarpc.h" #include "lsa.h" #include "librpc/rpc/dcesrv_core.h" +#include "librpc/rpc/dcerpc_helper.h" +#include "lib/param/loadparm.h" #include "lib/crypto/gnutls_helpers.h" #include @@ -1706,6 +1708,14 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p, gnutls_datum_t my_session_key; NTSTATUS status; int rc; + bool encrypted; + + encrypted = + dcerpc_is_transport_encrypted(p->session_info); + if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + return NT_STATUS_ACCESS_DENIED; + } status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES); if (!NT_STATUS_IS_OK(status)) { @@ -1717,11 +1727,13 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p, .size = lsession_key.length, }; + GNUTLS_FIPS140_SET_LAX_MODE(); rc = gnutls_cipher_init(&cipher_hnd, GNUTLS_CIPHER_ARCFOUR_128, &my_session_key, NULL); if (rc < 0) { + GNUTLS_FIPS140_SET_STRICT_MODE(); status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; } @@ -1730,6 +1742,7 @@ static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p, auth_blob->data, auth_blob->length); gnutls_cipher_deinit(cipher_hnd); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (rc < 0) { status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; -- 2.29.2 From 2f22b25cb718c70383ed3ba8ebd91d9f317c455e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 20 Aug 2020 13:51:39 +0200 Subject: [PATCH 099/108] s4:rpc_server: Allow to use RC4 for creating trusts Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy Reviewed-by: Stefan Metzmacher (cherry picked from commit c75dd1ea178325b8f65343cb5c35bb93f43a49a3) --- source4/rpc_server/lsa/dcesrv_lsa.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 4bb8aaa9592..5b3ef71d458 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -33,6 +33,8 @@ #include "libcli/lsarpc/util_lsarpc.h" #include "lib/messaging/irpc.h" #include "libds/common/roles.h" +#include "lib/param/loadparm.h" +#include "librpc/rpc/dcerpc_helper.h" #include "lib/crypto/gnutls_helpers.h" #include @@ -869,6 +871,19 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, gnutls_cipher_hd_t cipher_hnd = NULL; gnutls_datum_t _session_key; int rc; + struct auth_session_info *session_info = + dcesrv_call_session_info(dce_call); + struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; + bool encrypted; + + encrypted = + dcerpc_is_transport_encrypted(session_info); + if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED && + !encrypted) { + DBG_ERR("Transport isn't encrypted and weak crypto disallowed!\n"); + return NT_STATUS_ACCESS_DENIED; + } + nt_status = dcesrv_transport_session_key(dce_call, &session_key); if (!NT_STATUS_IS_OK(nt_status)) { @@ -880,11 +895,13 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, .size = session_key.length, }; + GNUTLS_FIPS140_SET_LAX_MODE(); rc = gnutls_cipher_init(&cipher_hnd, GNUTLS_CIPHER_ARCFOUR_128, &_session_key, NULL); if (rc < 0) { + GNUTLS_FIPS140_SET_STRICT_MODE(); nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; } @@ -893,6 +910,7 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, auth_blob->data, auth_blob->length); gnutls_cipher_deinit(cipher_hnd); + GNUTLS_FIPS140_SET_STRICT_MODE(); if (rc < 0) { nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID); goto out; -- 2.29.2 From 32a6dbc4bca9f104d7d88eaea2afce20416256d1 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 6 Nov 2020 10:13:48 +0100 Subject: [PATCH 100/108] sefltest: Enable the dcerpc.createtrustrelax test against ad_dc_fips Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy Reviewed-by: Stefan Metzmacher Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Mon Nov 9 10:22:51 UTC 2020 on sn-devel-184 (cherry picked from commit b89134013041e772418c2c8bcfffe8a9ade6db91) --- selftest/knownfail.d/createtrustrelax_server | 1 - 1 file changed, 1 deletion(-) delete mode 100644 selftest/knownfail.d/createtrustrelax_server diff --git a/selftest/knownfail.d/createtrustrelax_server b/selftest/knownfail.d/createtrustrelax_server deleted file mode 100644 index 80effda8343..00000000000 --- a/selftest/knownfail.d/createtrustrelax_server +++ /dev/null @@ -1 +0,0 @@ -^samba.tests.dcerpc.createtrustrelax.samba.tests.dcerpc.createtrustrelax.CreateTrustedDomainRelaxTest.test_create_trust_relax_encrypt\(ad_dc_fips\) -- 2.29.2 From ce72237a2ac40da4b78afbcceab13d5e58e4fe5e Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 11 Nov 2020 13:42:06 +0100 Subject: [PATCH 101/108] s3:smbd: Fix possible null pointer dereference in token_contains_name() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14572 Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy Autobuild-User(master): Alexander Bokovoy Autobuild-Date(master): Thu Nov 12 15:13:47 UTC 2020 on sn-devel-184 (cherry picked from commit 8036bf9717f83e83c3e4a9cf00fded42e9a5de15) --- source3/smbd/share_access.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/share_access.c b/source3/smbd/share_access.c index 57754a0f766..694c0c290e8 100644 --- a/source3/smbd/share_access.c +++ b/source3/smbd/share_access.c @@ -79,7 +79,7 @@ static bool token_contains_name(TALLOC_CTX *mem_ctx, enum lsa_SidType type; if (username != NULL) { - size_t domain_len = strlen(domain); + size_t domain_len = domain != NULL ? strlen(domain) : 0; /* Check if username starts with domain name */ if (domain_len > 0) { -- 2.29.2 From 08cd57786058ba735931a166c13375ce8a02e0e9 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 10 Nov 2020 17:35:24 +0200 Subject: [PATCH 102/108] lookup_name: allow lookup names prefixed with DNS forest root for FreeIPA DC In FreeIPA deployment with active Global Catalog service, when a two-way trust to Active Directory forest is established, Windows systems can look up FreeIPA users and groups. When using a security tab in Windows Explorer on AD side, a lookup over a trusted forest might come as realm\name instead of NetBIOS domain name: -------------------------------------------------------------------- [2020/01/13 11:12:39.859134, 1, pid=33253, effective(1732401004, 1732401004), real(1732401004, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:471(ndr_print_function_debug) lsa_LookupNames3: struct lsa_LookupNames3 in: struct lsa_LookupNames3 handle : * handle: struct policy_handle handle_type : 0x00000000 (0) uuid : 0000000e-0000-0000-1c5e-a750e5810000 num_names : 0x00000001 (1) names: ARRAY(1) names: struct lsa_String length : 0x001e (30) size : 0x0020 (32) string : * string : 'ipa.test\admins' sids : * sids: struct lsa_TransSidArray3 count : 0x00000000 (0) sids : NULL level : LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2 (6) count : * count : 0x00000000 (0) lookup_options : LSA_LOOKUP_OPTION_SEARCH_ISOLATED_NAMES (0) client_revision : LSA_CLIENT_REVISION_2 (2) -------------------------------------------------------------------- If we are running as a DC and PASSDB supports returning domain info (pdb_get_domain_info() returns a valid structure), check domain of the name in lookup_name() against DNS forest name and allow the request to be done against the primary domain. This corresponds to FreeIPA's use of Samba as a DC. For normal domain members a realm-based lookup falls back to a lookup over to its own domain controller with the help of winbindd. Signed-off-by: Alexander Bokovoy Reviewed-by: Stefan Metzmacher Autobuild-User(master): Alexander Bokovoy Autobuild-Date(master): Wed Nov 11 10:59:01 UTC 2020 on sn-devel-184 (cherry picked from commit 31c703766fd2b89737826fb7e9a707f0622bb8cd) --- source3/passdb/lookup_sid.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 82c47b3145b..864246da56e 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -113,17 +113,36 @@ bool lookup_name(TALLOC_CTX *mem_ctx, full_name, domain, name)); DEBUG(10, ("lookup_name: flags = 0x0%x\n", flags)); - if (((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) && - strequal(domain, get_global_sam_name())) - { + if ((flags & LOOKUP_NAME_DOMAIN) || (flags == 0)) { + bool check_global_sam = false; + + check_global_sam = strequal(domain, get_global_sam_name()); + + /* If we are running on a DC that has PASSDB module with domain + * information, check if DNS forest name is matching the domain + * name. This is the case of FreeIPA domain controller when + * trusted AD DC looks up users found in a Global Catalog of + * the forest root domain. */ + if (!check_global_sam && (IS_DC)) { + struct pdb_domain_info *dom_info = NULL; + dom_info = pdb_get_domain_info(tmp_ctx); + + if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) { + check_global_sam = strequal(domain, dom_info->dns_forest); + } - /* It's our own domain, lookup the name in passdb */ - if (lookup_global_sam_name(name, flags, &rid, &type)) { - sid_compose(&sid, get_global_sam_sid(), rid); - goto ok; + TALLOC_FREE(dom_info); + } + + if (check_global_sam) { + /* It's our own domain, lookup the name in passdb */ + if (lookup_global_sam_name(name, flags, &rid, &type)) { + sid_compose(&sid, get_global_sam_sid(), rid); + goto ok; + } + TALLOC_FREE(tmp_ctx); + return false; } - TALLOC_FREE(tmp_ctx); - return false; } if ((flags & LOOKUP_NAME_BUILTIN) && -- 2.29.2 From 0f694e82b7504bc902b08cfa1575099963cccd51 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 11 Nov 2020 14:42:55 +0200 Subject: [PATCH 103/108] auth_sam: use pdb_get_domain_info to look up DNS forest information When Samba is used as a part of FreeIPA domain controller, Windows clients for a trusted AD forest may try to authenticate (perform logon operation) as a REALM\name user account. Fix auth_sam plugins to accept DNS forest name if we are running on a DC with PASSDB module providing domain information (e.g. pdb_get_domain_info() returning non-NULL structure). Right now, only FreeIPA or Samba AD DC PASSDB backends return this information but Samba AD DC configuration is explicitly ignored by the two auth_sam (strict and netlogon3) modules. Detailed logs below: [2020/11/11 09:23:53.281296, 1, pid=42677, effective(65534, 65534), real(65534, 0), class=rpc_parse] ../../librpc/ndr/ndr.c:482(ndr_print_function_debug) netr_LogonSamLogonWithFlags: struct netr_LogonSamLogonWithFlags in: struct netr_LogonSamLogonWithFlags server_name : * server_name : '\\master.ipa.test' computer_name : * computer_name : 'AD1' credential : * credential: struct netr_Authenticator cred: struct netr_Credential data : 529f4b087c5f6546 timestamp : Wed Nov 11 09:23:55 AM 2020 UTC return_authenticator : * return_authenticator: struct netr_Authenticator cred: struct netr_Credential data : 204f28f622010000 timestamp : Fri May 2 06:37:50 AM 1986 UTC logon_level : NetlogonNetworkTransitiveInformation (6) logon : * logon : union netr_LogonLevel(case 6) network : * network: struct netr_NetworkInfo identity_info: struct netr_IdentityInfo domain_name: struct lsa_String length : 0x0010 (16) size : 0x01fe (510) string : * string : 'IPA.TEST' parameter_control : 0x00002ae0 (10976) 0: MSV1_0_CLEARTEXT_PASSWORD_ALLOWED 0: MSV1_0_UPDATE_LOGON_STATISTICS 0: MSV1_0_RETURN_USER_PARAMETERS 0: MSV1_0_DONT_TRY_GUEST_ACCOUNT 1: MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT 1: MSV1_0_RETURN_PASSWORD_EXPIRY 1: MSV1_0_USE_CLIENT_CHALLENGE 0: MSV1_0_TRY_GUEST_ACCOUNT_ONLY 1: MSV1_0_RETURN_PROFILE_PATH 0: MSV1_0_TRY_SPECIFIED_DOMAIN_ONLY 1: MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT 0: MSV1_0_DISABLE_PERSONAL_FALLBACK 1: MSV1_0_ALLOW_FORCE_GUEST 0: MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED 0: MSV1_0_USE_DOMAIN_FOR_ROUTING_ONLY 0: MSV1_0_ALLOW_MSVCHAPV2 0: MSV1_0_S4U2SELF 0: MSV1_0_CHECK_LOGONHOURS_FOR_S4U 0: MSV1_0_SUBAUTHENTICATION_DLL_EX logon_id : 0x0000000000884ef2 (8933106) account_name: struct lsa_String length : 0x000e (14) size : 0x000e (14) string : * string : 'idmuser' workstation: struct lsa_String length : 0x0000 (0) size : 0x0000 (0) string : * string : '' challenge : 417207867bd33c74 nt: struct netr_ChallengeResponse length : 0x00c0 (192) size : 0x00c0 (192) data : * data: ARRAY(192) [0000] A5 24 62 6E 31 DF 69 66 9E DC 54 D6 63 4C D6 2F .$bn1.if ..T.cL./ [0010] 01 01 00 00 00 00 00 00 50 37 D7 60 0C B8 D6 01 ........ P7.`.... [0020] 15 1B 38 4F 47 95 4D 62 00 00 00 00 02 00 0E 00 ..8OG.Mb ........ [0030] 57 00 49 00 4E 00 32 00 30 00 31 00 36 00 01 00 W.I.N.2. 0.1.6... [0040] 06 00 41 00 44 00 31 00 04 00 18 00 77 00 69 00 ..A.D.1. ....w.i. [0050] 6E 00 32 00 30 00 31 00 36 00 2E 00 74 00 65 00 n.2.0.1. 6...t.e. [0060] 73 00 74 00 03 00 20 00 61 00 64 00 31 00 2E 00 s.t... . a.d.1... [0070] 77 00 69 00 6E 00 32 00 30 00 31 00 36 00 2E 00 w.i.n.2. 0.1.6... [0080] 74 00 65 00 73 00 74 00 05 00 18 00 77 00 69 00 t.e.s.t. ....w.i. [0090] 6E 00 32 00 30 00 31 00 36 00 2E 00 74 00 65 00 n.2.0.1. 6...t.e. [00A0] 73 00 74 00 07 00 08 00 50 37 D7 60 0C B8 D6 01 s.t..... P7.`.... [00B0] 06 00 04 00 02 00 00 00 00 00 00 00 00 00 00 00 ........ ........ lm: struct netr_ChallengeResponse length : 0x0018 (24) size : 0x0018 (24) data : * data : 000000000000000000000000000000000000000000000000 validation_level : 0x0006 (6) flags : * flags : 0x00000000 (0) 0: NETLOGON_SAMLOGON_FLAG_PASS_TO_FOREST_ROOT 0: NETLOGON_SAMLOGON_FLAG_PASS_CROSS_FOREST_HOP 0: NETLOGON_SAMLOGON_FLAG_RODC_TO_OTHER_DOMAIN 0: NETLOGON_SAMLOGON_FLAG_RODC_NTLM_REQUEST In such case checks for a workgroup name will not match the DNS forest name used in the username specification: [2020/11/11 09:23:53.283055, 3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:200(auth_check_ntlm_password) check_ntlm_password: Checking password for unmapped user [IPA.TEST]\[idmuser]@[] with the new password interface [2020/11/11 09:23:53.283073, 3, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:203(auth_check_ntlm_password) check_ntlm_password: mapped user is: [IPA.TEST]\[idmuser]@[] [2020/11/11 09:23:53.283082, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:213(auth_check_ntlm_password) check_ntlm_password: auth_context challenge created by fixed [2020/11/11 09:23:53.283091, 10, pid=42677, effective(65534, 65534), real(65534, 0), class=auth] ../../source3/auth/auth.c:216(auth_check_ntlm_password) challenge is: [2020/11/11 09:23:53.283099, 5, pid=42677, effective(65534, 65534), real(65534, 0)] ../../lib/util/util.c:678(dump_data) [0000] 41 72 07 86 7B D3 3C 74 Ar..{. Reviewed-by: Andreas Schneider (cherry picked from commit 2a8b672652dcbcf55ec59be537773d76f0f14d0a) --- source3/auth/auth_sam.c | 45 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 3c12f959faf..e8e0d543f8c 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -22,6 +22,7 @@ #include "includes.h" #include "auth.h" +#include "passdb.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -142,10 +143,28 @@ static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context, break; case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: - if ( !is_local_name && !is_my_domain ) { - DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n", - effective_domain)); - return NT_STATUS_NOT_IMPLEMENTED; + if (!is_local_name && !is_my_domain) { + /* If we are running on a DC that has PASSDB module with domain + * information, check if DNS forest name is matching the domain + * name. This is the case of FreeIPA domain controller when + * trusted AD DCs attempt to authenticate FreeIPA users using + * the forest root domain (which is the only domain in FreeIPA). + */ + struct pdb_domain_info *dom_info = NULL; + + dom_info = pdb_get_domain_info(mem_ctx); + if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) { + is_my_domain = strequal(user_info->mapped.domain_name, + dom_info->dns_forest); + } + + TALLOC_FREE(dom_info); + if (!is_my_domain) { + DEBUG(6,("check_samstrict_security: %s is not one " + "of my local names or domain name (DC)\n", + effective_domain)); + return NT_STATUS_NOT_IMPLEMENTED; + } } break; @@ -230,6 +249,24 @@ static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context, } is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup()); + if (!is_my_domain) { + /* If we are running on a DC that has PASSDB module with domain + * information, check if DNS forest name is matching the domain + * name. This is the case of FreeIPA domain controller when + * trusted AD DCs attempt to authenticate FreeIPA users using + * the forest root domain (which is the only domain in FreeIPA). + */ + struct pdb_domain_info *dom_info = NULL; + dom_info = pdb_get_domain_info(mem_ctx); + + if ((dom_info != NULL) && (dom_info->dns_forest != NULL)) { + is_my_domain = strequal(user_info->mapped.domain_name, + dom_info->dns_forest); + } + + TALLOC_FREE(dom_info); + } + if (!is_my_domain) { DBG_INFO("%s is not our domain name (DC for %s)\n", effective_domain, lp_workgroup()); -- 2.29.2 From d1de17ecd572d827f38042d7a17536900b55b889 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 27 Nov 2020 11:22:15 +0100 Subject: [PATCH 104/108] docs-xml: Add a section about weak crypto in testparm manpage BUG: https://bugzilla.samba.org/show_bug.cgi?id=14583 Signed-off-by: Andreas Schneider Reviewed-by: Alexander Bokovoy Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Fri Nov 27 13:48:20 UTC 2020 on sn-devel-184 (cherry picked from commit 5c27740aeff273bcd5f027d36874e56170234146) --- docs-xml/manpages/testparm.1.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs-xml/manpages/testparm.1.xml b/docs-xml/manpages/testparm.1.xml index 9099cda010f..7c7abf50e8b 100644 --- a/docs-xml/manpages/testparm.1.xml +++ b/docs-xml/manpages/testparm.1.xml @@ -171,6 +171,15 @@ errors and warnings if the file did not load. If the file was loaded OK, the program then dumps all known service details to stdout. + + For certain use cases, SMB protocol requires use of + cryptographic algorithms which are known to be weak and already + broken. DES and ARCFOUR (RC4) ciphers and the SHA1 and MD5 hash + algorithms are considered weak but they are required for backward + compatibility. The testparm utility shows whether the Samba tools + will fall back to these weak crypto algorithms if it is not possible + to use strong cryptography by default. + In FIPS mode weak crypto cannot be enabled. -- 2.29.2 From 87bdffab6eae644d468f0fdc4489667fc21ac3a6 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Tue, 15 Dec 2020 15:17:04 +0100 Subject: [PATCH 105/108] HACK:s3:winbind: Rely on the domain child for online check --- source3/winbindd/winbindd_cm.c | 9 +++++++++ source3/winbindd/winbindd_dual.c | 3 +++ 2 files changed, 12 insertions(+) diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 466a0095ef2..ebc92e30706 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -89,6 +89,8 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND +extern bool wb_idmap_child; + struct dc_name_ip { fstring name; struct sockaddr_storage ss; @@ -176,6 +178,13 @@ static void msg_try_to_go_online(struct messaging_context *msg, continue; } + if (wb_child_domain() == NULL && !wb_idmap_child) { + DEBUG(5,("msg_try_to_go_online: domain %s " + "NOT CONNECTING IN MAIN PROCESS.\n", domainname)); + domain->online = true; + continue; + } + /* This call takes care of setting the online flag to true if we connected, or re-adding the offline handler if false. Bypasses online diff --git a/source3/winbindd/winbindd_dual.c b/source3/winbindd/winbindd_dual.c index 47efe988d65..d2006c95f54 100644 --- a/source3/winbindd/winbindd_dual.c +++ b/source3/winbindd/winbindd_dual.c @@ -1641,6 +1641,8 @@ static void child_handler(struct tevent_context *ev, struct tevent_fd *fde, } } +bool wb_idmap_child; + static bool fork_domain_child(struct winbindd_child *child) { int fdpair[2]; @@ -1745,6 +1747,7 @@ static bool fork_domain_child(struct winbindd_child *child) setproctitle("domain child [%s]", child_domain->name); } else if (child == idmap_child()) { setproctitle("idmap child"); + wb_idmap_child = true; } /* Handle online/offline messages. */ -- 2.29.2 From 6e724a5e7055e1b18e0c7e1a2ceb81729941dc2c Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 3 Feb 2021 10:30:08 +0100 Subject: [PATCH 106/108] lib:util: Add basic memcache unit test BUG: https://bugzilla.samba.org/show_bug.cgi?id=14625 Signed-off-by: Andreas Schneider Reviewed-by: Ralph Boehme (cherry picked from commit bebbf621d6052f797c5cf19a2a9bbc13e699d3f0) --- lib/util/tests/test_memcache.c | 122 +++++++++++++++++++++++++++++++++ lib/util/wscript_build | 8 ++- selftest/tests.py | 2 + 3 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 lib/util/tests/test_memcache.c diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c new file mode 100644 index 00000000000..8ea5e5b042e --- /dev/null +++ b/lib/util/tests/test_memcache.c @@ -0,0 +1,122 @@ +/* + * Unix SMB/CIFS implementation. + * + * Copyright (C) 2021 Andreas Schneider + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "lib/replace/replace.h" +#include "lib/util/talloc_stack.h" +#include "lib/util/memcache.h" + +static int setup_talloc_context(void **state) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + *state = frame; + return 0; +} + +static int teardown_talloc_context(void **state) +{ + TALLOC_CTX *frame = *state; + TALLOC_FREE(frame); + return 0; +} + +static void torture_memcache_init(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct memcache *cache = NULL; + + cache = memcache_init(mem_ctx, 0); + assert_non_null(cache); + + TALLOC_FREE(cache); + + cache = memcache_init(mem_ctx, 10); + assert_non_null(cache); + + TALLOC_FREE(cache); +} + +static void torture_memcache_add_lookup_delete(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct memcache *cache = NULL; + DATA_BLOB key1, key2; + char *path1 = NULL, *path2 = NULL; + + cache = memcache_init(mem_ctx, 0); + assert_non_null(cache); + + key1 = data_blob_const("key1", 4); + path1 = talloc_strdup(mem_ctx, "/tmp/one"); + assert_non_null(path1); + + key2 = data_blob_const("key2", 4); + path2 = talloc_strdup(mem_ctx, "/tmp/two"); + assert_non_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key1, &path1); + assert_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key2, &path2); + assert_null(path2); + + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1); + assert_non_null(path1); + assert_string_equal(path1, "/tmp/one"); + + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); + assert_non_null(path2); + assert_string_equal(path2, "/tmp/two"); + + memcache_delete(cache, GETWD_CACHE, key1); + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1); + assert_null(path1); + + memcache_flush(cache, GETWD_CACHE); + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); + assert_null(path2); + + TALLOC_FREE(cache); +} + +int main(int argc, char *argv[]) +{ + int rc; + const struct CMUnitTest tests[] = { + cmocka_unit_test(torture_memcache_init), + cmocka_unit_test(torture_memcache_add_lookup_delete), + }; + + if (argc == 2) { + cmocka_set_test_filter(argv[1]); + } + cmocka_set_message_output(CM_OUTPUT_SUBUNIT); + + rc = cmocka_run_group_tests(tests, + setup_talloc_context, + teardown_talloc_context); + + return rc; +} diff --git a/lib/util/wscript_build b/lib/util/wscript_build index bf3e44bf1d2..5a8a04965ec 100644 --- a/lib/util/wscript_build +++ b/lib/util/wscript_build @@ -310,4 +310,10 @@ else: source='tests/test_util.c', deps='cmocka replace talloc samba-util', local_include=False, - for_selftest=True); + for_selftest=True) + + bld.SAMBA_BINARY('test_memcache', + source='tests/test_memcache.c', + deps='cmocka replace talloc samba-util', + local_include=False, + for_selftest=True) diff --git a/selftest/tests.py b/selftest/tests.py index 4a968cdbe8a..003698a5eb3 100644 --- a/selftest/tests.py +++ b/selftest/tests.py @@ -403,6 +403,8 @@ plantestsuite("samba.unittests.util_paths", "none", [os.path.join(bindir(), "default/lib/util/test_util_paths")]) plantestsuite("samba.unittests.util", "none", [os.path.join(bindir(), "default/lib/util/test_util")]) +plantestsuite("samba.unittests.memcache", "none", + [os.path.join(bindir(), "default/lib/util/test_memcache")]) plantestsuite("samba.unittests.ntlm_check", "none", [os.path.join(bindir(), "default/libcli/auth/test_ntlm_check")]) plantestsuite("samba.unittests.gnutls", "none", -- 2.29.2 From 0f568ce9a376a7743372c502d0afd224e9b2649d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 3 Feb 2021 10:37:12 +0100 Subject: [PATCH 107/108] lib:util: Add cache oversize test for memcache BUG: https://bugzilla.samba.org/show_bug.cgi?id=14625 Signed-off-by: Andreas Schneider Reviewed-by: Ralph Boehme (cherry picked from commit 00543ab3b29e3fbfe8314e51919629803e14ede6) --- lib/util/tests/test_memcache.c | 39 ++++++++++++++++++++++++++++++++++ selftest/knownfail.d/memcache | 1 + 2 files changed, 40 insertions(+) create mode 100644 selftest/knownfail.d/memcache diff --git a/lib/util/tests/test_memcache.c b/lib/util/tests/test_memcache.c index 8ea5e5b042e..8a3997817c1 100644 --- a/lib/util/tests/test_memcache.c +++ b/lib/util/tests/test_memcache.c @@ -98,6 +98,44 @@ static void torture_memcache_add_lookup_delete(void **state) path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); assert_null(path2); + TALLOC_FREE(path1); + TALLOC_FREE(path2); + TALLOC_FREE(cache); +} + +static void torture_memcache_add_oversize(void **state) +{ + TALLOC_CTX *mem_ctx = *state; + struct memcache *cache = NULL; + DATA_BLOB key1, key2; + char *path1 = NULL, *path2 = NULL; + + cache = memcache_init(mem_ctx, 10); + assert_non_null(cache); + + key1 = data_blob_const("key1", 4); + path1 = talloc_strdup(mem_ctx, "/tmp/one"); + assert_non_null(path1); + + key2 = data_blob_const("key2", 4); + path2 = talloc_strdup(mem_ctx, "/tmp/two"); + assert_non_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key1, &path1); + assert_null(path1); + + memcache_add_talloc(cache, GETWD_CACHE, key2, &path2); + assert_null(path2); + + path1 = memcache_lookup_talloc(cache, GETWD_CACHE, key1); + assert_null(path1); + + path2 = memcache_lookup_talloc(cache, GETWD_CACHE, key2); + assert_non_null(path2); + assert_string_equal(path2, "/tmp/two"); + + TALLOC_FREE(path1); + TALLOC_FREE(path2); TALLOC_FREE(cache); } @@ -107,6 +145,7 @@ int main(int argc, char *argv[]) const struct CMUnitTest tests[] = { cmocka_unit_test(torture_memcache_init), cmocka_unit_test(torture_memcache_add_lookup_delete), + cmocka_unit_test(torture_memcache_add_oversize), }; if (argc == 2) { diff --git a/selftest/knownfail.d/memcache b/selftest/knownfail.d/memcache new file mode 100644 index 00000000000..0a74ace3003 --- /dev/null +++ b/selftest/knownfail.d/memcache @@ -0,0 +1 @@ +^samba.unittests.memcache.torture_memcache_add_oversize -- 2.29.2 From e8698352f3033ca1ce0dcdfe2049bae0bafe0dab Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 2 Feb 2021 18:10:38 +0100 Subject: [PATCH 108/108] lib:util: Avoid free'ing our own pointer BUG: https://bugzilla.samba.org/show_bug.cgi?id=14625 Signed-off-by: Andreas Schneider Reviewed-by: Ralph Boehme (cherry picked from commit 0bdbe50fac680be3fe21043246b8c75005611351) --- lib/util/memcache.c | 19 +++++++++++++++---- selftest/knownfail.d/memcache | 1 - 2 files changed, 15 insertions(+), 5 deletions(-) delete mode 100644 selftest/knownfail.d/memcache diff --git a/lib/util/memcache.c b/lib/util/memcache.c index 1e616bd0e9a..7b0b27eaddb 100644 --- a/lib/util/memcache.c +++ b/lib/util/memcache.c @@ -223,14 +223,25 @@ static void memcache_delete_element(struct memcache *cache, TALLOC_FREE(e); } -static void memcache_trim(struct memcache *cache) +static void memcache_trim(struct memcache *cache, struct memcache_element *e) { + struct memcache_element *tail = NULL; + if (cache->max_size == 0) { return; } - while ((cache->size > cache->max_size) && DLIST_TAIL(cache->mru)) { - memcache_delete_element(cache, DLIST_TAIL(cache->mru)); + for (tail = DLIST_TAIL(cache->mru); + (cache->size > cache->max_size) && (tail != NULL); + tail = DLIST_TAIL(cache->mru)) + { + if (tail == e) { + tail = DLIST_PREV(tail); + if (tail == NULL) { + break; + } + } + memcache_delete_element(cache, tail); } } @@ -351,7 +362,7 @@ void memcache_add(struct memcache *cache, enum memcache_number n, memcpy(&mtv, cache_value.data, sizeof(mtv)); cache->size += mtv.len; } - memcache_trim(cache); + memcache_trim(cache, e); } void memcache_add_talloc(struct memcache *cache, enum memcache_number n, diff --git a/selftest/knownfail.d/memcache b/selftest/knownfail.d/memcache deleted file mode 100644 index 0a74ace3003..00000000000 --- a/selftest/knownfail.d/memcache +++ /dev/null @@ -1 +0,0 @@ -^samba.unittests.memcache.torture_memcache_add_oversize -- 2.29.2