pagure tickets for migrating wiki pages
by Jakub Hrozek
Hi,
as we're migrating the wiki pages from the old fedorahosted wiki to
pagure, I would like to make sure two people are not working on the same
wiki page.
I'm thinking about just filing a bunch of issues over at
https://pagure.io/SSSD/docs/issues for the most important pages. Anyone
working on migrating those pages could just assign the issue. Also,
anyone working on migrating some other page w/o an issue would just
create an issue for that page.
Sounds good?
7 years
[PATCH] providers: Move hostid from ipa to sdap
by Hristo Venev
This just makes sss_ssh_knownhostsproxy work. There is no support for
hostgroups (although hostgroups in IPA should continue working).
---
Makefile.am | 9 +-
src/man/sssd-ipa.5.xml | 20 +-
src/man/sssd-ldap.5.xml | 109 +++++++
src/providers/ad/ad_opts.c | 1 +
src/providers/ipa/ipa_access.c | 15 +-
src/providers/ipa/ipa_common.c | 37 +--
src/providers/ipa/ipa_common.h | 31 +-
src/providers/ipa/ipa_hostid.c | 301 +------------------
src/providers/ipa/ipa_hosts.h | 44 ---
src/providers/ipa/ipa_init.c | 26 +-
src/providers/ipa/ipa_netgroups.c | 14 +-
src/providers/ipa/ipa_opts.c | 1 +
src/providers/ipa/ipa_selinux.c | 19 +-
src/providers/ipa/ipa_subdomains.c | 9 +-
src/providers/ipa/ipa_sudo_async.c | 20 +-
src/providers/ipa/ipa_sudo_conversion.c | 4 +-
src/providers/ldap/ldap_init.c | 21 ++
src/providers/ldap/ldap_options.c | 26 ++
src/providers/ldap/ldap_opts.c | 12 +
src/providers/ldap/ldap_opts.h | 4 +
src/providers/ldap/sdap.c | 12 +
src/providers/ldap/sdap.h | 25 ++
src/providers/ldap/sdap_async.h | 18 ++
.../{ipa/ipa_hosts.c => ldap/sdap_async_hosts.c} | 108 +++----
src/providers/ldap/sdap_hostid.c | 325 +++++++++++++++++++++
.../{ipa/ipa_hostid.h => ldap/sdap_hostid.h} | 31 +-
src/tests/ipa_ldap_opt-tests.c | 4 +-
27 files changed, 716 insertions(+), 530 deletions(-)
delete mode 100644 src/providers/ipa/ipa_hosts.h
rename src/providers/{ipa/ipa_hosts.c => ldap/sdap_async_hosts.c} (82%)
create mode 100644 src/providers/ldap/sdap_hostid.c
rename src/providers/{ipa/ipa_hostid.h => ldap/sdap_hostid.h} (55%)
diff --git a/Makefile.am b/Makefile.am
index c947e31e5..b5ba22e5f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -791,13 +791,11 @@ dist_noinst_HEADERS = \
src/providers/ipa/ipa_config.h \
src/providers/ipa/ipa_access.h \
src/providers/ipa/ipa_selinux.h \
- src/providers/ipa/ipa_hosts.h \
src/providers/ipa/ipa_selinux_maps.h \
src/providers/ipa/ipa_auth.h \
src/providers/ipa/ipa_dyndns.h \
src/providers/ipa/ipa_subdomains.h \
src/providers/ipa/ipa_id.h \
- src/providers/ipa/ipa_hostid.h \
src/providers/ipa/ipa_opts.h \
src/providers/ipa/ipa_srv.h \
src/providers/ipa/ipa_dn.h \
@@ -3682,11 +3680,13 @@ libsss_ldap_common_la_SOURCES = \
src/providers/ldap/sdap_async_initgroups_ad.c \
src/providers/ldap/sdap_async_connection.c \
src/providers/ldap/sdap_async_netgroups.c \
+ src/providers/ldap/sdap_async_hosts.c \
src/providers/ldap/sdap_async_services.c \
src/providers/ldap/sdap_online_check.c \
src/providers/ldap/sdap_ad_groups.c \
src/providers/ldap/sdap_child_helpers.c \
src/providers/ldap/sdap_fd_events.c \
+ src/providers/ldap/sdap_hostid.h \
src/providers/ldap/sdap_id_op.c \
src/providers/ldap/sdap_idmap.c \
src/providers/ldap/sdap_idmap.h \
@@ -3721,6 +3721,10 @@ if BUILD_SYSTEMTAP
libsss_ldap_common_la_LIBADD += stap_generated_probes.lo
endif
+if BUILD_SSH
+libsss_ldap_common_la_SOURCES += src/providers/ldap/sdap_hostid.c
+endif
+
if BUILD_SUDO
libsss_ldap_common_la_SOURCES += \
src/providers/ldap/sdap_async_sudo.c \
@@ -3846,7 +3850,6 @@ libsss_ipa_la_SOURCES = \
src/providers/ipa/ipa_auth.c \
src/providers/ipa/ipa_access.c \
src/providers/ipa/ipa_dyndns.c \
- src/providers/ipa/ipa_hosts.c \
src/providers/ipa/ipa_subdomains.c \
src/providers/ipa/ipa_subdomains_id.c \
src/providers/ipa/ipa_subdomains_server.c \
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
index fee644186..de768b652 100644
--- a/src/man/sssd-ipa.5.xml
+++ b/src/man/sssd-ipa.5.xml
@@ -307,33 +307,23 @@
</varlistentry>
<varlistentry>
- <term>ipa_hbac_search_base (string)</term>
+ <term>ipa_host_search_base (string)</term>
<listitem>
<para>
- Optional. Use the given string as search base for
- HBAC related objects.
- </para>
- <para>
- Default: Use base DN
+ Deprecated. Use ldap_host_search_base instead.
</para>
</listitem>
</varlistentry>
<varlistentry>
- <term>ipa_host_search_base (string)</term>
+ <term>ipa_hbac_search_base (string)</term>
<listitem>
<para>
Optional. Use the given string as search base for
- host objects.
- </para>
- <para>
- See <quote>ldap_search_base</quote> for
- information about configuring multiple search
- bases.
+ HBAC related objects.
</para>
<para>
- Default: the value of
- <emphasis>ldap_search_base</emphasis>
+ Default: Use base DN
</para>
</listitem>
</varlistentry>
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index fae669a8d..b47a664b4 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -1177,6 +1177,115 @@
</varlistentry>
<varlistentry>
+ <term>ldap_host_object_class (string)</term>
+ <listitem>
+ <para>
+ The object class of a host entry in LDAP.
+ </para>
+ <para>
+ Default: ipService
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ldap_host_name (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that corresponds to the host's
+ name.
+ </para>
+ <para>
+ Default: cn
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ldap_host_fqdn (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that corresponds to the host's
+ fully-qualified domain name.
+ </para>
+ <para>
+ Default: fqdn
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ldap_host_serverhostname (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that corresponds to the host's
+ name.
+ </para>
+ <para>
+ Default: serverHostname
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ldap_host_member_of (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that lists the host's group
+ memberships.
+ </para>
+ <para>
+ Default: memberOf
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ldap_host_search_base (string)</term>
+ <listitem>
+ <para>
+ Optional. Use the given string as search base for
+ host objects.
+ </para>
+ <para>
+ See <quote>ldap_search_base</quote> for
+ information about configuring multiple search
+ bases.
+ </para>
+ <para>
+ Default: the value of
+ <emphasis>ldap_search_base</emphasis>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry condition="with_ssh">
+ <term>ldap_host_ssh_public_key (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that contains the host's SSH
+ public keys.
+ </para>
+ <para>
+ Default: sshPublicKey
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ldap_host_uuid (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that contains the UUID/GUID of
+ an LDAP host object.
+ </para>
+ <para>
+ Default: not set
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_service_object_class (string)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index fc1dc6733..3980abac1 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -72,6 +72,7 @@ struct dp_option ad_def_ldap_opts[] = {
{ "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
{ "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "ldap_host_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_service_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sudo_full_refresh_interval", DP_OPT_NUMBER, { .number = 21600 }, NULL_NUMBER }, /* 360 mins */
diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c
index bebb47bf3..4dda0a462 100644
--- a/src/providers/ipa/ipa_access.c
+++ b/src/providers/ipa/ipa_access.c
@@ -30,7 +30,6 @@
#include "providers/ldap/sdap_access.h"
#include "providers/ipa/ipa_common.h"
#include "providers/ipa/ipa_access.h"
-#include "providers/ipa/ipa_hosts.h"
#include "providers/ipa/ipa_hbac_private.h"
#include "providers/ipa/ipa_hbac_rules.h"
@@ -273,12 +272,12 @@ static errno_t ipa_fetch_hbac_hostinfo(struct tevent_req *req)
hostname = dp_opt_get_string(state->ipa_options, IPA_HOSTNAME);
}
- subreq = ipa_host_info_send(state, state->ev,
- sdap_id_op_handle(state->sdap_op),
- state->sdap_ctx->opts, hostname,
- state->access_ctx->host_map,
- state->access_ctx->hostgroup_map,
- state->access_ctx->host_search_bases);
+ subreq = sdap_host_info_send(state, state->ev,
+ sdap_id_op_handle(state->sdap_op),
+ state->sdap_ctx->opts, hostname,
+ state->access_ctx->host_map,
+ state->access_ctx->hostgroup_map,
+ state->access_ctx->host_search_bases);
if (subreq == NULL) {
return ENOMEM;
}
@@ -297,7 +296,7 @@ static void ipa_fetch_hbac_hostinfo_done(struct tevent_req *subreq)
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ipa_fetch_hbac_state);
- ret = ipa_host_info_recv(subreq, state,
+ ret = sdap_host_info_recv(subreq, state,
&state->host_count, &state->hosts,
&state->hostgroup_count, &state->hostgroups);
talloc_zfree(subreq);
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 657994508..b020329b9 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -134,9 +134,6 @@ static errno_t ipa_parse_search_base(TALLOC_CTX *mem_ctx,
case IPA_HBAC_SEARCH_BASE:
class_name = "IPA_HBAC";
break;
- case IPA_HOST_SEARCH_BASE:
- class_name = "IPA_HOST";
- break;
case IPA_SELINUX_SEARCH_BASE:
class_name = "IPA_SELINUX";
break;
@@ -333,23 +330,27 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
&ipa_opts->id->sdom->netgroup_search_bases);
if (ret != EOK) goto done;
- if (NULL == dp_opt_get_string(ipa_opts->basic,
- IPA_HOST_SEARCH_BASE)) {
- ret = dp_opt_set_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_SEARCH_BASE));
+ if (NULL == dp_opt_get_string(ipa_opts->id->basic,
+ SDAP_HOST_SEARCH_BASE)) {
+
+ value = dp_opt_get_string(ipa_opts->basic, IPA_HOST_SEARCH_BASE);
+ if (!value) {
+ value = dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE);
+ }
+
+ ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_HOST_SEARCH_BASE,
+ value);
if (ret != EOK) {
goto done;
}
DEBUG(SSSDBG_CONF_SETTINGS, "Option %s set to %s\n",
- ipa_opts->basic[IPA_HOST_SEARCH_BASE].opt_name,
- dp_opt_get_string(ipa_opts->basic,
- IPA_HOST_SEARCH_BASE));
+ ipa_opts->id->basic[SDAP_HOST_SEARCH_BASE].opt_name,
+ value);
}
- ret = ipa_parse_search_base(ipa_opts->basic, ipa_opts->basic,
- IPA_HOST_SEARCH_BASE,
- &ipa_opts->host_search_bases);
+ ret = sdap_parse_search_base(ipa_opts->id->basic, ipa_opts->id->basic,
+ SDAP_HOST_SEARCH_BASE,
+ &ipa_opts->id->sdom->host_search_bases);
if (ret != EOK) goto done;
if (NULL == dp_opt_get_string(ipa_opts->basic,
@@ -566,8 +567,8 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
ret = sdap_get_map(ipa_opts->id,
cdb, conf_path,
ipa_host_map,
- IPA_OPTS_HOST,
- &ipa_opts->host_map);
+ SDAP_OPTS_HOST,
+ &ipa_opts->id->host_map);
if (ret != EOK) {
goto done;
}
@@ -575,8 +576,8 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
ret = sdap_get_map(ipa_opts->id,
cdb, conf_path,
ipa_hostgroup_map,
- IPA_OPTS_HOSTGROUP,
- &ipa_opts->hostgroup_map);
+ SDAP_OPTS_HOSTGROUP,
+ &ipa_opts->id->hostgroup_map);
if (ret != EOK) {
goto done;
}
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index add9df876..2b0147a2b 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -41,8 +41,8 @@ enum ipa_basic_opt {
IPA_SERVER,
IPA_BACKUP_SERVER,
IPA_HOSTNAME,
+ IPA_HOST_SEARCH_BASE, /* only used if ldap_host_search_base is not set */
IPA_HBAC_SEARCH_BASE,
- IPA_HOST_SEARCH_BASE,
IPA_SELINUX_SEARCH_BASE,
IPA_SUBDOMAINS_SEARCH_BASE,
IPA_MASTER_DOMAIN_SEARCH_BASE,
@@ -74,27 +74,6 @@ enum ipa_netgroup_attrs {
IPA_OPTS_NETGROUP /* attrs counter */
};
-enum ipa_host_attrs {
- IPA_OC_HOST = 0,
- IPA_AT_HOST_NAME,
- IPA_AT_HOST_FQDN,
- IPA_AT_HOST_SERVERHOSTNAME,
- IPA_AT_HOST_MEMBER_OF,
- IPA_AT_HOST_SSH_PUBLIC_KEY,
- IPA_AT_HOST_UUID,
-
- IPA_OPTS_HOST /* attrs counter */
-};
-
-enum ipa_hostgroup_attrs {
- IPA_OC_HOSTGROUP = 0,
- IPA_AT_HOSTGROUP_NAME,
- IPA_AT_HOSTGROUP_MEMBER_OF,
- IPA_AT_HOSTGROUP_UUID,
-
- IPA_OPTS_HOSTGROUP /* attrs counter */
-};
-
enum ipa_selinux_usermap_attrs {
IPA_OC_SELINUX_USERMAP = 0,
IPA_AT_SELINUX_USERMAP_NAME,
@@ -205,13 +184,10 @@ struct ipa_id_ctx {
struct ipa_options {
struct dp_option *basic;
- 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;
struct sdap_search_base **selinux_search_bases;
struct sdap_search_base **subdomains_search_bases;
@@ -260,6 +236,11 @@ int ipa_get_autofs_options(struct ipa_options *ipa_opts,
errno_t ipa_get_dyndns_options(struct be_ctx *be_ctx,
struct ipa_options *ctx);
+errno_t ipa_hostid_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct dp_method *dp_methods);
+
errno_t ipa_autofs_init(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
diff --git a/src/providers/ipa/ipa_hostid.c b/src/providers/ipa/ipa_hostid.c
index 87a36167b..891536f13 100644
--- a/src/providers/ipa/ipa_hostid.c
+++ b/src/providers/ipa/ipa_hostid.c
@@ -1,8 +1,8 @@
/*
Authors:
- Jan Cholasta <jcholast(a)redhat.com>
+ Hristo Venev <hristo(a)venev.name>
- Copyright (C) 2012 Red Hat
+ Copyright (C) 2017 Red Hat
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,298 +18,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "util/util.h"
-#include "util/crypto/sss_crypto.h"
-#include "db/sysdb_ssh.h"
-#include "providers/ldap/ldap_common.h"
#include "providers/ipa/ipa_common.h"
-#include "providers/ipa/ipa_hostid.h"
-#include "providers/ipa/ipa_hosts.h"
+#include "providers/ldap/sdap_hostid.h"
-struct hosts_get_state {
- struct tevent_context *ev;
- struct ipa_hostid_ctx *ctx;
- struct sdap_id_op *op;
- struct sss_domain_info *domain;
- const char *name;
- const char *alias;
-
- size_t count;
- struct sysdb_attrs **hosts;
- int dp_error;
-};
-
-static errno_t
-hosts_get_retry(struct tevent_req *req);
-static void
-hosts_get_connect_done(struct tevent_req *subreq);
-static void
-hosts_get_done(struct tevent_req *subreq);
-
-struct tevent_req *
-hosts_get_send(TALLOC_CTX *memctx,
- struct tevent_context *ev,
- struct ipa_hostid_ctx *hostid_ctx,
- const char *name,
- const char *alias)
-{
- struct tevent_req *req;
- struct hosts_get_state *state;
- struct sdap_id_ctx *ctx;
- errno_t ret;
-
- ctx = hostid_ctx->sdap_id_ctx;
-
- req = tevent_req_create(memctx, &state, struct hosts_get_state);
- if (!req) return NULL;
-
- state->ev = ev;
- state->ctx = hostid_ctx;
- state->dp_error = DP_ERR_FATAL;
-
- state->op = sdap_id_op_create(state, ctx->conn->conn_cache);
- if (!state->op) {
- DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
- ret = ENOMEM;
- goto fail;
- }
-
- state->domain = ctx->be->domain;
- state->name = name;
- state->alias = alias;
-
- ret = hosts_get_retry(req);
- if (ret != EOK) {
- goto fail;
- }
-
- return req;
-
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
-}
-
-static errno_t
-hosts_get_retry(struct tevent_req *req)
-{
- struct hosts_get_state *state = tevent_req_data(req,
- struct hosts_get_state);
- struct tevent_req *subreq;
- errno_t ret = EOK;
-
- subreq = sdap_id_op_connect_send(state->op, state, &ret);
- if (!subreq) {
- return ret;
- }
-
- tevent_req_set_callback(subreq, hosts_get_connect_done, req);
- return EOK;
-}
-
-static void
-hosts_get_connect_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hosts_get_state *state = tevent_req_data(req,
- struct hosts_get_state);
- int dp_error = DP_ERR_FATAL;
- errno_t ret;
-
- ret = sdap_id_op_connect_recv(subreq, &dp_error);
- talloc_zfree(subreq);
-
- if (ret != EOK) {
- state->dp_error = dp_error;
- tevent_req_error(req, ret);
- return;
- }
-
- subreq = ipa_host_info_send(state, state->ev,
- sdap_id_op_handle(state->op),
- state->ctx->sdap_id_ctx->opts, state->name,
- state->ctx->ipa_opts->host_map, NULL,
- state->ctx->host_search_bases);
- if (!subreq) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- tevent_req_set_callback(subreq, hosts_get_done, req);
-}
-
-static void
-hosts_get_done(struct tevent_req *subreq)
-{
- struct tevent_req *req = tevent_req_callback_data(subreq,
- struct tevent_req);
- struct hosts_get_state *state = tevent_req_data(req,
- struct hosts_get_state);
- int dp_error = DP_ERR_FATAL;
- errno_t ret;
- struct sysdb_attrs *attrs;
- time_t now = time(NULL);
-
- ret = ipa_host_info_recv(subreq, state,
- &state->count, &state->hosts,
- NULL, NULL);
- talloc_zfree(subreq);
-
- ret = sdap_id_op_done(state->op, ret, &dp_error);
- if (dp_error == DP_ERR_OK && ret != EOK) {
- /* retry */
- ret = hosts_get_retry(req);
- if (ret != EOK) {
- goto done;
- }
- return;
- }
-
- if (ret != EOK && ret != ENOENT) {
- goto done;
- }
-
- if (state->count == 0) {
- DEBUG(SSSDBG_OP_FAILURE,
- "No host with name [%s] found.\n", state->name);
-
- ret = sysdb_delete_ssh_host(state->domain, state->name);
- if (ret != EOK && ret != ENOENT) {
- goto done;
- }
-
- ret = EINVAL;
- goto done;
- }
-
- if (state->count > 1) {
- DEBUG(SSSDBG_CRIT_FAILURE,
- "Found more than one host with name [%s].\n", state->name);
- ret = EINVAL;
- goto done;
- }
-
- attrs = sysdb_new_attrs(state);
- if (!attrs) {
- ret = ENOMEM;
- goto done;
- }
-
- /* we are interested only in the host keys */
- ret = sysdb_attrs_copy_values(state->hosts[0], attrs, SYSDB_SSH_PUBKEY);
- if (ret != EOK) {
- goto done;
- }
-
- ret = sysdb_store_ssh_host(state->domain, state->name, state->alias,
- state->domain->ssh_host_timeout, now, attrs);
- if (ret != EOK) {
- goto done;
- }
-
- dp_error = DP_ERR_OK;
-
-done:
- state->dp_error = dp_error;
- if (ret == EOK) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
-}
-
-static errno_t
-hosts_get_recv(struct tevent_req *req,
- int *dp_error_out)
-{
- struct hosts_get_state *state = tevent_req_data(req,
- struct hosts_get_state);
-
- if (dp_error_out) {
- *dp_error_out = state->dp_error;
- }
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- return EOK;
-}
-
-struct ipa_hostid_handler_state {
- struct dp_reply_std reply;
-};
-
-static void ipa_hostid_handler_done(struct tevent_req *subreq);
-
-struct tevent_req *
-ipa_hostid_handler_send(TALLOC_CTX *mem_ctx,
- struct ipa_hostid_ctx *hostid_ctx,
- struct dp_hostid_data *data,
- struct dp_req_params *params)
-{
- struct ipa_hostid_handler_state *state;
- struct tevent_req *subreq;
- struct tevent_req *req;
- errno_t ret;
-
- req = tevent_req_create(mem_ctx, &state, struct ipa_hostid_handler_state);
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
- return NULL;
- }
-
- subreq = hosts_get_send(state, params->ev, hostid_ctx,
- data->name, data->alias);
- if (subreq == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request\n");
- ret = ENOMEM;
- goto immediately;
- }
-
- tevent_req_set_callback(subreq, ipa_hostid_handler_done, req);
-
- return req;
-
-immediately:
- dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
-
- /* TODO For backward compatibility we always return EOK to DP now. */
- tevent_req_done(req);
- tevent_req_post(req, params->ev);
-
- return req;
-}
-
-static void ipa_hostid_handler_done(struct tevent_req *subreq)
+errno_t ipa_hostid_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct dp_method *dp_methods)
{
- struct ipa_hostid_handler_state *state;
- struct tevent_req *req;
- int dp_error;
- errno_t ret;
-
- req = tevent_req_callback_data(subreq, struct tevent_req);
- state = tevent_req_data(req, struct ipa_hostid_handler_state);
-
- ret = hosts_get_recv(subreq, &dp_error);
- talloc_zfree(subreq);
-
- /* TODO For backward compatibility we always return EOK to DP now. */
- dp_reply_std_set(&state->reply, dp_error, ret, NULL);
- tevent_req_done(req);
-}
-
-errno_t
-ipa_hostid_handler_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- struct dp_reply_std *data)
-{
- struct ipa_hostid_handler_state *state = NULL;
-
- state = tevent_req_data(req, struct ipa_hostid_handler_state);
-
- TEVENT_REQ_RETURN_ON_ERROR(req);
-
- *data = state->reply;
-
- return EOK;
+ return sdap_hostid_init(mem_ctx, be_ctx, id_ctx->sdap_id_ctx, dp_methods);
}
diff --git a/src/providers/ipa/ipa_hosts.h b/src/providers/ipa/ipa_hosts.h
deleted file mode 100644
index a1ea7a22f..000000000
--- a/src/providers/ipa/ipa_hosts.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- SSSD
-
- Authors:
- Jan Zeleny <jzeleny(a)redhat.com>
-
- Copyright (C) 2012 Red Hat
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef IPA_HOSTS_H_
-#define IPA_HOSTS_H_
-
-struct tevent_req *
-ipa_host_info_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct sdap_handle *sh,
- struct sdap_options *opts,
- const char *hostname,
- struct sdap_attr_map *host_map,
- struct sdap_attr_map *hostgroup_map,
- struct sdap_search_base **search_bases);
-
-errno_t
-ipa_host_info_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- size_t *host_count,
- struct sysdb_attrs ***hosts,
- size_t *hostgroup_count,
- struct sysdb_attrs ***hostgroups);
-
-#endif /* IPA_HOSTS_H_ */
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 7dec4d1fb..228e2bf02 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -34,7 +34,6 @@
#include "providers/ipa/ipa_id.h"
#include "providers/ipa/ipa_auth.h"
#include "providers/ipa/ipa_access.h"
-#include "providers/ipa/ipa_hostid.h"
#include "providers/ipa/ipa_dyndns.h"
#include "providers/ipa/ipa_selinux.h"
#include "providers/ldap/sdap_access.h"
@@ -783,9 +782,9 @@ errno_t sssm_ipa_access_init(TALLOC_CTX *mem_ctx,
}
access_ctx->sdap_ctx = id_ctx->sdap_id_ctx;
- access_ctx->host_map = id_ctx->ipa_options->host_map;
- access_ctx->hostgroup_map = id_ctx->ipa_options->hostgroup_map;
- access_ctx->host_search_bases = id_ctx->ipa_options->host_search_bases;
+ access_ctx->host_map = id_ctx->ipa_options->id->host_map;
+ access_ctx->hostgroup_map = id_ctx->ipa_options->id->hostgroup_map;
+ access_ctx->host_search_bases = id_ctx->ipa_options->id->sdom->host_search_bases;
access_ctx->hbac_search_bases = id_ctx->ipa_options->hbac_search_bases;
ret = dp_copy_options(access_ctx, id_ctx->ipa_options->basic,
@@ -842,7 +841,7 @@ errno_t sssm_ipa_selinux_init(TALLOC_CTX *mem_ctx,
selinux_ctx->id_ctx = init_ctx->id_ctx;
selinux_ctx->hbac_search_bases = opts->hbac_search_bases;
- selinux_ctx->host_search_bases = opts->host_search_bases;
+ selinux_ctx->host_search_bases = opts->id->sdom->host_search_bases;
selinux_ctx->selinux_search_bases = opts->selinux_search_bases;
dp_set_method(dp_methods, DPM_SELINUX_HANDLER,
@@ -863,26 +862,13 @@ errno_t sssm_ipa_hostid_init(TALLOC_CTX *mem_ctx,
struct dp_method *dp_methods)
{
#ifdef BUILD_SSH
- struct ipa_hostid_ctx *hostid_ctx;
struct ipa_init_ctx *init_ctx;
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA host handler\n");
init_ctx = talloc_get_type(module_data, struct ipa_init_ctx);
- hostid_ctx = talloc_zero(mem_ctx, struct ipa_hostid_ctx);
- if (hostid_ctx == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
- return ENOMEM;
- }
-
- hostid_ctx->sdap_id_ctx = init_ctx->id_ctx->sdap_id_ctx;
- hostid_ctx->host_search_bases = init_ctx->options->host_search_bases;
- hostid_ctx->ipa_opts = init_ctx->options;
+ return ipa_hostid_init(mem_ctx, be_ctx, init_ctx->id_ctx, dp_methods);
- dp_set_method(dp_methods, DPM_HOSTID_HANDLER,
- ipa_hostid_handler_send, ipa_hostid_handler_recv, hostid_ctx,
- struct ipa_hostid_ctx, struct dp_hostid_data, struct dp_reply_std);
-
- return EOK;
#else
DEBUG(SSSDBG_MINOR_FAILURE, "HostID init handler called but SSSD is "
"built without SSH support, ignoring\n");
diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
index 17b11af5d..899131399 100644
--- a/src/providers/ipa/ipa_netgroups.c
+++ b/src/providers/ipa/ipa_netgroups.c
@@ -516,7 +516,7 @@ static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
int ret;
struct sdap_search_base **bases;
- bases = state->ipa_opts->host_search_bases;
+ bases = state->ipa_opts->id->sdom->host_search_bases;
if (bases[state->host_base_iter] == NULL) {
return ENOENT;
}
@@ -525,12 +525,12 @@ static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
state->filter,
base_filter?base_filter:"",
- state->ipa_opts->host_map[IPA_OC_HOST].name);
+ state->ipa_opts->id->host_map[SDAP_OC_HOST].name);
if (filter == NULL)
return ENOMEM;
- ret = build_attrs_from_map(state, state->ipa_opts->host_map,
- IPA_OPTS_HOST, NULL, &attrs, NULL);
+ ret = build_attrs_from_map(state, state->ipa_opts->id->host_map,
+ SDAP_OPTS_HOST, NULL, &attrs, NULL);
if (ret != EOK) {
talloc_free(filter);
return ret;
@@ -539,8 +539,8 @@ static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
bases[state->host_base_iter]->basedn,
bases[state->host_base_iter]->scope,
- filter, attrs, state->ipa_opts->host_map,
- IPA_OPTS_HOST, state->timeout, true);
+ filter, attrs, state->ipa_opts->id->host_map,
+ SDAP_OPTS_HOST, state->timeout, true);
state->current_entity = ENTITY_HOST;
if (subreq == NULL) {
@@ -918,7 +918,7 @@ static int ipa_netgr_process_all(struct ipa_get_netgroups_state *state)
DEBUG(SSSDBG_TRACE_ALL, "Extracting host members of netgroup %d\n", i);
ret = extract_members(state, state->netgroups[i],
SYSDB_ORIG_MEMBER_HOST,
- state->ipa_opts->host_map[IPA_AT_HOST_MEMBER_OF].sys_name,
+ state->ipa_opts->id->host_map[SDAP_AT_HOST_MEMBER_OF].sys_name,
state->new_hosts,
&hosts, &hosts_count);
if (ret != EOK) {
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index cd3fe9ae4..a680d2af3 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -81,6 +81,7 @@ struct dp_option ipa_def_ldap_opts[] = {
{ "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
{ "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "ldap_host_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_service_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sudo_full_refresh_interval", DP_OPT_NUMBER, { .number = 21600 }, NULL_NUMBER },
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c
index 6d0778d78..cf5e8dd66 100644
--- a/src/providers/ipa/ipa_selinux.c
+++ b/src/providers/ipa/ipa_selinux.c
@@ -30,7 +30,6 @@
#include "providers/ipa/ipa_common.h"
#include "providers/ipa/ipa_config.h"
#include "providers/ipa/ipa_selinux.h"
-#include "providers/ipa/ipa_hosts.h"
#include "providers/ipa/ipa_hbac_rules.h"
#include "providers/ipa/ipa_hbac_private.h"
#include "providers/ipa/ipa_access.h"
@@ -974,13 +973,13 @@ static void ipa_get_selinux_connect_done(struct tevent_req *subreq)
goto fail;
}
- subreq = ipa_host_info_send(state, state->be_ctx->ev,
- sdap_id_op_handle(state->op),
- id_ctx->sdap_id_ctx->opts,
- hostname,
- id_ctx->ipa_options->host_map,
- NULL,
- state->selinux_ctx->host_search_bases);
+ subreq = sdap_host_info_send(state, state->be_ctx->ev,
+ sdap_id_op_handle(state->op),
+ id_ctx->sdap_id_ctx->opts,
+ hostname,
+ id_ctx->ipa_options->id->host_map,
+ NULL,
+ state->selinux_ctx->host_search_bases);
if (subreq == NULL) {
ret = ENOMEM;
goto fail;
@@ -1087,8 +1086,8 @@ static void ipa_get_selinux_hosts_done(struct tevent_req *subreq)
struct sysdb_attrs **hostgroups;
struct sysdb_attrs **host;
- ret = ipa_host_info_recv(subreq, state, &host_count, &host,
- &hostgroup_count, &hostgroups);
+ ret = sdap_host_info_recv(subreq, state, &host_count, &host,
+ &hostgroup_count, &hostgroups);
talloc_free(subreq);
if (ret != EOK) {
goto done;
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index ef348adf4..4e5c7b8a6 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -1571,8 +1571,8 @@ ipa_subdomains_view_name_send(TALLOC_CTX *mem_ctx,
maps->num_attrs = IPA_OPTS_VIEW;
filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))",
- ipa_options->host_map[IPA_OC_HOST].name,
- ipa_options->host_map[IPA_AT_HOST_FQDN].name,
+ ipa_options->id->host_map[SDAP_OC_HOST].name,
+ ipa_options->id->host_map[SDAP_AT_HOST_FQDN].name,
dp_opt_get_string(ipa_options->basic, IPA_HOSTNAME));
if (filter == NULL) {
ret = ENOMEM;
@@ -1582,7 +1582,8 @@ ipa_subdomains_view_name_send(TALLOC_CTX *mem_ctx,
/* We add SDAP_DEREF_FLG_SILENT because old IPA servers don't have
* the attribute we dereference, causing the deref call to fail. */
subreq = sdap_deref_bases_return_first_send(state, ev,
- sd_ctx->sdap_id_ctx->opts, sh, sd_ctx->host_search_bases,
+ sd_ctx->sdap_id_ctx->opts, sh,
+ sd_ctx->host_search_bases,
maps, filter, attrs, IPA_ASSIGNED_ID_VIEW,
SDAP_DEREF_FLG_SILENT, 0);
if (subreq == NULL) {
@@ -2418,7 +2419,7 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx,
sd_ctx->search_bases = ipa_options->subdomains_search_bases;
sd_ctx->master_search_bases = ipa_options->master_domain_search_bases;
sd_ctx->ranges_search_bases = ipa_options->ranges_search_bases;
- sd_ctx->host_search_bases = ipa_options->host_search_bases;
+ sd_ctx->host_search_bases = ipa_options->id->sdom->host_search_bases;
dp_set_method(dp_methods, DPM_DOMAINS_HANDLER,
ipa_subdomains_handler_send, ipa_subdomains_handler_recv, sd_ctx,
diff --git a/src/providers/ipa/ipa_sudo_async.c b/src/providers/ipa/ipa_sudo_async.c
index 9ed121830..e09fbdfd7 100644
--- a/src/providers/ipa/ipa_sudo_async.c
+++ b/src/providers/ipa/ipa_sudo_async.c
@@ -24,8 +24,8 @@
#include "providers/ldap/sdap_ops.h"
#include "providers/ldap/sdap_sudo_shared.h"
+#include "providers/ldap/sdap_async.h"
#include "providers/ipa/ipa_common.h"
-#include "providers/ipa/ipa_hosts.h"
#include "providers/ipa/ipa_sudo.h"
#include "providers/ipa/ipa_dn.h"
#include "db/sysdb.h"
@@ -976,11 +976,11 @@ ipa_sudo_refresh_connect_done(struct tevent_req *subreq)
/* Obtain host information. */
hostname = dp_opt_get_string(state->ipa_opts->basic, IPA_HOSTNAME);
- subreq = ipa_host_info_send(state, state->ev,
- state->sh, state->sdap_opts, hostname,
- state->ipa_opts->host_map,
- state->ipa_opts->hostgroup_map,
- state->ipa_opts->host_search_bases);
+ subreq = sdap_host_info_send(state, state->ev,
+ state->sh, state->sdap_opts, hostname,
+ state->ipa_opts->id->host_map,
+ state->ipa_opts->id->hostgroup_map,
+ state->ipa_opts->id->sdom->host_search_bases);
if (subreq == NULL) {
state->dp_error = DP_ERR_FATAL;
tevent_req_error(req, ENOMEM);
@@ -1008,8 +1008,8 @@ ipa_sudo_refresh_host_done(struct tevent_req *subreq)
return;
}
- ret = ipa_host_info_recv(subreq, host, &host->num_hosts, &host->hosts,
- &host->num_hostgroups, &host->hostgroups);
+ ret = sdap_host_info_recv(subreq, host, &host->num_hosts, &host->hosts,
+ &host->num_hostgroups, &host->hostgroups);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve host information "
@@ -1023,8 +1023,8 @@ ipa_sudo_refresh_host_done(struct tevent_req *subreq)
state->sudo_ctx, host,
state->sdap_opts->user_map,
state->sdap_opts->group_map,
- state->ipa_opts->host_map,
- state->ipa_opts->hostgroup_map, state->sh,
+ state->ipa_opts->id->host_map,
+ state->ipa_opts->id->hostgroup_map, state->sh,
state->cmdgroups_filter, state->search_filter);
if (subreq == NULL) {
state->dp_error = DP_ERR_FATAL;
diff --git a/src/providers/ipa/ipa_sudo_conversion.c b/src/providers/ipa/ipa_sudo_conversion.c
index f6d17d82b..701de521c 100644
--- a/src/providers/ipa/ipa_sudo_conversion.c
+++ b/src/providers/ipa/ipa_sudo_conversion.c
@@ -43,8 +43,8 @@
#define MATCHRDN_USER(map) (map)[SDAP_AT_USER_NAME].name, "cn", "users", "cn", "accounts"
#define MATCHRDN_GROUP(map) (map)[SDAP_AT_GROUP_NAME].name, "cn", "groups", "cn", "accounts"
-#define MATCHRDN_HOST(map) (map)[IPA_AT_HOST_FQDN].name, "cn", "computers", "cn", "accounts"
-#define MATCHRDN_HOSTGROUP(map) (map)[IPA_AT_HOSTGROUP_NAME].name, "cn", "hostgroups", "cn", "accounts"
+#define MATCHRDN_HOST(map) (map)[SDAP_AT_HOST_FQDN].name, "cn", "computers", "cn", "accounts"
+#define MATCHRDN_HOSTGROUP(map) (map)[SDAP_AT_HOSTGROUP_NAME].name, "cn", "hostgroups", "cn", "accounts"
struct ipa_sudo_conv {
struct sss_domain_info *dom;
diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c
index b7102adb8..74337013f 100644
--- a/src/providers/ldap/ldap_init.c
+++ b/src/providers/ldap/ldap_init.c
@@ -26,6 +26,7 @@
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/sdap_access.h"
+#include "providers/ldap/sdap_hostid.h"
#include "providers/ldap/sdap_sudo.h"
#include "providers/ldap/sdap_autofs.h"
#include "providers/ldap/sdap_idmap.h"
@@ -618,6 +619,26 @@ done:
return ret;
}
+errno_t sssm_ldap_hostid_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ void *module_data,
+ struct dp_method *dp_methods)
+{
+#ifdef BUILD_SSH
+ struct ldap_init_ctx *init_ctx;
+
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing LDAP host handler\n");
+ init_ctx = talloc_get_type(module_data, struct ldap_init_ctx);
+
+ return sdap_hostid_init(mem_ctx, be_ctx, init_ctx->id_ctx, dp_methods);
+
+#else
+ DEBUG(SSSDBG_MINOR_FAILURE, "HostID init handler called but SSSD is "
+ "built without SSH support, ignoring\n");
+ return EOK;
+#endif
+}
+
errno_t sssm_ldap_autofs_init(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
void *module_data,
diff --git a/src/providers/ldap/ldap_options.c b/src/providers/ldap/ldap_options.c
index 15a2609f0..599914640 100644
--- a/src/providers/ldap/ldap_options.c
+++ b/src/providers/ldap/ldap_options.c
@@ -33,6 +33,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
struct sdap_attr_map *default_user_map;
struct sdap_attr_map *default_group_map;
struct sdap_attr_map *default_netgroup_map;
+ struct sdap_attr_map *default_host_map;
struct sdap_attr_map *default_service_map;
struct sdap_options *opts;
char *schema;
@@ -50,6 +51,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
const int search_base_options[] = { SDAP_USER_SEARCH_BASE,
SDAP_GROUP_SEARCH_BASE,
SDAP_NETGROUP_SEARCH_BASE,
+ SDAP_HOST_SEARCH_BASE,
SDAP_SERVICE_SEARCH_BASE,
-1 };
@@ -116,6 +118,12 @@ int ldap_get_options(TALLOC_CTX *memctx,
&opts->sdom->netgroup_search_bases);
if (ret != EOK && ret != ENOENT) goto done;
+ /* Netgroup search */
+ ret = sdap_parse_search_base(opts, opts->basic,
+ SDAP_HOST_SEARCH_BASE,
+ &opts->sdom->host_search_bases);
+ if (ret != EOK && ret != ENOENT) goto done;
+
/* Service search */
ret = sdap_parse_search_base(opts, opts->basic,
SDAP_SERVICE_SEARCH_BASE,
@@ -214,6 +222,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
default_user_map = rfc2307_user_map;
default_group_map = rfc2307_group_map;
default_netgroup_map = netgroup_map;
+ default_host_map = host_map;
default_service_map = service_map;
} else
if (strcasecmp(schema, "rfc2307bis") == 0) {
@@ -222,6 +231,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
default_user_map = rfc2307bis_user_map;
default_group_map = rfc2307bis_group_map;
default_netgroup_map = netgroup_map;
+ default_host_map = host_map;
default_service_map = service_map;
} else
if (strcasecmp(schema, "IPA") == 0) {
@@ -230,6 +240,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
default_user_map = rfc2307bis_user_map;
default_group_map = rfc2307bis_group_map;
default_netgroup_map = netgroup_map;
+ default_host_map = host_map;
default_service_map = service_map;
} else
if (strcasecmp(schema, "AD") == 0) {
@@ -238,6 +249,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
default_user_map = gen_ad2008r2_user_map;
default_group_map = gen_ad2008r2_group_map;
default_netgroup_map = netgroup_map;
+ default_host_map = host_map;
default_service_map = service_map;
} else {
DEBUG(SSSDBG_FATAL_FAILURE, "Unrecognized schema type: %s\n", schema);
@@ -285,6 +297,17 @@ int ldap_get_options(TALLOC_CTX *memctx,
}
ret = sdap_get_map(opts, cdb, conf_path,
+ default_host_map,
+ SDAP_OPTS_HOST,
+ &opts->host_map);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ /* Host groups are only available in IPA */
+ opts->hostgroup_map = NULL;
+
+ ret = sdap_get_map(opts, cdb, conf_path,
default_service_map,
SDAP_OPTS_SERVICES,
&opts->service_map);
@@ -598,6 +621,9 @@ errno_t sdap_parse_search_base(TALLOC_CTX *mem_ctx,
case SDAP_NETGROUP_SEARCH_BASE:
class_name = "NETGROUP";
break;
+ case SDAP_HOST_SEARCH_BASE:
+ class_name = "HOST";
+ break;
case SDAP_SUDO_SEARCH_BASE:
class_name = "SUDO";
break;
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
index c6efe332f..fbd527ef6 100644
--- a/src/providers/ldap/ldap_opts.c
+++ b/src/providers/ldap/ldap_opts.c
@@ -45,6 +45,7 @@ struct dp_option default_basic_opts[] = {
{ "ldap_group_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_group_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING },
{ "ldap_group_search_filter", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "ldap_host_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_service_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sudo_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ldap_sudo_full_refresh_interval", DP_OPT_NUMBER, { .number = 21600 }, NULL_NUMBER }, /* 360 mins */
@@ -325,6 +326,17 @@ struct sdap_attr_map netgroup_map[] = {
SDAP_ATTR_MAP_TERMINATOR
};
+struct sdap_attr_map host_map[] = {
+ { "ldap_host_object_class", "ipHost", SYSDB_HOST_CLASS, NULL },
+ { "ldap_host_name", "cn", SYSDB_NAME, NULL },
+ { "ldap_host_fqdn", "fqdn", SYSDB_FQDN, NULL },
+ { "ldap_host_serverhostname", "serverHostname", SYSDB_SERVERHOSTNAME, NULL },
+ { "ldap_host_member_of", "memberOf", SYSDB_ORIG_MEMBEROF, NULL },
+ { "ldap_host_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
+ { "ldap_host_uuid", NULL, SYSDB_UUID, NULL},
+ SDAP_ATTR_MAP_TERMINATOR
+};
+
struct sdap_attr_map native_sudorule_map[] = {
{ "ldap_sudorule_object_class", "sudoRole", SYSDB_SUDO_CACHE_OC, NULL },
{ "ldap_sudorule_name", "cn", SYSDB_SUDO_CACHE_AT_CN, NULL },
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index ef09a024d..d8125549e 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -48,6 +48,10 @@ extern struct sdap_attr_map gen_ad2008r2_group_map[];
extern struct sdap_attr_map netgroup_map[];
+extern struct sdap_attr_map host_map[];
+
+extern struct sdap_attr_map hostgroup_map[];
+
extern struct sdap_attr_map native_sudorule_map[];
extern struct sdap_attr_map service_map[];
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index d562a96e2..b69066064 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1136,6 +1136,9 @@ static errno_t sdap_set_search_base(struct sdap_options *opts,
case SDAP_NETGROUP_SEARCH_BASE:
bases = &sdom->netgroup_search_bases;
break;
+ case SDAP_HOST_SEARCH_BASE:
+ bases = &sdom->host_search_bases;
+ break;
case SDAP_SUDO_SEARCH_BASE:
bases = &sdom->sudo_search_bases;
break;
@@ -1178,6 +1181,7 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
|| !sdom->user_search_bases
|| !sdom->group_search_bases
|| !sdom->netgroup_search_bases
+ || !sdom->host_search_bases
|| !sdom->sudo_search_bases
|| !sdom->autofs_search_bases) {
naming_context = get_naming_context(opts->basic, rootdse);
@@ -1225,6 +1229,14 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse,
if (ret != EOK) goto done;
}
+ /* Hosts */
+ if (!sdom->host_search_bases) {
+ ret = sdap_set_search_base(opts, sdom,
+ SDAP_HOST_SEARCH_BASE,
+ naming_context);
+ if (ret != EOK) goto done;
+ }
+
/* Sudo */
if (!sdom->sudo_search_bases) {
ret = sdap_set_search_base(opts, sdom,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index afdc01948..5665c7289 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -162,6 +162,7 @@ enum sdap_basic_opt {
SDAP_GROUP_SEARCH_BASE,
SDAP_GROUP_SEARCH_SCOPE,
SDAP_GROUP_SEARCH_FILTER,
+ SDAP_HOST_SEARCH_BASE,
SDAP_SERVICE_SEARCH_BASE,
SDAP_SUDO_SEARCH_BASE,
SDAP_SUDO_FULL_REFRESH_INTERVAL,
@@ -339,6 +340,27 @@ enum sdap_sudorule_attrs {
SDAP_OPTS_SUDO /* attrs counter */
};
+enum sdap_host_attrs {
+ SDAP_OC_HOST = 0,
+ SDAP_AT_HOST_NAME,
+ SDAP_AT_HOST_FQDN,
+ SDAP_AT_HOST_SERVERHOSTNAME,
+ SDAP_AT_HOST_MEMBER_OF,
+ SDAP_AT_HOST_SSH_PUBLIC_KEY,
+ SDAP_AT_HOST_UUID,
+
+ SDAP_OPTS_HOST /* attrs counter */
+};
+
+enum sdap_hostgroup_attrs {
+ SDAP_OC_HOSTGROUP = 0,
+ SDAP_AT_HOSTGROUP_NAME,
+ SDAP_AT_HOSTGROUP_MEMBER_OF,
+ SDAP_AT_HOSTGROUP_UUID,
+
+ SDAP_OPTS_HOSTGROUP /* attrs counter */
+};
+
enum sdap_service_attrs {
SDAP_OC_SERVICE = 0,
SDAP_AT_SERVICE_NAME,
@@ -406,6 +428,7 @@ struct sdap_domain {
struct sdap_search_base **user_search_bases;
struct sdap_search_base **group_search_bases;
struct sdap_search_base **netgroup_search_bases;
+ struct sdap_search_base **host_search_bases;
struct sdap_search_base **sudo_search_bases;
struct sdap_search_base **service_search_bases;
struct sdap_search_base **autofs_search_bases;
@@ -453,6 +476,8 @@ struct sdap_options {
size_t user_map_cnt;
struct sdap_attr_map *group_map;
struct sdap_attr_map *netgroup_map;
+ struct sdap_attr_map *host_map;
+ struct sdap_attr_map *hostgroup_map;
struct sdap_attr_map *service_map;
/* ID-mapping support */
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 6e5800b42..a1101cb5f 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -123,6 +123,24 @@ int sdap_get_netgroups_recv(struct tevent_req *req,
size_t *reply_count,
struct sysdb_attrs ***reply);
+struct tevent_req *
+sdap_host_info_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_handle *sh,
+ struct sdap_options *opts,
+ const char *hostname,
+ struct sdap_attr_map *host_map,
+ struct sdap_attr_map *hostgroup_map,
+ struct sdap_search_base **search_bases);
+
+errno_t
+sdap_host_info_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *host_count,
+ struct sysdb_attrs ***hosts,
+ size_t *hostgroup_count,
+ struct sysdb_attrs ***hostgroups);
+
struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_handle *sh,
diff --git a/src/providers/ipa/ipa_hosts.c b/src/providers/ldap/sdap_async_hosts.c
similarity index 82%
rename from src/providers/ipa/ipa_hosts.c
rename to src/providers/ldap/sdap_async_hosts.c
index 5966e3c74..75579f4b0 100644
--- a/src/providers/ipa/ipa_hosts.c
+++ b/src/providers/ldap/sdap_async_hosts.c
@@ -22,11 +22,10 @@
#include "util/util.h"
#include "db/sysdb.h"
-#include "providers/ldap/sdap_async.h"
-#include "providers/ipa/ipa_hosts.h"
-#include "providers/ipa/ipa_common.h"
+#include "providers/ldap/sdap_async_private.h"
+#include "providers/ldap/ldap_common.h"
-struct ipa_host_state {
+struct sdap_host_state {
struct tevent_context *ev;
struct sysdb_ctx *sysdb;
struct sdap_handle *sh;
@@ -49,21 +48,20 @@ struct ipa_host_state {
size_t hostgroup_count;
struct sysdb_attrs **hostgroups;
- struct sdap_attr_map_info *ipa_hostgroup_map;
};
static void
-ipa_host_info_done(struct tevent_req *subreq);
+sdap_host_info_done(struct tevent_req *subreq);
static void
-ipa_hostgroup_info_done(struct tevent_req *subreq);
+sdap_hostgroup_info_done(struct tevent_req *subreq);
static errno_t
-ipa_host_info_next(struct tevent_req *req,
- struct ipa_host_state *state);
+sdap_host_info_next(struct tevent_req *req,
+ struct sdap_host_state *state);
static errno_t
-ipa_hostgroup_info_next(struct tevent_req *req,
- struct ipa_host_state *state);
+sdap_hostgroup_info_next(struct tevent_req *req,
+ struct sdap_host_state *state);
/**
* hostname == NULL -> look up all hosts / host groups
@@ -72,7 +70,7 @@ ipa_hostgroup_info_next(struct tevent_req *req,
* hostgroup_map == NULL -> skip looking up hostgroups
*/
struct tevent_req *
-ipa_host_info_send(TALLOC_CTX *mem_ctx,
+sdap_host_info_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct sdap_handle *sh,
struct sdap_options *opts,
@@ -82,10 +80,10 @@ ipa_host_info_send(TALLOC_CTX *mem_ctx,
struct sdap_search_base **search_bases)
{
errno_t ret;
- struct ipa_host_state *state;
+ struct sdap_host_state *state;
struct tevent_req *req;
- req = tevent_req_create(mem_ctx, &state, struct ipa_host_state);
+ req = tevent_req_create(mem_ctx, &state, struct sdap_host_state);
if (req == NULL) {
return NULL;
}
@@ -100,7 +98,7 @@ ipa_host_info_send(TALLOC_CTX *mem_ctx,
state->host_map = host_map;
state->hostgroup_map = hostgroup_map;
- ret = build_attrs_from_map(state, host_map, IPA_OPTS_HOST,
+ ret = build_attrs_from_map(state, host_map, SDAP_OPTS_HOST,
NULL, &state->attrs, NULL);
if (ret != EOK) {
goto immediate;
@@ -108,11 +106,11 @@ ipa_host_info_send(TALLOC_CTX *mem_ctx,
if (hostname == NULL) {
state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
- host_map[IPA_OC_HOST].name);
+ host_map[SDAP_OC_HOST].name);
} else {
state->host_filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=%s))",
- host_map[IPA_OC_HOST].name,
- host_map[IPA_AT_HOST_FQDN].name,
+ host_map[SDAP_OC_HOST].name,
+ host_map[SDAP_AT_HOST_FQDN].name,
hostname);
}
if (state->host_filter == NULL) {
@@ -120,7 +118,7 @@ ipa_host_info_send(TALLOC_CTX *mem_ctx,
goto immediate;
}
- ret = ipa_host_info_next(req, state);
+ ret = sdap_host_info_next(req, state);
if (ret == EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n");
ret = EINVAL;
@@ -142,8 +140,8 @@ immediate:
return req;
}
-static errno_t ipa_host_info_next(struct tevent_req *req,
- struct ipa_host_state *state)
+static errno_t sdap_host_info_next(struct tevent_req *req,
+ struct sdap_host_state *state)
{
struct sdap_search_base *base;
struct tevent_req *subreq;
@@ -164,7 +162,7 @@ static errno_t ipa_host_info_next(struct tevent_req *req,
state->sh, base->basedn,
base->scope, state->cur_filter,
state->attrs, state->host_map,
- IPA_OPTS_HOST,
+ SDAP_OPTS_HOST,
dp_opt_get_int(state->opts->basic,
SDAP_ENUM_SEARCH_TIMEOUT),
true);
@@ -173,20 +171,22 @@ static errno_t ipa_host_info_next(struct tevent_req *req,
talloc_zfree(state->cur_filter);
return EIO;
}
- tevent_req_set_callback(subreq, ipa_host_info_done, req);
+ tevent_req_set_callback(subreq, sdap_host_info_done, req);
return EAGAIN;
}
static void
-ipa_host_info_done(struct tevent_req *subreq)
+sdap_host_info_done(struct tevent_req *subreq)
{
errno_t ret;
struct tevent_req *req =
tevent_req_callback_data(subreq, struct tevent_req);
- struct ipa_host_state *state =
- tevent_req_data(req, struct ipa_host_state);
+ struct sdap_host_state *state =
+ tevent_req_data(req, struct sdap_host_state);
const char *host_dn;
+ struct sdap_attr_map_info *maps;
+ const int num_maps = 1;
ret = sdap_get_generic_recv(subreq, state,
&state->host_count,
@@ -199,7 +199,7 @@ ipa_host_info_done(struct tevent_req *subreq)
if (state->host_count == 0) {
state->search_base_iter++;
- ret = ipa_host_info_next(req, state);
+ ret = sdap_host_info_next(req, state);
if (ret == EOK) {
/* No more search bases to try */
tevent_req_error(req, ENOENT);
@@ -212,7 +212,7 @@ ipa_host_info_done(struct tevent_req *subreq)
if (state->hostgroup_map) {
talloc_free(state->attrs);
ret = build_attrs_from_map(state, state->hostgroup_map,
- IPA_OPTS_HOSTGROUP, NULL,
+ SDAP_OPTS_HOSTGROUP, NULL,
&state->attrs, NULL);
if (ret != EOK) {
tevent_req_error(req, ret);
@@ -223,14 +223,14 @@ ipa_host_info_done(struct tevent_req *subreq)
if (state->hostname == NULL) {
talloc_zfree(state->host_filter);
state->host_filter = talloc_asprintf(state, "(objectClass=%s)",
- state->hostgroup_map[IPA_OC_HOSTGROUP].name);
+ state->hostgroup_map[SDAP_OC_HOSTGROUP].name);
if (state->host_filter == NULL) {
tevent_req_error(req, ENOMEM);
return;
}
state->search_base_iter = 0;
- ret = ipa_hostgroup_info_next(req, state);
+ ret = sdap_hostgroup_info_next(req, state);
if (ret == EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "No host search base configured?\n");
tevent_req_error(req, EINVAL);
@@ -240,14 +240,6 @@ ipa_host_info_done(struct tevent_req *subreq)
return;
}
} else {
- state->ipa_hostgroup_map = talloc_zero(state, struct sdap_attr_map_info);
- if (state->ipa_hostgroup_map == NULL) {
- tevent_req_error(req, ENOMEM);
- return;
- }
- state->ipa_hostgroup_map->map = state->hostgroup_map;
- state->ipa_hostgroup_map->num_attrs = IPA_OPTS_HOSTGROUP;
-
ret = sysdb_attrs_get_string(state->hosts[0], SYSDB_ORIG_DN, &host_dn);
if (ret != EOK) {
tevent_req_error(req, ret);
@@ -260,19 +252,29 @@ ipa_host_info_done(struct tevent_req *subreq)
return;
}
+ maps = talloc_array(state, struct sdap_attr_map_info, num_maps+1);
+ if (maps == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ maps[0].map = state->hostgroup_map;
+ maps[0].num_attrs = SDAP_OPTS_HOSTGROUP;
+ maps[1].map = NULL;
+
subreq = sdap_deref_search_send(state, state->ev, state->opts, state->sh,
host_dn,
- state->hostgroup_map[IPA_AT_HOSTGROUP_MEMBER_OF].name,
+ state->hostgroup_map[SDAP_AT_HOSTGROUP_MEMBER_OF].name,
state->attrs,
- 1, state->ipa_hostgroup_map,
+ num_maps, maps,
dp_opt_get_int(state->opts->basic,
SDAP_ENUM_SEARCH_TIMEOUT));
if (subreq == NULL) {
+ talloc_free(maps);
DEBUG(SSSDBG_CRIT_FAILURE, "Error requesting host info\n");
tevent_req_error(req, EIO);
return;
}
- tevent_req_set_callback(subreq, ipa_hostgroup_info_done, req);
+ tevent_req_set_callback(subreq, sdap_hostgroup_info_done, req);
}
} else {
/* Nothing else to do, just complete the req */
@@ -280,8 +282,8 @@ ipa_host_info_done(struct tevent_req *subreq)
}
}
-static errno_t ipa_hostgroup_info_next(struct tevent_req *req,
- struct ipa_host_state *state)
+static errno_t sdap_hostgroup_info_next(struct tevent_req *req,
+ struct sdap_host_state *state)
{
struct sdap_search_base *base;
struct tevent_req *subreq;
@@ -302,7 +304,7 @@ static errno_t ipa_hostgroup_info_next(struct tevent_req *req,
base->basedn, base->scope,
state->cur_filter, state->attrs,
state->hostgroup_map,
- IPA_OPTS_HOSTGROUP,
+ SDAP_OPTS_HOSTGROUP,
dp_opt_get_int(state->opts->basic,
SDAP_ENUM_SEARCH_TIMEOUT),
true);
@@ -311,19 +313,19 @@ static errno_t ipa_hostgroup_info_next(struct tevent_req *req,
talloc_zfree(state->cur_filter);
return EIO;
}
- tevent_req_set_callback(subreq, ipa_hostgroup_info_done, req);
+ tevent_req_set_callback(subreq, sdap_hostgroup_info_done, req);
return EAGAIN;
}
static void
-ipa_hostgroup_info_done(struct tevent_req *subreq)
+sdap_hostgroup_info_done(struct tevent_req *subreq)
{
errno_t ret;
struct tevent_req *req =
tevent_req_callback_data(subreq, struct tevent_req);
- struct ipa_host_state *state =
- tevent_req_data(req, struct ipa_host_state);
+ struct sdap_host_state *state =
+ tevent_req_data(req, struct sdap_host_state);
size_t hostgroups_total;
size_t hostgroup_count;
@@ -367,7 +369,7 @@ ipa_hostgroup_info_done(struct tevent_req *subreq)
/* Now look in the next base */
state->search_base_iter++;
- ret = ipa_hostgroup_info_next(req, state);
+ ret = sdap_hostgroup_info_next(req, state);
if (ret != EOK && ret != EAGAIN) {
tevent_req_error(req, ret);
}
@@ -407,7 +409,7 @@ ipa_hostgroup_info_done(struct tevent_req *subreq)
}
ret = sysdb_attrs_get_string(deref_result[i]->attrs,
- state->hostgroup_map[IPA_AT_HOSTGROUP_NAME].sys_name,
+ state->hostgroup_map[SDAP_AT_HOSTGROUP_NAME].sys_name,
&hostgroup_name);
if (ret != EOK) goto done;
@@ -430,7 +432,7 @@ done:
}
}
-errno_t ipa_host_info_recv(struct tevent_req *req,
+errno_t sdap_host_info_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *host_count,
struct sysdb_attrs ***hosts,
@@ -438,8 +440,8 @@ errno_t ipa_host_info_recv(struct tevent_req *req,
struct sysdb_attrs ***hostgroups)
{
size_t c;
- struct ipa_host_state *state =
- tevent_req_data(req, struct ipa_host_state);
+ struct sdap_host_state *state =
+ tevent_req_data(req, struct sdap_host_state);
TEVENT_REQ_RETURN_ON_ERROR(req);
diff --git a/src/providers/ldap/sdap_hostid.c b/src/providers/ldap/sdap_hostid.c
new file mode 100644
index 000000000..b3cd676d0
--- /dev/null
+++ b/src/providers/ldap/sdap_hostid.c
@@ -0,0 +1,325 @@
+/*
+ Authors:
+ Jan Cholasta <jcholast(a)redhat.com>
+
+ Copyright (C) 2012 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include "util/crypto/sss_crypto.h"
+#include "db/sysdb_ssh.h"
+#include "providers/ldap/ldap_common.h"
+#include "providers/ldap/sdap_async.h"
+#include "providers/ldap/sdap_hostid.h"
+
+struct hosts_get_state {
+ struct tevent_context *ev;
+ struct sdap_id_ctx *id_ctx;
+ struct sdap_id_op *op;
+ struct sss_domain_info *domain;
+ const char *name;
+ const char *alias;
+
+ size_t count;
+ struct sysdb_attrs **hosts;
+ int dp_error;
+};
+
+static errno_t
+hosts_get_retry(struct tevent_req *req);
+static void
+hosts_get_connect_done(struct tevent_req *subreq);
+static void
+hosts_get_done(struct tevent_req *subreq);
+
+struct tevent_req *
+hosts_get_send(TALLOC_CTX *memctx,
+ struct tevent_context *ev,
+ struct sdap_id_ctx *id_ctx,
+ const char *name,
+ const char *alias)
+{
+ struct tevent_req *req;
+ struct hosts_get_state *state;
+ errno_t ret;
+
+ req = tevent_req_create(memctx, &state, struct hosts_get_state);
+ if (!req) return NULL;
+
+ state->ev = ev;
+ state->id_ctx = id_ctx;
+ state->dp_error = DP_ERR_FATAL;
+
+ state->op = sdap_id_op_create(state, id_ctx->conn->conn_cache);
+ if (!state->op) {
+ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ state->domain = id_ctx->be->domain;
+ state->name = name;
+ state->alias = alias;
+
+ ret = hosts_get_retry(req);
+ if (ret != EOK) {
+ goto fail;
+ }
+
+ return req;
+
+fail:
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static errno_t
+hosts_get_retry(struct tevent_req *req)
+{
+ struct hosts_get_state *state = tevent_req_data(req,
+ struct hosts_get_state);
+ struct tevent_req *subreq;
+ errno_t ret = EOK;
+
+ subreq = sdap_id_op_connect_send(state->op, state, &ret);
+ if (!subreq) {
+ return ret;
+ }
+
+ tevent_req_set_callback(subreq, hosts_get_connect_done, req);
+ return EOK;
+}
+
+static void
+hosts_get_connect_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct hosts_get_state *state = tevent_req_data(req,
+ struct hosts_get_state);
+ int dp_error = DP_ERR_FATAL;
+ errno_t ret;
+
+ ret = sdap_id_op_connect_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ if (ret != EOK) {
+ state->dp_error = dp_error;
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ subreq = sdap_host_info_send(state, state->ev,
+ sdap_id_op_handle(state->op),
+ state->id_ctx->opts, state->name,
+ state->id_ctx->opts->host_map, NULL,
+ state->id_ctx->opts->sdom->host_search_bases);
+ if (!subreq) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+ tevent_req_set_callback(subreq, hosts_get_done, req);
+}
+
+static void
+hosts_get_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct hosts_get_state *state = tevent_req_data(req,
+ struct hosts_get_state);
+ int dp_error = DP_ERR_FATAL;
+ errno_t ret;
+ struct sysdb_attrs *attrs;
+ time_t now = time(NULL);
+
+ ret = sdap_host_info_recv(subreq, state,
+ &state->count, &state->hosts,
+ NULL, NULL);
+ talloc_zfree(subreq);
+
+ ret = sdap_id_op_done(state->op, ret, &dp_error);
+ if (dp_error == DP_ERR_OK && ret != EOK) {
+ /* retry */
+ ret = hosts_get_retry(req);
+ if (ret != EOK) {
+ goto done;
+ }
+ return;
+ }
+
+ if (ret != EOK && ret != ENOENT) {
+ goto done;
+ }
+
+ if (state->count == 0) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "No host with name [%s] found.\n", state->name);
+
+ ret = sysdb_delete_ssh_host(state->domain, state->name);
+ if (ret != EOK && ret != ENOENT) {
+ goto done;
+ }
+
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (state->count > 1) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Found more than one host with name [%s].\n", state->name);
+ ret = EINVAL;
+ goto done;
+ }
+
+ attrs = sysdb_new_attrs(state);
+ if (!attrs) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ /* we are interested only in the host keys */
+ ret = sysdb_attrs_copy_values(state->hosts[0], attrs, SYSDB_SSH_PUBKEY);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_store_ssh_host(state->domain, state->name, state->alias,
+ state->domain->ssh_host_timeout, now, attrs);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ dp_error = DP_ERR_OK;
+
+done:
+ state->dp_error = dp_error;
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+}
+
+static errno_t
+hosts_get_recv(struct tevent_req *req,
+ int *dp_error_out)
+{
+ struct hosts_get_state *state = tevent_req_data(req,
+ struct hosts_get_state);
+
+ if (dp_error_out) {
+ *dp_error_out = state->dp_error;
+ }
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
+
+struct sdap_hostid_handler_state {
+ struct dp_reply_std reply;
+};
+
+static void sdap_hostid_handler_done(struct tevent_req *subreq);
+
+struct tevent_req *
+sdap_hostid_handler_send(TALLOC_CTX *mem_ctx,
+ struct sdap_id_ctx *id_ctx,
+ struct dp_hostid_data *data,
+ struct dp_req_params *params)
+{
+ struct sdap_hostid_handler_state *state;
+ struct tevent_req *subreq;
+ struct tevent_req *req;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct sdap_hostid_handler_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ subreq = hosts_get_send(state, params->ev, id_ctx,
+ data->name, data->alias);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to send request\n");
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, sdap_hostid_handler_done, req);
+
+ return req;
+
+immediately:
+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL);
+
+ /* TODO For backward compatibility we always return EOK to DP now. */
+ tevent_req_done(req);
+ tevent_req_post(req, params->ev);
+
+ return req;
+}
+
+static void sdap_hostid_handler_done(struct tevent_req *subreq)
+{
+ struct sdap_hostid_handler_state *state;
+ struct tevent_req *req;
+ int dp_error;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_hostid_handler_state);
+
+ ret = hosts_get_recv(subreq, &dp_error);
+ talloc_zfree(subreq);
+
+ /* TODO For backward compatibility we always return EOK to DP now. */
+ dp_reply_std_set(&state->reply, dp_error, ret, NULL);
+ tevent_req_done(req);
+}
+
+errno_t
+sdap_hostid_handler_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ struct dp_reply_std *data)
+{
+ struct sdap_hostid_handler_state *state = NULL;
+
+ state = tevent_req_data(req, struct sdap_hostid_handler_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *data = state->reply;
+
+ return EOK;
+}
+
+errno_t sdap_hostid_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct sdap_id_ctx *id_ctx,
+ struct dp_method *dp_methods)
+{
+ (void)be_ctx;
+
+ dp_set_method(dp_methods, DPM_HOSTID_HANDLER,
+ sdap_hostid_handler_send, sdap_hostid_handler_recv, id_ctx,
+ struct sdap_id_ctx, struct dp_hostid_data, struct dp_reply_std);
+
+ return EOK;
+}
diff --git a/src/providers/ipa/ipa_hostid.h b/src/providers/ldap/sdap_hostid.h
similarity index 55%
rename from src/providers/ipa/ipa_hostid.h
rename to src/providers/ldap/sdap_hostid.h
index 2611e455e..6968cbd77 100644
--- a/src/providers/ipa/ipa_hostid.h
+++ b/src/providers/ldap/sdap_hostid.h
@@ -18,25 +18,24 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef _IPA_HOSTID_H_
-#define _IPA_HOSTID_H_
+#ifndef _SDAP_HOSTID_H_
+#define _SDAP_HOSTID_H_
-struct ipa_hostid_ctx {
- struct sdap_id_ctx *sdap_id_ctx;
- struct ipa_options *ipa_opts;
-
- struct sdap_search_base **host_search_bases;
-};
+errno_t sdap_hostid_init(TALLOC_CTX *mem_ctx,
+ struct be_ctx *be_ctx,
+ struct sdap_id_ctx *id_ctx,
+ struct dp_method *dp_methods);
struct tevent_req *
-ipa_hostid_handler_send(TALLOC_CTX *mem_ctx,
- struct ipa_hostid_ctx *hostid_ctx,
- struct dp_hostid_data *data,
- struct dp_req_params *params);
+sdap_hostid_handler_send(TALLOC_CTX *mem_ctx,
+ struct sdap_id_ctx *id_ctx,
+ struct dp_hostid_data *data,
+ struct dp_req_params *params);
errno_t
-ipa_hostid_handler_recv(TALLOC_CTX *mem_ctx,
- struct tevent_req *req,
- struct dp_reply_std *data);
+sdap_hostid_handler_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ struct dp_reply_std *data);
+
+#endif /* _SDAP_HOSTID_H_ */
-#endif /* _IPA_HOSTID_H_ */
diff --git a/src/tests/ipa_ldap_opt-tests.c b/src/tests/ipa_ldap_opt-tests.c
index 30e09f75b..339406d64 100644
--- a/src/tests/ipa_ldap_opt-tests.c
+++ b/src/tests/ipa_ldap_opt-tests.c
@@ -230,8 +230,8 @@ START_TEST(test_sdap_opt_sentinel)
fail_unless_sdap_opt_is_terminator(&ad_netgroup_map[SDAP_OPTS_NETGROUP]);
fail_unless_sdap_opt_is_terminator(&ipa_netgroup_map[IPA_OPTS_NETGROUP]);
- fail_unless_sdap_opt_is_terminator(&ipa_host_map[IPA_OPTS_HOST]);
- fail_unless_sdap_opt_is_terminator(&ipa_hostgroup_map[IPA_OPTS_HOSTGROUP]);
+ fail_unless_sdap_opt_is_terminator(&ipa_host_map[SDAP_OPTS_HOST]);
+ fail_unless_sdap_opt_is_terminator(&ipa_hostgroup_map[SDAP_OPTS_HOSTGROUP]);
fail_unless_sdap_opt_is_terminator(&ipa_selinux_user_map[IPA_OPTS_SELINUX_USERMAP]);
fail_unless_sdap_opt_is_terminator(&ipa_view_map[IPA_OPTS_VIEW]);
fail_unless_sdap_opt_is_terminator(&ipa_override_map[IPA_OPTS_OVERRIDE]);
--
2.12.2
7 years
pam_sss auth vs access
by zachhh@temple.edu
Hi list,
This is more of a feature request, and I don't know if this is the right venue to ask. If not, kindly direct me to the proper place.
The sssd configuration separates identity, authentication, and access providers. It would be nice to specify that only the access provider be enforced in a particular PAM stack. Generically, this is the authn vs authz issue. I would like to be able to use sssd for authz exclusively in some instances where other authentication is deemed satisfactory.
Use cases:
ssh with public key + 2nd factor token authentication + sssd access filtering
su without password + sssd access filtering
custom service with external authentication + sssd access filtering
I haven't delved too deeply into the sssd source to see how hard it would be to implement something like a pam argument authz_only that skips the auth provider, but it seems like it should be reasonable.
Thoughts?
Sincerely,
Zach
7 years
[sssd PR#231][comment] changing all talloc_get_type() with talloc_get_type_abort()
by simo5
URL: https://github.com/SSSD/sssd/pull/231
Title: #231: changing all talloc_get_type() with talloc_get_type_abort()
simo5 commented:
"""
So I can't really comment inline because there are too many lines in the patch but I grepped throught the code:
I see:
+ void sss_talloc_abort(const char reason){
Well .. that should be a const char * to start with as you want to pass a pointer to string not a single character
Also the style is incorrect as the opening brace should be on the next line.
The content of the function also is not what the issue describes.
the issue describes the option to either abort() or print a debug error based on configuration (or perhaps build flags). Instead this code unconditionally prints a debug error (this may be ok actually) and then unconditionally calls abort().
Finally this patchset is going to be big as it touches thousands of file in a mostly mecahnical way.
To improve reviewability it wuld be nice to split this PR in 2/3 patches:
1. Introduce the new sss_talloc_abort() function in the first patch with a good commit message that explains what this will bring us.
2. a separate patch that enables it everywhere
3. a separate patch that changes the invocations ofa talloc_get_type() to talloc_get_type_abort()
HTH.
"""
See the full comment at https://github.com/SSSD/sssd/pull/231#issuecomment-292973967
7 years
Design document - SSSD KCM server
by Jakub Hrozek
Hi,
I was working on a KCM server for SSSD for some time already in parallel
with the files provider and had some discussions with Simo as well. Of
course my intent wasn't to implement a feature secretly without a design
review, but to have a prototype to base a proper design on :)
However it makes sense to have a peer-reviewed design page now, also
because of Fedora's move towards Kerberos and KDC proxy, which leads to
questions on the Fedora lists about ccache renewals and so on -- so I
think it makes sense to pitch the design to Fedora at least already..
Here is the design page:
https://fedorahosted.org/sssd/wiki/DesignDocs/KCM
and here is the code of the KCM responder so far:
https://github.com/jhrozek/sssd/tree/kcm
Time-wise, I would like to pivot to return to working on KCM now that the
files provider is more or less done and tested.
For your convenience, the design page text is included below as well.
= KCM server for SSSD =
Related ticket(s):
* https://fedorahosted.org/sssd/ticket/2887
External links:
* [http://k5wiki.kerberos.org/wiki/Projects/KCM_client MIT wiki KCM documentation]
=== Problem statement ===
This design page describes adding a new SSSD responder, called
`sssd_kcm`. This component would manage Kerberos credential caches and
store them in SSSD's secrets storage.
=== Use cases ===
* A sysadmin needs to deploy applications in containers without worrying about applications clobbering each other's credential caches in a kernel keyring as keyrings are not namespaced
* A user wants to keep having her Kerberos ticket automatically renewed regardless of the ticket being acquired through a PAM conversation with SSSD or from the command line with kinit
* A system admin wants to leverage a collection-aware credentials cache for most of applications on their systems, yet enable a legacy application that can only work with a FILE-based ccache to interoperate with them
=== Overview of the solution ===
Over time, both libkrb5 and SSSD used different credential cache types
to store Kerberos credentials - going from a simple file-based storage
(`FILE:`) to a directory (`DIR:`) and most recently a kernel-keyring based
cache (`KEYRING:`).
Each of these caches has its own set of advantages and disadvantages. The
`FILE` ccache is very widely supported, but does not support multiple
primary caches. The `DIR` cache does, but creating and managing the
directories including proper access control can be tricky. The `KEYRING` cache
is not well suited for cases where multiple semi-isolated environments
might share the same kernel. Managing credential caches' lifetime is not
well solved in neither of these cache types automatically, only with the
help of a daemon like SSSD.
An interesting credentials cache that might solve the issues mentioned above
is `KCM`. With KCM, the Kerberos caches are not stored in a "passive"
store, but managed by a daemon. In this setup, the Kerberos library
(typically used through an application, like for example, `kinit`) is a
"KCM client" and the daemon is being referred to as a "KCM server".
Having the Kerberos credential caches managed by a deamon has several
advantages:
* the daemon is stateful and can perform tasks like Kerberos credential cache renewals or reaping old ccaches. Some tasks, like renewals are possible already with SSSD, but only for tickets that SSSD itself acquired (typically via a login through `pam_sss.so`) and tracks. Tickets acquired otherwise, most notably though kinit wouldn't be tracked and renewed.
* since the process runs in userspace, it is subject to UID namespacing, [http://www.projectatomic.io/blog/2014/09/yet-another-reason-containers-do... unlike the kernel keyring]
* unlike the kernel keyring-based cache, which is entirely dependant on UIDs of the caller and in a containerized environment is shared between all containers, the KCM server's entry point is a UNIX socket which can be bind-mounted to only some containers
* the protocol between the client and the server can be extended for custom operations such as dumping a cache in a different format to a specific location. This would be beneficial for applications that only understand a certain Kerberos ccache type - for example, some legacy applications only know how to deal with a FILE-based cache, thus preventing the use of cache collections
Only the Heimdal Kerberos implementation currently implements a KCM server,
but both Heimdal and MIT implement the client-side operations (in libkrb5)
to manage KCM-based Kerberos ccaches. This design page describes adding a
KCM server to SSSD. While it's of course possible to create a completely
standalone deamon that would implement a KCM server, doing so in the
context of SSSD has several advantages, notably:
* An easy access to the authentication provider of SSSD that already has existing and tested code to renew Kerberos credentials on user's behalf
* SSSD already has a D-Bus API that could publish information about Kerberos tickets and for example emit signals that a graphical application can consume
* SSSD has a 'secrets provider' to store data at rest. It makes sense to leverage this component to store Kerberos ccaches persistently
=== Implementation details ===
A new SSSD responder will be added. Since accessing the Kerberos credentials
is quite an infrequent operation, the responder will be socket-activated.
This responder would implement the same subset of the KCM protocol the MIT
client libraries implement. Contrary to Heimdal's KCM server that just
stores the credential caches in memory, the SSSD KCM server would store
the ccaches in the secrets database through the sssd-secret's responder
[https://jhrozek.fedorapeople.org/sssd/1.14.2/man/sssd-secrets.5.html public REST API].
For user credentials the KCM Server would use a secrets responder URI
like `/kcm/users/1234/X` where 1234 is the user ID and X is the residual.
The client then gets assigned a KRB5CCNAME of KCM:1234:X. Internally in the
secrets responder we will store the credential caches under a new base DN
`cn=kcm`.
The secret responder's quota on secrets must be made modular to allow
different number of secrets per base DN (so, different number of secrets
and credentials pretty much). What to do in case the quota is reached is
debatable - we should probably first remove service (non-TGT) tickets first
for valid TGTs and if that's not possible, just fail. A failure in this
case would be no different than a failure if a disk is full when trying
to store a FILE-based ccache.
The KCM responder would renew the user credentials by starting a tevent
timer which would then contact the SSSD Data Provider for the given UID
and principal, asking for the credentials to be renewed. Another tevent
timer would reap and remove a ccache that reaches its lifetime.
In the future, SSSD-specific operations such as writing out a FILE-based
ccache might be added. The SSSD D-Bus interface would also be extended to
publish information about credentials activity (such as - a ticket being
acquired, a ticket was renewed etc)
=== Configuration changes ===
No KCM-specific configuration options will be added. The SSSD KCM responder
would use the same common options like other SSSD services such as idle
timeout.
We can add a configurable KCM socket location later, if needed, but for
the start it's fine to default to `/var/run/.heim_org.h5l.kcm-socket`
mostly because that's what MIT defaults to as well.
'''Q''': Should we add an option to explicitly enable ccache renewals and
default to no renewals? I don't think this would any any security though,
the attacker can just run 'kinit -R' on behalf of the user anyway.
=== How To Test ===
In order for the admin to start using the KCM service, the sssd-kcm
responder's systemd service must be enabled. Then, libkrb5 must also be
configured to use KCM as its default ccache type in `/etc/krb5.conf`
{{{
[libdefaults]
default_ccache_name = KCM
}}}
After that, all common operations like kinit, kdestroy or login through
pam_sss should just work and store their credentials in the KCM server.
The KCM server must implement access control correctly, so even
trying to access other user's KCM credentials by setting KRB5CCNAME to
`KCM:1234:RESIDUAL` would not work (except for root).
Restarting the KCM server or rebooting the machine must persist the tickets.
As far as automatic unit and integration testing is required, we need to make
sure that MIT's testsuite passes with Kerberos ccache defaulting to KCM
and SSSD KCM deamon running. In the SSSD upstream, we should write
integration tests that run a MIT KDC under socket_wrapper to exercise the
KCM server.
=== How To Debug ===
The SSSD KCM server would use the same DEBUG facility as other SSSD
services. In order to debug the client side operations, setting the
`KRB5_TRACE` variable might come handy.
When debugging the setup, the admin might also inspect the SSSD secrets
database (if permissable by SELinux policy) to see what credential caches
have been stored by the SSSD.
=== Authors ===
* Jakub Hrozek <jhrozek(a)redhat.com>
* Simo Sorce <simo(a)redhat.com>
7 years