[Freeipa-devel] [PATCHES][RFC] Implement special operation to revoer NT hash for a user

Alexander Bokovoy abokovoy at redhat.com
Fri Jul 27 04:15:46 UTC 2012


On Thu, 12 Jul 2012, Alexander Bokovoy wrote:
>On Thu, 12 Jul 2012, Simo Sorce wrote:
>>On Thu, 2012-07-12 at 10:48 +0300, Alexander Bokovoy wrote:
>>>On Wed, 11 Jul 2012, Simo Sorce wrote:
>>>>From 84ef09a1193ff42fc301fb71354055c5039f51a5 Mon Sep 17 00:00:00 2001
>>>>From: Simo Sorce <ssorce at redhat.com>
>>>>Date: Fri, 6 Jul 2012 16:18:29 -0400
>>>>Subject: [PATCH] Add special modify op to regen ipaNTHash
>>>>
>>>>The NT Hash is the same thing as the RC4-HMAC key, so we add a function to
>>>>extract it from krb5 keys if they are available to avoid forcing a password
>>>>change when configuring trust relationships.
>>>>---
>>>> .../ipa-pwd-extop/ipapwd_prepost.c                 |  147 +++++++++++++++++++-
>>>> 1 file changed, 144 insertions(+), 3 deletions(-)
>>>>
>>>>diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
>>>>index deae6477772f82edcc4674a1c9580661c3dae94b..24fa52eb9ac92004576ccdba4f576162c358770d 100644
>>>>--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
>>>>+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c
>>>>@@ -41,7 +41,12 @@
>>>> #  include <config.h>
>>>> #endif
>>>>
>>>>-#define _XOPEN_SOURCE /* strptime needs this */
>>>>+/* strptime needs _XOPEN_SOURCE and endian.h needs __USE_BSD
>>>>+ * _GNU_SOURCE imply both, and we use it elsewhere, so use this */
>>>>+#ifndef _GNU_SOURCE
>>>>+#define _GNU_SOURCE 1
>>>>+#endif
>>>>+
>>>> #include <stdio.h>
>>>> #include <string.h>
>>>> #include <strings.h>
>>>>@@ -53,6 +58,7 @@
>>>> #include <dirsrv/slapi-plugin.h>
>>>> #include <lber.h>
>>>> #include <time.h>
>>>>+#include <endian.h>
>>>>
>>>> #include "ipapwd.h"
>>>> #include "util.h"
>>>>@@ -379,6 +385,12 @@ done:
>>>>     return 0;
>>>> }
>>>>
>>>>+#define NTHASH_REGEN_VAL "MagicRegen"
>>>>+#define NTHASH_REGEN_LEN sizeof(NTHASH_REGEN_VAL)
>>>>+static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
>>>>+                               char *dn, struct slapi_entry *entry,
>>>>+                               struct ipapwd_krbcfg *krbcfg);
>>>>+
>>>> /* PRE MOD Operation:
>>>>  * Gets the clean text password (fail the operation if the password came
>>>>  * pre-hashed, unless this is a replicated operation).
>>>>@@ -407,6 +419,7 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
>>>>     int has_krb_keys = 0;
>>>>     int has_history = 0;
>>>>     int gen_krb_keys = 0;
>>>>+    int is_magic_regen = 0;
>>>>     int ret, rc;
>>>>
>>>>     LOG_TRACE( "=>\n");
>>>>@@ -447,6 +460,27 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
>>>>             default:
>>>>                 break;
>>>>             }
>>>>+        } else if (slapi_attr_types_equivalent(lmod->mod_type, "ipaNTHash")) {
>>>>+            /* check op filtering out LDAP_MOD_BVALUES */
>>>>+            switch (lmod->mod_op & 0x0f) {
>>>>+            case LDAP_MOD_REPLACE:
>>>This is still LDAP_MOD_REPLACE, not LDAP_MOD_ADD.
>>
>>This is because I resent the old patch :(
>>
>>Hopefully the correct patch is now attached.
>Yes, now it is updated, thanks.
>
>I'm going to experiment a bit with these patches, adding ipasam
>responder to test them.
Here is ipasam part.



-- 
/ Alexander Bokovoy
-------------- next part --------------
>From 0cd261dd74154efc9ef6b09ef283cc1fe3448d5e Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Thu, 26 Jul 2012 22:05:25 +0300
Subject: [PATCH 6/6] When ipaNTHash is missing, ask IPA to generate it from
 kerberos keys

---
 daemons/ipa-sam/ipa_sam.c |   96 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 93 insertions(+), 3 deletions(-)

diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
index ab4b116c5f2b3b8dae6e8309403afba5fdf86708..aa54429b5bec4b26906b2a34e59ff95299a67f80 100644
--- a/daemons/ipa-sam/ipa_sam.c
+++ b/daemons/ipa-sam/ipa_sam.c
@@ -2400,6 +2400,74 @@ static bool init_sam_from_td(struct samu *user, struct pdb_trusted_domain *td,
 	return true;
 }
 
+static bool ipasam_nthash_retrieve(struct ldapsam_privates *ldap_state,
+				       TALLOC_CTX *mem_ctx,
+				       char *entry_dn,
+				       DATA_BLOB *nthash)
+{
+	int ret;
+	bool retval;
+	LDAPMessage *result;
+	LDAPMessage *entry = NULL;
+	int count;
+	struct smbldap_state *smbldap_state = ldap_state->smbldap_state;
+	const char *attr_list[] = {
+					LDAP_ATTRIBUTE_NTHASH,
+					NULL
+				  };
+
+	ret = smbldap_search(smbldap_state, entry_dn,
+			     LDAP_SCOPE_BASE, "", attr_list, 0,
+			     &result);
+	if (ret != LDAP_SUCCESS) {
+		DEBUG(1, ("Failed to get NT hash: %s\n",
+			  ldap_err2string (ret)));
+		return false;
+	}
+
+	count = ldap_count_entries(smbldap_state->ldap_struct, result);
+
+	if (count != 1) {
+		DEBUG(1, ("Unexpected number of results [%d] for NT hash "
+			  "of the single entry search.\n", count));
+		ldap_msgfree(result);
+		return false;
+	}
+
+	entry = ldap_first_entry(smbldap_state->ldap_struct, result);
+	if (entry == NULL) {
+		DEBUG(0, ("Could not get entry\n"));
+		ldap_msgfree(result);
+		return false;
+	}
+
+	retval = smbldap_talloc_single_blob(mem_ctx,
+					smbldap_state->ldap_struct,
+					entry, LDAP_ATTRIBUTE_NTHASH,
+					nthash);
+	ldap_msgfree(result);
+	return retval;
+}
+
+static bool ipasam_nthash_regen(struct ldapsam_privates *ldap_state,
+				TALLOC_CTX *mem_ctx,
+				char * entry_dn)
+{
+	LDAPMod **mods;
+	int ret;
+
+	mods = NULL;
+	smbldap_make_mod(ldap_state->smbldap_state->ldap_struct,
+			 NULL, &mods, LDAP_ATTRIBUTE_NTHASH, "MagicRegen");
+
+	talloc_autofree_ldapmod(mem_ctx, mods);
+	ret = smbldap_add(ldap_state->smbldap_state, entry_dn, mods);
+	if (ret != LDAP_SUCCESS) {
+		DEBUG(5, ("ipasam: attempt to regen ipaNTHash failed\n"));
+	}
+	return (ret == LDAP_SUCCESS);
+}
+
 static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 				struct samu * sampass,
 				LDAPMessage * entry)
@@ -2414,6 +2482,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 	char *profile_path = NULL;
 	char *temp = NULL;
 	bool ret = false;
+	bool retval = false;
 	DATA_BLOB nthash;
 
 	TALLOC_CTX *tmp_ctx = talloc_init("init_sam_from_ldap");
@@ -2504,14 +2573,35 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state,
 
 	pdb_set_acct_ctrl(sampass, ACB_NORMAL, PDB_SET);
 
-	if (!smbldap_talloc_single_blob(tmp_ctx,
+	retval = smbldap_talloc_single_blob(tmp_ctx,
 					ldap_state->smbldap_state->ldap_struct,
 					entry, LDAP_ATTRIBUTE_NTHASH,
-					&nthash)) {
+					&nthash);
+	if (!retval) {
+		/* NT Hash is not in place. Attempt to retrieve it from
+		 * the RC4-HMAC key if that exists in Kerberos credentials.
+		 * IPA 389-ds plugin allows to ask for it by setting
+		 * ipaNTHash to MagicRegen value.
+		 * */
+		temp = smbldap_talloc_dn(tmp_ctx, ldap_state->smbldap_state->ldap_struct, entry);
+		if (temp) {
+			retval = ipasam_nthash_regen(tmp_ctx,
+						     ldap_state->smbldap_state->ldap_struct,
+						     temp);
+			if (retval) {
+				retval = ipasam_nthash_retrieve(tmp_ctx,
+							ldap_state->smbldap_state->ldap_struct,
+							temp, &nthash);
+			}
+		}
+	}
+
+	if (!retval) {
 		DEBUG(5, ("Failed to read NT hash form LDAP response.\n"));
 	}
+
 	if (nthash.length != NT_HASH_LEN && nthash.length != 0) {
-		DEBUG(5, ("NT hash from LDAP has the wrong size.\n"));
+		DEBUG(5, ("NT hash from LDAP has the wrong size. Perhaps password was not re-set?\n"));
 	} else {
 		if (!pdb_set_nt_passwd(sampass, nthash.data, PDB_SET)) {
 			DEBUG(5, ("Failed to set NT hash.\n"));
-- 
1.7.10.4



More information about the Freeipa-devel mailing list