1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

s4:libnet_export_keytab: add only_current_keys option

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>
This commit is contained in:
Stefan Metzmacher 2024-03-15 16:11:10 +01:00 committed by Andrew Bartlett
parent 7f1e89488a
commit e2a5fbf5cf
6 changed files with 99 additions and 9 deletions

View 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

View File

@ -1 +0,0 @@
^samba.tests.dckeytab.samba.tests.dckeytab.DCKeytabTests.test_export_keytab_change3_update_keep

View 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,

View 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);

View 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;

View File

@ -31,13 +31,14 @@
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;