|
|
2fc102 |
From 0324d31d0479e5de0d3aac05bf5fb922d84f84c4 Mon Sep 17 00:00:00 2001
|
|
|
2fc102 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
2fc102 |
Date: Mon, 9 Dec 2013 11:45:28 +0100
|
|
|
2fc102 |
Subject: [PATCH 17/17] AD: use LDAP for group lookups
|
|
|
2fc102 |
|
|
|
2fc102 |
The group memberships cannot be reliable retrieved from the Global
|
|
|
2fc102 |
Catalog. By default the memberOf attribute is not replicated to the GC
|
|
|
2fc102 |
at all and the member attribute is copied from the local LDAP instance
|
|
|
2fc102 |
to the GC running on the same host, but is only replicated to other GC
|
|
|
2fc102 |
instances for groups with universal scope. Additionally the tokenGroups
|
|
|
2fc102 |
attribute contains invalid SIDs when used with the GC for users from a
|
|
|
2fc102 |
different domains than the GC belongs to.
|
|
|
2fc102 |
|
|
|
2fc102 |
As a result the requests which tries to resolve group-memberships of a
|
|
|
2fc102 |
AD user have to go to a LDAP server from the domain of the user.
|
|
|
2fc102 |
|
|
|
2fc102 |
Fixes https://fedorahosted.org/sssd/ticket/2161 and
|
|
|
2fc102 |
https://fedorahosted.org/sssd/ticket/2148 as a side-effect.
|
|
|
2fc102 |
---
|
|
|
2fc102 |
src/providers/ad/ad_id.c | 20 +++++-
|
|
|
2fc102 |
src/providers/ad/ad_subdomains.c | 133 ++++++++++++++++++++++++++++++++++++++-
|
|
|
2fc102 |
src/providers/ldap/sdap.h | 2 +
|
|
|
2fc102 |
3 files changed, 152 insertions(+), 3 deletions(-)
|
|
|
2fc102 |
|
|
|
2fc102 |
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
|
|
|
2fc102 |
index 87b69c66892ebfa48a1067c63006f3e3bd2e7444..dadb50da92cac87d3162bddb44395dad7d2abbc4 100644
|
|
|
2fc102 |
--- a/src/providers/ad/ad_id.c
|
|
|
2fc102 |
+++ b/src/providers/ad/ad_id.c
|
|
|
2fc102 |
@@ -188,6 +188,8 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
|
|
|
2fc102 |
struct sss_domain_info *dom, struct be_acct_req *ar)
|
|
|
2fc102 |
{
|
|
|
2fc102 |
struct sdap_id_conn_ctx **clist;
|
|
|
2fc102 |
+ struct sdap_domain *sdom;
|
|
|
2fc102 |
+ struct ad_id_ctx *subdom_id_ctx;
|
|
|
2fc102 |
|
|
|
2fc102 |
/* LDAP, GC, sentinel */
|
|
|
2fc102 |
clist = talloc_zero_array(breq, struct sdap_id_conn_ctx *, 3);
|
|
|
2fc102 |
@@ -197,8 +199,6 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
|
|
|
2fc102 |
case BE_REQ_USER: /* user */
|
|
|
2fc102 |
case BE_REQ_BY_SECID: /* by SID */
|
|
|
2fc102 |
case BE_REQ_USER_AND_GROUP: /* get SID */
|
|
|
2fc102 |
- case BE_REQ_GROUP: /* group */
|
|
|
2fc102 |
- case BE_REQ_INITGROUPS: /* init groups for user */
|
|
|
2fc102 |
/* Always try GC first */
|
|
|
2fc102 |
clist[0] = ad_ctx->gc_ctx;
|
|
|
2fc102 |
if (IS_SUBDOMAIN(dom) == true) {
|
|
|
2fc102 |
@@ -216,6 +216,22 @@ get_conn_list(struct be_req *breq, struct ad_id_ctx *ad_ctx,
|
|
|
2fc102 |
clist[1] = ad_ctx->ldap_ctx;
|
|
|
2fc102 |
break;
|
|
|
2fc102 |
|
|
|
2fc102 |
+ case BE_REQ_GROUP: /* group */
|
|
|
2fc102 |
+ case BE_REQ_INITGROUPS: /* init groups for user */
|
|
|
2fc102 |
+ if (IS_SUBDOMAIN(dom)) {
|
|
|
2fc102 |
+ sdom = sdap_domain_get(ad_ctx->sdap_id_ctx->opts, dom);
|
|
|
2fc102 |
+ if (sdom == NULL || sdom->pvt == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CRIT_FAILURE, ("No ID ctx available for [%s].\n",
|
|
|
2fc102 |
+ dom->name));
|
|
|
2fc102 |
+ return NULL;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ subdom_id_ctx = talloc_get_type(sdom->pvt, struct ad_id_ctx);
|
|
|
2fc102 |
+ clist[0] = subdom_id_ctx->ldap_ctx;
|
|
|
2fc102 |
+ } else {
|
|
|
2fc102 |
+ clist[0] = ad_ctx->ldap_ctx;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ break;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
default:
|
|
|
2fc102 |
clist[0] = ad_ctx->ldap_ctx;
|
|
|
2fc102 |
break;
|
|
|
2fc102 |
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
|
|
|
2fc102 |
index 18414523096ba0e53261415551eea57b4b2758b2..28c5eafb395b70e8f3630a43b67c61810683fe7c 100644
|
|
|
2fc102 |
--- a/src/providers/ad/ad_subdomains.c
|
|
|
2fc102 |
+++ b/src/providers/ad/ad_subdomains.c
|
|
|
2fc102 |
@@ -25,6 +25,7 @@
|
|
|
2fc102 |
#include "providers/ldap/sdap_async.h"
|
|
|
2fc102 |
#include "providers/ad/ad_subdomains.h"
|
|
|
2fc102 |
#include "providers/ad/ad_domain_info.h"
|
|
|
2fc102 |
+#include "providers/ad/ad_srv.h"
|
|
|
2fc102 |
#include "providers/ldap/sdap_idmap.h"
|
|
|
2fc102 |
#include "util/util_sss_idmap.h"
|
|
|
2fc102 |
#include <ctype.h>
|
|
|
2fc102 |
@@ -68,6 +69,7 @@ struct ad_subdomains_ctx {
|
|
|
2fc102 |
|
|
|
2fc102 |
time_t last_refreshed;
|
|
|
2fc102 |
struct tevent_timer *timer_event;
|
|
|
2fc102 |
+ struct ad_id_ctx *ad_id_ctx;
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
struct ad_subdomains_req_ctx {
|
|
|
2fc102 |
@@ -86,10 +88,138 @@ struct ad_subdomains_req_ctx {
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
static errno_t
|
|
|
2fc102 |
+ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
|
|
|
2fc102 |
+ struct ad_id_ctx *id_ctx,
|
|
|
2fc102 |
+ struct sss_domain_info *subdom,
|
|
|
2fc102 |
+ struct ad_id_ctx **_subdom_id_ctx)
|
|
|
2fc102 |
+{
|
|
|
2fc102 |
+ struct ad_options *ad_options;
|
|
|
2fc102 |
+ struct ad_id_ctx *ad_id_ctx;
|
|
|
2fc102 |
+ const char *gc_service_name;
|
|
|
2fc102 |
+ struct ad_srv_plugin_ctx *srv_ctx;
|
|
|
2fc102 |
+ char *ad_domain;
|
|
|
2fc102 |
+ struct sdap_domain *sdom;
|
|
|
2fc102 |
+ errno_t ret;
|
|
|
2fc102 |
+ const char *realm;
|
|
|
2fc102 |
+ const char *hostname;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM);
|
|
|
2fc102 |
+ hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME);
|
|
|
2fc102 |
+ if (realm == NULL || hostname == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_CONF_SETTINGS, ("Missing realm or hostname.\n"));
|
|
|
2fc102 |
+ return EINVAL;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ad_options = ad_create_default_options(id_ctx, realm, hostname);
|
|
|
2fc102 |
+ if (ad_options == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot initialize AD options\n"));
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ad_domain = subdom->name;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = dp_opt_set_string(ad_options->basic, AD_DOMAIN, ad_domain);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot set AD domain\n"));
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ gc_service_name = talloc_asprintf(ad_options, "%s%s", "gc_", subdom->name);
|
|
|
2fc102 |
+ if (gc_service_name == NULL) {
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = ad_failover_init(ad_options, be_ctx, NULL, NULL, realm,
|
|
|
2fc102 |
+ subdom->name, gc_service_name,
|
|
|
2fc102 |
+ subdom->name, &ad_options->service);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot initialize AD failover\n"));
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ad_id_ctx = ad_id_ctx_init(ad_options, be_ctx);
|
|
|
2fc102 |
+ if (ad_id_ctx == NULL) {
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ ad_id_ctx->sdap_id_ctx->opts = ad_options->id;
|
|
|
2fc102 |
+ ad_options->id_ctx = ad_id_ctx;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* use AD plugin */
|
|
|
2fc102 |
+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res,
|
|
|
2fc102 |
+ default_host_dbs,
|
|
|
2fc102 |
+ ad_id_ctx->ad_options->id,
|
|
|
2fc102 |
+ hostname,
|
|
|
2fc102 |
+ ad_domain);
|
|
|
2fc102 |
+ if (srv_ctx == NULL) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory?\n"));
|
|
|
2fc102 |
+ return ENOMEM;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ be_fo_set_srv_lookup_plugin(be_ctx, ad_srv_plugin_send,
|
|
|
2fc102 |
+ ad_srv_plugin_recv, srv_ctx, "AD");
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_domain_subdom_add(ad_id_ctx->sdap_id_ctx,
|
|
|
2fc102 |
+ ad_id_ctx->sdap_id_ctx->opts->sdom,
|
|
|
2fc102 |
+ subdom->parent);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot initialize sdap domain\n"));
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ sdom = sdap_domain_get(ad_id_ctx->sdap_id_ctx->opts, subdom);
|
|
|
2fc102 |
+ if (sdom == NULL) {
|
|
|
2fc102 |
+ return EFAULT;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_id_setup_tasks(ad_id_ctx->sdap_id_ctx,
|
|
|
2fc102 |
+ ad_id_ctx->ldap_ctx, sdom,
|
|
|
2fc102 |
+ ldap_enumeration_send,
|
|
|
2fc102 |
+ ldap_enumeration_recv);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ talloc_free(ad_options);
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ /* Set up the ID mapping object */
|
|
|
2fc102 |
+ ad_id_ctx->sdap_id_ctx->opts->idmap_ctx =
|
|
|
2fc102 |
+ id_ctx->sdap_id_ctx->opts->idmap_ctx;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ *_subdom_id_ctx = ad_id_ctx;
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
+}
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+static errno_t
|
|
|
2fc102 |
ads_store_sdap_subdom(struct ad_subdomains_ctx *ctx,
|
|
|
2fc102 |
struct sss_domain_info *parent)
|
|
|
2fc102 |
{
|
|
|
2fc102 |
- return sdap_domain_subdom_add(ctx->sdap_id_ctx, ctx->sdom, parent);
|
|
|
2fc102 |
+ int ret;
|
|
|
2fc102 |
+ struct sdap_domain *sditer;
|
|
|
2fc102 |
+ struct ad_id_ctx *subdom_id_ctx;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ ret = sdap_domain_subdom_add(ctx->sdap_id_ctx, ctx->sdom, parent);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("sdap_domain_subdom_add failed.\n"));
|
|
|
2fc102 |
+ return ret;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ DLIST_FOR_EACH(sditer, ctx->sdom) {
|
|
|
2fc102 |
+ if (IS_SUBDOMAIN(sditer->dom) && sditer->pvt == NULL) {
|
|
|
2fc102 |
+ ret = ad_subdom_ad_ctx_new(ctx->be_ctx, ctx->ad_id_ctx,
|
|
|
2fc102 |
+ sditer->dom, &subdom_id_ctx);
|
|
|
2fc102 |
+ if (ret != EOK) {
|
|
|
2fc102 |
+ DEBUG(SSSDBG_OP_FAILURE, ("ad_subdom_ad_ctx_new failed.\n"));
|
|
|
2fc102 |
+ } else {
|
|
|
2fc102 |
+ sditer->pvt = subdom_id_ctx;
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+ }
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ return EOK;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
|
|
|
2fc102 |
static errno_t
|
|
|
2fc102 |
@@ -630,6 +760,7 @@ int ad_subdom_init(struct be_ctx *be_ctx,
|
|
|
2fc102 |
DEBUG(SSSDBG_OP_FAILURE, ("talloc_strdup failed.\n"));
|
|
|
2fc102 |
return ENOMEM;
|
|
|
2fc102 |
}
|
|
|
2fc102 |
+ ctx->ad_id_ctx = id_ctx;
|
|
|
2fc102 |
*ops = &ad_subdomains_ops;
|
|
|
2fc102 |
*pvt_data = ctx;
|
|
|
2fc102 |
|
|
|
2fc102 |
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
|
|
|
2fc102 |
index c53471b9bd6d9b18f37a8bf4089c8700d4a1163d..fa641730bb78b6a96c0b9640af7612b876f56533 100644
|
|
|
2fc102 |
--- a/src/providers/ldap/sdap.h
|
|
|
2fc102 |
+++ b/src/providers/ldap/sdap.h
|
|
|
2fc102 |
@@ -394,6 +394,8 @@ struct sdap_domain {
|
|
|
2fc102 |
struct timeval last_enum;
|
|
|
2fc102 |
/* cleanup loop timer */
|
|
|
2fc102 |
struct timeval last_purge;
|
|
|
2fc102 |
+
|
|
|
2fc102 |
+ void *pvt;
|
|
|
2fc102 |
};
|
|
|
2fc102 |
|
|
|
2fc102 |
struct sdap_options {
|
|
|
2fc102 |
--
|
|
|
2fc102 |
1.8.4.2
|
|
|
2fc102 |
|