The branch, master has been updated via 7a19fde9260 auth:creds: Update the documentation for set_principal and set_realm via 5879410caf9 auth:creds: Make sure to uppercase the realm of a principal via e848671f34f auth:creds: Validate realm names in set_realm and set_principal via f86739e3abd s3:utils: Keep password secret in ntlm_auth get_password() via 34482f4ad01 auth:creds: Keep password secret in cmdline_get_userpassword() via 705db6c8b29 auth:creds: Keep the password secret via 67c2feba290 auth:creds: Allow to reset the principal by passing NULL to set_principal via 4f8ff3a567d auth:creds: Also uppercase realm set via a callback via e5608cdb2e5 auth:creds: Allow to reset the realm by passing NULL from e20c64e14fb libsmb: Avoid smb-level encryption if quic is trusted
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 7a19fde92605a3a3699998fb226e3e787de0b5ca Author: Andreas Schneider <a...@samba.org> Date: Wed Aug 6 07:54:52 2025 +0200 auth:creds: Update the documentation for set_principal and set_realm BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> Autobuild-User(master): Alexander Bokovoy <a...@samba.org> Autobuild-Date(master): Mon Aug 25 12:08:22 UTC 2025 on atb-devel-224 commit 5879410caf9303a378f3d90365e60928a735e65a Author: Andreas Schneider <a...@samba.org> Date: Wed Aug 6 16:33:21 2025 +0200 auth:creds: Make sure to uppercase the realm of a principal BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit e848671f34f969634d55eb7b846d70e6334034ae Author: Andreas Schneider <a...@samba.org> Date: Tue Aug 5 15:25:54 2025 +0200 auth:creds: Validate realm names in set_realm and set_principal See also https://web.mit.edu/kerberos/krb5-latest/doc/admin/realm_config.html#realm-name BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit f86739e3abd63ba0b7ba632d796968fec9fa2f8f Author: Andreas Schneider <a...@samba.org> Date: Thu Aug 7 13:48:26 2025 +0200 s3:utils: Keep password secret in ntlm_auth get_password() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit 34482f4ad014a09c84b484097a8d03dfec4f6512 Author: Andreas Schneider <a...@samba.org> Date: Thu Aug 7 13:48:04 2025 +0200 auth:creds: Keep password secret in cmdline_get_userpassword() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit 705db6c8b295f65f40b7dcd0d5dc0f6db901c8d7 Author: Andreas Schneider <a...@samba.org> Date: Thu Aug 7 13:45:48 2025 +0200 auth:creds: Keep the password secret BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit 67c2feba290764c62ab01602d5bc9d4d122c2c12 Author: Andreas Schneider <a...@samba.org> Date: Wed Aug 6 14:42:51 2025 +0200 auth:creds: Allow to reset the principal by passing NULL to set_principal We do that e.g. in cli_credentials_set_anonymous() BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit 4f8ff3a567d6318c71b0960345592224721c9594 Author: Andreas Schneider <a...@samba.org> Date: Thu Aug 7 13:32:47 2025 +0200 auth:creds: Also uppercase realm set via a callback BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit e5608cdb2e5a7ef2641ec0e7b0ce0b4640a02ce1 Author: Andreas Schneider <a...@samba.org> Date: Wed Aug 6 14:40:34 2025 +0200 auth:creds: Allow to reset the realm by passing NULL This is e.g. done by cli_credentials_set_anonymous(). We can't call TALLOC_FREE(cred->realm), as this would break cli_credentials_shallow_copy(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15893 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: auth/credentials/credentials.c | 140 ++++++++++++++++++++++++++++----- auth/credentials/credentials_cmdline.c | 1 + python/samba/tests/credentials.py | 4 +- source3/utils/ntlm_auth.c | 1 + 4 files changed, 123 insertions(+), 23 deletions(-) Changeset truncated at 500 lines: diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index c31470a81d2..dab1c047c13 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -33,6 +33,18 @@ #include "system/filesys.h" #include "system/passwd.h" +static bool str_is_ascii(const char *s) { + if (s != NULL) { + for (; s[0] != '\0'; s++) { + if (!isascii(s[0])) { + return false; + } + } + } + + return true; +} + /** * Create a new credentials structure * @param mem_ctx TALLOC_CTX parent for credentials structure @@ -367,9 +379,31 @@ _PUBLIC_ char *cli_credentials_get_principal_and_obtained(struct cli_credentials if (cred->principal_obtained == CRED_CALLBACK && !cred->callback_running) { + const char *princ = NULL; + cred->callback_running = true; - cred->principal = cred->principal_cb(cred); + princ = cred->principal_cb(cred); cred->callback_running = false; + + cred->principal = NULL; + if (princ != NULL) { + char *p = NULL; + + cred->principal = talloc_strdup(cred, princ); + if (cred->principal == NULL) { + return NULL; + } + + p = strchr(cred->principal, '@'); + if (p != NULL) { + p += 1; + + for (; p[0] != '\0'; p++) { + *p = toupper(p[0]); + } + } + } + if (cred->principal_obtained == CRED_CALLBACK) { cred->principal_obtained = CRED_CALLBACK_RESULT; cli_credentials_invalidate_ccache(cred, cred->principal_obtained); @@ -427,17 +461,52 @@ _PUBLIC_ char *cli_credentials_get_principal(struct cli_credentials *cred, TALLO return cli_credentials_get_principal_and_obtained(cred, mem_ctx, &obtained); } +/** + * @brief Set the principal for the credentials context. + * + * The realm of the principal will be checked if it is ASCII only and upper + * cased if it isn't yet. + * + * @param cred The credential context. + * + * @param val The principal to set or NULL to reset. + * + * @param obtained This way the described principal was specified. + * + * @return true on success, false if the realm is not ASCII or the allocation + * failed. + */ _PUBLIC_ bool cli_credentials_set_principal(struct cli_credentials *cred, - const char *val, - enum credentials_obtained obtained) + const char *val, + enum credentials_obtained obtained) { if (obtained >= cred->principal_obtained) { - cred->principal = talloc_strdup(cred, val); - if (cred->principal == NULL) { - return false; + /* If `val = NULL` is passed, principal is reset */ + cred->principal = NULL; + if (val != NULL) { + char *p = strchr(val, '@'); + if (p != NULL) { + /* For realm names, only ASCII is allowed */ + if (!str_is_ascii(p + 1)) { + return false; + } + } + + cred->principal = talloc_strdup(cred, val); + if (cred->principal == NULL) { + return false; + } + + p = strchr(cred->principal, '@'); + if (p != NULL) { + p += 1; + + for (; p[0] != '\0'; p++) { + *p = toupper(p[0]); + } + } } cred->principal_obtained = obtained; - cli_credentials_invalidate_ccache(cred, cred->principal_obtained); return true; } @@ -623,6 +692,7 @@ _PUBLIC_ bool cli_credentials_set_password(struct cli_credentials *cred, if (cred->password == NULL) { return false; } + talloc_keep_secret(discard_const(cred->password)); /* Don't print the actual password in talloc memory dumps */ talloc_set_name_const(cred->password, @@ -912,9 +982,20 @@ _PUBLIC_ const char *cli_credentials_get_realm(struct cli_credentials *cred) if (cred->realm_obtained == CRED_CALLBACK && !cred->callback_running) { + const char *realm = NULL; + cred->callback_running = true; - cred->realm = cred->realm_cb(cred); + realm = cred->realm_cb(cred); cred->callback_running = false; + + cred->realm = NULL; + if (realm != NULL) { + cred->realm = strupper_talloc(cred, realm); + if (cred->realm == NULL) { + return NULL; + } + } + if (cred->realm_obtained == CRED_CALLBACK) { cred->realm_obtained = CRED_CALLBACK_RESULT; cli_credentials_invalidate_ccache(cred, cred->realm_obtained); @@ -925,15 +1006,37 @@ _PUBLIC_ const char *cli_credentials_get_realm(struct cli_credentials *cred) } /** - * Set the realm for this credentials context, and force it to - * uppercase for the sanity of our local kerberos libraries + * @brief Set the realm for this credentials context. + * + * The realm be checked if it is ASCII only and upper cased if it isn't yet. + * + * @param cred The credential context. + * + * @param val The realm to set or NULL to reset. + * + * @param obtained This way the described realm was specified. + * + * @return true on success, false if the realm is not ASCII or the allocation + * failed. */ _PUBLIC_ bool cli_credentials_set_realm(struct cli_credentials *cred, - const char *val, - enum credentials_obtained obtained) + const char *val, + enum credentials_obtained obtained) { if (obtained >= cred->realm_obtained) { - cred->realm = strupper_talloc(cred, val); + /* If `val = NULL` is passed, realm is reset */ + cred->realm = NULL; + if (val != NULL) { + /* For realm names, only ASCII is allowed */ + if (!str_is_ascii(val)) { + return false; + } + + cred->realm = strupper_talloc(cred, val); + if (cred->realm == NULL) { + return false; + } + } cred->realm_obtained = obtained; cli_credentials_invalidate_ccache(cred, cred->realm_obtained); return true; @@ -1030,8 +1133,6 @@ _PUBLIC_ void cli_credentials_parse_string(struct cli_credentials *credentials, } if ((p = strchr_m(uname,'@'))) { - char *x = NULL; - /* * We also need to set username and domain * in order to undo the effect of @@ -1040,11 +1141,6 @@ _PUBLIC_ void cli_credentials_parse_string(struct cli_credentials *credentials, cli_credentials_set_username(credentials, uname, obtained); cli_credentials_set_domain(credentials, "", obtained); - /* Make sure the realm is uppercase */ - for (x = p + 1; x[0] != '\0'; x++) { - *x = toupper_m(*x); - } - cli_credentials_set_principal(credentials, uname, obtained); *p = 0; cli_credentials_set_realm(credentials, p+1, obtained); @@ -1535,7 +1631,9 @@ _PUBLIC_ void cli_credentials_get_ntlm_username_domain(struct cli_credentials *c const char **username, const char **domain) { - if (cred->principal_obtained >= cred->username_obtained) { + if (!cli_credentials_is_anonymous(cred) && + cred->principal_obtained >= cred->username_obtained) + { *domain = talloc_strdup(mem_ctx, ""); *username = cli_credentials_get_principal(cred, mem_ctx); } else { diff --git a/auth/credentials/credentials_cmdline.c b/auth/credentials/credentials_cmdline.c index c8c7c183c22..e9cdc80d52a 100644 --- a/auth/credentials/credentials_cmdline.c +++ b/auth/credentials/credentials_cmdline.c @@ -46,6 +46,7 @@ static const char *cmdline_get_userpassword(struct cli_credentials *creds) goto fail; } talloc_set_name_const(ret, __location__); + talloc_keep_secret(ret); fail: ZERO_STRUCT(pwd); TALLOC_FREE(frame); diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index bc132681c48..1835d9b7b59 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -361,7 +361,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_username(), "env_user") self.assertEqual(creds.get_domain(), lp.get("workgroup").upper()) self.assertEqual(creds.get_realm(), realm.upper()) - self.assertEqual(creds.get_principal(), "unkn...@realm.example.com") + self.assertEqual(creds.get_principal(), "unkn...@realm.example.com") creds.parse_string("domain\\user") self.assertEqual(creds.get_username(), "user") self.assertEqual(creds.get_domain(), "DOMAIN") @@ -385,7 +385,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_username(), "env_user") self.assertEqual(creds.get_domain(), lp.get("workgroup").upper()) self.assertEqual(creds.get_realm(), realm.upper()) - self.assertEqual(creds.get_principal(), "unkn...@realm.example.com") + self.assertEqual(creds.get_principal(), "unkn...@realm.example.com") creds.parse_string("domain\\user") self.assertEqual(creds.get_username(), "user") self.assertEqual(creds.get_domain(), "DOMAIN") diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index d5ae7c85b22..a424990baa8 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -254,6 +254,7 @@ static const char *get_password(struct cli_credentials *credentials) manage_squid_request(NUM_HELPER_MODES /* bogus */, NULL, state, manage_gensec_get_pw_request, (void **)&password); talloc_steal(credentials, password); + talloc_keep_secret(password); TALLOC_FREE(frame); return password; } -- Samba Shared Repository