diff options
author | Simo Sorce <simo@redhat.com> | 2015-09-06 14:35:13 -0400 |
---|---|---|
committer | Simo Sorce <simo@redhat.com> | 2015-09-07 19:08:16 -0400 |
commit | 4165cc696d2110983e3afa02b1bfedf4713a515c (patch) | |
tree | c8c03e03dda41c47f6fedb204d780d81ac1c6185 | |
parent | 8665d4c9122db296855d82d200dc8df811f57427 (diff) | |
download | freeipa-AD-binds.tar.gz freeipa-AD-binds.tar.xz freeipa-AD-binds.zip |
Support AD-style LDAP BindsAD-binds
In Active Directory it is allowed to bind to LDAP providing the bare
username instead of a full user DN.
Add support for it exclusively for regular IPA users.
Signed-off-by: Simo Sorce <simo@redhat.com>
-rw-r--r-- | daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c index f830e3bfe..796754f16 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/prepost.c @@ -1373,6 +1373,53 @@ done: } +/* Try to authenticate users when the "DN" provided is just the user name. + * Although this violate LDAP standards it is supported by AD and a few + * appliances do try to use this method to authenticate users as it saves + * the need to have extra credentials to search the LDAP tree to find the + * right DN. + * Treats target_dn as a plain username */ +static int ipapwd_ad_compat_bind(Slapi_PBlock *pb, + char *target_dn, + const char **attrs_list, + char **dn, Slapi_Entry **entry) +{ + Slapi_DN *old_sdn = NULL; + Slapi_DN *sdn; + char *check_dn; + int ret = 0; + + check_dn = slapi_ch_smprintf("uid=%s,cn=users,cn=accounts,%s", + target_dn, ipa_realm_tree); + if (!check_dn) { + LOG_TRACE("Building AD-compat bind DN failed\n"); + return 1; + } + + ret = ipapwd_getEntry(check_dn, entry, (char **)attrs_list); + if (ret != LDAP_SUCCESS) { + LOG("failed to retrieve AD-compat user entry: %s\n", check_dn); + slapi_ch_free_string(&check_dn); + return 1; + } + + /* Found something! */ + sdn = slapi_sdn_dup(slapi_entry_get_sdn_const(*entry)); + if (!sdn) { + LOG("Failed to get SDN from entry (%s)\n", check_dn); + slapi_ch_free_string(&check_dn); + return 1; + } + + /* Replace sdn in pblock and return the user dn to caller */ + slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &old_sdn); + slapi_sdn_free(&old_sdn); + slapi_pblock_set(pb, SLAPI_BIND_TARGET_SDN, sdn); + slapi_pblock_get(pb, SLAPI_BIND_TARGET, dn); + return 0; +} + + /* PRE BIND Operation * * Used for: @@ -1417,7 +1464,13 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb) ret = ipapwd_getEntry(dn, &entry, (char **) attrs_list); if (ret) { LOG("failed to retrieve user entry: %s\n", dn); - return 0; + + /* Try AD-compat option */ + if (method == LDAP_AUTH_SIMPLE) { + ret = ipapwd_ad_compat_bind(pb, dn, attrs_list, &dn, &entry); + } + + if (ret) return 0; } /* Check if the principal is not expired */ |