From: Andrew Bartlett Date: Wed, 6 Mar 2024 22:59:21 +0000 (+1300) Subject: samba-tool: Add option --keep-stale-entries to "samba-tool domain exportkeytab" X-Git-Tag: tdb-1.4.11~1451 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0cb1e4dbf8ef92d678eb2da7fc0a3c283ea68193;p=thirdparty%2Fsamba.git samba-tool: Add option --keep-stale-entries to "samba-tool domain exportkeytab" This will keep stale keys in the keytab, which may be useful for wireshark but is not correct if the keytab is used for accepting Kerberos tickets, as tickets encrypted with old passwords would still be accepted. Signed-off-by: Andrew Bartlett Reviewed-by: Jo Sutton --- diff --git a/python/samba/netcmd/domain/keytab.py b/python/samba/netcmd/domain/keytab.py index 84e5e78e4e3..5c2419b0485 100644 --- a/python/samba/netcmd/domain/keytab.py +++ b/python/samba/netcmd/domain/keytab.py @@ -46,6 +46,7 @@ else: takes_options = [ Option("--principal", help="extract only this principal", type=str), + Option("--keep-stale-entries", help="keep stale keys in keytab (useful for collecting keys for Wireshark)", action="store_true"), ] takes_args = ["keytab"] @@ -56,8 +57,12 @@ else: sambaopts=None, versionopts=None, hostopts=None, - principal=None): + principal=None, + keep_stale_entries=None): lp = sambaopts.get_loadparm() net = Net(None, lp) samdb = self.ldb_connect(hostopts, sambaopts, credopts) - net.export_keytab(samdb=samdb, keytab=keytab, principal=principal) + net.export_keytab(samdb=samdb, + keytab=keytab, + principal=principal, + keep_stale_entries=keep_stale_entries) diff --git a/source4/libnet/libnet_export_keytab.c b/source4/libnet/libnet_export_keytab.c index 2f144aff4d5..6374f2b0e56 100644 --- a/source4/libnet/libnet_export_keytab.c +++ b/source4/libnet/libnet_export_keytab.c @@ -35,6 +35,7 @@ static NTSTATUS sdb_kt_copy(TALLOC_CTX *mem_ctx, struct samba_kdc_db_context *db_ctx, const char *keytab_name, const char *principal, + bool keep_stale_entries, const char **error_string) { struct sdb_entry sentry = {}; @@ -100,7 +101,7 @@ static NTSTATUS sdb_kt_copy(TALLOC_CTX *mem_ctx, goto done; } - if (copy_one_principal) { + if (!keep_stale_entries) { code = smb_krb5_remove_obsolete_keytab_entries(mem_ctx, context, keytab, @@ -238,9 +239,11 @@ NTSTATUS libnet_export_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, s const char *error_string = NULL; NTSTATUS status; + bool keep_stale_entries = r->in.keep_stale_entries; + ret = smb_krb5_init_context(ctx, ctx->lp_ctx, &smb_krb5_context); if (ret) { - return NT_STATUS_NO_MEMORY; + return NT_STATUS_NO_MEMORY; } base_ctx = talloc_zero(mem_ctx, struct samba_kdc_base_context); @@ -259,23 +262,27 @@ NTSTATUS libnet_export_keytab(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, s if (r->in.principal != NULL) { DEBUG(0, ("Export one principal to %s\n", r->in.keytab_name)); - status = sdb_kt_copy(mem_ctx, - smb_krb5_context, - db_ctx, - r->in.keytab_name, - r->in.principal, - &error_string); } else { - unlink(r->in.keytab_name); DEBUG(0, ("Export complete keytab to %s\n", r->in.keytab_name)); - status = sdb_kt_copy(mem_ctx, - smb_krb5_context, - db_ctx, - r->in.keytab_name, - NULL, - &error_string); + if (!keep_stale_entries) { + unlink(r->in.keytab_name); + /* + * No point looking for old + * keys in a empty file + */ + keep_stale_entries = true; + } } + + status = sdb_kt_copy(mem_ctx, + smb_krb5_context, + db_ctx, + r->in.keytab_name, + r->in.principal, + keep_stale_entries, + &error_string); + talloc_free(db_ctx); talloc_free(base_ctx); diff --git a/source4/libnet/libnet_export_keytab.h b/source4/libnet/libnet_export_keytab.h index 726475f79aa..70aa88800cf 100644 --- a/source4/libnet/libnet_export_keytab.h +++ b/source4/libnet/libnet_export_keytab.h @@ -24,6 +24,7 @@ struct libnet_export_keytab { const char *keytab_name; const char *principal; struct ldb_context *samdb; + bool keep_stale_entries; } in; struct { const char *error_string; diff --git a/source4/libnet/py_net_dckeytab.c b/source4/libnet/py_net_dckeytab.c index 73a174d9f0d..597b30b42fd 100644 --- a/source4/libnet/py_net_dckeytab.c +++ b/source4/libnet/py_net_dckeytab.c @@ -35,17 +35,30 @@ static PyObject *py_net_export_keytab(py_net_Object *self, PyObject *args, PyObj struct libnet_export_keytab r; PyObject *py_samdb = NULL; TALLOC_CTX *mem_ctx; - const char *kwnames[] = { "keytab", "samdb", "principal", NULL }; + const char *kwnames[] = { "keytab", + "samdb", + "principal", + "keep_stale_entries", + NULL }; NTSTATUS status; + /* + * int, with values true or false, to match expectation of + * PyArg_ParseTupleAndKeywords() + */ + int keep_stale_entries = false; + r.in.principal = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Oz:export_keytab", discard_const_p(char *, kwnames), + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|Ozp:export_keytab", discard_const_p(char *, kwnames), &r.in.keytab_name, &py_samdb, - &r.in.principal)) { + &r.in.principal, + &keep_stale_entries)) { return NULL; } + r.in.keep_stale_entries = keep_stale_entries; + if (py_samdb == NULL) { r.in.samdb = NULL; } else {