86baa9
From 4be3de451c8b2a6314c29df43e5ade17f39d8777 Mon Sep 17 00:00:00 2001
86baa9
From: Alexander Bokovoy <abokovoy@redhat.com>
86baa9
Date: Fri, 22 Mar 2019 18:56:52 +0200
86baa9
Subject: [PATCH] trusts: add support for one-way shared secret trust
86baa9
86baa9
Refactor ipa-sam code to generate principals with additional POSIX
86baa9
information so that FreeIPA is capable to establish trust when using a
86baa9
shared secret from Active Directory domain controller side.
86baa9
86baa9
Trust verification process from Samba AD DC or Microsoft Windows AD DC
86baa9
side requires us to have a working local TDO object with POSIX
86baa9
attributes so that smbd would be able to map incoming authenticated
86baa9
Kerberos principal for the TDO to a local POSIX account.
86baa9
86baa9
Note that FreeIPA stores TDO objects in a subtree of cn=trusts,$SUFFIX
86baa9
and thus SSSD is not able to see these POSIX accounts unless
86baa9
specifically instructed to do so via multiple search bases. The support
86baa9
for automatically enabling cn=trusts,$SUFFIX search base in IPA server
86baa9
mode was added to SSSD 1.16.3 and 2.1.0 with the commit
86baa9
https://pagure.io/SSSD/sssd/c/14faec9cd9437ef116ae054412d25ec2e820e409
86baa9
86baa9
Fixes: https://pagure.io/freeipa/issue/6077
86baa9
(cherry picked from commit f30f7e380ef9d327ced3e1b0e5c800a8b1069097)
86baa9
86baa9
Reviewed-By: Christian Heimes <cheimes@redhat.com>
86baa9
---
86baa9
 daemons/ipa-sam/ipa_sam.c | 232 +++++++++++++++++++++++++++++---------
86baa9
 1 file changed, 179 insertions(+), 53 deletions(-)
86baa9
86baa9
diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c
86baa9
index 675a511f0febf13cc5e00b547c18a050ac534f2e..3cf878c3f99774f7715f776c31d70e2950f9451c 100644
86baa9
--- a/daemons/ipa-sam/ipa_sam.c
86baa9
+++ b/daemons/ipa-sam/ipa_sam.c
86baa9
@@ -140,6 +140,7 @@ bool E_md4hash(const char *passwd, uint8_t p16[16]); /* available in libcliauth-
86baa9
 #define LDAP_ATTRIBUTE_OBJECTCLASS "objectClass"
86baa9
 #define LDAP_ATTRIBUTE_HOME_DRIVE "ipaNTHomeDirectoryDrive"
86baa9
 #define LDAP_ATTRIBUTE_HOME_PATH "ipaNTHomeDirectory"
86baa9
+#define LDAP_ATTRIBUTE_HOMEDIRECTORY "homeDirectory"
86baa9
 #define LDAP_ATTRIBUTE_LOGON_SCRIPT "ipaNTLogonScript"
86baa9
 #define LDAP_ATTRIBUTE_PROFILE_PATH "ipaNTProfilePath"
86baa9
 #define LDAP_ATTRIBUTE_SID_BLACKLIST_INCOMING "ipaNTSIDBlacklistIncoming"
86baa9
@@ -1797,9 +1798,10 @@ done:
86baa9
 #define KRB_PRINC_CREATE_DISABLED           0x00000001
86baa9
 #define KRB_PRINC_CREATE_AGENT_PERMISSION   0x00000002
86baa9
 
86baa9
+
86baa9
 static bool set_krb_princ(struct ipasam_private *ipasam_state,
86baa9
 			  TALLOC_CTX *mem_ctx,
86baa9
-			  const char *princ, const char *saltprinc,
86baa9
+			  const char *princ, const char *alias,
86baa9
 			  const char *pwd,
86baa9
 			  const char *base_dn,
86baa9
 			  uint32_t   create_flags)
86baa9
@@ -1857,14 +1859,15 @@ static bool set_krb_princ(struct ipasam_private *ipasam_state,
86baa9
 			 LDAP_ATTRIBUTE_KRB_CANONICAL, princ);
86baa9
 	smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
 			 LDAP_ATTRIBUTE_KRB_PRINCIPAL, princ);
86baa9
-        if (saltprinc) {
86baa9
-	    smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
-			    LDAP_ATTRIBUTE_KRB_PRINCIPAL, saltprinc);
86baa9
-        }
86baa9
+	if (alias) {
86baa9
+		smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
+				LDAP_ATTRIBUTE_KRB_PRINCIPAL, alias);
86baa9
+	}
86baa9
 
86baa9
 	if ((create_flags & KRB_PRINC_CREATE_DISABLED)) {
86baa9
-		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
-				LDAP_ATTRIBUTE_KRB_TICKET_FLAGS, __TALLOC_STRING_LINE2__(IPASAM_DISALLOW_ALL_TIX));
86baa9
+		smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
+				LDAP_ATTRIBUTE_KRB_TICKET_FLAGS,
86baa9
+				__TALLOC_STRING_LINE2__(IPASAM_DISALLOW_ALL_TIX));
86baa9
 	}
86baa9
 
86baa9
 	if ((create_flags & KRB_PRINC_CREATE_AGENT_PERMISSION)) {
86baa9
@@ -1877,18 +1880,19 @@ static bool set_krb_princ(struct ipasam_private *ipasam_state,
86baa9
 		smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
 				LDAP_ATTRIBUTE_OBJECTCLASS,
86baa9
 				LDAP_OBJ_IPAOPALLOW);
86baa9
-		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
-				LDAP_ATTRIBUTE_IPAOPALLOW, agent_dn);
86baa9
+		smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
+				LDAP_ATTRIBUTE_IPAOPALLOW,
86baa9
+				agent_dn);
86baa9
 		agent_dn = talloc_asprintf(mem_ctx, LDAP_CN_ADTRUST_ADMINS",%s", ipasam_state->base_dn);
86baa9
 		if (agent_dn == NULL) {
86baa9
 			DEBUG(1, ("error configuring cross realm principal data for trust admins!\n"));
86baa9
 			return false;
86baa9
 		}
86baa9
-		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
-				LDAP_ATTRIBUTE_IPAOPALLOW, agent_dn);
86baa9
+		smbldap_set_mod(&mods, LDAP_MOD_ADD,
86baa9
+				LDAP_ATTRIBUTE_IPAOPALLOW,
86baa9
+				agent_dn);
86baa9
 	}
86baa9
 
86baa9
-
86baa9
 	if (entry == NULL) {
86baa9
 		ret = smbldap_add(ipasam_state->ldap_state, dn, mods);
86baa9
 	} else {
86baa9
@@ -1899,7 +1903,7 @@ static bool set_krb_princ(struct ipasam_private *ipasam_state,
86baa9
 		return false;
86baa9
 	}
86baa9
 
86baa9
-	ret = set_cross_realm_pw(ipasam_state, saltprinc ? saltprinc : princ, pwd);
86baa9
+	ret = set_cross_realm_pw(ipasam_state, princ, pwd);
86baa9
 	if (ret != 0) {
86baa9
 		DEBUG(1, ("set_cross_realm_pw failed.\n"));
86baa9
 		return false;
86baa9
@@ -1941,18 +1945,21 @@ enum princ_mod {
86baa9
 };
86baa9
 
86baa9
 static bool handle_cross_realm_princs(struct ipasam_private *ipasam_state,
86baa9
-				      const char *domain, const char *pwd,
86baa9
+				      const char *domain, const char *flat_name,
86baa9
+				      const char *pwd_incoming,
86baa9
+				      const char *pwd_outgoing,
86baa9
 				      uint32_t trust_direction,
86baa9
 				      enum princ_mod mod)
86baa9
 {
86baa9
 	char *trusted_dn;
86baa9
 	char *princ_l;
86baa9
 	char *princ_r;
86baa9
-	char *princ_tdo;
86baa9
-	char *saltprinc_tdo;
86baa9
+	char *princ_r_tdo, *princ_l_tdo;
86baa9
 	char *remote_realm;
86baa9
 	bool ok;
86baa9
+        int failed = 0;
86baa9
 	TALLOC_CTX *tmp_ctx;
86baa9
+	const char *r_tdo_alias, *l_tdo_alias;
86baa9
 
86baa9
 	tmp_ctx = talloc_new(NULL);
86baa9
 	if (tmp_ctx == NULL) {
86baa9
@@ -1967,46 +1974,111 @@ static bool handle_cross_realm_princs(struct ipasam_private *ipasam_state,
86baa9
 
86baa9
 	trusted_dn = trusted_domain_dn(tmp_ctx, ipasam_state, domain);
86baa9
 
86baa9
-	princ_l = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s", remote_realm,
86baa9
-			ipasam_state->realm);
86baa9
-	princ_r = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
86baa9
-			ipasam_state->realm, remote_realm);
86baa9
+	princ_l = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
86baa9
+				  remote_realm, ipasam_state->realm);
86baa9
+	princ_l_tdo = talloc_asprintf(tmp_ctx, "%s$@%s",
86baa9
+				      flat_name, ipasam_state->realm);
86baa9
+	l_tdo_alias = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
86baa9
+				      flat_name, ipasam_state->realm);
86baa9
 
86baa9
-	princ_tdo = talloc_asprintf(tmp_ctx, "%s$@%s",
86baa9
-			ipasam_state->flat_name, remote_realm);
86baa9
+	princ_r = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
86baa9
+				  ipasam_state->realm, remote_realm);
86baa9
+	princ_r_tdo = talloc_asprintf(tmp_ctx, "%s$@%s",
86baa9
+				      ipasam_state->flat_name, remote_realm);
86baa9
 
86baa9
-	saltprinc_tdo = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
86baa9
+	r_tdo_alias = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
86baa9
 			ipasam_state->flat_name, remote_realm);
86baa9
 
86baa9
-	if (trusted_dn == NULL || princ_l == NULL ||
86baa9
-	    princ_r == NULL || princ_tdo == NULL || saltprinc_tdo == NULL) {
86baa9
+	if (trusted_dn == NULL || princ_l == NULL || princ_l_tdo == NULL ||
86baa9
+		l_tdo_alias == NULL || princ_r == NULL || princ_r_tdo == NULL ||
86baa9
+		r_tdo_alias == NULL) {
86baa9
 		ok = false;
86baa9
 		goto done;
86baa9
 	}
86baa9
 
86baa9
 	switch (mod) {
86baa9
 		case SET_PRINC:
86baa9
-			/* Create Kerberos principal for inbound trust, enabled by default */
86baa9
-			ok   = set_krb_princ(ipasam_state, tmp_ctx, princ_r, NULL, pwd, trusted_dn, KRB_PRINC_CREATE_DEFAULT);
86baa9
-			/* Create Kerberos principal corresponding to TDO in AD for SSSD usage, disabled by default */
86baa9
-			ok |= set_krb_princ(ipasam_state, tmp_ctx, princ_tdo, saltprinc_tdo, pwd, trusted_dn,
86baa9
-					    KRB_PRINC_CREATE_DISABLED | KRB_PRINC_CREATE_AGENT_PERMISSION);
86baa9
-			if ((trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) != 0) {
86baa9
-				/* Create Kerberos principal for outbound trust, enabled by default */
86baa9
-				ok |= set_krb_princ(ipasam_state, tmp_ctx, princ_l, NULL, pwd, trusted_dn, KRB_PRINC_CREATE_DEFAULT);
86baa9
+			/* We must use two sets by two principals here because
86baa9
+			 * they are used for different needs and must have
86baa9
+			 * different salts */
86baa9
+
86baa9
+			failed = 0;
86baa9
+			/* INBOUND TRUST */
86baa9
+			if ((trust_direction & LSA_TRUST_DIRECTION_INBOUND) != 0) {
86baa9
+				/* First: krbtgt/<OUR REALM>@<REMOTE REALM>, enabled by default
86baa9
+				 * in case of the inboud trust */
86baa9
+				failed += !set_krb_princ(ipasam_state, tmp_ctx, princ_r, NULL,
86baa9
+							 pwd_outgoing, trusted_dn,
86baa9
+							 KRB_PRINC_CREATE_DEFAULT);
86baa9
+
86baa9
+				/* Second: <OUR FLATNAME$>@<REMOTE REALM> is only used
86baa9
+				 * for SSSD to be able to talk to AD DCs but it has to
86baa9
+				 * have canonical name set to <OUR FLATNAME>$ because
86baa9
+				 * this is the salt used by AD DCs when using this
86baa9
+				 * principal, otherwise authentication will fail.
86baa9
+				 *
86baa9
+				 * *disable* use of this principal on our side as it is
86baa9
+				 * only used to retrieve trusted domain credentials by
86baa9
+				 * AD Trust Agents across the IPA topology */
86baa9
+				failed += !set_krb_princ(ipasam_state, tmp_ctx,
86baa9
+							 r_tdo_alias, princ_r_tdo,
86baa9
+							 pwd_incoming, trusted_dn,
86baa9
+							 (KRB_PRINC_CREATE_DISABLED |
86baa9
+							  KRB_PRINC_CREATE_AGENT_PERMISSION));
86baa9
+
86baa9
+	                        ok = (failed == 0);
86baa9
+				if (!ok) {
86baa9
+					goto done;
86baa9
+				}
86baa9
 			}
86baa9
-			if (!ok) {
86baa9
-				goto done;
86baa9
+
86baa9
+			failed = 0;
86baa9
+			/* OUTBOUND TRUST */
86baa9
+			if ((trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) != 0) {
86baa9
+				/* First: krbtgt/<REMOTE REALM>@<OUR REALM>, enabled by default */
86baa9
+				failed += !set_krb_princ(ipasam_state, tmp_ctx,
86baa9
+							 princ_l, NULL,
86baa9
+							 pwd_outgoing, trusted_dn,
86baa9
+							 KRB_PRINC_CREATE_DEFAULT);
86baa9
+
86baa9
+				/* Second: <REMOTE FLAT NAME>$@<OUR REALM>, enabled by default
86baa9
+				 * as it is used for a remote DC to authenticate against IPA Samba
86baa9
+				 *
86baa9
+				 * A local account for the outbound trust must have
86baa9
+				 * POSIX and SMB identities associated with our domain but we associate
86baa9
+				 * them with the trust domain object itself */
86baa9
+				failed += !set_krb_princ(ipasam_state, tmp_ctx,
86baa9
+							 princ_l_tdo, l_tdo_alias,
86baa9
+							 pwd_incoming, trusted_dn,
86baa9
+							 KRB_PRINC_CREATE_DEFAULT);
86baa9
+
86baa9
+	                        ok = (failed == 0);
86baa9
+				if (!ok) {
86baa9
+					goto done;
86baa9
+				}
86baa9
 			}
86baa9
 			break;
86baa9
 		case DEL_PRINC:
86baa9
-			ok  = del_krb_princ(ipasam_state, tmp_ctx, princ_r, trusted_dn);
86baa9
-			ok |= del_krb_princ(ipasam_state, tmp_ctx, princ_tdo, trusted_dn);
86baa9
-			if ((trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) != 0) {
86baa9
-				ok |= del_krb_princ(ipasam_state, tmp_ctx, princ_l, trusted_dn);
86baa9
+			failed = 0;
86baa9
+			if ((trust_direction & LSA_TRUST_DIRECTION_INBOUND) != 0) {
86baa9
+				failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_r, trusted_dn);
86baa9
+				failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_r_tdo, trusted_dn);
86baa9
+
86baa9
+	                        ok = (failed == 0);
86baa9
+				if (!ok) {
86baa9
+					goto done;
86baa9
+				}
86baa9
 			}
86baa9
-			if (!ok) {
86baa9
-				goto done;
86baa9
+
86baa9
+			failed = 0;
86baa9
+			if ((trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) != 0) {
86baa9
+				failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_l, trusted_dn);
86baa9
+				failed += !del_krb_princ(ipasam_state, tmp_ctx, princ_l_tdo, trusted_dn);
86baa9
+
86baa9
+	                        ok = (failed == 0);
86baa9
+				if (!ok) {
86baa9
+					goto done;
86baa9
+				}
86baa9
 			}
86baa9
 			break;
86baa9
 		default:
86baa9
@@ -2022,16 +2094,22 @@ done:
86baa9
 }
86baa9
 
86baa9
 static bool set_cross_realm_princs(struct ipasam_private *ipasam_state,
86baa9
-				   const char *domain, const char *pwd, uint32_t trust_direction)
86baa9
+				   const char *domain, const char* flat_name,
86baa9
+				   const char *pwd_incoming, const char *pwd_outgoing,
86baa9
+				   uint32_t trust_direction)
86baa9
 {
86baa9
-	return handle_cross_realm_princs(ipasam_state, domain, pwd, trust_direction, SET_PRINC);
86baa9
+	return handle_cross_realm_princs(ipasam_state, domain, flat_name,
86baa9
+					 pwd_incoming,
86baa9
+					 pwd_outgoing,
86baa9
+					 trust_direction, SET_PRINC);
86baa9
 }
86baa9
 
86baa9
 static bool del_cross_realm_princs(struct ipasam_private *ipasam_state,
86baa9
-				   const char *domain)
86baa9
+				   const char *domain, const char *flat_name)
86baa9
 {
86baa9
 	uint32_t trust_direction = LSA_TRUST_DIRECTION_INBOUND | LSA_TRUST_DIRECTION_OUTBOUND;
86baa9
-	return handle_cross_realm_princs(ipasam_state, domain, NULL, trust_direction, DEL_PRINC);
86baa9
+	return handle_cross_realm_princs(ipasam_state, domain, flat_name,
86baa9
+					 NULL, NULL, trust_direction, DEL_PRINC);
86baa9
 }
86baa9
 
86baa9
 static bool get_trusted_domain_int(struct ipasam_private *ipasam_state,
86baa9
@@ -2439,8 +2517,8 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
86baa9
 	int ret, i, count;
86baa9
 	NTSTATUS status;
86baa9
 	TALLOC_CTX *tmp_ctx;
86baa9
-	char *trustpw;
86baa9
-	char *sid;
86baa9
+	char *trustpw_incoming, *trustpw_outgoing;
86baa9
+	char *sid, *tda_name;
86baa9
 	char **in_blacklist = NULL;
86baa9
 	char **out_blacklist = NULL;
86baa9
 	uint32_t enctypes, trust_offset;
86baa9
@@ -2465,6 +2543,8 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
86baa9
 				 LDAP_OBJ_TRUSTED_DOMAIN);
86baa9
 		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, "objectClass",
86baa9
 				 LDAP_OBJ_ID_OBJECT);
86baa9
+		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods, "objectClass",
86baa9
+				 LDAP_OBJ_POSIXACCOUNT);
86baa9
 	}
86baa9
 
86baa9
 	if (entry != NULL) {
86baa9
@@ -2477,12 +2557,23 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
86baa9
 		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
 		                 LDAP_ATTRIBUTE_GIDNUMBER,
86baa9
 				 ipasam_state->fallback_primary_group_gid_str);
86baa9
+		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
+		                 LDAP_ATTRIBUTE_HOMEDIRECTORY,
86baa9
+				 "/dev/null");
86baa9
 	}
86baa9
 
86baa9
 	if (td->netbios_name != NULL) {
86baa9
+		tda_name = talloc_asprintf(tmp_ctx, "%s$", td->netbios_name);
86baa9
+		if (!tda_name) {
86baa9
+			status = NT_STATUS_UNSUCCESSFUL;
86baa9
+			goto done;
86baa9
+		}
86baa9
 		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
 				 LDAP_ATTRIBUTE_FLAT_NAME,
86baa9
 				 td->netbios_name);
86baa9
+		smbldap_make_mod(priv2ld(ipasam_state), entry, &mods,
86baa9
+				 LDAP_ATTRIBUTE_UID,
86baa9
+				 tda_name);
86baa9
 	}
86baa9
 
86baa9
 	if (td->domain_name != NULL) {
86baa9
@@ -2618,13 +2709,38 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
86baa9
 
86baa9
 	if (entry == NULL) { /* FIXME: allow password updates here */
86baa9
 		status = get_trust_pwd(tmp_ctx, &td->trust_auth_incoming,
86baa9
-				       &trustpw, NULL);
86baa9
+				       &trustpw_incoming, NULL);
86baa9
 		if (!NT_STATUS_IS_OK(status)) {
86baa9
 			goto done;
86baa9
 		}
86baa9
-		res = set_cross_realm_princs(ipasam_state, td->domain_name,
86baa9
-					     trustpw, td->trust_direction);
86baa9
-		memset(trustpw, 0, strlen(trustpw));
86baa9
+		status = get_trust_pwd(tmp_ctx, &td->trust_auth_outgoing,
86baa9
+				       &trustpw_outgoing, NULL);
86baa9
+		if (!NT_STATUS_IS_OK(status)) {
86baa9
+			goto done;
86baa9
+		}
86baa9
+		res = set_cross_realm_princs(ipasam_state, td->domain_name, td->netbios_name,
86baa9
+					     trustpw_incoming, trustpw_outgoing,
86baa9
+					     td->trust_direction);
86baa9
+		{
86baa9
+			/* Replace memset() use by an explicit loop to avoid
86baa9
+			 * both compile time and link time optimisations.
86baa9
+			 * We could have used memset_s() from C++11 but it is
86baa9
+			 * currently not implemented by GCC or glibc.
86baa9
+			 */
86baa9
+			volatile char *p = (void *) trustpw_incoming;
86baa9
+			volatile char *q = (void *) trustpw_outgoing;
86baa9
+			size_t plen = strlen(trustpw_incoming);
86baa9
+			size_t qlen = strlen(trustpw_outgoing);
86baa9
+
86baa9
+			while (plen--) {
86baa9
+				*p++ = '\0';
86baa9
+			}
86baa9
+
86baa9
+			while (qlen--) {
86baa9
+				*q++ = '\0';
86baa9
+			}
86baa9
+		}
86baa9
+
86baa9
 		if (!res) {
86baa9
 			DEBUG(1, ("error writing cross realm principals!\n"));
86baa9
 			status = NT_STATUS_UNSUCCESSFUL;
86baa9
@@ -2693,7 +2809,7 @@ static NTSTATUS ipasam_del_trusted_domain(struct pdb_methods *methods,
86baa9
 		talloc_get_type_abort(methods->private_data, struct ipasam_private);
86baa9
 	LDAPMessage *entry = NULL;
86baa9
 	char *dn;
86baa9
-	const char *domain_name;
86baa9
+	const char *domain_name, *flat_name;
86baa9
 	TALLOC_CTX *tmp_ctx;
86baa9
 	NTSTATUS status;
86baa9
 
86baa9
@@ -2731,7 +2847,17 @@ static NTSTATUS ipasam_del_trusted_domain(struct pdb_methods *methods,
86baa9
 		goto done;
86baa9
 	}
86baa9
 
86baa9
-	if (!del_cross_realm_princs(ipasam_state, domain_name)) {
86baa9
+	flat_name = get_single_attribute(tmp_ctx, priv2ld(ipasam_state), entry,
86baa9
+					 LDAP_ATTRIBUTE_FLAT_NAME);
86baa9
+	if (flat_name == NULL) {
86baa9
+		DEBUG(1, ("Attribute %s not present.\n",
86baa9
+			  LDAP_ATTRIBUTE_FLAT_NAME));
86baa9
+		status = NT_STATUS_INVALID_PARAMETER;
86baa9
+		goto done;
86baa9
+	}
86baa9
+
86baa9
+
86baa9
+	if (!del_cross_realm_princs(ipasam_state, domain_name, flat_name)) {
86baa9
 		DEBUG(1, ("error deleting cross realm principals!\n"));
86baa9
 		status = NT_STATUS_UNSUCCESSFUL;
86baa9
 		goto done;
86baa9
-- 
86baa9
2.20.1
86baa9