summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2015-09-06 14:35:13 -0400
committerSimo Sorce <simo@redhat.com>2015-09-07 19:08:16 -0400
commit4165cc696d2110983e3afa02b1bfedf4713a515c (patch)
treec8c03e03dda41c47f6fedb204d780d81ac1c6185
parent8665d4c9122db296855d82d200dc8df811f57427 (diff)
downloadfreeipa-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.c55
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 */