summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-09-16 15:26:24 +0200
committerSumit Bose <sbose@redhat.com>2014-09-16 15:27:48 +0200
commita2525ccdcd232330109ad196f64a034ce88f56f4 (patch)
treeddf077867aaee87b91462b322acb3c250fa6ef48
parent6cb2bac6412d5d4d6be2c6e50a645565f3c74107 (diff)
downloadsssd-wip-extdom.tar.gz
sssd-wip-extdom.tar.xz
sssd-wip-extdom.zip
IPA: add view supportwip-extdom
-rw-r--r--src/db/sysdb.h4
-rw-r--r--src/providers/ipa/ipa_common.c44
-rw-r--r--src/providers/ipa/ipa_common.h27
-rw-r--r--src/providers/ipa/ipa_init.c6
-rw-r--r--src/providers/ipa/ipa_opts.h23
-rw-r--r--src/providers/ipa/ipa_subdomains.c166
6 files changed, 260 insertions, 10 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index fca2aec2a..9c4e04ad8 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -142,6 +142,10 @@
#define SYSDB_VIEW_CLASS "view"
#define SYSDB_VIEW_NAME "viewName"
+#define SYSDB_OVERRIDE_CLASS "overrride"
+#define SYSDB_OVERRIDE_ANCHOR_UUID "overrideAnchorUUID"
+#define SYSDB_OVERRIDE_USER_CLASS "userOverride"
+#define SYSDB_OVERRIDE_GROUP_CLASS "groupOverride"
#define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)"
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index f594de27a..2940a42cc 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -149,6 +149,9 @@ static errno_t ipa_parse_search_base(TALLOC_CTX *mem_ctx,
case IPA_RANGES_SEARCH_BASE:
class_name = "IPA_RANGES";
break;
+ case IPA_VIEWS_SEARCH_BASE:
+ class_name = "IPA_VIEWS";
+ break;
default:
DEBUG(SSSDBG_CONF_SETTINGS,
"Unknown search base type: [%d]\n", class);
@@ -530,6 +533,29 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
&ipa_opts->ranges_search_bases);
if (ret != EOK) goto done;
+ if (NULL == dp_opt_get_string(ipa_opts->basic,
+ IPA_VIEWS_SEARCH_BASE)) {
+ value = talloc_asprintf(tmpctx, "cn=views,cn=accounts,%s", basedn);
+ if (value == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = dp_opt_set_string(ipa_opts->basic, IPA_VIEWS_SEARCH_BASE, value);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n",
+ ipa_opts->basic[IPA_VIEWS_SEARCH_BASE].opt_name,
+ dp_opt_get_string(ipa_opts->basic,
+ IPA_VIEWS_SEARCH_BASE));
+ }
+ ret = ipa_parse_search_base(ipa_opts, ipa_opts->basic,
+ IPA_VIEWS_SEARCH_BASE,
+ &ipa_opts->views_search_bases);
+ if (ret != EOK) goto done;
+
ret = sdap_get_map(ipa_opts->id, cdb, conf_path,
ipa_attr_map,
SDAP_AT_GENERAL,
@@ -611,6 +637,24 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
goto done;
}
+ ret = sdap_get_map(ipa_opts->id,
+ cdb, conf_path,
+ ipa_view_map,
+ IPA_OPTS_VIEW,
+ &ipa_opts->view_map);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sdap_get_map(ipa_opts->id,
+ cdb, conf_path,
+ ipa_override_map,
+ IPA_OPTS_OVERRIDE,
+ &ipa_opts->override_map);
+ if (ret != EOK) {
+ goto done;
+ }
+
ret = EOK;
*_opts = ipa_opts->id;
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 0b8a17c53..2207604b7 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -53,6 +53,7 @@ enum ipa_basic_opt {
IPA_RANGES_SEARCH_BASE,
IPA_ENABLE_DNS_SITES,
IPA_SERVER_MODE,
+ IPA_VIEWS_SEARCH_BASE,
IPA_OPTS_BASIC /* opts counter */
};
@@ -107,6 +108,28 @@ enum ipa_selinux_usermap_attrs {
IPA_OPTS_SELINUX_USERMAP /* attrs counter */
};
+enum ipa_view_attrs {
+ IPA_OC_VIEW = 0,
+ IPA_AT_VIEW_NAME,
+
+ IPA_OPTS_VIEW
+};
+
+enum ipa_override_attrs {
+ IPA_OC_OVERRIDE = 0,
+ IPA_AT_OVERRIDE_ANCHOR_UUID,
+ IPA_AT_OVERRIDE_USER_NAME,
+ IPA_AT_OVERRIDE_UID_NUMBER,
+ IPA_AT_OVERRIDE_USER_GID_NUMBER,
+ IPA_AT_OVERRIDE_GECOS,
+ IPA_AT_OVERRIDE_HOMEDIR,
+ IPA_AT_OVERRIDE_SHELL,
+ IPA_AT_OVERRIDE_GROUP,
+ IPA_AT_OVERRIDE_GROUP_GID_NUMBER,
+
+ IPA_OPTS_OVERRIDE
+};
+
struct ipa_auth_ctx {
struct krb5_ctx *krb5_auth_ctx;
struct sdap_id_ctx *sdap_id_ctx;
@@ -120,6 +143,7 @@ struct ipa_id_ctx {
struct sdap_id_ctx *sdap_id_ctx;
struct ipa_options *ipa_options;
+ char *view_name;
/* Only used with server mode */
struct ipa_server_mode_ctx *server_mode;
};
@@ -130,6 +154,8 @@ struct ipa_options {
struct sdap_attr_map *host_map;
struct sdap_attr_map *hostgroup_map;
struct sdap_attr_map *selinuxuser_map;
+ struct sdap_attr_map *view_map;
+ struct sdap_attr_map *override_map;
struct sdap_search_base **host_search_bases;
struct sdap_search_base **hbac_search_bases;
@@ -137,6 +163,7 @@ struct ipa_options {
struct sdap_search_base **subdomains_search_bases;
struct sdap_search_base **master_domain_search_bases;
struct sdap_search_base **ranges_search_bases;
+ struct sdap_search_base **views_search_bases;
struct ipa_service *service;
/* id provider */
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index c1a9cc71d..51d8b1e3d 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -244,6 +244,12 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
server_mode = dp_opt_get_bool(ipa_options->basic, IPA_SERVER_MODE);
if (server_mode == true) {
+ ipa_ctx->view_name = talloc_strdup(ipa_ctx, "default");
+ if (ipa_ctx->view_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
ipa_servers = dp_opt_get_string(ipa_options->basic, IPA_SERVER);
if (srv_in_server_list(ipa_servers) == true
|| dp_opt_get_bool(ipa_options->basic,
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 30cb96b3d..4785e0164 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -50,6 +50,7 @@ struct dp_option ipa_basic_opts[] = {
{ "ipa_ranges_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ipa_enable_dns_sites", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
{ "ipa_server_mode", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+ { "ipa_views_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
DP_OPTION_TERMINATOR
};
@@ -263,6 +264,28 @@ struct sdap_attr_map ipa_selinux_user_map[] = {
SDAP_ATTR_MAP_TERMINATOR
};
+struct sdap_attr_map ipa_view_map[] = {
+ { "ipa_view_class", "nsContainer", SYSDB_VIEW_CLASS, NULL},
+ { "ipa_view_name", "cn", SYSDB_VIEW_NAME, NULL},
+ SDAP_ATTR_MAP_TERMINATOR
+};
+
+struct sdap_attr_map ipa_override_map[] = {
+ { "ipa_overide_object_class", "ipaOverrideAnchor", SYSDB_OVERRIDE_CLASS, NULL},
+ { "ipa_anchor_uuid", "ipaAnchorUUID", SYSDB_OVERRIDE_ANCHOR_UUID, NULL},
+ { "ipa_user_override_object_class", "ipaUserOverride", SYSDB_OVERRIDE_USER_CLASS, NULL},
+ { "ipa_group_override_object_class", "ipaGroupOverride", SYSDB_OVERRIDE_GROUP_CLASS, NULL},
+ { "ldap_user_name", "uid", SYSDB_NAME, NULL },
+ { "ldap_user_uid_number", "uidNumber", SYSDB_UIDNUM, NULL },
+ { "ldap_user_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
+ { "ldap_user_gecos", "gecos", SYSDB_GECOS, NULL },
+ { "ldap_user_home_directory", "homeDirectory", SYSDB_HOMEDIR, NULL },
+ { "ldap_user_shell", "loginShell", SYSDB_SHELL, NULL },
+ { "ldap_group_name", "cn", SYSDB_NAME, NULL },
+ { "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
+ SDAP_ATTR_MAP_TERMINATOR
+};
+
struct dp_option ipa_def_krb5_opts[] = {
{ "krb5_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "krb5_backup_server", DP_OPT_STRING, NULL_STRING, NULL_STRING },
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 524504846..1fe4c4d8d 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -44,6 +44,9 @@
#define IPA_SECONDARY_BASE_RID "ipaSecondaryBaseRID"
#define OBJECTCLASS "objectClass"
+#define IPA_ASSIGNED_ID_VIEW "ipaAssignedIDView"
+#define DEFAULT_VIEW "default"
+
/* do not refresh more often than every 5 seconds for now */
#define IPA_SUBDOMAIN_REFRESH_LIMIT 5
@@ -70,6 +73,7 @@ struct ipa_subdomains_ctx {
struct sdap_search_base **search_bases;
struct sdap_search_base **master_search_bases;
struct sdap_search_base **ranges_search_bases;
+ struct sdap_search_base **host_search_bases;
time_t last_refreshed;
struct tevent_timer *timer_event;
@@ -943,6 +947,111 @@ ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
return EAGAIN;
}
+static void ipa_get_view_name_done(struct tevent_req *req);
+static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx);
+
+static errno_t ipa_get_view_name(struct ipa_subdomains_req_ctx *ctx)
+{
+ struct tevent_req *req;
+ struct sdap_search_base *base;
+ const char *attrs[] = {IPA_CN, OBJECTCLASS, NULL};
+ struct sdap_attr_map_info *maps;
+
+ maps = talloc_zero(ctx, struct sdap_attr_map_info);
+ if (maps == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
+ return ENOMEM;
+ }
+ maps->map = ctx->sd_ctx->id_ctx->ipa_options->view_map;
+ maps->num_attrs = IPA_OPTS_VIEW;
+
+ base = ctx->search_bases[ctx->search_base_iter];
+ if (base == NULL) {
+ return EOK;
+ }
+
+ req = sdap_deref_search_with_filter_send(ctx, ctx->sd_ctx->be_ctx->ev,
+ ctx->sd_ctx->sdap_id_ctx->opts,
+ sdap_id_op_handle(ctx->sdap_op),
+ base->basedn,
+ ctx->current_filter, IPA_ASSIGNED_ID_VIEW, attrs,
+ 1, maps,
+ dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
+ SDAP_SEARCH_TIMEOUT));
+
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(req, ipa_get_view_name_done, ctx);
+
+ return EAGAIN;
+}
+
+static void ipa_get_view_name_done(struct tevent_req *req)
+{
+ int ret;
+ struct ipa_subdomains_req_ctx *ctx;
+ size_t reply_count;
+ struct sdap_deref_attrs **reply = NULL;
+ const char *view_name;
+ int dp_error = DP_ERR_FATAL;
+
+ ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
+
+ ret = sdap_deref_search_recv(req, ctx, &reply_count, &reply);
+ talloc_zfree(req);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "get_view_name request failed.\n");
+ goto done;
+ }
+
+ if (reply_count == 0) {
+ ctx->search_base_iter++;
+ ret = ipa_get_view_name(ctx);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_ALL, "No view found, using default");
+ view_name = DEFAULT_VIEW;
+ } else {
+ goto done;
+ }
+ } else if (reply_count > 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "get_view_name request returned more than one object.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_string(reply[0]->attrs, SYSDB_VIEW_NAME, &view_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, "Found view name [%s].\n", view_name);
+
+ ret = sysdb_update_view_name(ctx->sd_ctx->be_ctx->domain, view_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot add/update view name to sysdb.\n");
+ }
+
+ ret = ipa_check_master(ctx);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret != EOK) {
+ goto done;
+ }
+
+done:
+ if (ret == EOK) {
+ dp_error = DP_ERR_OK;
+ }
+ be_req_terminate(ctx->be_req, dp_error, ret, NULL);
+}
+
static void ipa_subdomains_handler_done(struct tevent_req *req)
{
int ret;
@@ -1005,9 +1114,51 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
}
}
+ ctx->search_base_iter = 0;
+ ctx->search_bases = ctx->sd_ctx->host_search_bases;
+ talloc_zfree(ctx->current_filter);
+ ctx->current_filter = talloc_asprintf(ctx, "(&(objectClass=%s)(%s=%s))",
+ ctx->sd_ctx->id_ctx->ipa_options->host_map[IPA_OC_HOST].name,
+ ctx->sd_ctx->id_ctx->ipa_options->host_map[IPA_AT_HOST_FQDN].name,
+ dp_opt_get_string(ctx->sd_ctx->id_ctx->ipa_options->basic,
+ IPA_HOSTNAME));
+ if (ctx->current_filter == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ipa_get_view_name(ctx);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret != EOK) {
+ goto done;
+ }
+
+ ret = ipa_check_master(ctx);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret != EOK) {
+ goto done;
+ }
+
+done:
+ if (ret == EOK) {
+ dp_error = DP_ERR_OK;
+ }
+ be_req_terminate(ctx->be_req, dp_error, ret, NULL);
+}
+
+static errno_t ipa_check_master(struct ipa_subdomains_req_ctx *ctx)
+{
+ int ret;
+ struct sss_domain_info *domain;
+
+ domain = ctx->sd_ctx->be_ctx->domain;
+
ret = sysdb_master_domain_update(domain);
if (ret != EOK) {
- goto done;
+ return ret;
}
if (domain->flat_name == NULL ||
@@ -1018,19 +1169,13 @@ static void ipa_subdomains_handler_done(struct tevent_req *req)
ctx->search_bases = ctx->sd_ctx->master_search_bases;
ret = ipa_subdomains_handler_get(ctx, IPA_SUBDOMAINS_MASTER);
if (ret == EAGAIN) {
- return;
+ return EAGAIN;
} else if (ret != EOK) {
- goto done;
+ return ret;
}
- } else {
- ret = EOK;
}
-done:
- if (ret == EOK) {
- dp_error = DP_ERR_OK;
- }
- be_req_terminate(ctx->be_req, dp_error, ret, NULL);
+ return EOK;
}
@@ -1328,6 +1473,7 @@ int ipa_subdom_init(struct be_ctx *be_ctx,
ctx->search_bases = id_ctx->ipa_options->subdomains_search_bases;
ctx->master_search_bases = id_ctx->ipa_options->master_domain_search_bases;
ctx->ranges_search_bases = id_ctx->ipa_options->ranges_search_bases;
+ ctx->host_search_bases = id_ctx->ipa_options->host_search_bases;
ctx->configured_explicit = configured_explicit;
ctx->disabled_until = 0;
*ops = &ipa_subdomains_ops;