>From 46e08f7c82f4d481323d424288ed687225744eec Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 17 Jun 2013 18:32:53 +0200 Subject: [PATCH 3/8] AD: decouple ad_id_ctx initialization The IPA subdomain code will perform lookups on its own in the server mode. For this, the AD provider must offer a way to initialize the ad_id_ctx for external consumers. Subtask of: https://fedorahosted.org/sssd/ticket/1962 --- src/providers/ad/ad_common.c | 350 +++++++++++++++++++++++++++++++++---------- src/providers/ad/ad_common.h | 7 + src/providers/ad/ad_init.c | 30 ++-- 3 files changed, 285 insertions(+), 102 deletions(-) diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c index b06691206f319bf2988f6b56c4d052e02aff423d..2f87bc63ea237e768e550deb7ffe3319d3cf6daf 100644 --- a/src/providers/ad/ad_common.c +++ b/src/providers/ad/ad_common.c @@ -29,6 +29,214 @@ struct ad_server_data { bool gc; }; +errno_t ad_set_search_bases(struct sdap_options *id_opts); +static errno_t ad_set_ad_id_options(struct ad_options *ad_opts, + struct sdap_options *id_opts); + +static struct sdap_options * +ad_create_default_sdap_options(TALLOC_CTX *mem_ctx) +{ + struct sdap_options *id_opts; + errno_t ret; + + id_opts = talloc_zero(mem_ctx, struct sdap_options); + if (!id_opts) { + return NULL; + } + + ret = dp_copy_options(id_opts, + ad_def_ldap_opts, + SDAP_OPTS_BASIC, + &id_opts->basic); + if (ret != EOK) { + goto fail; + } + + /* Get sdap option maps */ + + /* General Attribute Map */ + ret = sdap_copy_map(id_opts, + ad_2008r2_attr_map, + SDAP_AT_GENERAL, + &id_opts->gen_map); + if (ret != EOK) { + goto fail; + } + + /* User map */ + ret = sdap_copy_map(id_opts, + ad_2008r2_user_map, + SDAP_OPTS_USER, + &id_opts->user_map); + if (ret != EOK) { + goto fail; + } + + /* Group map */ + ret = sdap_copy_map(id_opts, + ad_2008r2_group_map, + SDAP_OPTS_GROUP, + &id_opts->group_map); + if (ret != EOK) { + goto fail; + } + + /* Netgroup map */ + ret = sdap_copy_map(id_opts, + ad_netgroup_map, + SDAP_OPTS_NETGROUP, + &id_opts->netgroup_map); + if (ret != EOK) { + goto fail; + } + + /* Services map */ + ret = sdap_copy_map(id_opts, + ad_service_map, + SDAP_OPTS_SERVICES, + &id_opts->service_map); + if (ret != EOK) { + goto fail; + } + + return id_opts; + +fail: + talloc_free(id_opts); + return NULL; +} + +struct ad_options * +ad_create_default_options(TALLOC_CTX *mem_ctx, + const char *realm, + const char *hostname) +{ + struct ad_options *ad_options; + errno_t ret; + + ad_options = talloc_zero(mem_ctx, struct ad_options); + if (ad_options == NULL) return NULL; + + ret = dp_copy_options(ad_options, + ad_basic_opts, + AD_OPTS_BASIC, + &ad_options->basic); + if (ret != EOK) { + talloc_free(ad_options); + return NULL; + } + + ad_options->id = ad_create_default_sdap_options(ad_options); + if (ad_options->id == NULL) { + DEBUG(SSSDBG_OP_FAILURE, ("Cannot initialize AD LDAP options\n")); + talloc_free(ad_options); + return NULL; + } + + ret = dp_opt_set_string(ad_options->basic, AD_KRB5_REALM, realm); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Cannot set AD domain\n")); + talloc_free(ad_options); + return NULL; + } + + ret = dp_opt_set_string(ad_options->basic, AD_HOSTNAME, hostname); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, ("Cannot set AD domain\n")); + talloc_free(ad_options); + return NULL; + } + + ret = ad_set_ad_id_options(ad_options, ad_options->id); + if (ret != EOK) { + talloc_free(ad_options); + return NULL; + } + + return ad_options; +} + +static errno_t +ad_create_sdap_options(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *conf_path, + struct sdap_options **_id_opts) +{ + struct sdap_options *id_opts; + errno_t ret; + + id_opts = talloc_zero(mem_ctx, struct sdap_options); + if (!id_opts) { + ret = ENOMEM; + goto done; + } + + ret = dp_get_options(id_opts, cdb, conf_path, + ad_def_ldap_opts, + SDAP_OPTS_BASIC, + &id_opts->basic); + if (ret != EOK) { + goto done; + } + + /* Get sdap option maps */ + + /* General Attribute Map */ + ret = sdap_get_map(id_opts, + cdb, conf_path, + ad_2008r2_attr_map, + SDAP_AT_GENERAL, + &id_opts->gen_map); + if (ret != EOK) { + goto done; + } + + /* User map */ + ret = sdap_get_map(id_opts, + cdb, conf_path, + ad_2008r2_user_map, + SDAP_OPTS_USER, + &id_opts->user_map); + if (ret != EOK) { + goto done; + } + + /* Group map */ + ret = sdap_get_map(id_opts, + cdb, conf_path, + ad_2008r2_group_map, + SDAP_OPTS_GROUP, + &id_opts->group_map); + if (ret != EOK) { + goto done; + } + + /* Netgroup map */ + ret = sdap_get_map(id_opts, + cdb, conf_path, + ad_netgroup_map, + SDAP_OPTS_NETGROUP, + &id_opts->netgroup_map); + if (ret != EOK) { + goto done; + } + + /* Services map */ + ret = sdap_get_map(id_opts, + cdb, conf_path, + ad_service_map, + SDAP_OPTS_SERVICES, + &id_opts->service_map); + if (ret != EOK) { + goto done; + } + + ret = EOK; + *_id_opts = id_opts; +done: + return ret; +} + errno_t ad_get_common_options(TALLOC_CTX *mem_ctx, struct confdb_ctx *cdb, @@ -576,49 +784,14 @@ done: return; } -errno_t -ad_set_search_bases(struct sdap_options *id_opts); - -errno_t -ad_get_id_options(struct ad_options *ad_opts, - struct confdb_ctx *cdb, - const char *conf_path, - struct sdap_options **_opts) +static errno_t +ad_set_ad_id_options(struct ad_options *ad_opts, + struct sdap_options *id_opts) { errno_t ret; - TALLOC_CTX *tmp_ctx; - struct sdap_options *id_opts; char *krb5_realm; char *keytab_path; - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) return ENOMEM; - - id_opts = talloc_zero(tmp_ctx, struct sdap_options); - if (!id_opts) { - ret = ENOMEM; - goto done; - } - - ret = sdap_domain_add(id_opts, - ad_opts->id_ctx->sdap_id_ctx->be->domain, - NULL); - if (ret != EOK) { - goto done; - } - - ret = dp_get_options(id_opts, cdb, conf_path, - ad_def_ldap_opts, - SDAP_OPTS_BASIC, - &id_opts->basic); - if (ret != EOK) { - goto done; - } - - /* Set up search bases if they were assigned explicitly */ - ret = ad_set_search_bases(id_opts); - if (ret != EOK) goto done; - /* We only support Kerberos password policy with AD, so * force that on. */ @@ -671,64 +844,49 @@ ad_get_id_options(struct ad_options *ad_opts, /* fix schema to AD */ id_opts->schema_type = SDAP_SCHEMA_AD; - /* Get sdap option maps */ + ad_opts->id = id_opts; + ret = EOK; +done: + return ret; +} - /* General Attribute Map */ - ret = sdap_get_map(id_opts, - cdb, conf_path, - ad_2008r2_attr_map, - SDAP_AT_GENERAL, - &id_opts->gen_map); - if (ret != EOK) { - goto done; - } +errno_t +ad_get_id_options(struct ad_options *ad_opts, + struct confdb_ctx *cdb, + const char *conf_path, + struct sdap_options **_opts) +{ + struct sdap_options *id_opts; + errno_t ret; - /* User map */ - ret = sdap_get_map(id_opts, - cdb, conf_path, - ad_2008r2_user_map, - SDAP_OPTS_USER, - &id_opts->user_map); + ret = ad_create_sdap_options(ad_opts, cdb, conf_path, &id_opts); if (ret != EOK) { - goto done; + return ENOMEM; } - /* Group map */ - ret = sdap_get_map(id_opts, - cdb, conf_path, - ad_2008r2_group_map, - SDAP_OPTS_GROUP, - &id_opts->group_map); + ret = ad_set_ad_id_options(ad_opts, id_opts); if (ret != EOK) { - goto done; + talloc_free(id_opts); + return ret; } - /* Netgroup map */ - ret = sdap_get_map(id_opts, - cdb, conf_path, - ad_netgroup_map, - SDAP_OPTS_NETGROUP, - &id_opts->netgroup_map); + ret = sdap_domain_add(id_opts, + ad_opts->id_ctx->sdap_id_ctx->be->domain, + NULL); if (ret != EOK) { - goto done; + talloc_free(id_opts); + return ret; } - /* Services map */ - ret = sdap_get_map(id_opts, - cdb, conf_path, - ad_service_map, - SDAP_OPTS_SERVICES, - &id_opts->service_map); + /* Set up search bases if they were assigned explicitly */ + ret = ad_set_search_bases(id_opts); if (ret != EOK) { - goto done; + talloc_free(id_opts); + return ret; } - ad_opts->id = talloc_steal(ad_opts, id_opts); *_opts = id_opts; - ret = EOK; -done: - talloc_free(tmp_ctx); - return ret; + return EOK; } errno_t @@ -898,3 +1056,33 @@ errno_t ad_get_dyndns_options(struct be_ctx *be_ctx, return EOK; } + + +struct ad_id_ctx * +ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx) +{ + struct sdap_id_ctx *sdap_ctx; + struct ad_id_ctx *ad_ctx; + + ad_ctx = talloc_zero(ad_opts, struct ad_id_ctx); + if (ad_ctx == NULL) { + return NULL; + } + ad_ctx->ad_options = ad_opts; + + sdap_ctx = sdap_id_ctx_new(ad_ctx, bectx, ad_opts->service->sdap); + if (sdap_ctx == NULL) { + talloc_free(ad_ctx); + return NULL; + } + ad_ctx->sdap_id_ctx = sdap_ctx; + ad_ctx->ldap_ctx = sdap_ctx->conn; + + ad_ctx->gc_ctx = sdap_id_ctx_conn_add(sdap_ctx, ad_opts->service->gc); + if (ad_ctx->gc_ctx == NULL) { + talloc_free(ad_ctx); + return NULL; + } + + return ad_ctx; +} diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h index 500f49c783d488e217955fad2472177fbf733de5..11075423c15854a236e0acabbdcce4551b6097b2 100644 --- a/src/providers/ad/ad_common.h +++ b/src/providers/ad/ad_common.h @@ -82,6 +82,10 @@ ad_get_common_options(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, struct ad_options **_opts); +struct ad_options *ad_create_default_options(TALLOC_CTX *mem_ctx, + const char *realm, + const char *hostname); + errno_t ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, const char *primary_servers, @@ -104,6 +108,9 @@ errno_t ad_get_dyndns_options(struct be_ctx *be_ctx, struct ad_options *ad_opts); +struct ad_id_ctx * +ad_id_ctx_init(struct ad_options *ad_opts, struct be_ctx *bectx); + /* AD dynamic DNS updates */ errno_t ad_dyndns_init(struct be_ctx *be_ctx, struct ad_options *ctx); diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c index 5c6b6f5c84afc3597ff2a65e91e20d2fb7e69f9a..5efe05e6424784484ebbad0a950849fc128bc81d 100644 --- a/src/providers/ad/ad_init.c +++ b/src/providers/ad/ad_init.c @@ -109,7 +109,6 @@ sssm_ad_id_init(struct be_ctx *bectx, { errno_t ret; struct ad_id_ctx *ad_ctx; - struct sdap_id_ctx *sdap_ctx; const char *hostname; const char *ad_domain; struct ad_srv_plugin_ctx *srv_ctx; @@ -128,26 +127,14 @@ sssm_ad_id_init(struct be_ctx *bectx, return EOK; } - ad_ctx = talloc_zero(ad_options, struct ad_id_ctx); + + ad_ctx = ad_id_ctx_init(ad_options, bectx); if (ad_ctx == NULL) { return ENOMEM; } - ad_ctx->ad_options = ad_options; ad_options->id_ctx = ad_ctx; - sdap_ctx = sdap_id_ctx_new(ad_options, bectx, ad_options->service->sdap); - if (sdap_ctx == NULL) { - return ENOMEM; - } - ad_ctx->sdap_id_ctx = sdap_ctx; - ad_ctx->ldap_ctx = sdap_ctx->conn; - - ad_ctx->gc_ctx = sdap_id_ctx_conn_add(sdap_ctx, ad_options->service->gc); - if (ad_ctx->gc_ctx == NULL) { - return ENOMEM; - } - - ret = ad_dyndns_init(sdap_ctx->be, ad_options); + ret = ad_dyndns_init(ad_ctx->sdap_id_ctx->be, ad_options); if (ret != EOK) { DEBUG(SSSDBG_MINOR_FAILURE, ("Failure setting up automatic DNS update\n")); @@ -165,22 +152,23 @@ sssm_ad_id_init(struct be_ctx *bectx, /* Set up various SDAP options */ ret = ad_get_id_options(ad_options, bectx->cdb, bectx->conf_path, - &sdap_ctx->opts); + &ad_ctx->sdap_id_ctx->opts); if (ret != EOK) { goto done; } - ret = sdap_id_setup_tasks(sdap_ctx); + ret = sdap_id_setup_tasks(ad_ctx->sdap_id_ctx); if (ret != EOK) { goto done; } /* Set up the ID mapping object */ - ret = sdap_idmap_init(sdap_ctx, sdap_ctx, &sdap_ctx->opts->idmap_ctx); + ret = sdap_idmap_init(ad_ctx->sdap_id_ctx, ad_ctx->sdap_id_ctx, + &ad_ctx->sdap_id_ctx->opts->idmap_ctx); if (ret != EOK) goto done; - ret = setup_tls_config(sdap_ctx->opts->basic); + ret = setup_tls_config(ad_ctx->sdap_id_ctx->opts->basic); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, ("setup_tls_config failed [%s]\n", strerror(ret))); @@ -217,7 +205,7 @@ sssm_ad_id_init(struct be_ctx *bectx, ret = be_refresh_add_cb(bectx->refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, sdap_refresh_netgroups_send, sdap_refresh_netgroups_recv, - sdap_ctx); + ad_ctx->sdap_id_ctx); if (ret != EOK && ret != EEXIST) { DEBUG(SSSDBG_MINOR_FAILURE, ("Periodical refresh of netgroups " "will not work [%d]: %s\n", ret, strerror(ret))); -- 1.8.3.1