The branch, master has been updated via 4fcfcc2dd31 docs-xml: Update documentation for --use-kerberos and --use-krb5-ccache via b5fe30ef6d1 lib:cmdline: Check if we have a valid default ccache via 7a4c8d6f84c librpc:gse: Implement storing tickets into an emtpy ccache via a6915ab9600 auth:creds: Add cli_credentials_get_out_ccache_name() via d86ec3abce7 auth:creds: Always store the ccache name via 28745e99707 auth:creds: Make sure when parsing username that realm is uppercase from 942f407337b source3/printing: Fix CID 1273086 - Resource Leak
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 4fcfcc2dd31d1ebcaa58fe12d1c8d3a2695263ce Author: Andreas Schneider <a...@samba.org> Date: Tue Aug 5 09:15:43 2025 +0200 docs-xml: Update documentation for --use-kerberos and --use-krb5-ccache Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Tue Aug 5 11:49:35 UTC 2025 on atb-devel-224 commit b5fe30ef6d128863417cb799a0fa336dde9f5ba4 Author: Andreas Schneider <a...@samba.org> Date: Fri Apr 25 17:32:16 2025 +0200 lib:cmdline: Check if we have a valid default ccache If you don't specify anything, and we have a valid ccache then try to use it! > smbclient -L //samba1.earth.milkyway.site Anonymous login successful Sharename Type Comment --------- ---- ------- print$ Disk Printer Drivers IPC$ IPC IPC Service (Samba 4.22.1) SMB1 disabled -- no workgroup available In case the user specifies a principal, it will ask for a password: > bin/smbclient -L //samba1.earth.milkyway.site -uali...@earth.milkyway.site Password for [ali...@earth.milkyway.site]: Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit 7a4c8d6f84cabfe9d27fcb795a4030de93a1b8cb Author: Andreas Schneider <a...@samba.org> Date: Fri Apr 4 13:37:21 2025 +0200 librpc:gse: Implement storing tickets into an emtpy ccache smbclient //server/share --krb5-use-ccache=/tmp/foo Will write the ticket to the specified ccache. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit a6915ab96000e3a8c247b2e65eb16378cc425c12 Author: Andreas Schneider <a...@samba.org> Date: Fri Apr 4 13:33:19 2025 +0200 auth:creds: Add cli_credentials_get_out_ccache_name() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit d86ec3abce71706e8ee535c7b83ea3da6d82e328 Author: Andreas Schneider <a...@samba.org> Date: Fri Apr 4 13:32:41 2025 +0200 auth:creds: Always store the ccache name This will allow us to specify the cache as one to fill with credentials. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> commit 28745e997070e8a7ca3c19cd0fabef789e17cc2d Author: Andreas Schneider <a...@samba.org> Date: Fri Apr 25 11:30:14 2025 +0200 auth:creds: Make sure when parsing username that realm is uppercase Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Alexander Bokovoy <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: auth/credentials/credentials.c | 7 ++++ auth/credentials/credentials.h | 1 + auth/credentials/credentials_internal.h | 1 + auth/credentials/credentials_krb5.c | 13 +++++++ auth/credentials/tests/test_creds.c | 2 +- docs-xml/build/DTD/samba.entities | 19 +++++++--- lib/cmdline/cmdline.c | 4 +- python/samba/tests/credentials.py | 4 +- source3/librpc/crypto/gse.c | 65 +++++++++++++++++++++++++++++++++ wscript_configure_embedded_heimdal | 1 + wscript_configure_system_heimdal | 9 +++++ wscript_configure_system_mitkrb5 | 7 ++++ 12 files changed, 123 insertions(+), 10 deletions(-) Changeset truncated at 500 lines: diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index a88a458f82b..c31470a81d2 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -1030,6 +1030,8 @@ _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 @@ -1038,6 +1040,11 @@ _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); diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index cae6a94b450..9f945726440 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -262,6 +262,7 @@ int cli_credentials_set_ccache(struct cli_credentials *cred, const char *name, enum credentials_obtained obtained, const char **error_string); +const char *cli_credentials_get_out_ccache_name(struct cli_credentials *cred); bool cli_credentials_parse_password_file(struct cli_credentials *credentials, const char *file, enum credentials_obtained obtained); bool cli_credentials_parse_password_fd(struct cli_credentials *credentials, int fd, enum credentials_obtained obtained); diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index cda361e1dd0..72ec390ad7e 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -74,6 +74,7 @@ struct cli_credentials { DATA_BLOB nt_response; DATA_BLOB nt_session_key; + const char *ccache_name; struct ccache_container *ccache; struct gssapi_creds_container *client_gss_creds; struct keytab_container *keytab; diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index f905fe736cc..4dc7e7be67e 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -280,6 +280,11 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred, return 0; } +_PUBLIC_ const char *cli_credentials_get_out_ccache_name(struct cli_credentials *cred) +{ + return cred->ccache_name; +} + _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, struct loadparm_context *lp_ctx, const char *name, @@ -293,6 +298,14 @@ _PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, return 0; } + if (name != NULL) { + cred->ccache_name = talloc_strdup(cred, name); + if (cred->ccache_name == NULL) { + (*error_string) = error_message(ENOMEM); + return ENOMEM; + } + } + ccc = talloc(cred, struct ccache_container); if (!ccc) { (*error_string) = error_message(ENOMEM); diff --git a/auth/credentials/tests/test_creds.c b/auth/credentials/tests/test_creds.c index fa8755e0a40..4abb7e4b90c 100644 --- a/auth/credentials/tests/test_creds.c +++ b/auth/credentials/tests/test_creds.c @@ -219,7 +219,7 @@ static void torture_creds_parse_string(void **state) usr_obtained = cli_credentials_get_username_obtained(creds); assert_int_equal(usr_obtained, CRED_SPECIFIED); - assert_string_equal(creds->principal, "wurst@brot.realm"); + assert_string_equal(creds->principal, "wurst@BROT.REALM"); princ_obtained = cli_credentials_get_principal_obtained(creds); assert_int_equal(princ_obtained, CRED_SPECIFIED); diff --git a/docs-xml/build/DTD/samba.entities b/docs-xml/build/DTD/samba.entities index cefddacd9b7..65d597ae8ff 100644 --- a/docs-xml/build/DTD/samba.entities +++ b/docs-xml/build/DTD/samba.entities @@ -764,10 +764,19 @@ <term>--use-kerberos=desired|required|off</term> <listitem> <para> - This parameter determines whether Samba client tools - will try to authenticate using Kerberos. For Kerberos - authentication you need to use dns names instead of IP - addresses when connecting to a service. + This parameter determines whether Samba client tools + will try to authenticate using Kerberos. For Kerberos + authentication you should use DNS names instead of IP + addresses when connecting to a service. + + By default Samba client tools will try to use the + default Kerberos credential cache (ccache). + In case the ccache does not exist or -U|--user option + was specified, clients will ask to enter a password and + will obtain a Kerberos ticket (kinit) for you. + + If you want to use an alternative Kerberos credentical + cache, use the --use-krb5-ccache option. </para> <para> @@ -789,7 +798,7 @@ </para> <para> - This will set --use-kerberos=required too. + This will enforce --use-kerberos=required. </para> </listitem> </varlistentry> diff --git a/lib/cmdline/cmdline.c b/lib/cmdline/cmdline.c index e434d65a2ef..f96ca88f95b 100644 --- a/lib/cmdline/cmdline.c +++ b/lib/cmdline/cmdline.c @@ -1031,8 +1031,8 @@ static void popt_common_credentials_callback(poptContext popt_ctx, } } - if (cli_credentials_get_kerberos_state(creds) == - CRED_USE_KERBEROS_REQUIRED) + if (cli_credentials_get_kerberos_state(creds) != + CRED_USE_KERBEROS_DISABLED) { enum credentials_obtained ccache_obtained = CRED_UNINITIALISED; diff --git a/python/samba/tests/credentials.py b/python/samba/tests/credentials.py index f9781f8ba03..bc132681c48 100644 --- a/python/samba/tests/credentials.py +++ b/python/samba/tests/credentials.py @@ -403,7 +403,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_username(), "u...@samba.org") self.assertEqual(creds.get_domain(), "") self.assertEqual(creds.get_realm(), "SAMBA.ORG") - self.assertEqual(creds.get_principal(), "u...@samba.org") + self.assertEqual(creds.get_principal(), "u...@samba.org") self.assertEqual(creds.is_anonymous(), False) self.assertEqual(creds.authentication_requested(), True) @@ -445,7 +445,7 @@ class CredentialsTests(samba.tests.TestCaseInTempDir): self.assertEqual(creds.get_domain(), "") self.assertEqual(creds.get_password(), "pass") self.assertEqual(creds.get_realm(), "SAMBA.ORG") - self.assertEqual(creds.get_principal(), "u...@samba.org") + self.assertEqual(creds.get_principal(), "u...@samba.org") self.assertEqual(creds.is_anonymous(), False) self.assertEqual(creds.authentication_requested(), True) diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c index e6f96d2464e..d29122c9ce6 100644 --- a/source3/librpc/crypto/gse.c +++ b/source3/librpc/crypto/gse.c @@ -632,6 +632,71 @@ init_sec_context_done: goto done; } + /* + * In case we have a ccache specified on the command line we probably + * want to use it to store credentials we got it. + */ +#ifdef HAVE_GSS_KEY_VALUE_SET_DESC + if (NT_STATUS_IS_OK(status)) { + struct cli_credentials *creds = gensec_get_credentials( + gensec_security); + bool ccache_valid = false; + enum credentials_obtained ccache_obtained = CRED_UNINITIALISED; + + ccache_valid = cli_credentials_get_ccache_name_obtained( + creds, gse_ctx, NULL, &ccache_obtained); + /* + * In case we don't have a valid ccache yet, try to create it if + * one has been specified. + */ + if (!ccache_valid) { + gss_key_value_set_desc store; + const char *ccache_name = + cli_credentials_get_out_ccache_name(creds); + + if (ccache_name == NULL) { + goto done; + } + + store.elements = talloc_zero_array( + mem_ctx, + struct gss_key_value_element_struct, + 1); + if (store.elements == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } + + store.count = 1; + store.elements[0] = + (struct gss_key_value_element_struct){ + .key = "ccache", + .value = ccache_name, + }; + + /* + * We attempt to store the cred into the ccache. It + * might fail but we don't need to act on it for the + * purpose of the authentication. + */ + gss_maj = gss_store_cred_into(&gss_min, + gse_ctx->creds, + GSS_C_INITIATE, + GSS_C_NO_OID, + /* overwrite_cred = */ 1, + /* default_cred = */ 1, + &store, + NULL, + NULL); + if (gss_maj != 0) { + DBG_ERR("Failed to store Kerberos credentials " + "into ccache: %s\n", + ccache_name); + } + } + } +#endif /* HAVE_GSS_KEY_VALUE_SET_DESC */ + /* we may be told to return nothing */ if (out_data.length) { blob = data_blob_talloc(mem_ctx, out_data.value, out_data.length); diff --git a/wscript_configure_embedded_heimdal b/wscript_configure_embedded_heimdal index c1488e5506e..325b1b11d4b 100644 --- a/wscript_configure_embedded_heimdal +++ b/wscript_configure_embedded_heimdal @@ -15,3 +15,4 @@ conf.RECURSE('third_party/heimdal_build') conf.define('HAVE_CLIENT_GSS_C_CHANNEL_BOUND_FLAG', 1) conf.define('HAVE_KRB5_INIT_CREDS_STEP', 1) +conf.define('HAVE_GSS_KEY_VALUE_SET_DESC', 1) diff --git a/wscript_configure_system_heimdal b/wscript_configure_system_heimdal index c320a76ea17..6256bbac4e6 100644 --- a/wscript_configure_system_heimdal +++ b/wscript_configure_system_heimdal @@ -66,3 +66,12 @@ conf.CHECK_FUNCS(''' ''', lib='krb5', headers='krb5.h') + +# gss_key_value_set_desc is not part of system heimdal in the build image. Maybe +# the distro we use is too old. +conf.CHECK_CODE( + "gss_key_value_set_desc", + "HAVE_GSS_KEY_VALUE_SET_DESC", + headers="gssapi/gssapi.h", + lib="gssapi", +) diff --git a/wscript_configure_system_mitkrb5 b/wscript_configure_system_mitkrb5 index 0bf755bc0cb..6b70f2530ed 100644 --- a/wscript_configure_system_mitkrb5 +++ b/wscript_configure_system_mitkrb5 @@ -339,6 +339,13 @@ conf.CHECK_CODE(''' headers='krb5.h', lib='krb5', execute=False, msg="Checking whether krb5_creds have flags property") +conf.CHECK_CODE( + "gss_key_value_set_desc", + "HAVE_GSS_KEY_VALUE_SET_DESC", + headers="gssapi/gssapi_ext.h", + lib="gssapi", +) + # Check for MIT KDC if conf.CONFIG_SET('AD_DC_BUILD_IS_ENABLED'): Logs.info("Looking for MIT KDC") -- Samba Shared Repository