]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s4:libnet_export_keytab: add only_current_keys option
authorStefan Metzmacher <metze@samba.org>
Fri, 15 Mar 2024 15:11:10 +0000 (16:11 +0100)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 22 May 2024 03:04:34 +0000 (03:04 +0000)
By default we also export on the old and older passwords...

In order to do a kinit with a keytab it might we useful to
include only the current keys.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
python/samba/tests/dckeytab.py
selftest/knownfail.d/export-keytab [deleted file]
source4/auth/kerberos/srv_keytab.c
source4/libnet/libnet_export_keytab.c
source4/libnet/libnet_export_keytab.h
source4/libnet/py_net_dckeytab.c

index 31139c0360f657de65cbb30761f1b802692d28cc..7e47ab488983b46cd0fa252b5fbb874a54304088 100644 (file)
@@ -259,7 +259,7 @@ class DCKeytabTests(TestCaseInTempDir):
         # keytab
         self.samdb.setpassword(f"(userPrincipalName={new_principal})", "5rfvBGT%")
         self.samdb.setpassword(f"(userPrincipalName={new_principal})", "6rfvBGT%")
-        self.samdb.setpassword(f"(userPrincipalName={new_principal})", "6rfvBGT%")
+        self.samdb.setpassword(f"(userPrincipalName={new_principal})", "7rfvBGT%")
 
         net.export_keytab(keytab=self.ktfile, principal=new_principal, keep_stale_entries=True)
 
@@ -279,7 +279,7 @@ class DCKeytabTests(TestCaseInTempDir):
             if principal == new_principal and enctype == credentials.ENCTYPE_AES128_CTS_HMAC_SHA1_96:
                 found += 1
 
-        # Samba currently does not export the previous keys into the keytab, but could.
+        # We exported the previous keys into the keytab...
         self.assertEqual(found, 4)
 
         # confirm at least 12 keys (4 changes, 1 in orig export and 3
diff --git a/selftest/knownfail.d/export-keytab b/selftest/knownfail.d/export-keytab
deleted file mode 100644 (file)
index 34c1607..0000000
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.dckeytab.samba.tests.dckeytab.DCKeytabTests.test_export_keytab_change3_update_keep
index a2f0d172e024d54ca91cb2d8b441b75c2636938e..875d06971cc2dfd849776f583f60c7dec11514e4 100644 (file)
@@ -231,6 +231,7 @@ NTSTATUS smb_krb5_fill_keytab_gmsa_keys(TALLOC_CTX *mem_ctx,
                                        krb5_principal principal,
                                        struct ldb_context *samdb,
                                        struct ldb_dn *dn,
+                                       bool include_historic_keys,
                                        const char **error_string)
 {
        const char *gmsa_attrs[] = {
@@ -402,7 +403,7 @@ NTSTATUS smb_krb5_fill_keytab_gmsa_keys(TALLOC_CTX *mem_ctx,
                                   &principal,
                                   context,
                                   keytab,
-                                  true,
+                                  include_historic_keys,
                                   error_string);
        if (ret) {
                *error_string = talloc_asprintf(mem_ctx,
index 69b47c8834f02b0ef8a568784b53f5534a6400f0..68912285e3b6a6d7dd1900d39f2890e2fb497e3f 100644 (file)
@@ -36,6 +36,7 @@ static NTSTATUS sdb_kt_copy(TALLOC_CTX *mem_ctx,
                            const char *keytab_name,
                            const char *principal,
                            bool keep_stale_entries,
+                           bool include_historic_keys,
                            const char **error_string)
 {
        struct sdb_entry sentry = {};
@@ -148,6 +149,7 @@ static NTSTATUS sdb_kt_copy(TALLOC_CTX *mem_ctx,
                                                                sentry.principal,
                                                                db_ctx->samdb,
                                                                dn,
+                                                               include_historic_keys,
                                                                error_string);
                        if (NT_STATUS_IS_OK(status)) {
                                keys_exported = true;
@@ -199,6 +201,90 @@ static NTSTATUS sdb_kt_copy(TALLOC_CTX *mem_ctx,
                                        continue;
                                }
 
+                               code = krb5_kt_add_entry(context, keytab, &kt_entry);
+                               if (code != 0) {
+                                       status = NT_STATUS_UNSUCCESSFUL;
+                                       *error_string = smb_get_krb5_error_message(context,
+                                                                                  code,
+                                                                                  mem_ctx);
+                                       DEBUG(0, ("smb_krb5_kt_add_entry failed code=%d, error = %s\n",
+                                                 code, *error_string));
+                                       goto done;
+                               }
+                               keys_exported = true;
+                       }
+                       kt_entry.vno -= 1;
+                       for (i = 0; include_historic_keys && i < sentry.old_keys.len; i++) {
+                               struct sdb_key *s = &(sentry.old_keys.val[i]);
+                               krb5_keyblock *keyp;
+                               bool found;
+
+                               keyp = KRB5_KT_KEY(&kt_entry);
+
+                               *keyp = s->key;
+
+                               code = smb_krb5_is_exact_entry_in_keytab(mem_ctx,
+                                                                        context,
+                                                                        keytab,
+                                                                        &kt_entry,
+                                                                        &found,
+                                                                        error_string);
+                               if (code != 0) {
+                                       status = NT_STATUS_UNSUCCESSFUL;
+                                       *error_string = smb_get_krb5_error_message(context,
+                                                                                  code,
+                                                                                  mem_ctx);
+                                       DEBUG(0, ("smb_krb5_is_exact_entry_in_keytab failed code=%d, error = %s\n",
+                                                 code, *error_string));
+                                       goto done;
+                               }
+
+                               if (found) {
+                                       continue;
+                               }
+
+                               code = krb5_kt_add_entry(context, keytab, &kt_entry);
+                               if (code != 0) {
+                                       status = NT_STATUS_UNSUCCESSFUL;
+                                       *error_string = smb_get_krb5_error_message(context,
+                                                                                  code,
+                                                                                  mem_ctx);
+                                       DEBUG(0, ("smb_krb5_kt_add_entry failed code=%d, error = %s\n",
+                                                 code, *error_string));
+                                       goto done;
+                               }
+                               keys_exported = true;
+                       }
+                       kt_entry.vno -= 1;
+                       for (i = 0; include_historic_keys && i < sentry.older_keys.len; i++) {
+                               struct sdb_key *s = &(sentry.older_keys.val[i]);
+                               krb5_keyblock *keyp;
+                               bool found;
+
+                               keyp = KRB5_KT_KEY(&kt_entry);
+
+                               *keyp = s->key;
+
+                               code = smb_krb5_is_exact_entry_in_keytab(mem_ctx,
+                                                                        context,
+                                                                        keytab,
+                                                                        &kt_entry,
+                                                                        &found,
+                                                                        error_string);
+                               if (code != 0) {
+                                       status = NT_STATUS_UNSUCCESSFUL;
+                                       *error_string = smb_get_krb5_error_message(context,
+                                                                                  code,
+                                                                                  mem_ctx);
+                                       DEBUG(0, ("smb_krb5_is_exact_entry_in_keytab failed code=%d, error = %s\n",
+                                                 code, *error_string));
+                                       goto done;
+                               }
+
+                               if (found) {
+                                       continue;
+                               }
+
                                code = krb5_kt_add_entry(context, keytab, &kt_entry);
                                if (code != 0) {
                                        status = NT_STATUS_UNSUCCESSFUL;
@@ -329,6 +415,7 @@ NTSTATUS libnet_export_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, s
                             r->in.keytab_name,
                             r->in.principal,
                             keep_stale_entries,
+                            !r->in.only_current_keys,
                             &error_string);
 
        talloc_free(db_ctx);
index 117d2121806bdc8b891d3dd2c1c57ddc0654da65..706e88c2e20bc5fa449c090dd33dba73fb289521 100644 (file)
@@ -25,6 +25,7 @@ struct libnet_export_keytab {
                const char *principal;
                struct ldb_context *samdb;
                bool keep_stale_entries;
+               bool only_current_keys;
        } in;
        struct {
                const char *error_string;
index 39deb5d3601cb68d98c74985ae39a5ebd55fcb7f..efdecf68be4623d04aab97bc5363d4506a2e9367 100644 (file)
 
 static PyObject *py_net_export_keytab(py_net_Object *self, PyObject *args, PyObject *kwargs)
 {
-       struct libnet_export_keytab r;
+       struct libnet_export_keytab r = { .in = { .principal = NULL, }};
        PyObject *py_samdb = NULL;
        TALLOC_CTX *mem_ctx;
        const char *kwnames[] = { "keytab",
                                  "samdb",
                                  "principal",
                                  "keep_stale_entries",
+                                 "only_current_keys",
                                  NULL };
        NTSTATUS status;
        /*
@@ -45,18 +46,19 @@ static PyObject *py_net_export_keytab(py_net_Object *self, PyObject *args, PyObj
         * PyArg_ParseTupleAndKeywords()
         */
        int keep_stale_entries = false;
+       int only_current_keys = false;
 
-       r.in.principal = NULL;
-
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Ozp:export_keytab", discard_const_p(char *, kwnames),
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Ozpp:export_keytab", discard_const_p(char *, kwnames),
                                         &r.in.keytab_name,
                                         &py_samdb,
                                         &r.in.principal,
-                                        &keep_stale_entries)) {
+                                        &keep_stale_entries,
+                                        &only_current_keys)) {
                return NULL;
        }
 
        r.in.keep_stale_entries = keep_stale_entries;
+       r.in.only_current_keys = only_current_keys;
 
        if (py_samdb == NULL) {
                r.in.samdb = NULL;