From 2e8eb0f5fe82be58be88fa0d9b07ee7af69d8829 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 10 Nov 2020 09:37:19 +0200 Subject: [PATCH] ipasam: allow search of users by user principal name (UPN) lookup_name() in Samba may call PASSDB API to search by a UPN (e.g. username@suffix). Support this call by detecting '@' in the passed name and setting up filter to be (&(objectClass=ipaNTUserAttrs)(objectClass=krbPrincipalAux)(krbPrincipalName:caseIgnoreIA5Match:=%s)) instead of (&(objectClass=ipaNTUserAttrs)(uid=%s)) The result of the search would still contain a proper user entry as we always have krbPrincipalName in LDAP entries of IPA users. Note that the match must be case-insensitive because otherwise krbPrincipalName is matched with exact case in the schema. We use the same matching override in KDB driver already. Fixes: https://pagure.io/freeipa/issue/8661 Signed-of-by: Alexander Bokovoy Reviewed-By: Christian Heimes Reviewed-By: Rob Crittenden Reviewed-By: Christian Heimes Reviewed-By: Rob Crittenden --- daemons/ipa-sam/ipa_sam.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/daemons/ipa-sam/ipa_sam.c b/daemons/ipa-sam/ipa_sam.c index 3ec9f8a13..46c28f6c7 100644 --- a/daemons/ipa-sam/ipa_sam.c +++ b/daemons/ipa-sam/ipa_sam.c @@ -3855,6 +3855,7 @@ static NTSTATUS ipasam_getsampwnam(struct pdb_methods *methods, LDAPMessage *entry = NULL; int ret; int count; + bool search_for_upn = false; lastidx = strlen(sname); if (lastidx > 0) { @@ -3877,16 +3878,36 @@ static NTSTATUS ipasam_getsampwnam(struct pdb_methods *methods, return NT_STATUS_NO_MEMORY; } + if (strchr(sname, '@') != NULL) { + search_for_upn = true; + } + escaped_user = escape_ldap_string(tmp_ctx, sname); if (escaped_user == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } - filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", - LDAP_ATTRIBUTE_OBJECTCLASS, - LDAP_OBJ_SAMBASAMACCOUNT, - LDAP_ATTRIBUTE_UID, escaped_user); + + if (search_for_upn) { + /* Search krbPrincipalName case-insensitive for UPN suffixes to + * match because default matching rule is case-sensitive for + * IA5String */ + filter = talloc_asprintf(tmp_ctx, + "(&(%s=%s)(%s=%s)(%s:caseIgnoreIA5Match:=%s))", + LDAP_ATTRIBUTE_OBJECTCLASS, + LDAP_OBJ_SAMBASAMACCOUNT, + LDAP_ATTRIBUTE_OBJECTCLASS, + LDAP_OBJ_KRB_PRINCIPAL_AUX, + LDAP_ATTRIBUTE_KRB_PRINCIPAL, + escaped_user); + } else { + filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", + LDAP_ATTRIBUTE_OBJECTCLASS, + LDAP_OBJ_SAMBASAMACCOUNT, + LDAP_ATTRIBUTE_UID, escaped_user); + } + if (filter == NULL) { status = NT_STATUS_NO_MEMORY; goto done;