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>
# 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)
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
+++ /dev/null
-^samba.tests.dckeytab.samba.tests.dckeytab.DCKeytabTests.test_export_keytab_change3_update_keep
krb5_principal principal,
struct ldb_context *samdb,
struct ldb_dn *dn,
+ bool include_historic_keys,
const char **error_string)
{
const char *gmsa_attrs[] = {
&principal,
context,
keytab,
- true,
+ include_historic_keys,
error_string);
if (ret) {
*error_string = talloc_asprintf(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 = {};
sentry.principal,
db_ctx->samdb,
dn,
+ include_historic_keys,
error_string);
if (NT_STATUS_IS_OK(status)) {
keys_exported = true;
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;
r->in.keytab_name,
r->in.principal,
keep_stale_entries,
+ !r->in.only_current_keys,
&error_string);
talloc_free(db_ctx);
const char *principal;
struct ldb_context *samdb;
bool keep_stale_entries;
+ bool only_current_keys;
} in;
struct {
const char *error_string;
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;
/*
* 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;