]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3/librpc/crypto: Don't keep growing in memory keytab
authorNoel Power <noel.power@suse.com>
Thu, 26 Mar 2026 12:03:55 +0000 (12:03 +0000)
committerNoel Power <npower@samba.org>
Mon, 30 Mar 2026 09:36:45 +0000 (09:36 +0000)
When we have long living concurrent connections every rpc bind
ends up calling and subsequently adding keytab entries to the
memory keytab returned by 'gse_krb5_get_server_keytab(...)'. This is
happening because as long as there is a handle open for the
keytab named "MEMORY:cifs_srv_keytab" then we keep adding entries to
it.

Note: There is no leak of gensec_security nor the krb5_keytab
      it contains. When rpc clients connected to the rpc worker process
      exit the gensec_security and the krb5_keytab structures are
      destructed as expected. However because we use a fixed name
      "MEMORY:cifs_srv_keytab" clients end up with a handle to a
      reference counted shared keytab. Destruction of the keytab results
      in the associated reference count being decremented. When the
      reference count reaches 0 the keytab is destroyed.

To avoid the keytab being extended the easiest solution is to ensure a
unique memory keytab is created for each client.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=16042
Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Autobuild-User(master): Noel Power <npower@samba.org>
Autobuild-Date(master): Mon Mar 30 09:36:45 UTC 2026 on atb-devel-224

source3/librpc/crypto/gse_krb5.c

index 8e719e1ae0c19438acafd30314f02553d59391c0..669ff2da1e992416829848609151fb425b0bb2b4 100644 (file)
@@ -554,20 +554,36 @@ out:
 krb5_error_code gse_krb5_get_server_keytab(krb5_context krbctx,
                                           krb5_keytab *keytab)
 {
+       char *memktab_name = NULL;
        krb5_error_code ret = 0;
        krb5_error_code ret1 = 0;
        krb5_error_code ret2 = 0;
 
        *keytab = NULL;
 
+       /*
+        * create a unique name so concurrent or long lived
+        * processes don't append to existing in memory copy
+        */
+       memktab_name = talloc_asprintf(NULL,
+                                      "%s-%p",
+                                      SRV_MEM_KEYTAB_NAME,
+                                      krbctx);
+       if (memktab_name == NULL) {
+               DBG_ERR("out of memory\n");
+               return ENOMEM;
+       }
        /* create memory keytab */
-       ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab);
+       ret = krb5_kt_resolve(krbctx, memktab_name, keytab);
        if (ret) {
                DEBUG(1, (__location__ ": Failed to get memory "
                          "keytab!\n"));
+               TALLOC_FREE(memktab_name);
                return ret;
        }
 
+       TALLOC_FREE(memktab_name);
+
        switch (lp_kerberos_method()) {
        default:
        case KERBEROS_VERIFY_SECRETS: