summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Židek <mzidek@redhat.com>2017-03-02 02:47:11 +0100
committerJakub Hrozek <jhrozek@redhat.com>2017-03-15 16:28:53 +0100
commit231bd1b34023daa3080cf461085e6e4aa7f4d733 (patch)
tree433d578274bfcf2da271939a08eb2140130a54c7 /src
parentebe05e32b5af9b1ee404ebe492e52096d45fb675 (diff)
downloadsssd-231bd1b34023daa3080cf461085e6e4aa7f4d733.tar.gz
sssd-231bd1b34023daa3080cf461085e6e4aa7f4d733.tar.xz
sssd-231bd1b34023daa3080cf461085e6e4aa7f4d733.zip
SUBDOMAINS: Configurable search bases
Added new trusted domain section in the sssd.conf were the search bases for the trusted domain can be specified. Resolves: https://pagure.io/SSSD/sssd/issue/2599 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/providers/ad/ad_common.c274
-rw-r--r--src/providers/ad/ad_common.h22
-rw-r--r--src/providers/ad/ad_subdomains.c13
-rw-r--r--src/providers/ipa/ipa_subdomains_server.c37
-rw-r--r--src/tests/cmocka/test_ad_common.c52
5 files changed, 250 insertions, 148 deletions
diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c
index 9a6fece5d..ec952d3bb 100644
--- a/src/providers/ad/ad_common.c
+++ b/src/providers/ad/ad_common.c
@@ -33,6 +33,13 @@ errno_t ad_set_search_bases(struct sdap_options *id_opts);
static errno_t ad_set_sdap_options(struct ad_options *ad_opts,
struct sdap_options *id_opts);
+char *create_subdom_conf_path(TALLOC_CTX *mem_ctx,
+ const char *conf_path,
+ const char *subdom_name)
+{
+ return talloc_asprintf(mem_ctx, "%s/%s", conf_path, subdom_name);
+}
+
static struct sdap_options *
ad_create_default_sdap_options(TALLOC_CTX *mem_ctx)
{
@@ -107,8 +114,119 @@ fail:
return NULL;
}
+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 = EOK;
+
+ if (cdb == NULL || conf_path == NULL) {
+ /* Fallback to defaults if there is no confdb */
+ id_opts = ad_create_default_sdap_options(mem_ctx);
+ if (id_opts == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Failed to initialize default sdap options\n");
+ ret = EIO;
+ }
+ /* Nothing to do without cdb */
+ goto done;
+ }
+
+ 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;
+ }
+
+ ret = sdap_extend_map_with_list(id_opts, id_opts,
+ SDAP_USER_EXTRA_ATTRS,
+ id_opts->user_map,
+ SDAP_OPTS_USER,
+ &id_opts->user_map,
+ &id_opts->user_map_cnt);
+ 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;
+done:
+ if (ret == EOK) {
+ *_id_opts = id_opts;
+ } else {
+ talloc_free(id_opts);
+ }
+
+ return ret;
+}
+
struct ad_options *
-ad_create_default_options(TALLOC_CTX *mem_ctx)
+ad_create_options(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
+ struct sss_domain_info *subdom)
{
struct ad_options *ad_options;
errno_t ret;
@@ -116,17 +234,32 @@ ad_create_default_options(TALLOC_CTX *mem_ctx)
ad_options = talloc_zero(mem_ctx, struct ad_options);
if (ad_options == NULL) return NULL;
- ret = dp_copy_defaults(ad_options,
- ad_basic_opts,
- AD_OPTS_BASIC,
- &ad_options->basic);
+ if (cdb != NULL && conf_path != NULL) {
+ ret = dp_get_options(ad_options,
+ cdb,
+ conf_path,
+ ad_basic_opts,
+ AD_OPTS_BASIC,
+ &ad_options->basic);
+ } else {
+ /* Fallback to reading the defaults only if no confdb
+ * is available */
+ ret = dp_copy_defaults(ad_options,
+ ad_basic_opts,
+ AD_OPTS_BASIC,
+ &ad_options->basic);
+ }
if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get basic AD options\n");
talloc_free(ad_options);
return NULL;
}
- ad_options->id = ad_create_default_sdap_options(ad_options);
- if (ad_options->id == NULL) {
+ ret = ad_create_sdap_options(ad_options,
+ cdb,
+ conf_path,
+ &ad_options->id);
+ if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD LDAP options\n");
talloc_free(ad_options);
return NULL;
@@ -175,26 +308,33 @@ set_common_ad_trust_opts(struct ad_options *ad_options,
struct ad_options *
ad_create_2way_trust_options(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
const char *realm,
- const char *ad_domain,
+ struct sss_domain_info *subdom,
const char *hostname,
const char *keytab)
{
struct ad_options *ad_options;
errno_t ret;
- ad_options = ad_create_default_options(mem_ctx);
- if (ad_options == NULL) return NULL;
+ ad_options = ad_create_options(mem_ctx, cdb, conf_path, subdom);
+ if (ad_options == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "ad_create_options failed\n");
+ return NULL;
+ }
- ret = set_common_ad_trust_opts(ad_options, realm, ad_domain, hostname,
+ ret = set_common_ad_trust_opts(ad_options, realm, subdom->name, hostname,
keytab);
if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "set_common_ad_trust_opts failed\n");
talloc_free(ad_options);
return NULL;
}
ret = ad_set_sdap_options(ad_options, ad_options->id);
if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "ad_set_sdap_options failed");
talloc_free(ad_options);
return NULL;
}
@@ -204,7 +344,9 @@ ad_create_2way_trust_options(TALLOC_CTX *mem_ctx,
struct ad_options *
ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
- const char *ad_domain,
+ struct confdb_ctx *cdb,
+ const char *subdom_conf_path,
+ struct sss_domain_info *subdom,
const char *hostname,
const char *keytab,
const char *sasl_authid)
@@ -213,18 +355,25 @@ ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
const char *realm;
errno_t ret;
- ad_options = ad_create_default_options(mem_ctx);
- if (ad_options == NULL) return NULL;
+ ad_options = ad_create_options(mem_ctx, cdb, subdom_conf_path, subdom);
+ if (ad_options == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "ad_create_options failed\n");
+ return NULL;
+ }
- realm = get_uppercase_realm(ad_options, ad_domain);
+ realm = get_uppercase_realm(ad_options, subdom->name);
if (!realm) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to get uppercase realm\n");
talloc_free(ad_options);
return NULL;
}
ret = set_common_ad_trust_opts(ad_options, realm,
- ad_domain, hostname, keytab);
+ subdom->name, hostname, keytab);
if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "set_common_ad_trust_opts failed [%d]: %s\n",
+ ret, sss_strerror(ret));
talloc_free(ad_options);
return NULL;
}
@@ -240,6 +389,8 @@ ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
ret = ad_set_sdap_options(ad_options, ad_options->id);
if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "ad_set_sdap_options failed [%d]: %s\n",
+ ret, sss_strerror(ret));
talloc_free(ad_options);
return NULL;
}
@@ -247,97 +398,6 @@ ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
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;
- }
-
- ret = sdap_extend_map_with_list(id_opts, id_opts,
- SDAP_USER_EXTRA_ATTRS,
- id_opts->user_map,
- SDAP_OPTS_USER,
- &id_opts->user_map,
- &id_opts->user_map_cnt);
- 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,
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index 23351e328..e02b932cd 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -99,6 +99,10 @@ struct ad_options {
struct be_nsupdate_ctx *dyndns_ctx;
};
+char *create_subdom_conf_path(TALLOC_CTX *mem_ctx,
+ const char *conf_path,
+ const char *subdom_name);
+
errno_t
ad_get_common_options(TALLOC_CTX *mem_ctx,
struct confdb_ctx *cdb,
@@ -106,20 +110,32 @@ 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);
+/* FIXME: ad_get_common_options and ad_create_options are
+ * similar. The later is subdomain specific. It may be
+ * good to merge the two into one more generic funtion. */
+struct ad_options *ad_create_options(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
+ struct sss_domain_info *subdom);
struct ad_options *ad_create_2way_trust_options(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
const char *realm,
- const char *ad_domain,
+ struct sss_domain_info *subdom,
const char *hostname,
const char *keytab);
struct ad_options *ad_create_1way_trust_options(TALLOC_CTX *mem_ctx,
- const char *ad_domain,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
+ struct sss_domain_info *subdom,
const char *hostname,
const char *keytab,
const char *sasl_authid);
+errno_t ad_set_search_bases(struct sdap_options *id_opts);
+
errno_t
ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx,
const char *primary_servers,
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
index ad075c19a..6787abd59 100644
--- a/src/providers/ad/ad_subdomains.c
+++ b/src/providers/ad/ad_subdomains.c
@@ -158,6 +158,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
const char *realm;
const char *hostname;
const char *keytab;
+ char *subdom_conf_path;
realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM);
hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME);
@@ -168,8 +169,18 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx,
return EINVAL;
}
- ad_options = ad_create_2way_trust_options(id_ctx, realm, ad_domain,
+ subdom_conf_path = create_subdom_conf_path(id_ctx,
+ be_ctx->conf_path,
+ subdom->name);
+ if (subdom_conf_path == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "subdom_conf_path failed\n");
+ return ENOMEM;
+ }
+
+ ad_options = ad_create_2way_trust_options(id_ctx, be_ctx->cdb,
+ subdom_conf_path, realm, subdom,
hostname, keytab);
+ talloc_free(subdom_conf_path);
if (ad_options == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
talloc_free(ad_options);
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index ddd66bf4f..cb270f50d 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -129,6 +129,8 @@ const char *ipa_trust_dir2str(uint32_t direction)
static struct ad_options *
ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx,
+ struct be_ctx *be_ctx,
+ const char *subdom_conf_path,
const char *forest,
const char *forest_realm,
struct sss_domain_info *subdom)
@@ -136,9 +138,7 @@ ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx,
char *keytab;
char *principal;
struct ad_options *ad_options;
- const char *ad_domain;
- ad_domain = subdom->name;
keytab = forest_keytab(id_ctx, forest);
principal = subdomain_trust_princ(id_ctx, forest_realm, subdom);
if (keytab == NULL || principal == NULL) {
@@ -146,7 +146,9 @@ ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx,
}
ad_options = ad_create_1way_trust_options(id_ctx,
- ad_domain,
+ be_ctx->cdb,
+ subdom_conf_path,
+ subdom,
id_ctx->server_mode->hostname,
keytab,
principal);
@@ -159,32 +161,46 @@ ipa_create_1way_trust_ctx(struct ipa_id_ctx *id_ctx,
return ad_options;
}
-static struct ad_options *ipa_ad_options_new(struct ipa_id_ctx *id_ctx,
+static struct ad_options *ipa_ad_options_new(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
struct sss_domain_info *subdom)
{
struct ad_options *ad_options = NULL;
uint32_t direction;
const char *forest;
const char *forest_realm;
+ char *subdom_conf_path;
/* Trusts are only established with forest roots */
direction = subdom->forest_root->trust_direction;
forest_realm = subdom->forest_root->realm;
forest = subdom->forest_root->forest;
+ subdom_conf_path = create_subdom_conf_path(id_ctx,
+ be_ctx->conf_path,
+ subdom->name);
+ if (subdom_conf_path == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "subdom_conf_path failed\n");
+ return NULL;
+ }
+
if (direction & LSA_TRUST_DIRECTION_OUTBOUND) {
ad_options = ad_create_2way_trust_options(id_ctx,
+ be_ctx->cdb,
+ subdom_conf_path,
id_ctx->server_mode->realm,
- subdom->name,
+ subdom,
id_ctx->server_mode->hostname,
NULL);
} else if (direction & LSA_TRUST_DIRECTION_INBOUND) {
- ad_options = ipa_create_1way_trust_ctx(id_ctx, forest,
+ ad_options = ipa_create_1way_trust_ctx(id_ctx, be_ctx,
+ subdom_conf_path, forest,
forest_realm, subdom);
} else {
DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported trust direction!\n");
ad_options = NULL;
}
+ talloc_free(subdom_conf_path);
if (ad_options == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
@@ -214,7 +230,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
ad_domain = subdom->name;
DEBUG(SSSDBG_TRACE_LIBS, "Setting up AD subdomain %s\n", subdom->name);
- ad_options = ipa_ad_options_new(id_ctx, subdom);
+ ad_options = ipa_ad_options_new(be_ctx, id_ctx, subdom);
if (ad_options == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD options\n");
talloc_free(ad_options);
@@ -313,6 +329,13 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx,
return EFAULT;
}
+ ret = ad_set_search_bases(ad_options->id);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD search bases\n");
+ talloc_free(ad_options);
+ return ret;
+ }
+
sdap_inherit_options(subdom->parent->sd_inherit,
id_ctx->sdap_id_ctx->opts,
ad_id_ctx->sdap_id_ctx->opts);
diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c
index ea9998951..3187af1b0 100644
--- a/src/tests/cmocka/test_ad_common.c
+++ b/src/tests/cmocka/test_ad_common.c
@@ -389,24 +389,6 @@ struct ad_common_test_ctx {
struct sss_domain_info *subdom;
};
-static void test_ad_create_default_options(void **state)
-{
- struct ad_options *ad_options;
- const char *s;
-
- ad_options = ad_create_default_options(global_talloc_context);
-
- assert_non_null(ad_options->basic);
-
- /* Not too much to test here except some defaults */
- s = dp_opt_get_string(ad_options->basic, AD_DOMAIN);
- assert_null(s);
-
- assert_non_null(ad_options->id);
-
- talloc_free(ad_options);
-}
-
static int test_ad_common_setup(void **state)
{
struct ad_common_test_ctx *test_ctx;
@@ -462,9 +444,12 @@ static void test_ad_create_1way_trust_options(void **state)
/* Make sure this is not the keytab that __wrap_krb5_kt_default uses */
mock_keytab_with_contents(test_ctx, ONEWAY_KEYTAB_PATH, ONEWAY_TEST_PRINC);
+ test_ctx->subdom->name = discard_const(ONEWAY_DOMNAME);
test_ctx->ad_ctx->ad_options = ad_create_1way_trust_options(
test_ctx->ad_ctx,
- ONEWAY_DOMNAME,
+ NULL,
+ NULL,
+ test_ctx->subdom,
ONEWAY_HOST_NAME,
ONEWAY_KEYTAB_PATH,
ONEWAY_AUTHID);
@@ -524,13 +509,17 @@ static void test_ad_create_2way_trust_options(void **state)
call_real_sasl_options = true;
mock_keytab_with_contents(test_ctx, KEYTAB_PATH, KEYTAB_TEST_PRINC);
+ test_ctx->subdom->name = discard_const(DOMNAME);
test_ctx->ad_ctx->ad_options = ad_create_2way_trust_options(
- test_ctx->ad_ctx,
- REALMNAME,
- DOMNAME,
- HOST_NAME,
- NULL);
+ test_ctx->ad_ctx,
+ NULL,
+ NULL,
+ REALMNAME,
+ test_ctx->subdom,
+ HOST_NAME,
+ NULL);
+
assert_non_null(test_ctx->ad_ctx->ad_options);
assert_int_equal(test_ctx->ad_ctx->ad_options->id->schema_type,
@@ -592,11 +581,15 @@ test_ldap_conn_setup(void **state)
ad_ctx = test_ctx->ad_ctx;
- ad_ctx->ad_options = ad_create_2way_trust_options(ad_ctx,
- REALMNAME,
- DOMNAME,
- HOST_NAME,
- NULL);
+ test_ctx->ad_ctx->ad_options = ad_create_2way_trust_options(
+ ad_ctx,
+ NULL,
+ NULL,
+ REALMNAME,
+ test_ctx->subdom,
+ HOST_NAME,
+ NULL);
+
assert_non_null(ad_ctx->ad_options);
ad_ctx->gc_ctx = talloc_zero(ad_ctx, struct sdap_id_conn_ctx);
@@ -889,7 +882,6 @@ int main(int argc, const char *argv[])
};
const struct CMUnitTest tests[] = {
- cmocka_unit_test(test_ad_create_default_options),
cmocka_unit_test_setup_teardown(test_ad_create_1way_trust_options,
test_ad_common_setup,
test_ad_common_teardown),