From 3b03410a679d6a5ca5c0d080757498b75ef7ec10 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Sun, 29 Aug 2010 22:15:06 +0200
Subject: [PATCH 7/7] Deobfuscate password in back ends

When obfuscated password is used in config file, the LDAP backend
converts it back to clear text and uses it to authenticate to the
server.
---
 Makefile.am                                |    6 ++-
 src/man/sssd-ldap.5.xml                    |   11 +++++-
 src/providers/ldap/sdap_async_connection.c |   58 ++++++++++++++++++++++++---
 3 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 9bcbf7c..98175b8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -781,7 +781,8 @@ libsss_ldap_la_CFLAGS = \
 libsss_ldap_la_LIBADD = \
     $(OPENLDAP_LIBS) \
     $(DHASH_LIBS) \
-    $(KRB5_LIBS)
+    $(KRB5_LIBS) \
+    libsss_crypt.la
 libsss_ldap_la_LDFLAGS = \
     -version-info 1:0:0 \
     -module
@@ -869,7 +870,8 @@ libsss_ipa_la_LIBADD = \
     $(OPENLDAP_LIBS) \
     $(DHASH_LIBS) \
     $(KEYUTILS_LIBS) \
-    $(KRB5_LIBS)
+    $(KRB5_LIBS) \
+    libsss_crypt.la
 libsss_ipa_la_LDFLAGS = \
     -version-info 1:0:0 \
     -module
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 333ab31..aa73b58 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -120,7 +120,16 @@
                     <listitem>
                         <para>
                             The type of the authentication token of the
-                            default bind DN. The only currently supported value is "password".
+                            default bind DN.
+                        </para>
+                        <para>
+                            The two mechanisms currently supported are:
+                        </para>
+                        <para>
+                            password
+                        </para>
+                        <para>
+                            obfuscated_password
                         </para>
                     </listitem>
                 </varlistentry>
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 806bd5f..d640042 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -24,6 +24,7 @@
 #include "util/util.h"
 #include "util/sss_krb5.h"
 #include "providers/ldap/sdap_async_private.h"
+#include "util/crypto/sss_crypto.h"
 
 #define LDAP_X_SSSD_PASSWORD_EXPIRED 0x555D
 
@@ -750,6 +751,10 @@ struct sdap_auth_state {
 };
 
 static void sdap_auth_done(struct tevent_req *subreq);
+static int sdap_auth_get_authtok(TALLOC_CTX *memctx,
+                                 const char *authtok_type,
+                                 struct dp_opt_blob authtok,
+                                 struct berval *pw);
 
 /* TODO: handle sasl_cred */
 struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
@@ -763,18 +768,24 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
 {
     struct tevent_req *req, *subreq;
     struct sdap_auth_state *state;
-
-    if (authtok_type != NULL && strcasecmp(authtok_type,"password") != 0) {
-        DEBUG(1,("Authentication token type [%s] is not supported"));
-        return NULL;
-    }
+    int ret;
 
     req = tevent_req_create(memctx, &state, struct sdap_auth_state);
     if (!req) return NULL;
 
     state->user_dn = user_dn;
-    state->pw.bv_val = (char *)authtok.data;
-    state->pw.bv_len = authtok.length;
+
+    ret = sdap_auth_get_authtok(state, authtok_type, authtok, &state->pw);
+    if (ret != EOK) {
+        if (ret == ENOSYS) {
+            DEBUG(1, ("Getting authtok is not supported with the "
+                      "crypto backend used, authentication might fail!\n"));
+        } else {
+            DEBUG(1, ("Cannot parse authtok.\n"));
+            tevent_req_error(req, ret);
+            return tevent_req_post(req, ev);
+        }
+    }
 
     if (sasl_mech) {
         state->is_sasl = true;
@@ -796,6 +807,39 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
     return req;
 }
 
+static int sdap_auth_get_authtok(TALLOC_CTX *mem_ctx,
+                                 const char *authtok_type,
+                                 struct dp_opt_blob authtok,
+                                 struct berval *pw)
+{
+    char *cleartext;
+    int ret;
+
+    if (!authtok_type) return EOK;
+    if (!pw) return EINVAL;
+
+    if (strcasecmp(authtok_type,"password") == 0) {
+        pw->bv_len = authtok.length;
+        pw->bv_val = (char *) authtok.data;
+    } else if (strcasecmp(authtok_type,"obfuscated_password") == 0) {
+        ret = sss_password_decrypt(mem_ctx, (char *) authtok.data, &cleartext);
+        if (ret != EOK) {
+            DEBUG(1, ("Cannot convert the obfuscated "
+                      "password back to cleartext\n"));
+            return ret;
+        }
+
+        pw->bv_len = strlen(cleartext);
+        pw->bv_val = (char *) cleartext;
+    } else {
+        DEBUG(1, ("Authentication token type [%s] is not supported\n",
+                  authtok_type));
+        return EINVAL;
+    }
+
+    return EOK;
+}
+
 static void sdap_auth_done(struct tevent_req *subreq)
 {
     struct tevent_req *req = tevent_req_callback_data(subreq,
-- 
1.7.2.2

