[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Wed May 22 04:08:02 UTC 2024
The branch, master has been updated
via bdfbf25255e test_kinit_export_keytab: reset pw of the test account and test --only-current-keys
via b4be5718d3d samba-tool: let 'samba-tool domain exportkeytab' take an --only-current-keys option
via 2793ef3e163 samba.tests.dckeytab: add test_export_keytab_change3_update_only_current_keep()
via e2a5fbf5cf2 s4:libnet_export_keytab: add only_current_keys option
via 7f1e89488a7 s4:kdc: also provide cross-realm keys via samba_kdc_seq()
via 37292f8a60f s4:kdc: let samba_kdc_trust_message2entry() return all keys with SDB_F_ADMIN_DATA
via 6ecc607edee s4:kdc: split out samba_kdc_fill_trust_keys() helper
via f5c8c212dcb s4:kdc: add available_enctypes to supported_session_etypes in samba_kdc_trust_message2entry()
via f48699641cf s4:kdc: add a returned_kvno helper variable in samba_kdc_trust_message2entry()
via d1efc396de4 s4:kdc: let samba_kdc_trust_message2entry() ignore KRB5_PROG_ETYPE_NOSUPP
via 8cfebc36edc s4:kdc: split out samba_kdc_fill_trust_keys() helper
via 83f03513fd5 s3:libnet: add a debug message to libnet_keytab_add_to_keytab_entries()
via 888a785f476 s3:libnet: add support for trusted domains in libnet_dssync_keytab.c
via 2b2cc544725 s3:libnet: split out store_or_fetch_attribute() from parse_user() in libnet_dssync_keytab.c
via feff15fc88b s3:libnet: split out parse_user() in libnet_dssync_keytab.c
via 52df4063871 s3:libnet: let parse_user() in libnet_dssync_keytab.c work without nt hash
from 01849ab1bca s4:kdc: Implement KDC plugin hardware authentication policy
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit bdfbf25255e457c3e5d5d75ee09fca3af461c5a7
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Apr 17 16:15:17 2024 +0200
test_kinit_export_keytab: reset pw of the test account and test --only-current-keys
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Wed May 22 04:07:02 UTC 2024 on atb-devel-224
commit b4be5718d3de3bc90d142cb53f79fe067d0a3e0a
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 16:14:18 2024 +0100
samba-tool: let 'samba-tool domain exportkeytab' take an --only-current-keys option
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 2793ef3e1632c735f9caac015503aab06f53d543
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 16:31:22 2024 +0100
samba.tests.dckeytab: add test_export_keytab_change3_update_only_current_keep()
This tests that only_current_keys=True works.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit e2a5fbf5cf2b65db77e7c5a859c896acca69f432
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 16:11:10 2024 +0100
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 at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 7f1e89488a7212832819380a93fe137a6fa28c37
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 3 14:14:06 2022 +0100
s4:kdc: also provide cross-realm keys via samba_kdc_seq()
This means that 'samba-tool domain exportkeytab' is able to
export them.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 37292f8a60f8fa82faa7bde4314919dcae6fb7ab
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 19:23:46 2024 +0100
s4:kdc: let samba_kdc_trust_message2entry() return all keys with SDB_F_ADMIN_DATA
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 6ecc607edeeeb1877b5ecf02ba60d6c8799f583a
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 19:19:20 2024 +0100
s4:kdc: split out samba_kdc_fill_trust_keys() helper
This simplifies the logic in samba_kdc_trust_message2entry(),
is very similar to our samba_kdc_fill_user_keys() helper
and will make it trivial to provide the previous keys
in entry->old_keys in the next commit.
Review with: git show -p --patience
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit f5c8c212dcba48167d8ae8c555a5c4750cb763fd
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 19:19:20 2024 +0100
s4:kdc: add available_enctypes to supported_session_etypes in samba_kdc_trust_message2entry()
This aligns the logic of samba_kdc_trust_message2entry() with
samba_kdc_message2entry_keys().
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit f48699641cf95f1e2d197e0f8ea1ed4ce2c4fb41
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 19:19:20 2024 +0100
s4:kdc: add a returned_kvno helper variable in samba_kdc_trust_message2entry()
This will simplifiy further changes.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit d1efc396de4855a90c7dfd3d935028a21d780272
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 19:19:20 2024 +0100
s4:kdc: let samba_kdc_trust_message2entry() ignore KRB5_PROG_ETYPE_NOSUPP
We already handle it in samba_kdc_fill_user_keys() mostly for DES keys,
but other encryption types might be from kerberos libraries in future.
And things like FIPS mode may also alter the runtime behaviour.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 8cfebc36edcf5a4ba259d11c6e319aba303ea8ff
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Mar 15 19:19:20 2024 +0100
s4:kdc: split out samba_kdc_fill_trust_keys() helper
Let samba_kdc_trust_message2entry() also fill in the salt used
by the key. This is not strictly needed, but it's better to
be consistent.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 83f03513fd5221cb3bf914bd996c86f0840f34dd
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 3 18:27:19 2022 +0100
s3:libnet: add a debug message to libnet_keytab_add_to_keytab_entries()
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 888a785f476c64cd34a67149f69bd20f9b7749d8
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 3 18:27:19 2022 +0100
s3:libnet: add support for trusted domains in libnet_dssync_keytab.c
It means that keytabs generated via 'net rpc vampire keytab' are
able to decrypt cross-realm tickets in wireshark.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 2b2cc544725368e1922c3c71541c2b478a47586b
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 3 14:48:03 2022 +0100
s3:libnet: split out store_or_fetch_attribute() from parse_user() in libnet_dssync_keytab.c
This way we can easily re-use the logic in the next commits...
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit feff15fc88b548f9b59aef1427dd1fb5d72ef2a1
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 3 14:48:03 2022 +0100
s3:libnet: split out parse_user() in libnet_dssync_keytab.c
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 52df4063871bb6b18e84e559a94fd05ebf33b012
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Feb 3 14:48:03 2022 +0100
s3:libnet: let parse_user() in libnet_dssync_keytab.c work without nt hash
It happens in setups with 'nt hash store = never'.
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
-----------------------------------------------------------------------
Summary of changes:
python/samba/netcmd/domain/keytab.py | 9 +-
python/samba/tests/dckeytab.py | 53 ++-
selftest/knownfail.d/export-keytab | 1 -
source3/libnet/libnet_dssync_keytab.c | 595 ++++++++++++++++++++++---
source3/libnet/libnet_keytab.c | 2 +
source4/auth/kerberos/srv_keytab.c | 3 +-
source4/kdc/db-glue.c | 556 +++++++++++++++++------
source4/libnet/libnet_export_keytab.c | 87 ++++
source4/libnet/libnet_export_keytab.h | 1 +
source4/libnet/py_net_dckeytab.c | 12 +-
testprogs/blackbox/test_kinit_export_keytab.sh | 22 +-
11 files changed, 1110 insertions(+), 231 deletions(-)
delete mode 100644 selftest/knownfail.d/export-keytab
Changeset truncated at 500 lines:
diff --git a/python/samba/netcmd/domain/keytab.py b/python/samba/netcmd/domain/keytab.py
index 0136a11436f..a6d5291ae1a 100644
--- a/python/samba/netcmd/domain/keytab.py
+++ b/python/samba/netcmd/domain/keytab.py
@@ -47,6 +47,9 @@ 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"),
+ Option("--only-current-keys",
+ help="This avoids exporting old and older keys (useful for keytabs used by kinit)",
+ action="store_true"),
]
takes_args = ["keytab"]
@@ -58,7 +61,8 @@ else:
versionopts=None,
hostopts=None,
principal=None,
- keep_stale_entries=None):
+ keep_stale_entries=None,
+ only_current_keys=None):
lp = sambaopts.get_loadparm()
net = Net(None, lp)
samdb = self.ldb_connect(hostopts, sambaopts, credopts)
@@ -66,6 +70,7 @@ else:
net.export_keytab(samdb=samdb,
keytab=keytab,
principal=principal,
- keep_stale_entries=keep_stale_entries)
+ keep_stale_entries=keep_stale_entries,
+ only_current_keys=only_current_keys)
except NTSTATUSError as error:
raise CommandError(f"Failed to export domain keys into keytab {keytab}: {error.args[1]}")
diff --git a/python/samba/tests/dckeytab.py b/python/samba/tests/dckeytab.py
index 31139c0360f..9424c8e50ff 100644
--- a/python/samba/tests/dckeytab.py
+++ b/python/samba/tests/dckeytab.py
@@ -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,13 +279,62 @@ 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
# history in 2nd export, 3 enctypes) were exported
self.assertGreaterEqual(len(keytab_as_set), 12)
+ def test_export_keytab_change3_update_only_current_keep(self):
+ new_principal=f"keytab_testuser@{self.creds.get_realm()}"
+ self.samdb.newuser("keytab_testuser", "4rfvBGT%")
+ self.addCleanup(self.samdb.deleteuser, "keytab_testuser")
+ net = Net(None, self.lp)
+ self.addCleanup(self.rm_files, self.ktfile)
+ net.export_keytab(keytab=self.ktfile, principal=new_principal)
+ self.assertTrue(os.path.exists(self.ktfile), 'keytab was not created')
+
+ # Parse the first entry in the keytab
+ with open(self.ktfile, 'rb') as bytes_kt:
+ keytab_orig_bytes = bytes_kt.read()
+
+ # By changing the password three times, we allow Samba to fill
+ # out current, old, older from supplementalCredentials and
+ # still have one password that must still be from the original
+ # keytab
+ self.samdb.setpassword(f"(userPrincipalName={new_principal})", "5rfvBGT%")
+ 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,
+ only_current_keys=True)
+
+ with open(self.ktfile, 'rb') as bytes_kt:
+ keytab_change_bytes = bytes_kt.read()
+
+ self.assertNotEqual(keytab_orig_bytes, keytab_change_bytes)
+
+ # self.keytab_as_set() will also check we got each entry
+ # exactly once
+ keytab_as_set = self.keytab_as_set(keytab_change_bytes)
+
+ # Look for the new principal, showing this was updated but the old kept
+ found = 0
+ for entry in keytab_as_set:
+ (principal, enctype, kvno, key) = entry
+ if principal == new_principal and enctype == credentials.ENCTYPE_AES128_CTS_HMAC_SHA1_96:
+ found += 1
+
+ # By default previous keys are not exported into the keytab.
+ self.assertEqual(found, 2)
+
+ # confirm at least 6 keys (1 change, 1 in orig export
+ # both with 3 enctypes) were exported
+ self.assertGreaterEqual(len(keytab_as_set), 6)
+
def test_export_keytab_change2_export2_update_keep(self):
new_principal=f"keytab_testuser@{self.creds.get_realm()}"
self.samdb.newuser("keytab_testuser", "4rfvBGT%")
diff --git a/selftest/knownfail.d/export-keytab b/selftest/knownfail.d/export-keytab
deleted file mode 100644
index 34c16072f5a..00000000000
--- a/selftest/knownfail.d/export-keytab
+++ /dev/null
@@ -1 +0,0 @@
-^samba.tests.dckeytab.samba.tests.dckeytab.DCKeytabTests.test_export_keytab_change3_update_keep
diff --git a/source3/libnet/libnet_dssync_keytab.c b/source3/libnet/libnet_dssync_keytab.c
index 41893b4f7fd..a4fc4e98b0c 100644
--- a/source3/libnet/libnet_dssync_keytab.c
+++ b/source3/libnet/libnet_dssync_keytab.c
@@ -23,6 +23,7 @@
#include "libnet/libnet_dssync.h"
#include "libnet/libnet_keytab.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
+#include "lib/crypto/md4.h"
#if defined(HAVE_ADS)
@@ -233,9 +234,76 @@ done:
return status;
}
-static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
- struct libnet_keytab_context *ctx,
- struct drsuapi_DsReplicaObjectListItemEx *cur)
+static NTSTATUS store_or_fetch_attribute(TALLOC_CTX *mem_ctx,
+ struct libnet_keytab_context *ctx,
+ const char *object_dn,
+ const char *attr,
+ char **value)
+{
+ DATA_BLOB blob = { .length = 0, };
+ NTSTATUS status;
+
+ if (*value == NULL) {
+ /* look into keytab ... */
+ struct libnet_keytab_entry *entry = NULL;
+ char *principal = NULL;
+
+ D_DEBUG("looking for %s/%s@%s in keytayb...\n",
+ attr, object_dn, ctx->dns_domain_name);
+
+ principal = talloc_asprintf(mem_ctx,
+ "%s/%s@%s",
+ attr,
+ object_dn,
+ ctx->dns_domain_name);
+ if (principal == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ entry = libnet_keytab_search(ctx,
+ principal,
+ 0,
+ ENCTYPE_NULL,
+ mem_ctx);
+ if (entry != NULL) {
+ *value = talloc_strndup(mem_ctx,
+ (char *)entry->password.data,
+ entry->password.length);
+ if (*value == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ D_DEBUG("found %s: %s\n", attr, *value);
+ TALLOC_FREE(entry);
+ } else {
+ *value = NULL;
+ D_DEBUG("entry not found\n");
+ }
+ TALLOC_FREE(principal);
+ return NT_STATUS_OK;
+ }
+
+ blob = data_blob_string_const_null(*value);
+ blob = data_blob_dup_talloc(mem_ctx, blob);
+ if (blob.data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx,
+ ctx,
+ 0,
+ object_dn,
+ attr,
+ ENCTYPE_NULL,
+ blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static NTSTATUS parse_user(TALLOC_CTX *mem_ctx,
+ struct libnet_keytab_context *ctx,
+ struct drsuapi_DsReplicaObjectListItemEx *cur)
{
NTSTATUS status = NT_STATUS_OK;
uchar nt_passwd[16];
@@ -266,7 +334,7 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
- DEBUG(3, ("parsing object '%s'\n", object_dn));
+ DEBUG(3, ("parsing user '%s'\n", object_dn));
for (i=0; i < cur->object.attribute_ctr.num_attributes; i++) {
@@ -278,6 +346,9 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
spn = talloc_array(mem_ctx, char *, num_spns);
for (count = 0; count < num_spns; count++) {
blob = attr->value_ctr.values[count].blob;
+ if (blob == NULL) {
+ continue;
+ }
pull_string_talloc(spn, NULL, 0,
&spn[count],
blob->data, blob->length,
@@ -285,6 +356,18 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
}
}
+ if (attr->attid == DRSUAPI_ATTID_unicodePwd &&
+ cur->meta_data_ctr != NULL &&
+ cur->meta_data_ctr->count ==
+ cur->object.attribute_ctr.num_attributes)
+ {
+ /*
+ * pick the kvno from the unicodePwd
+ * meta data, even without a unicodePwd blob
+ */
+ kvno = cur->meta_data_ctr->meta_data[i].version;
+ }
+
if (attr->value_ctr.num_values != 1) {
continue;
}
@@ -304,18 +387,6 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
memcpy(&nt_passwd, blob->data, 16);
got_pwd = true;
-
- /* pick the kvno from the meta_data version,
- * thanks, metze, for explaining this */
-
- if (!cur->meta_data_ctr) {
- break;
- }
- if (cur->meta_data_ctr->count !=
- cur->object.attribute_ctr.num_attributes) {
- break;
- }
- kvno = cur->meta_data_ctr->meta_data[i].version;
break;
case DRSUAPI_ATTID_ntPwdHistory:
pwd_history_len = blob->length / 16;
@@ -353,53 +424,16 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
}
}
- if (!got_pwd) {
- DEBUG(10, ("no password (unicodePwd) found - skipping.\n"));
- return NT_STATUS_OK;
- }
-
- if (name) {
- status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, 0, object_dn,
- "SAMACCOUNTNAME",
- ENCTYPE_NULL,
- data_blob_talloc(mem_ctx, name,
- strlen(name) + 1));
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- } else {
- /* look into keytab ... */
- struct libnet_keytab_entry *entry = NULL;
- char *principal = NULL;
-
- DEBUG(10, ("looking for SAMACCOUNTNAME/%s@%s in keytayb...\n",
- object_dn, ctx->dns_domain_name));
-
- principal = talloc_asprintf(mem_ctx, "%s/%s@%s",
- "SAMACCOUNTNAME",
- object_dn,
- ctx->dns_domain_name);
- if (!principal) {
- DEBUG(1, ("talloc failed\n"));
- return NT_STATUS_NO_MEMORY;
- }
- entry = libnet_keytab_search(ctx, principal, 0, ENCTYPE_NULL,
- mem_ctx);
- if (entry) {
- name = (char *)talloc_memdup(mem_ctx,
- entry->password.data,
- entry->password.length);
- if (!name) {
- DEBUG(1, ("talloc failed!\n"));
- return NT_STATUS_NO_MEMORY;
- } else {
- DEBUG(10, ("found name %s\n", name));
- }
- TALLOC_FREE(entry);
- } else {
- DEBUG(10, ("entry not found\n"));
- }
- TALLOC_FREE(principal);
+ status = store_or_fetch_attribute(mem_ctx,
+ ctx,
+ object_dn,
+ "SAMACCOUNTNAME",
+ &name);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("store_or_fetch_attribute(%s, %s, %s): %s\n",
+ object_dn, "SAMACCOUNTNAME", name,
+ nt_errstr(status));
+ return status;
}
if (!name) {
@@ -422,12 +456,14 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
}
DEBUGADD(1,("\n"));
- status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
- ENCTYPE_ARCFOUR_HMAC,
- data_blob_talloc(mem_ctx, nt_passwd, 16));
+ if (got_pwd) {
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx, kvno, name, NULL,
+ ENCTYPE_ARCFOUR_HMAC,
+ data_blob_talloc(mem_ctx, nt_passwd, 16));
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
}
/* add kerberos keys (if any) */
@@ -528,6 +564,429 @@ static NTSTATUS parse_object(TALLOC_CTX *mem_ctx,
return status;
}
+static NTSTATUS parse_AuthenticationInformation(TALLOC_CTX *mem_ctx,
+ struct libnet_keytab_context *ctx,
+ const char *dn,
+ const char *trust_name,
+ const char *attr_name,
+ const char *salt_principal,
+ const char *type,
+ uint32_t *kvno,
+ const struct AuthenticationInformationArray *ia)
+{
+ uint32_t i;
+ struct samr_Password _nthash = {{ 0, }};
+ const struct samr_Password *nthash = NULL;
+ const struct AuthInfoClear *clear = NULL;
+ DATA_BLOB password_utf8 = data_blob_null;
+
+ for (i = 0; i < ia->count; i++) {
+ const struct AuthenticationInformation *a = &ia->array[i];
+
+ switch (a->AuthType) {
+ case TRUST_AUTH_TYPE_VERSION:
+ *kvno = a->AuthInfo.version.version;
+ break;
+ case TRUST_AUTH_TYPE_NT4OWF:
+ nthash = &a->AuthInfo.nt4owf.password;
+ break;
+ case TRUST_AUTH_TYPE_CLEAR:
+ clear = &a->AuthInfo.clear;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (clear != NULL && clear->size != 0) {
+ DATA_BLOB password_utf16 = data_blob_null;
+ bool ok;
+
+ password_utf16 = data_blob_const(clear->password,
+ clear->size);
+
+ if (nthash == NULL) {
+ mdfour(_nthash.hash,
+ password_utf16.data,
+ password_utf16.length);
+ nthash = &_nthash;
+ }
+
+ ok = convert_string_talloc(mem_ctx,
+ CH_UTF16MUNGED, CH_UTF8,
+ password_utf16.data,
+ password_utf16.length,
+ (void *)&password_utf8.data,
+ &password_utf8.length);
+ if (!ok) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ if (password_utf8.length != 0) {
+ krb5_principal salt_princ = NULL;
+ krb5_data salt = { 0, };
+ krb5_data cleartext_data = { 0, };
+ krb5_enctype enctypes[] = {
+ ENCTYPE_AES256_CTS_HMAC_SHA1_96,
+ ENCTYPE_AES128_CTS_HMAC_SHA1_96,
+ };
+ size_t ei;
+ krb5_error_code kret;
+ NTSTATUS status;
+
+ kret = smb_krb5_parse_name(ctx->context,
+ salt_principal,
+ &salt_princ);
+ if (kret != 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ cleartext_data.data = discard_const_p(char, password_utf8.data);
+ cleartext_data.length = password_utf8.length;
+
+ kret = smb_krb5_get_pw_salt(ctx->context,
+ salt_princ,
+ &salt);
+ if (kret != 0) {
+ krb5_free_principal(ctx->context, salt_princ);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (ei = 0; ei < ARRAY_SIZE(enctypes); ei++) {
+ krb5_keyblock keyb = { 0, };
+ DATA_BLOB blob = data_blob_null;
+
+ kret = smb_krb5_create_key_from_string(ctx->context,
+ salt_princ,
+ &salt,
+ &cleartext_data,
+ enctypes[ei],
+ &keyb);
+ if (kret != 0) {
+ smb_krb5_free_data_contents(ctx->context, &salt);
+ krb5_free_principal(ctx->context, salt_princ);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ blob = data_blob_talloc(mem_ctx,
+ KRB5_KEY_DATA(&keyb),
+ KRB5_KEY_LENGTH(&keyb));
+ krb5_free_keyblock_contents(ctx->context, &keyb);
+
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx,
+ ctx,
+ *kvno,
+ trust_name,
+ attr_name,
+ enctypes[ei],
+ blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ smb_krb5_free_data_contents(ctx->context, &salt);
+ krb5_free_principal(ctx->context, salt_princ);
+ return status;
+ }
+ }
+
+ smb_krb5_free_data_contents(ctx->context, &salt);
+ krb5_free_principal(ctx->context, salt_princ);
+ }
+
+ if (nthash != NULL) {
+ DATA_BLOB blob = data_blob_null;
+ NTSTATUS status;
+
+ blob = data_blob_talloc(mem_ctx, nthash->hash, sizeof(nthash->hash));
+
+ status = libnet_keytab_add_to_keytab_entries(mem_ctx, ctx,
+ *kvno,
+ trust_name,
+ attr_name,
+ ENCTYPE_ARCFOUR_HMAC,
+ blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ }
+
+ return NT_STATUS_OK;
--
Samba Shared Repository
More information about the samba-cvs
mailing list