[Pkg-sssd-devel] sssd: Changes to 'ubuntu'

Stéphane Graber stgraber-guest at alioth.debian.org
Wed Sep 4 18:51:20 UTC 2013


 debian/changelog              |    8 
 debian/patches/ml-016435.diff | 1205 ++++++++++++++++++++++++++++++++++++++++++
 debian/patches/ml-016436.diff |  205 +++++++
 debian/patches/series         |    2 
 4 files changed, 1420 insertions(+)

New commits:
commit 2571f79ba2e0230b9220daee495e7ef5a8182621
Author: Stéphane Graber <stgraber at ubuntu.com>
Date:   Wed Sep 4 14:50:26 2013 -0400

    releasing version 1.11.0-0ubuntu3

diff --git a/debian/changelog b/debian/changelog
index 865adea..50d321e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,10 @@
-sssd (1.11.0-0ubuntu3) UNRELEASED; urgency=low
+sssd (1.11.0-0ubuntu3) saucy; urgency=low
 
   * Cherry-pick two bugfixes from the sssd-devel mailing-list (pre-git):
     - ml-016435.diff (AD: async request to retrieve master domain info)
     - ml-016436.diff (AD: Failure to get flat name is not fatal)
 
- -- Stéphane Graber <stgraber at ubuntu.com>  Wed, 04 Sep 2013 14:47:46 -0400
+ -- Stéphane Graber <stgraber at ubuntu.com>  Wed, 04 Sep 2013 14:50:06 -0400
 
 sssd (1.11.0-0ubuntu2) saucy; urgency=low
 

commit 236b05ee8d5f52d54ff72c54374ffa2f7757a595
Author: Stéphane Graber <stgraber at ubuntu.com>
Date:   Wed Sep 4 14:49:18 2013 -0400

    Cherry-pick AD fixes from the mailing-list.
    
    Signed-off-by: Stéphane Graber <stgraber at ubuntu.com>

diff --git a/debian/changelog b/debian/changelog
index 3d7aa6b..865adea 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+sssd (1.11.0-0ubuntu3) UNRELEASED; urgency=low
+
+  * Cherry-pick two bugfixes from the sssd-devel mailing-list (pre-git):
+    - ml-016435.diff (AD: async request to retrieve master domain info)
+    - ml-016436.diff (AD: Failure to get flat name is not fatal)
+
+ -- Stéphane Graber <stgraber at ubuntu.com>  Wed, 04 Sep 2013 14:47:46 -0400
+
 sssd (1.11.0-0ubuntu2) saucy; urgency=low
 
   * rules: Disable parallel building again, causes weird memory corruption
diff --git a/debian/patches/ml-016435.diff b/debian/patches/ml-016435.diff
new file mode 100644
index 0000000..133c581
--- /dev/null
+++ b/debian/patches/ml-016435.diff
@@ -0,0 +1,1205 @@
+>From 88c26495cc453e55fd6771eb7c8c711fe5fd8a06 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek at redhat.com>
+Date: Sat, 17 Aug 2013 01:12:21 +0200
+Subject: [PATCH 1/3] AD: async request to retrieve master domain info
+
+Adds a reusable async request to download the master domain info.
+---
+ Makefile.am                       |   3 +
+ src/providers/ad/ad_domain_info.c | 350 ++++++++++++++++++++++++++++++++++++++
+ src/providers/ad/ad_domain_info.h |  41 +++++
+ src/providers/ad/ad_init.c        |   2 +-
+ src/providers/ad/ad_subdomains.c  | 235 +++----------------------
+ 5 files changed, 417 insertions(+), 214 deletions(-)
+ create mode 100644 src/providers/ad/ad_domain_info.c
+ create mode 100644 src/providers/ad/ad_domain_info.h
+
+diff --git a/Makefile.am b/Makefile.am
+index b913a12b895d68f1f3e23c185e493e576641d0e2..eb8592fcd19bce503c99a5745be2a67d3f70d48b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1587,6 +1587,7 @@ libsss_ipa_la_SOURCES = \
+     src/providers/ad/ad_dyndns.c \
+     src/providers/ad/ad_id.c \
+     src/providers/ad/ad_srv.c \
++    src/providers/ad/ad_domain_info.c \
+     src/util/user_info_msg.c \
+     src/util/find_uid.c \
+     src/util/sss_ldap.c \
+@@ -1638,6 +1639,8 @@ libsss_ad_la_SOURCES = \
+     src/providers/ad/ad_srv.c \
+     src/providers/ad/ad_subdomains.c \
+     src/providers/ad/ad_subdomains.h \
++    src/providers/ad/ad_domain_info.c \
++    src/providers/ad/ad_domain_info.h \
+     src/util/find_uid.c \
+     src/util/user_info_msg.c \
+     src/util/sss_krb5.c \
+diff --git a/src/providers/ad/ad_domain_info.c b/src/providers/ad/ad_domain_info.c
+new file mode 100644
+index 0000000000000000000000000000000000000000..252f1678e453f1cec671b30cf891c0ec74f6c749
+--- /dev/null
++++ b/src/providers/ad/ad_domain_info.c
+@@ -0,0 +1,350 @@
++/*
++    SSSD
++
++    AD Subdomains Module
++
++    Authors:
++        Sumit Bose <sbose at redhat.com>
++
++    Copyright (C) 2013 Red Hat
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 3 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++#include <errno.h>
++#include <tevent.h>
++#include <ctype.h>
++#include <ndr.h>
++#include <ndr/ndr_nbt.h>
++
++#include "providers/ldap/sdap.h"
++#include "providers/ldap/sdap_async.h"
++#include "providers/ldap/sdap_idmap.h"
++#include "util/util.h"
++
++#define AD_AT_OBJECT_SID "objectSID"
++#define AD_AT_DNS_DOMAIN "DnsDomain"
++#define AD_AT_NT_VERSION "NtVer"
++#define AD_AT_NETLOGON   "netlogon"
++
++#define MASTER_DOMAIN_SID_FILTER "objectclass=domain"
++
++struct ad_master_domain_state {
++    struct tevent_context *ev;
++    struct sdap_id_conn_ctx *conn;
++    struct sdap_id_op *id_op;
++    struct sdap_id_ctx *id_ctx;
++    struct sdap_options *opts;
++
++    const char *dom_name;
++    int base_iter;
++
++    char *flat;
++    char *sid;
++};
++
++static errno_t ad_master_domain_next(struct tevent_req *req);
++static void ad_master_domain_next_done(struct tevent_req *subreq);
++static void ad_master_domain_netlogon_done(struct tevent_req *req);
++
++struct tevent_req *
++ad_master_domain_send(TALLOC_CTX *mem_ctx,
++                      struct tevent_context *ev,
++                      struct sdap_id_conn_ctx *conn,
++                      struct sdap_id_op *op,
++                      const char *dom_name)
++{
++    errno_t ret;
++    struct tevent_req *req;
++    struct ad_master_domain_state *state;
++
++    req = tevent_req_create(mem_ctx, &state, struct ad_master_domain_state);
++    if (!req) return NULL;
++
++    state->ev = ev;
++    state->id_op = op;
++    state->conn = conn;
++    state->id_ctx = conn->id_ctx;
++    state->opts = conn->id_ctx->opts;
++    state->dom_name = dom_name;
++
++    ret = ad_master_domain_next(req);
++    if (ret != EOK && ret != EAGAIN) {
++        goto immediate;
++    }
++
++    return req;
++
++immediate:
++    if (ret != EOK) {
++        tevent_req_error(req, ret);
++    } else {
++        tevent_req_done(req);
++    }
++    tevent_req_post(req, ev);
++    return req;
++}
++
++static errno_t
++ad_master_domain_next(struct tevent_req *req)
++{
++    struct tevent_req *subreq;
++    struct sdap_search_base *base;
++    const char *master_sid_attrs[] = {AD_AT_OBJECT_SID, NULL};
++
++    struct ad_master_domain_state *state =
++        tevent_req_data(req, struct ad_master_domain_state);
++
++    base = state->opts->sdom->search_bases[state->base_iter];
++    if (base == NULL) {
++        return EOK;
++    }
++
++    subreq = sdap_get_generic_send(state, state->ev,
++                                   state->id_ctx->opts,
++                                   sdap_id_op_handle(state->id_op),
++                                   base->basedn, LDAP_SCOPE_BASE,
++                                   MASTER_DOMAIN_SID_FILTER, master_sid_attrs,
++                                   NULL, 0,
++                                   dp_opt_get_int(state->opts->basic,
++                                                  SDAP_SEARCH_TIMEOUT),
++                                   false);
++    if (subreq == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
++        return ENOMEM;
++    }
++    tevent_req_set_callback(subreq, ad_master_domain_next_done, req);
++
++    return EAGAIN;
++}
++
++static void
++ad_master_domain_next_done(struct tevent_req *subreq)
++{
++    errno_t ret;
++    size_t reply_count;
++    struct sysdb_attrs **reply = NULL;
++    struct ldb_message_element *el;
++    char *sid_str;
++    enum idmap_error_code err;
++    static const char *attrs[] = {AD_AT_NETLOGON, NULL};
++    char *filter;
++    char *ntver;
++
++    struct tevent_req *req = tevent_req_callback_data(subreq,
++                                                      struct tevent_req);
++    struct ad_master_domain_state *state =
++        tevent_req_data(req, struct ad_master_domain_state);
++
++    ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
++    talloc_zfree(subreq);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
++        goto done;
++    }
++
++    if (reply_count == 0) {
++        state->base_iter++;
++        ret = ad_master_domain_next(req);
++        if (ret == EAGAIN) {
++            /* Async request will get us back here again */
++            return;
++        } else if (ret != EOK) {
++            goto done;
++        }
++
++        /* EOK */
++        tevent_req_done(req);
++        return;
++    } else if (reply_count == 1) {
++        ret = sysdb_attrs_get_el(reply[0], AD_AT_OBJECT_SID, &el);
++        if (ret != EOK || el->num_values != 1) {
++            DEBUG(SSSDBG_OP_FAILURE, ("sdap_attrs_get_el failed.\n"));
++            goto done;
++        }
++
++        err = sss_idmap_bin_sid_to_sid(state->opts->idmap_ctx->map,
++                                       el->values[0].data,
++                                       el->values[0].length,
++                                       &sid_str);
++        if (err != IDMAP_SUCCESS) {
++            DEBUG(SSSDBG_MINOR_FAILURE,
++                  ("Could not convert SID: [%s].\n", idmap_error_string(err)));
++            ret = EFAULT;
++            goto done;
++        }
++
++        state->sid = talloc_steal(state, sid_str);
++    } else {
++        DEBUG(SSSDBG_OP_FAILURE,
++              ("More than one result for domain SID found.\n"));
++        ret = EINVAL;
++        goto done;
++    }
++
++    DEBUG(SSSDBG_TRACE_FUNC, ("Found SID [%s].\n", state->sid));
++
++    ntver = sss_ldap_encode_ndr_uint32(state, NETLOGON_NT_VERSION_5EX |
++                                       NETLOGON_NT_VERSION_WITH_CLOSEST_SITE);
++    if (ntver == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, ("sss_ldap_encode_ndr_uint32 failed.\n"));
++        ret = ENOMEM;
++        goto done;
++    }
++
++    filter = talloc_asprintf(state, "(&(%s=%s)(%s=%s))",
++                             AD_AT_DNS_DOMAIN, state->dom_name,
++                             AD_AT_NT_VERSION, ntver);
++    if (filter == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, ("talloc_asprintf failed.\n"));
++        ret = ENOMEM;
++        goto done;
++    }
++
++    subreq = sdap_get_generic_send(state, state->ev,
++                                   state->id_ctx->opts,
++                                   sdap_id_op_handle(state->id_op),
++                                   "", LDAP_SCOPE_BASE, filter, attrs, NULL, 0,
++                                   dp_opt_get_int(state->opts->basic,
++                                                  SDAP_SEARCH_TIMEOUT),
++                                   false);
++    if (subreq == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
++        ret = ENOMEM;
++        goto done;
++    }
++
++    tevent_req_set_callback(subreq, ad_master_domain_netlogon_done, req);
++    return;
++
++done:
++    tevent_req_error(req, ret);
++}
++
++static void
++ad_master_domain_netlogon_done(struct tevent_req *subreq)
++{
++    int ret;
++    size_t reply_count;
++    struct sysdb_attrs **reply = NULL;
++    struct ldb_message_element *el;
++    DATA_BLOB blob;
++    enum ndr_err_code ndr_err;
++    struct ndr_pull *ndr_pull = NULL;
++    struct netlogon_samlogon_response response;
++
++    struct tevent_req *req = tevent_req_callback_data(subreq,
++                                                      struct tevent_req);
++    struct ad_master_domain_state *state =
++        tevent_req_data(req, struct ad_master_domain_state);
++
++    ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
++    talloc_zfree(subreq);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
++        goto done;
++    }
++
++    if (reply_count == 0) {
++        DEBUG(SSSDBG_TRACE_FUNC, ("No netlogon data available.\n"));
++        ret = ENOENT;
++        goto done;
++    } else if (reply_count > 1) {
++        DEBUG(SSSDBG_OP_FAILURE,
++              ("More than one netlogon info returned.\n"));
++        ret = EINVAL;
++        goto done;
++    }
++
++    ret = sysdb_attrs_get_el(reply[0], AD_AT_NETLOGON, &el);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_el() failed\n"));
++        goto done;
++    }
++
++    if (el->num_values == 0) {
++        DEBUG(SSSDBG_OP_FAILURE, ("netlogon has no value\n"));
++        ret = ENOENT;
++        goto done;
++    } else if (el->num_values > 1) {
++        DEBUG(SSSDBG_OP_FAILURE, ("More than one netlogon value?\n"));
++        ret = EIO;
++        goto done;
++    }
++
++    blob.data =  el->values[0].data;
++    blob.length = el->values[0].length;
++
++    ndr_pull = ndr_pull_init_blob(&blob, state);
++    if (ndr_pull == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, ("ndr_pull_init_blob() failed.\n"));
++        ret = ENOMEM;
++        goto done;
++    }
++
++    ndr_err = ndr_pull_netlogon_samlogon_response(ndr_pull, NDR_SCALARS,
++                                                  &response);
++    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
++        DEBUG(SSSDBG_OP_FAILURE, ("ndr_pull_netlogon_samlogon_response() "
++                                  "failed [%d]\n", ndr_err));
++        ret = EBADMSG;
++        goto done;
++    }
++
++    if (!(response.ntver & NETLOGON_NT_VERSION_5EX)) {
++        DEBUG(SSSDBG_OP_FAILURE, ("Wrong version returned [%x]\n",
++                                  response.ntver));
++        ret = EBADMSG;
++        goto done;
++    }
++
++    if (response.data.nt5_ex.domain_name != NULL &&
++        *response.data.nt5_ex.domain_name != '\0') {
++        state->flat = talloc_strdup(state, response.data.nt5_ex.domain_name);
++        if (state->flat == NULL) {
++            DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
++            ret = ENOMEM;
++            goto done;
++        }
++    }
++
++    DEBUG(SSSDBG_TRACE_FUNC, ("Found flat name [%s].\n", state->flat));
++    tevent_req_done(req);
++    return;
++
++done:
++    tevent_req_error(req, ret);
++}
++
++errno_t
++ad_master_domain_recv(struct tevent_req *req,
++                      TALLOC_CTX *mem_ctx,
++                      char **_flat,
++                      char **_id)
++{
++    struct ad_master_domain_state *state = tevent_req_data(req,
++                                              struct ad_master_domain_state);
++
++    TEVENT_REQ_RETURN_ON_ERROR(req);
++
++    if (_flat) {
++        *_flat = talloc_steal(mem_ctx, state->flat);
++    }
++
++    if (_id) {
++        *_id = talloc_steal(mem_ctx, state->sid);
++    }
++
++    return EOK;
++}
+diff --git a/src/providers/ad/ad_domain_info.h b/src/providers/ad/ad_domain_info.h
+new file mode 100644
+index 0000000000000000000000000000000000000000..d21706396034509a498391e666e03a8e2eda8e08
+--- /dev/null
++++ b/src/providers/ad/ad_domain_info.h
+@@ -0,0 +1,41 @@
++/*
++    SSSD
++
++    AD Master Domain Module
++
++    Authors:
++        Sumit Bose <sbose at redhat.com>
++
++    Copyright (C) 2013 Red Hat
++
++    This program is free software; you can redistribute it and/or modify
++    it under the terms of the GNU General Public License as published by
++    the Free Software Foundation; either version 3 of the License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++    GNU General Public License for more details.
++
++    You should have received a copy of the GNU General Public License
++    along with this program.  If not, see <http://www.gnu.org/licenses/>.
++*/
++
++#ifndef _AD_MASTER_DOMAIN_H_
++#define _AD_MASTER_DOMAIN_H_
++
++struct tevent_req *
++ad_master_domain_send(TALLOC_CTX *mem_ctx,
++                      struct tevent_context *ev,
++                      struct sdap_id_conn_ctx *conn,
++                      struct sdap_id_op *op,
++                      const char *dom_name);
++
++errno_t
++ad_master_domain_recv(struct tevent_req *req,
++                      TALLOC_CTX *mem_ctx,
++                      char **_flat,
++                      char **_id);
++
++#endif /* _AD_MASTER_DOMAIN_H_ */
+diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
+index f181afe6e37ace4cd0d7fba83923129b3161aad3..992881951edc215c9ad6b94efcab905abb3812f5 100644
+--- a/src/providers/ad/ad_init.c
++++ b/src/providers/ad/ad_init.c
+@@ -40,6 +40,7 @@
+ #include "providers/ad/ad_srv.h"
+ #include "providers/dp_dyndns.h"
+ #include "providers/ad/ad_subdomains.h"
++#include "providers/ad/ad_domain_info.h"
+ 
+ struct ad_options *ad_options = NULL;
+ 
+@@ -214,7 +215,6 @@ sssm_ad_id_init(struct be_ctx *bectx,
+                           &ad_ctx->sdap_id_ctx->opts->idmap_ctx);
+     if (ret != EOK) goto done;
+ 
+-
+     ret = setup_tls_config(ad_ctx->sdap_id_ctx->opts->basic);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_CRIT_FAILURE,
+diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
+index afd2031fe6be557f43555b6dd8b47731d9833585..399957ee16ab0a01c97c8dde4b0adc5ded1c4e25 100644
+--- a/src/providers/ad/ad_subdomains.c
++++ b/src/providers/ad/ad_subdomains.c
+@@ -24,6 +24,7 @@
+ 
+ #include "providers/ldap/sdap_async.h"
+ #include "providers/ad/ad_subdomains.h"
++#include "providers/ad/ad_domain_info.h"
+ #include <ctype.h>
+ #include <ndr.h>
+ #include <ndr/ndr_nbt.h>
+@@ -263,9 +264,7 @@ done:
+ }
+ 
+ static void ad_subdomains_get_conn_done(struct tevent_req *req);
+-static errno_t ad_subdomains_get_master_sid(struct ad_subdomains_req_ctx *ctx);
+-static void ad_subdomains_get_master_sid_done(struct tevent_req *req);
+-static void ad_subdomains_get_netlogon_done(struct tevent_req *req);
++static void ad_subdomains_master_dom_done(struct tevent_req *req);
+ static errno_t ad_subdomains_get_slave(struct ad_subdomains_req_ctx *ctx);
+ 
+ static void ad_subdomains_retrieve(struct ad_subdomains_ctx *ctx,
+@@ -340,236 +339,46 @@ static void ad_subdomains_get_conn_done(struct tevent_req *req)
+         goto fail;
+     }
+ 
+-    ret = ad_subdomains_get_master_sid(ctx);
+-    if (ret == EAGAIN) {
+-        return;
+-    } else if (ret != EOK) {
++    req = ad_master_domain_send(ctx, ctx->sd_ctx->be_ctx->ev,
++                                ctx->sd_ctx->ldap_ctx,
++                                ctx->sdap_op,
++                                ctx->sd_ctx->domain_name);
++    if (req == NULL) {
++        DEBUG(SSSDBG_OP_FAILURE, ("ad_master_domain_send failed.\n"));
++        ret = ENOMEM;
+         goto fail;
+     }
+-
+-    DEBUG(SSSDBG_OP_FAILURE, ("No search base available.\n"));
+-    ret = EINVAL;
++    tevent_req_set_callback(req, ad_subdomains_master_dom_done, ctx);
++    return;
+ 
+ fail:
+     be_req_terminate(ctx->be_req, dp_error, ret, NULL);
+ }
+ 
+-static errno_t ad_subdomains_get_master_sid(struct ad_subdomains_req_ctx *ctx)
++static void ad_subdomains_master_dom_done(struct tevent_req *req)
+ {
+-    struct tevent_req *req;
+-    struct sdap_search_base *base;
+-    const char *master_sid_attrs[] = {AD_AT_OBJECT_SID, NULL};
+-
+-
+-    base = ctx->sd_ctx->sdom->search_bases[ctx->base_iter];
+-    if (base == NULL) {
+-        return EOK;
+-    }
+-
+-    req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
+-                           ctx->sd_ctx->sdap_id_ctx->opts,
+-                           sdap_id_op_handle(ctx->sdap_op),
+-                           base->basedn, LDAP_SCOPE_BASE,
+-                           MASTER_DOMAIN_SID_FILTER, master_sid_attrs,
+-                           NULL, 0,
+-                           dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
+-                                          SDAP_SEARCH_TIMEOUT),
+-                           false);
+-
+-    if (req == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
+-        return ENOMEM;
+-    }
+-
+-    tevent_req_set_callback(req, ad_subdomains_get_master_sid_done, ctx);
+-
+-    return EAGAIN;
+-}
+-
+-static void ad_subdomains_get_master_sid_done(struct tevent_req *req)
+-{
+-    int ret;
+-    size_t reply_count;
+-    struct sysdb_attrs **reply = NULL;
+     struct ad_subdomains_req_ctx *ctx;
+-    struct ldb_message_element *el;
+-    char *sid_str;
+-    enum idmap_error_code err;
+-    static const char *attrs[] = {AD_AT_NETLOGON, NULL};
+-    char *filter;
+-    char *ntver;
++    errno_t ret;
+ 
+     ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
+ 
+-    ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
++    ret = ad_master_domain_recv(req, ctx,
++                                &ctx->flat_name, &ctx->master_sid);
+     talloc_zfree(req);
+     if (ret != EOK) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
+-        goto done;
+-    }
+-
+-    if (reply_count == 0) {
+-        ctx->base_iter++;
+-        ret = ad_subdomains_get_master_sid(ctx);
+-        if (ret == EAGAIN) {
+-            return;
+-        } else if (ret != EOK) {
+-            goto done;
+-        }
+-    } else if (reply_count == 1) {
+-        ret = sysdb_attrs_get_el(reply[0], AD_AT_OBJECT_SID, &el);
+-        if (ret != EOK || el->num_values != 1) {
+-            DEBUG(SSSDBG_OP_FAILURE, ("sdap_attrs_get_el failed.\n"));
+-            goto done;
+-        }
+-
+-        err = sss_idmap_bin_sid_to_sid(ctx->sd_ctx->idmap_ctx,
+-                                       el->values[0].data,
+-                                       el->values[0].length,
+-                                       &sid_str);
+-        if (err != IDMAP_SUCCESS) {
+-            DEBUG(SSSDBG_MINOR_FAILURE,
+-                  ("Could not convert SID: [%s].\n", idmap_error_string(err)));
+-            ret = EFAULT;
+-            goto done;
+-        }
+-
+-        ctx->master_sid = talloc_steal(ctx, sid_str);
+-    } else {
+-        DEBUG(SSSDBG_OP_FAILURE,
+-              ("More than one result for domain SID found.\n"));
+-        ret = EINVAL;
++        DEBUG(SSSDBG_OP_FAILURE, ("Cannot retrieve master domain info\n"));
+         goto done;
+     }
+ 
+-    DEBUG(SSSDBG_TRACE_FUNC, ("Found SID [%s].\n", ctx->master_sid));
+-
+-    ntver = sss_ldap_encode_ndr_uint32(ctx, NETLOGON_NT_VERSION_5EX |
+-                                       NETLOGON_NT_VERSION_WITH_CLOSEST_SITE);
+-    if (ntver == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("sss_ldap_encode_ndr_uint32 failed.\n"));
+-        ret = ENOMEM;
+-        goto done;
+-    }
+-
+-    filter = talloc_asprintf(ctx, "(&(%s=%s)(%s=%s))",
+-                             AD_AT_DNS_DOMAIN, ctx->sd_ctx->domain_name,
+-                             AD_AT_NT_VERSION, ntver);
+-    if (filter == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("talloc_asprintf failed.\n"));
+-        ret = ENOMEM;
+-        goto done;
+-    }
+-
+-    req = sdap_get_generic_send(ctx, ctx->sd_ctx->be_ctx->ev,
+-                           ctx->sd_ctx->sdap_id_ctx->opts,
+-                           sdap_id_op_handle(ctx->sdap_op),
+-                           "", LDAP_SCOPE_BASE, filter, attrs, NULL, 0,
+-                           dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
+-                                          SDAP_SEARCH_TIMEOUT),
+-                           false);
+-    if (req == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send failed.\n"));
+-        ret = ENOMEM;
+-        goto done;
+-    }
+-
+-    tevent_req_set_callback(req, ad_subdomains_get_netlogon_done, ctx);
+-    return;
+-
+-done:
+-    be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL);
+-}
+-
+-static void ad_subdomains_get_netlogon_done(struct tevent_req *req)
+-{
+-    int ret;
+-    size_t reply_count;
+-    struct sysdb_attrs **reply = NULL;
+-    struct ad_subdomains_req_ctx *ctx;
+-    struct ldb_message_element *el;
+-    DATA_BLOB blob;
+-    enum ndr_err_code ndr_err;
+-    struct ndr_pull *ndr_pull = NULL;
+-    struct netlogon_samlogon_response response;
+-    int dp_error = DP_ERR_FATAL;
+-
+-    ctx = tevent_req_callback_data(req, struct ad_subdomains_req_ctx);
+-
+-    ret = sdap_get_generic_recv(req, ctx, &reply_count, &reply);
+-    talloc_zfree(req);
+-    if (ret != EOK) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("sdap_get_generic_send request failed.\n"));
+-        goto done;
+-    }
+-
+-    if (reply_count == 0) {
+-        DEBUG(SSSDBG_TRACE_FUNC, ("No netlogon data available.\n"));
+-        ret = ENOENT;
+-        goto done;
+-    } else if (reply_count > 1) {
+-        DEBUG(SSSDBG_OP_FAILURE,
+-              ("More than one netlogon info returned.\n"));
+-        ret = EINVAL;
+-        goto done;
+-    }
+-
+-    ret = sysdb_attrs_get_el(reply[0], AD_AT_NETLOGON, &el);
+-    if (ret != EOK) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_el() failed\n"));
+-        goto done;
+-    }
+-
+-    if (el->num_values == 0) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("netlogon has no value\n"));
+-        ret = ENOENT;
+-        goto done;
+-    } else if (el->num_values > 1) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("More than one netlogon value?\n"));
+-        ret = EIO;
+-        goto done;
+-    }
+-
+-    blob.data =  el->values[0].data;
+-    blob.length = el->values[0].length;
+-
+-    ndr_pull = ndr_pull_init_blob(&blob, ctx);
+-    if (ndr_pull == NULL) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("ndr_pull_init_blob() failed.\n"));
+-        ret = ENOMEM;
+-        goto done;
+-    }
+-
+-    ndr_err = ndr_pull_netlogon_samlogon_response(ndr_pull, NDR_SCALARS,
+-                                                  &response);
+-    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("ndr_pull_netlogon_samlogon_response() "
+-                                  "failed [%d]\n", ndr_err));
+-        ret = EBADMSG;
+-        goto done;
+-    }
+-
+-    if (!(response.ntver & NETLOGON_NT_VERSION_5EX)) {
+-        DEBUG(SSSDBG_OP_FAILURE, ("Wrong version returned [%x]\n",
+-                                  response.ntver));
+-        ret = EBADMSG;
+-        goto done;
+-    }
+-
+-    if (response.data.nt5_ex.domain_name != NULL &&
+-        *response.data.nt5_ex.domain_name != '\0') {
+-        ctx->flat_name = talloc_strdup(ctx, response.data.nt5_ex.domain_name);
+-        if (ctx->flat_name == NULL) {
+-            DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
+-            ret = ENOMEM;
+-            goto done;
+-        }
+-    }
+-
+     DEBUG(SSSDBG_TRACE_FUNC, ("Found flat name [%s].\n", ctx->flat_name));
++    DEBUG(SSSDBG_TRACE_FUNC, ("Found master SID [%s].\n", ctx->master_sid));
+ 
+     ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain,
+                                        ctx->flat_name, ctx->master_sid);
++    if (ret != EOK) {
++        DEBUG(SSSDBG_OP_FAILURE, ("Cannot save master domain info\n"));
++        goto done;
++    }
+ 
+     ret = ad_subdomains_get_slave(ctx);
+     if (ret == EAGAIN) {
+@@ -579,7 +388,7 @@ static void ad_subdomains_get_netlogon_done(struct tevent_req *req)
+     }
+ 
+ done:
+-    be_req_terminate(ctx->be_req, dp_error, ret, NULL);
++    be_req_terminate(ctx->be_req, DP_ERR_FATAL, ret, NULL);
+ }
+ 
+ static void ad_subdomains_get_slave_domain_done(struct tevent_req *req);
+-- 
+1.8.3.1
+
+-------------- next part --------------
+>From 2d47aaae98953b954898171212e579f3463881a6 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek at redhat.com>
+Date: Sat, 24 Aug 2013 14:43:57 +0200
+Subject: [PATCH 2/3] LDAP: sdap_id_setup_tasks accepts a custom enum request
+
+AD provider will override the default with its own.
+---
+ src/providers/ipa/ipa_subdomains.c |  4 +++-
+ src/providers/ldap/ldap_common.c   | 10 +++++++---
+ src/providers/ldap/ldap_common.h   | 16 ++++++++++++++--
+ src/providers/ldap/ldap_id_enum.c  | 17 +++++------------
+ 4 files changed, 29 insertions(+), 18 deletions(-)
+
+diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
+index c28af0e76a41352b80ab816076de156607243c1d..496af42b7c134bec8b106b3302cfb09a2a7fbc53 100644
+--- a/src/providers/ipa/ipa_subdomains.c
++++ b/src/providers/ipa/ipa_subdomains.c
+@@ -186,7 +186,9 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
+     }
+ 
+     ret = sdap_id_setup_tasks(ad_id_ctx->sdap_id_ctx,
+-                              ad_id_ctx->ldap_ctx, sdom);
++                              ad_id_ctx->ldap_ctx, sdom,
++                              ldap_enumeration_send,
++                              ldap_enumeration_recv);
+     if (ret != EOK) {
+         talloc_free(ad_options);
+         return ret;
+diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
+index f7ad71182a4f46a20386e70ffda129347c5e3d87..3058bba4807069fd993c1bdefa9d7f095fe51551 100644
+--- a/src/providers/ldap/ldap_common.c
++++ b/src/providers/ldap/ldap_common.c
+@@ -938,12 +938,16 @@ void sdap_mark_offline(struct sdap_id_ctx *ctx)
+ 
+ int ldap_id_setup_tasks(struct sdap_id_ctx *ctx)
+ {
+-    return sdap_id_setup_tasks(ctx, ctx->conn, ctx->opts->sdom);
++    return sdap_id_setup_tasks(ctx, ctx->conn, ctx->opts->sdom,
++                               ldap_enumeration_send,
++                               ldap_enumeration_recv);
+ }
+ 
+ int sdap_id_setup_tasks(struct sdap_id_ctx *ctx,
+                         struct sdap_id_conn_ctx *conn,
+-                        struct sdap_domain *sdom)
++                        struct sdap_domain *sdom,
++                        be_ptask_send_t send_fn,
++                        be_ptask_recv_t recv_fn)
+ {
+     struct timeval tv;
+     int ret = EOK;
+@@ -952,7 +956,7 @@ int sdap_id_setup_tasks(struct sdap_id_ctx *ctx,
+     /* set up enumeration task */
+     if (sdom->dom->enumerate) {
+         DEBUG(SSSDBG_TRACE_FUNC, ("Setting up enumeration for %s\n", sdom->dom->name));
+-        ret = ldap_setup_enumeration(ctx, conn, sdom);
++        ret = ldap_setup_enumeration(ctx, conn, sdom, send_fn, recv_fn);
+     } else {
+         /* the enumeration task, runs the cleanup process by itself,
+          * but if enumeration is not running we need to schedule it */
+diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
+index e5b7f1151e57fd22bce856c81801c2df7a60f0c3..a2ab16d6e30d9fed12ac949c5e328d721958bc02 100644
+--- a/src/providers/ldap/ldap_common.h
++++ b/src/providers/ldap/ldap_common.h
+@@ -95,7 +95,9 @@ void sdap_handle_account_info(struct be_req *breq, struct sdap_id_ctx *ctx,
+ int ldap_id_setup_tasks(struct sdap_id_ctx *ctx);
+ int sdap_id_setup_tasks(struct sdap_id_ctx *ctx,
+                         struct sdap_id_conn_ctx *conn,
+-                        struct sdap_domain *sdom);
++                        struct sdap_domain *sdom,
++                        be_ptask_send_t send_fn,
++                        be_ptask_recv_t recv_fn);
+ 
+ struct tevent_req *
+ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
+@@ -169,7 +171,17 @@ int ldap_get_autofs_options(TALLOC_CTX *memctx,
+ 
+ errno_t ldap_setup_enumeration(struct sdap_id_ctx *ctx,
+                                struct sdap_id_conn_ctx *conn,
+-                               struct sdap_domain *sdom);
++                               struct sdap_domain *sdom,
++                               be_ptask_send_t send_fn,
++                               be_ptask_recv_t recv_fn);
++struct tevent_req *
++ldap_enumeration_send(TALLOC_CTX *mem_ctx,
++                      struct tevent_context *ev,
++                      struct be_ctx *be_ctx,
++                      struct be_ptask *be_ptask,
++                      void *pvt);
++errno_t ldap_enumeration_recv(struct tevent_req *req);
++
+ errno_t ldap_id_cleanup(struct sdap_options *opts,
+                         struct sss_domain_info *dom);
+ int ldap_id_cleanup_create_timer(struct sdap_id_ctx *ctx,
+diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c
+index 961c72f3d888fa92d1002ca483776319d007b679..2a42fdafb66eff9640b30c1f21b8c6470f5abc4f 100644
+--- a/src/providers/ldap/ldap_id_enum.c
++++ b/src/providers/ldap/ldap_id_enum.c
+@@ -27,14 +27,6 @@
+ #include "providers/ldap/ldap_common.h"
+ #include "providers/ldap/sdap_async_enum.h"
+ 
+-static struct tevent_req *
+-ldap_enumeration_send(TALLOC_CTX *mem_ctx,
+-                      struct tevent_context *ev,
+-                      struct be_ctx *be_ctx,
+-                      struct be_ptask *be_ptask,
+-                      void *pvt);
+-errno_t ldap_enumeration_recv(struct tevent_req *req);
+-
+ struct ldap_enum_ctx {
+     struct sdap_id_ctx *ctx;
+     struct sdap_domain *sdom;
+@@ -43,7 +35,9 @@ struct ldap_enum_ctx {
+ 
+ errno_t ldap_setup_enumeration(struct sdap_id_ctx *ctx,
+                                struct sdap_id_conn_ctx *conn,
+-                               struct sdap_domain *sdom)
++                               struct sdap_domain *sdom,
++                               be_ptask_send_t send_fn,
++                               be_ptask_recv_t recv_fn)
+ {
+     errno_t ret;
+     time_t first_delay;
+@@ -88,7 +82,7 @@ errno_t ldap_setup_enumeration(struct sdap_id_ctx *ctx,
+                           5,                        /* enabled delay */
+                           period,                   /* timeout */
+                           BE_PTASK_OFFLINE_SKIP,
+-                          ldap_enumeration_send, ldap_enumeration_recv,
++                          send_fn, recv_fn,
+                           ectx, "enumeration", &sdom->enum_task);
+     if (ret != EOK) {
+         DEBUG(SSSDBG_FATAL_FAILURE,
+@@ -101,7 +95,6 @@ errno_t ldap_setup_enumeration(struct sdap_id_ctx *ctx,
+     return EOK;
+ }
+ 
+-
+ struct ldap_enumeration_state {
+     struct ldap_enum_ctx *ectx;
+     struct sss_domain_info *dom;
+@@ -109,7 +102,7 @@ struct ldap_enumeration_state {
+ 
+ static void ldap_enumeration_done(struct tevent_req *subreq);
+ 
+-static struct tevent_req *
++struct tevent_req *
+ ldap_enumeration_send(TALLOC_CTX *mem_ctx,
+                       struct tevent_context *ev,
+                       struct be_ctx *be_ctx,
+-- 
+1.8.3.1
+
+-------------- next part --------------
+>From d5e37b2681436cbd65042267ddb791dcbddcf254 Mon Sep 17 00:00:00 2001
+From: Jakub Hrozek <jhrozek at redhat.com>
+Date: Sat, 24 Aug 2013 15:45:57 +0200
+Subject: [PATCH 3/3] AD: Download master domain info when enumerating
+
+https://fedorahosted.org/sssd/ticket/2068
+
+With the current design, downloading master domain data was tied to
+subdomains refresh, triggered by responders. But because enumeration is
+a background task that can't be triggered on its own, we can't rely on
+responders to download the master domain data and we need to check the
+master domain on each enumeration request.
+---
+ src/providers/ad/ad_id.c          | 185 ++++++++++++++++++++++++++++++++++++++
+ src/providers/ad/ad_id.h          |  10 +++
+ src/providers/ad/ad_init.c        |   6 +-
+ src/providers/ldap/ldap_common.h  |  11 +++
+ src/providers/ldap/ldap_id_enum.c |   6 --
+ 5 files changed, 211 insertions(+), 7 deletions(-)
+
+diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
+index 48ad842590d0a8904744cd5518ac511205416f28..1d45440e197e79a60dbc038d2b0c0c8ffe823642 100644
+--- a/src/providers/ad/ad_id.c
++++ b/src/providers/ad/ad_id.c
+@@ -22,6 +22,8 @@
+ #include "util/util.h"
+ #include "providers/ad/ad_common.h"
+ #include "providers/ad/ad_id.h"
++#include "providers/ad/ad_domain_info.h"
++#include "providers/ldap/sdap_async_enum.h"
+ 
+ struct ad_handle_acct_info_state {
+     struct be_req *breq;



More information about the Pkg-sssd-devel mailing list