]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
librpc:gse: Implement storing tickets into an emtpy ccache
authorAndreas Schneider <asn@samba.org>
Fri, 4 Apr 2025 11:37:21 +0000 (13:37 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Tue, 5 Aug 2025 10:49:34 +0000 (10:49 +0000)
smbclient //server/share --krb5-use-ccache=/tmp/foo

Will write the ticket to the specified ccache.

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Alexander Bokovoy <ab@samba.org>
source3/librpc/crypto/gse.c
wscript_configure_embedded_heimdal
wscript_configure_system_heimdal
wscript_configure_system_mitkrb5

index e6f96d2464e26f64cbd101b92363fba89a9936e2..d29122c9ce685410a2eb0541cb8452c4f2f31593 100644 (file)
@@ -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);
index c1488e5506ead6a7979c14e7cdac3696d5e73db9..325b1b11d4be2a7eb4d9a09808dd32c680350d18 100644 (file)
@@ -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)
index c320a76ea17164cb9b686b3ffb84a53eb33b4678..6256bbac4e6908a5fd499616f40e8878bb7d8591 100644 (file)
@@ -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",
+)
index 0bf755bc0cb89fbbaecc697801637a7f313b84f0..6b70f2530ede32865636874a6cf07c06aeea72ab 100644 (file)
@@ -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")