[SSSD] [PATCH] Check for controls before using them

Sumit Bose sbose at redhat.com
Fri Sep 10 09:16:27 UTC 2010


On Thu, Sep 02, 2010 at 09:44:02AM -0400, Stephen Gallagher wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> On 07/09/2010 05:59 AM, Sumit Bose wrote:
> > On Fri, Mar 19, 2010 at 02:15:06PM +0100, Sumit Bose wrote:
> >> On Fri, Mar 19, 2010 at 08:48:49AM -0400, Simo Sorce wrote:
> >>> On Fri, 19 Mar 2010 12:00:47 +0100
> >>> Sumit Bose <sbose at redhat.com> wrote:
> >>>
> >>>> On Thu, Mar 18, 2010 at 05:51:13PM -0400, Simo Sorce wrote:
> >>>>>
> >>>>> Some time ago I added code to fetch the rootdse on connection, but
> >>>>> didn't publicize it too much.
> >>>>>
> >>>>> Attached find 2 patches.
> >>>>>
> >>>>> 1) Rework the way we store data fetched from the rootdse so the it
> >>>>> is more useful and is actually attached to the ldap handle.  
> >>>>
> >>>> I'm in general fine with this one, although I haven't tested it
> >>>> throughly yet.
> >>>>>
> >>>>> 2) Check controls are supported before using them.  
> >>>>
> >>>> I have two comments here:
> >>>>
> >>>> - sdap_is_control_supported() should be integrated in
> >>>>   sss_ldap_control_create() or a new call should be created which
> >>>> calls sdap_is_control_supported() and then sss_ldap_control_create().
> >>>> - the debug message 'Server does not support the Password Policy
> >>>>   control' should have a much lower level than 7. Because if the
> >>>> control is missing the user might not see the expected
> >>>> behaviour/performance.
> >>>
> >>> Sumit,
> >>> do you want to take over the second patch ?
> >>> I don't have a way to thoroughly test it anyway and I am a bit short on
> >>> time.
> >>
> >> sure
> >>
> > 
> > Hi,
> > 
> > not even 4 months later here are the revised versions of these patches.
> > I had it add two more changes to the first patch to make it build on
> > master because of the change to sdap_cli_connect_recv().
> > 
> > In the second patch if have created a new call sdap_control_create()
> > which checks if the control is supported with
> > sdap_is_control_supported() and calls sss_ldap_control_create() on
> > success. I think this approach is more clean, because it leaves
> > sss_ldap_control_create() as a pure replacement function.
> > 
> 
> Naturally, we only got around to reviewing this two months after this
> revision :(
> 
> Unfortunately, the changes made to the creation of LDAP operations in
> SSSD 1.3.0 conflict madly with these changes. Would it be possible for
> you to rebase this patch atop the current master?
> 
> If not, I'll add it to my todo list post-1.4.0.
> 

rebased versions attached.

bye,
Sumit

> - -- 
> Stephen Gallagher
> RHCE 804006346421761
> 
> Delivering value year after year.
> Red Hat ranks #1 in value among software vendors.
> http://www.redhat.com/promo/vendor/
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
> Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
> 
> iEYEARECAAYFAkx/qiIACgkQeiVVYja6o6MFHQCeIhpJQ4Ttk0+76fKo6uAsVHhB
> cy8AnRsnD3Fy736/lAJVEc7BioJGpYI8
> =KNjZ
> -----END PGP SIGNATURE-----
> _______________________________________________
> sssd-devel mailing list
> sssd-devel at lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/sssd-devel
-------------- next part --------------
From 7952ef9953eec2d5a3d1b4100eb14ea140abcb99 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 9 Sep 2010 15:15:36 +0200
Subject: [PATCH 1/2] Store rootdse supported features in sdap_handler

---
 src/providers/ipa/ipa_auth.c               |    4 +-
 src/providers/ldap/ldap_common.h           |    3 +
 src/providers/ldap/sdap.c                  |   84 ++++++++++++++++++++++------
 src/providers/ldap/sdap.h                  |   23 +++++++-
 src/providers/ldap/sdap_async.h            |    8 +--
 src/providers/ldap/sdap_async_connection.c |   50 ++++++----------
 src/providers/ldap/sdap_id_op.c            |    4 +-
 7 files changed, 116 insertions(+), 60 deletions(-)

diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c
index 2d91457..23095e5 100644
--- a/src/providers/ipa/ipa_auth.c
+++ b/src/providers/ipa/ipa_auth.c
@@ -92,7 +92,7 @@ static struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx,
 
     subreq = sdap_cli_connect_send(state, ev, sdap_auth_ctx->opts,
                                    sdap_auth_ctx->be, sdap_auth_ctx->service,
-                                   NULL);
+                                   true);
     if (subreq == NULL) {
         DEBUG(1, ("sdap_cli_connect_send failed.\n"));
         goto fail;
@@ -118,7 +118,7 @@ static void get_password_migration_flag_auth_done(struct tevent_req *subreq)
     char *search_base;
     const char **attrs;
 
-    ret = sdap_cli_connect_recv(subreq, state, &state->sh, NULL);
+    ret = sdap_cli_connect_recv(subreq, state, &state->sh);
     talloc_zfree(subreq);
     if (ret) {
         DEBUG(1, ("sdap_auth request failed.\n"));
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 5b7298b..2a0e976 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -42,6 +42,9 @@ struct sdap_id_ctx {
     struct fo_service *fo_service;
     struct sdap_service *service;
 
+    /* what rootDSE returns */
+    struct sysdb_attrs *rootDSE;
+
     /* LDAP connection cache */
     struct sdap_id_conn_cache *conn_cache;
 
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index 39c67cc..e0f5038 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -325,37 +325,85 @@ errno_t setup_tls_config(struct dp_option *basic_opts)
 }
 
 
-bool sdap_rootdse_sasl_mech_is_supported(struct sysdb_attrs *rootdse,
-                                         const char *sasl_mech)
+bool sdap_check_sup_list(struct sup_list *l, const char *val)
 {
-    struct ldb_message_element *el = NULL;
-    struct ldb_val *val;
     int i;
 
-    if (!sasl_mech) return false;
+    if (!val) {
+        return false;
+    }
 
-    for (i = 0; i < rootdse->num; i++) {
-        if (strcasecmp(rootdse->a[i].name, "supportedSASLMechanisms")) {
+    for (i = 0; i < l->num_vals; i++) {
+        if (strcasecmp(val, (char *)l->vals[i])) {
             continue;
         }
-        el = &rootdse->a[i];
-        break;
+        return true;
     }
 
-    if (!el) {
-        /* no supported SASL Mechanism at all ? */
-        return false;
+    return false;
+}
+
+static int sdap_init_sup_list(TALLOC_CTX *memctx,
+                              struct sup_list *list,
+                              int num, struct ldb_val *vals)
+{
+    int i;
+
+    list->vals = talloc_array(memctx, char *, num);
+    if (!list->vals) {
+        return ENOMEM;
     }
 
-    for (i = 0; i < el->num_values; i++) {
-        val = &el->values[i];
-        if (strncasecmp(sasl_mech, (const char *)val->data, val->length)) {
-            continue;
+    for (i = 0; i < num; i++) {
+        list->vals[i] = talloc_strndup(list->vals,
+                                       (char *)vals[i].data, vals[i].length);
+        if (!list->vals[i]) {
+            return ENOMEM;
         }
-        return true;
     }
 
-    return false;
+    list->num_vals = num;
+
+    return EOK;
+}
+
+int sdap_set_rootdse_supported_lists(struct sysdb_attrs *rootdse,
+                                     struct sdap_handle *sh)
+{
+    struct ldb_message_element *el = NULL;
+    int ret;
+    int i;
+
+    for (i = 0; i < rootdse->num; i++) {
+        el = &rootdse->a[i];
+        if (strcasecmp(el->name, "supportedControl") == 0) {
+
+            ret = sdap_init_sup_list(sh, &sh->supported_controls,
+                                     el->num_values, el->values);
+            if (ret) {
+                return ret;
+            }
+        }
+        if (strcasecmp(el->name, "supportedExtension") == 0) {
+
+            ret = sdap_init_sup_list(sh, &sh->supported_extensions,
+                                     el->num_values, el->values);
+            if (ret) {
+                return ret;
+            }
+        }
+        if (strcasecmp(el->name, "supportedSASLMechanisms") == 0) {
+
+            ret = sdap_init_sup_list(sh, &sh->supported_saslmechs,
+                                     el->num_values, el->values);
+            if (ret) {
+                return ret;
+            }
+        }
+    }
+
+    return EOK;
+
 }
 
 int build_attrs_from_map(TALLOC_CTX *memctx,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 61e7fe2..c7921c7 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -93,6 +93,11 @@ struct ldap_cb_data {
     void *wakeup_cb_data;
 };
 
+struct sup_list {
+    int num_vals;
+    char **vals;
+};
+
 struct sdap_handle {
     LDAP *ldap;
     bool connected;
@@ -101,6 +106,10 @@ struct sdap_handle {
 
     struct sdap_fd_events *sdap_fd_events;
 
+    struct sup_list supported_saslmechs;
+    struct sup_list supported_controls;
+    struct sup_list supported_extensions;
+
     struct sdap_op *ops;
 
     /* during release we need to lock access to the handler
@@ -288,8 +297,18 @@ int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh,
 
 errno_t setup_tls_config(struct dp_option *basic_opts);
 
-bool sdap_rootdse_sasl_mech_is_supported(struct sysdb_attrs *rootdse,
-                                         const char *sasl_mech);
+int sdap_set_rootdse_supported_lists(struct sysdb_attrs *rootdse,
+                                     struct sdap_handle *sh);
+bool sdap_check_sup_list(struct sup_list *l, const char *val);
+
+#define sdap_is_sasl_mech_supported(sh, sasl_mech) \
+    sdap_check_sup_list(&((sh)->supported_saslmechs), sasl_mech)
+
+#define sdap_is_control_supported(sh, ctrl_oid) \
+    sdap_check_sup_list(&((sh)->supported_controls), ctrl_oid)
+
+#define sdap_is_extension_supported(sh, ext_oid) \
+    sdap_check_sup_list(&((sh)->supported_extensions), ext_oid)
 
 int build_attrs_from_map(TALLOC_CTX *memctx,
                          struct sdap_attr_map *map,
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 6053506..e5a60da 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -110,16 +110,14 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
                                          struct sdap_options *opts,
                                          struct be_ctx *be,
                                          struct sdap_service *service,
-                                         struct sysdb_attrs **rootdse);
+                                         bool skip_rootdse);
 int sdap_cli_connect_recv(struct tevent_req *req,
                           TALLOC_CTX *memctx,
-                          struct sdap_handle **gsh,
-                          struct sysdb_attrs **rootdse);
+                          struct sdap_handle **gsh);
 int sdap_cli_connect_recv_ext(struct tevent_req *req,
                           TALLOC_CTX *memctx,
                           bool *can_retry,
-                          struct sdap_handle **gsh,
-                          struct sysdb_attrs **rootdse);
+                          struct sdap_handle **gsh);
 
 struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx,
                                          struct tevent_context *ev,
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 682d74c..35720c0 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -939,7 +939,6 @@ struct sdap_cli_connect_state {
     struct be_ctx *be;
 
     bool use_rootdse;
-    struct sysdb_attrs *rootdse;
 
     struct sdap_handle *sh;
 
@@ -961,7 +960,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
                                          struct sdap_options *opts,
                                          struct be_ctx *be,
                                          struct sdap_service *service,
-                                         struct sysdb_attrs **rootdse)
+                                         bool skip_rootdse)
 {
     struct sdap_cli_connect_state *state;
     struct tevent_req *req;
@@ -977,12 +976,10 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
     state->srv = NULL;
     state->be = be;
 
-    if (rootdse) {
-        state->use_rootdse = true;
-        state->rootdse = *rootdse;
-    } else {
+    if (skip_rootdse) {
         state->use_rootdse = false;
-        state->rootdse = NULL;
+    } else {
+        state->use_rootdse = true;
     }
 
     ret = sdap_cli_resolve_next(req);
@@ -1068,7 +1065,7 @@ static void sdap_cli_connect_done(struct tevent_req *subreq)
         return;
     }
 
-    if (state->use_rootdse && !state->rootdse) {
+    if (state->use_rootdse) {
         /* fetch the rootDSE this time */
         sdap_cli_rootdse_step(req);
         return;
@@ -1078,8 +1075,7 @@ static void sdap_cli_connect_done(struct tevent_req *subreq)
 
     if (sasl_mech && state->use_rootdse) {
         /* check if server claims to support GSSAPI */
-        if (!sdap_rootdse_sasl_mech_is_supported(state->rootdse,
-                                                 sasl_mech)) {
+        if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) {
             tevent_req_error(req, ENOTSUP);
             return;
         }
@@ -1127,10 +1123,11 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq)
                                                       struct tevent_req);
     struct sdap_cli_connect_state *state = tevent_req_data(req,
                                              struct sdap_cli_connect_state);
+    struct sysdb_attrs *rootdse;
     const char *sasl_mech;
     int ret;
 
-    ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse);
+    ret = sdap_get_rootdse_recv(subreq, state, &rootdse);
     talloc_zfree(subreq);
     if (ret) {
         if (ret == ETIMEDOUT) { /* retry another server */
@@ -1158,12 +1155,18 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq)
         }
     }
 
+    /* save rootdse data about supported features */
+    ret = sdap_set_rootdse_supported_lists(rootdse, state->sh);
+    if (ret) {
+        tevent_req_error(req, ret);
+        return;
+    }
+
     sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
 
     if (sasl_mech && state->use_rootdse) {
         /* check if server claims to support GSSAPI */
-        if (!sdap_rootdse_sasl_mech_is_supported(state->rootdse,
-                                                 sasl_mech)) {
+        if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) {
             tevent_req_error(req, ENOTSUP);
             return;
         }
@@ -1287,17 +1290,15 @@ static void sdap_cli_auth_done(struct tevent_req *subreq)
 
 int sdap_cli_connect_recv(struct tevent_req *req,
                           TALLOC_CTX *memctx,
-                          struct sdap_handle **gsh,
-                          struct sysdb_attrs **rootdse)
+                          struct sdap_handle **gsh)
 {
-    return sdap_cli_connect_recv_ext(req, memctx, NULL, gsh, rootdse);
+    return sdap_cli_connect_recv_ext(req, memctx, NULL, gsh);
 }
 
 int sdap_cli_connect_recv_ext(struct tevent_req *req,
                               TALLOC_CTX *memctx,
                               bool *can_retry,
-                              struct sdap_handle **gsh,
-                              struct sysdb_attrs **rootdse)
+                              struct sdap_handle **gsh)
 {
     struct sdap_cli_connect_state *state = tevent_req_data(req,
                                              struct sdap_cli_connect_state);
@@ -1337,19 +1338,6 @@ int sdap_cli_connect_recv_ext(struct tevent_req *req,
         talloc_zfree(state->sh);
     }
 
-    if (rootdse) {
-        if (state->use_rootdse) {
-            *rootdse = talloc_steal(memctx, state->rootdse);
-            if (!*rootdse) {
-                return ENOMEM;
-            }
-        } else {
-            *rootdse = NULL;
-        }
-    } else {
-        talloc_zfree(rootdse);
-    }
-
     return EOK;
 }
 
diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c
index a005f0f..4fa7733 100644
--- a/src/providers/ldap/sdap_id_op.c
+++ b/src/providers/ldap/sdap_id_op.c
@@ -460,7 +460,7 @@ static int sdap_id_op_connect_step(struct tevent_req *req)
     conn_data->conn_cache = conn_cache;
     subreq = sdap_cli_connect_send(conn_data, conn_cache->be->ev,
                                    conn_cache->opts, conn_cache->be,
-                                   conn_cache->service, &conn_data->rootDSE);
+                                   conn_cache->service, false);
     if (!subreq) {
         ret = ENOMEM;
         goto done;
@@ -497,7 +497,7 @@ static void sdap_id_op_connect_done(struct tevent_req *subreq)
     int ret;
 
     ret = sdap_cli_connect_recv_ext(subreq, conn_data, &can_retry,
-                                    &conn_data->sh, &conn_data->rootDSE);
+                                    &conn_data->sh);
     conn_data->connect_req = NULL;
     talloc_zfree(subreq);
 
-- 
1.7.2.2

-------------- next part --------------
From f0d5d1d3817dc4c4eaa127c6c718390f80a23e18 Mon Sep 17 00:00:00 2001
From: Simo Sorce <ssorce at redhat.com>
Date: Thu, 18 Mar 2010 17:24:00 -0400
Subject: [PATCH 2/2] Check if control is supported before using it.

---
 src/providers/ldap/sdap.c                  |   18 ++++++++++++++++++
 src/providers/ldap/sdap.h                  |    3 +++
 src/providers/ldap/sdap_async.c            |   17 ++++++++++-------
 src/providers/ldap/sdap_async_connection.c |   16 +++++++++-------
 4 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index e0f5038..370ffde 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -434,3 +434,21 @@ int build_attrs_from_map(TALLOC_CTX *memctx,
     return EOK;
 }
 
+int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical,
+                        struct berval *value, int dupval, LDAPControl **ctrlp)
+{
+    int ret;
+
+    if (sdap_is_control_supported(sh, oid)) {
+        ret = sss_ldap_control_create(oid, iscritical, value, dupval, ctrlp);
+        if (ret != LDAP_SUCCESS) {
+            DEBUG(1, ("sss_ldap_control_create failed [%d][%s].\n",
+                      ret, ldap_err2string(ret)));
+        }
+    } else {
+        DEBUG(3, ("Server does not support the requested control [%s].\n", oid));
+        ret = LDAP_NOT_SUPPORTED;
+    }
+
+    return ret;
+}
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index c7921c7..91d35e0 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -313,4 +313,7 @@ bool sdap_check_sup_list(struct sup_list *l, const char *val);
 int build_attrs_from_map(TALLOC_CTX *memctx,
                          struct sdap_attr_map *map,
                          size_t size, const char ***_attrs);
+
+int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical,
+                        struct berval *value, int dupval, LDAPControl **ctrlp);
 #endif /* _SDAP_H_ */
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 104a72e..5bde3b8 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -566,7 +566,9 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
     int ret;
     BerElement *ber = NULL;
     struct berval *bv = NULL;
-    LDAPControl *request_controls[2];
+    int msgid;
+    LDAPControl **request_controls = NULL;
+    LDAPControl *ctrls[2] = { NULL, NULL };
 
     req = tevent_req_create(memctx, &state,
                             struct sdap_exop_modify_passwd_state);
@@ -602,13 +604,14 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
         return NULL;
     }
 
-    ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
-                                  0, NULL, 0, &request_controls[0]);
-    if (ret != LDAP_SUCCESS) {
-        DEBUG(1, ("sss_ldap_control_create failed.\n"));
+    ret = sdap_control_create(state->sh, LDAP_CONTROL_PASSWORDPOLICYREQUEST,
+                              0, NULL, 0, &ctrls[0]);
+    if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {
+        DEBUG(1, ("sdap_control_create failed to create "
+                  "Password Policy control.\n"));
         goto fail;
     }
-    request_controls[1] = NULL;
+    request_controls = ctrls;
 
     DEBUG(4, ("Executing extended operation\n"));
 
@@ -616,7 +619,7 @@ struct tevent_req *sdap_exop_modify_passwd_send(TALLOC_CTX *memctx,
                                           LDAP_EXOP_MODIFY_PASSWD, bv,
                                           request_controls, NULL);
     ber_bvfree(bv);
-    ldap_control_free(request_controls[0]);
+    if (ctrls[0]) ldap_control_free(ctrls[0]);
 
     if (!subreq) {
         DEBUG(1, ("ldap_extended_operation_send failed.\n"));
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 35720c0..f5c6511 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -308,8 +308,9 @@ static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
     struct tevent_req *req;
     struct simple_bind_state *state;
     int ret = EOK;
-    LDAPControl *request_controls[2];
     struct tevent_req *subreq;
+    LDAPControl **request_controls = NULL;
+    LDAPControl *ctrls[2] = { NULL, NULL };
 
     req = tevent_req_create(memctx, &state, struct simple_bind_state);
     if (!req) return NULL;
@@ -325,19 +326,20 @@ static struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
     state->user_dn = user_dn;
     state->pw = pw;
 
-    ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
-                                  0, NULL, 0, &request_controls[0]);
-    if (ret != LDAP_SUCCESS) {
-        DEBUG(1, ("sss_ldap_control_create failed.\n"));
+    ret = sdap_control_create(state->sh, LDAP_CONTROL_PASSWORDPOLICYREQUEST,
+                              0, NULL, 0, &ctrls[0]);
+    if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {
+        DEBUG(1, ("sdap_control_create failed to create "
+                  "Password Policy control.\n"));
         goto fail;
     }
-    request_controls[1] = NULL;
+    request_controls = ctrls;
 
     DEBUG(4, ("Executing simple bind as: %s\n", state->user_dn));
 
     subreq = ldap_sasl_bind_send(state, ev, sh, user_dn, LDAP_SASL_SIMPLE, pw,
                                  request_controls, NULL);
-    ldap_control_free(request_controls[0]);
+    if (ctrls[0]) ldap_control_free(ctrls[0]);
 
     if (!subreq) goto fail;
     tevent_req_set_callback(subreq, simple_bind_step, req);
-- 
1.7.2.2



More information about the sssd-devel mailing list