summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2014-09-16 15:26:24 +0200
committerJakub Hrozek <jhrozek@redhat.com>2014-10-16 17:55:56 +0200
commit08ab0d4ede41a1749e0bc26f78a37a4d10c20db8 (patch)
treea1d48e031c34d373e57927a0935411f41f0cf9bc /src
parent00c283ca719717ed483958571982d0e9ff95c4b1 (diff)
downloadsssd-08ab0d4ede41a1749e0bc26f78a37a4d10c20db8.tar.gz
sssd-08ab0d4ede41a1749e0bc26f78a37a4d10c20db8.tar.xz
sssd-08ab0d4ede41a1749e0bc26f78a37a4d10c20db8.zip
IPA: add view support and get view name
Related to https://fedorahosted.org/sssd/ticket/2375 Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Diffstat (limited to 'src')
-rw-r--r--src/config/SSSDConfig/__init__.py.in7
-rw-r--r--src/config/etc/sssd.api.d/sssd-ipa.conf7
-rw-r--r--src/db/sysdb.h4
-rw-r--r--src/man/sssd-ipa.5.xml142
-rw-r--r--src/providers/ipa/ipa_common.c44
-rw-r--r--src/providers/ipa/ipa_common.h29
-rw-r--r--src/providers/ipa/ipa_id.h2
-rw-r--r--src/providers/ipa/ipa_init.c65
-rw-r--r--src/providers/ipa/ipa_opts.h23
-rw-r--r--src/providers/ipa/ipa_subdomains.c193
10 files changed, 488 insertions, 28 deletions
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index ee48094d0..6c9553086 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -161,6 +161,13 @@ option_strings = {
'ipa_master_domain_search_base': _("Search base for object containing info about IPA domain"),
'ipa_ranges_search_base': _("Search base for objects containing info about ID ranges"),
'ipa_enable_dns_sites': _("Enable DNS sites - location based service discovery"),
+ 'ipa_views_search_base': _("Search base for view containers"),
+ 'ipa_view_class': _("Objectclass for view containers"),
+ 'ipa_view_name': _("Attribute with the name of the view"),
+ 'ipa_overide_object_class': _("Objectclass for override objects"),
+ 'ipa_anchor_uuid': _("Attribute with the reference to the original object"),
+ 'ipa_user_override_object_class': _("Objectclass for user override objects"),
+ 'ipa_group_override_object_class': _("Objectclass for group override objects"),
# [provider/ad]
'ad_domain' : _('Active Directory domain'),
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 92d8aa082..8713385fc 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -131,6 +131,13 @@ ldap_use_tokengroups = bool, None, false
ldap_rfc2307_fallback_to_local_users = bool, None, false
ipa_server_mode = bool, None, false
ldap_pwdlockout_dn = str, None, false
+ipa_views_search_base = str, None, false
+ipa_view_class = str, None, false
+ipa_view_name = str, None, false
+ipa_overide_object_class = str, None, false
+ipa_anchor_uuid = str, None, false
+ipa_user_override_object_class = str, None, false
+ipa_group_override_object_class = str, None, false
[provider/ipa/auth]
krb5_ccachedir = str, None, false
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index b87b956c9..c2de00892 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -150,6 +150,10 @@
#define SYSDB_VIEW_CLASS "view"
#define SYSDB_VIEW_NAME "viewName"
#define SYSDB_DEFAULT_VIEW_NAME "default"
+#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/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index dfcc595de..51f14f8fc 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -346,6 +346,25 @@
</varlistentry>
<varlistentry>
+ <term>ipa_views_search_base (string)</term>
+ <listitem>
+ <para>
+ Optional. Use the given string as search base for
+ views containers.
+ </para>
+ <para>
+ See <quote>ldap_search_base</quote> for
+ information about configuring multiple search
+ bases.
+ </para>
+ <para>
+ Default: the value of
+ <emphasis>cn=views,cn=accounts,%basedn</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>krb5_validate (boolean)</term>
<listitem>
<para>
@@ -519,6 +538,129 @@
</varlistentry>
</variablelist>
</para>
+ <refsect2 id='views'>
+ <title>VIEWS AND OVERRIDES</title>
+ <para>
+ SSSD can handle views and overrides which are offered by
+ FreeIPA 4.1 and later version. Since all paths and objectclasses
+ are fixed on the server side there is basically no need to
+ configure anything. For completeness the related options are
+ listed here with their default values.
+ <variablelist>
+ <varlistentry>
+ <term>ipa_view_class (string)</term>
+ <listitem>
+ <para>
+ Objectclass of the view container.
+ </para>
+ <para>
+ Default: nsContainer
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ipa_view_name (string)</term>
+ <listitem>
+ <para>
+ Name of the attribute holding the name of the
+ view.
+ </para>
+ <para>
+ Default: cn
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ipa_overide_object_class (string)</term>
+ <listitem>
+ <para>
+ Objectclass of the override objects.
+ </para>
+ <para>
+ Default: ipaOverrideAnchor
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ipa_anchor_uuid (string)</term>
+ <listitem>
+ <para>
+ Name of the attribute containing the reference
+ to the original object in a remote domain.
+ </para>
+ <para>
+ Default: ipaAnchorUUID
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ipa_user_override_object_class (string)</term>
+ <listitem>
+ <para>
+ Name of the objectclass for user overrides. It
+ is used to determine if the found override
+ object is related to a user or a group.
+ </para>
+ <para>
+ User overrides can contain attributes given by
+ <itemizedlist>
+ <listitem>
+ <para>ldap_user_name</para>
+ </listitem>
+ <listitem>
+ <para>ldap_user_uid_number</para>
+ </listitem>
+ <listitem>
+ <para>ldap_user_gid_number</para>
+ </listitem>
+ <listitem>
+ <para>ldap_user_gecos</para>
+ </listitem>
+ <listitem>
+ <para>ldap_user_home_directory</para>
+ </listitem>
+ <listitem>
+ <para>ldap_user_shell</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Default: ipaUserOverride
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ipa_group_override_object_class (string)</term>
+ <listitem>
+ <para>
+ Name of the objectclass for group overrides. It
+ is used to determine if the found override
+ object is related to a user or a group.
+ </para>
+ <para>
+ Group overrides can contain attributes given by
+ <itemizedlist>
+ <listitem>
+ <para>ldap_group_name</para>
+ </listitem>
+ <listitem>
+ <para>ldap_group_gid_number</para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ Default: ipaGroupOverride
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect2>
</refsect1>
<refsect1 id='subdomains_provider'>
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..0e9324f5b 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,30 @@ 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_OC_OVERRIDE_USER,
+ IPA_OC_OVERRIDE_GROUP,
+ 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_NAME,
+ 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 +145,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 +156,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 +165,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_id.h b/src/providers/ipa/ipa_id.h
index 9a255ffbd..9f05d2507 100644
--- a/src/providers/ipa/ipa_id.h
+++ b/src/providers/ipa/ipa_id.h
@@ -31,6 +31,8 @@
#include "providers/ldap/sdap.h"
#include "providers/ipa/ipa_subdomains.h"
+#define IPA_DEFAULT_VIEW_NAME "Default Trust View"
+
void ipa_account_info_handler(struct be_req *breq);
struct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index c1a9cc71d..45abd0e2a 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -244,6 +244,20 @@ 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, SYSDB_DEFAULT_VIEW_NAME);
+ if (ipa_ctx->view_name == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = sysdb_update_view_name(bectx->domain->sysdb, ipa_ctx->view_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot add/update view name to sysdb.\n");
+ 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,
@@ -295,26 +309,41 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
"will be ignored in ipa_server_mode\n");
}
}
- } else if (dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES)) {
- /* use IPA plugin */
- ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
- srv_ctx = ipa_srv_plugin_ctx_init(bectx, bectx->be_res->resolv,
- hostname, ipa_domain);
- if (srv_ctx == NULL) {
- DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
- ret = ENOMEM;
- goto done;
- }
-
- be_fo_set_srv_lookup_plugin(bectx, ipa_srv_plugin_send,
- ipa_srv_plugin_recv, srv_ctx, "IPA");
} else {
- /* fall back to standard plugin on clients. */
- ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname);
+ ret = sysdb_get_view_name(ipa_ctx, bectx->domain->sysdb,
+ &ipa_ctx->view_name);
if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
- "[%d]: %s\n", ret, strerror(ret));
- goto done;
+ if (ret == ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot find view name in the cache. " \
+ "Will do online lookup later.\n");
+ } else {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_view_name failed.\n");
+ goto done;
+ }
+ }
+
+ if (dp_opt_get_bool(ipa_options->basic, IPA_ENABLE_DNS_SITES)) {
+ /* use IPA plugin */
+ ipa_domain = dp_opt_get_string(ipa_options->basic, IPA_DOMAIN);
+ srv_ctx = ipa_srv_plugin_ctx_init(bectx, bectx->be_res->resolv,
+ hostname, ipa_domain);
+ if (srv_ctx == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "Out of memory?\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ be_fo_set_srv_lookup_plugin(bectx, ipa_srv_plugin_send,
+ ipa_srv_plugin_recv, srv_ctx, "IPA");
+ } else {
+ /* fall back to standard plugin on clients. */
+ ret = be_fo_set_dns_srv_lookup_plugin(bectx, hostname);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
+ "[%d]: %s\n", ret, strerror(ret));
+ goto done;
+ }
}
}
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..0ff61cff9 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -26,6 +26,8 @@
#include "providers/ldap/sdap_idmap.h"
#include "providers/ipa/ipa_subdomains.h"
#include "providers/ipa/ipa_common.h"
+#include "providers/ipa/ipa_id.h"
+
#include <ctype.h>
#define SUBDOMAINS_FILTER "objectclass=ipaNTTrustedDomain"
@@ -44,6 +46,8 @@
#define IPA_SECONDARY_BASE_RID "ipaSecondaryBaseRID"
#define OBJECTCLASS "objectClass"
+#define IPA_ASSIGNED_ID_VIEW "ipaAssignedIDView"
+
/* do not refresh more often than every 5 seconds for now */
#define IPA_SUBDOMAIN_REFRESH_LIMIT 5
@@ -70,6 +74,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 +948,134 @@ 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_with_filter_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_FUNC, "No view found, using default.\n");
+ view_name = SYSDB_DEFAULT_VIEW_NAME;
+ } 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;
+ } else {
+ 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_FUNC, "Found view name [%s].\n", view_name);
+ if (strcmp(view_name, IPA_DEFAULT_VIEW_NAME) == 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Found IPA default view name, replacing with sysdb default.\n");
+ view_name = SYSDB_DEFAULT_VIEW_NAME;
+ }
+
+ if (ctx->sd_ctx->id_ctx->view_name != NULL
+ && strcmp(ctx->sd_ctx->id_ctx->view_name, view_name) != 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "View name changed, this is currently not supported!\n");
+ } else {
+ ret = sysdb_update_view_name(ctx->sd_ctx->be_ctx->domain->sysdb,
+ view_name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot add/update view name to sysdb.\n");
+ } else {
+ if (ctx->sd_ctx->id_ctx->view_name == NULL) {
+ ctx->sd_ctx->id_ctx->view_name =
+ talloc_strdup(ctx->sd_ctx->id_ctx,
+ view_name);
+ if (ctx->sd_ctx->id_ctx->view_name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot copy view name.\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 +1138,54 @@ 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;
+ }
+
+ if (ctx->sd_ctx->id_ctx->server_mode == NULL) {
+ /* Only get view on clients, on servers it is always 'default' */
+ 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 +1196,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 +1500,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;