summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Šrubař <xsruba03@stud.fit.vutbr.cz>2014-09-18 19:29:38 +0200
committerLukas Slebodnik <lslebodn@redhat.com>2015-10-09 11:43:10 +0200
commitb326061a4af321c3bea9e96bc071d52c9d9d16f4 (patch)
tree720740b9c3d6941672c623110b3d406ef08b23de
parentc65de71bc38753320b9fd6f6fe1386244a2ff54a (diff)
downloadsssd-b326061a4af321c3bea9e96bc071d52c9d9d16f4.tar.gz
sssd-b326061a4af321c3bea9e96bc071d52c9d9d16f4.tar.xz
sssd-b326061a4af321c3bea9e96bc071d52c9d9d16f4.zip
SUDO: Support the IPA schema
https://fedorahosted.org/sssd/ticket/1108 IPA SUDO Provider uses LDAP sudo plugin for downloading sudo rules from IPA. It also uses its purge/store sysdb functions.
-rw-r--r--src/providers/ldap/sdap_async_sudo.c171
-rw-r--r--src/providers/ldap/sdap_sudo.c10
-rw-r--r--src/providers/ldap/sdap_sudo.h53
3 files changed, 161 insertions, 73 deletions
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index b4899cbaa..124d35949 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -5,6 +5,7 @@
Authors:
Pavel Březina <pbrezina@redhat.com>
+ MIchal Šrubař <xsruba03@stud.fit.vutbr.cz>
Copyright (C) 2012 Red Hat
@@ -34,23 +35,6 @@
#include "providers/ldap/sdap_sudo_cache.h"
#include "db/sysdb_sudo.h"
-struct sdap_sudo_refresh_state {
- struct be_ctx *be_ctx;
- struct sdap_options *opts;
- struct sdap_id_op *sdap_op;
- struct sdap_id_conn_cache *sdap_conn_cache;
- struct sysdb_ctx *sysdb;
- struct sss_domain_info *domain;
-
- const char *ldap_filter; /* search */
- const char *sysdb_filter; /* delete */
-
- int dp_error;
- int error;
- char *highest_usn;
- size_t num_rules;
-};
-
struct sdap_sudo_load_sudoers_state {
struct tevent_context *ev;
struct sdap_options *opts;
@@ -79,27 +63,9 @@ static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req);
static void sdap_sudo_load_sudoers_process(struct tevent_req *subreq);
-static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- size_t *rules_count,
- struct sysdb_attrs ***rules);
-
-static void sdap_sudo_refresh_load_done(struct tevent_req *subreq);
-
-static int sdap_sudo_purge_sudoers(struct sss_domain_info *dom,
- const char *filter,
- struct sdap_attr_map *map,
- size_t rules_count,
- struct sysdb_attrs **rules);
-
-static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- struct sdap_options *opts,
- size_t rules_count,
- struct sysdb_attrs **rules,
- int cache_timeout,
- time_t now,
- char **_usn);
+static void sdap_sudo_refresh_load_done_ex(struct tevent_req *subreq);
+static void sdap_sudo_refresh_load_done_ldap(struct tevent_req *subreq);
+static void sdap_sudo_refresh_load_done_ipa(struct tevent_req *subreq);
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
struct be_ctx *be_ctx,
@@ -167,7 +133,8 @@ int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx,
int *dp_error,
int *error,
char **usn,
- size_t *num_rules)
+ size_t *num_rules,
+ struct sysdb_attrs ***rules)
{
struct sdap_sudo_refresh_state *state;
@@ -186,6 +153,10 @@ int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx,
*num_rules = state->num_rules;
}
+ if (rules != NULL) {
+ *rules = talloc_steal(mem_ctx, state->ldap_rules);
+ }
+
return EOK;
}
@@ -264,7 +235,7 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq)
goto fail;
}
- tevent_req_set_callback(subreq, sdap_sudo_refresh_load_done, req);
+ tevent_req_set_callback(subreq, sdap_sudo_refresh_load_done_ex, req);
return;
@@ -279,9 +250,6 @@ static struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
struct sdap_options *opts,
struct sdap_handle *sh,
const char *ldap_filter)
-
-
-
{
struct tevent_req *req;
struct sdap_sudo_load_sudoers_state *state;
@@ -310,8 +278,16 @@ static struct tevent_req * sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
}
/* create attrs from map */
- ret = build_attrs_from_map(state, opts->sudorule_map, SDAP_OPTS_SUDO,
- NULL, &state->attrs, NULL);
+ if (state->opts->schema_type == SDAP_SCHEMA_IPA_V1) {
+ /* req from ipa_sudo_refresh_send() */
+ ret = build_attrs_from_map(state, opts->ipa_sudorule_map,
+ SDAP_OPTS_IPA_SUDO, NULL, &state->attrs, NULL);
+ } else {
+ /* req from sdap_sudo_refresh_send() */
+ ret = build_attrs_from_map(state, opts->sudorule_map, SDAP_OPTS_SUDO,
+ NULL, &state->attrs, NULL);
+ }
+
if (ret != EOK) {
goto fail;
}
@@ -337,6 +313,8 @@ static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req)
struct sdap_sudo_load_sudoers_state *state;
struct sdap_search_base *search_base;
struct tevent_req *subreq;
+ struct sdap_attr_map *map;
+ int attr_count;
char *filter;
state = tevent_req_data(req, struct sdap_sudo_load_sudoers_state);
@@ -359,6 +337,16 @@ static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req)
"Searching for sudo rules with base [%s]\n",
search_base->basedn);
+ if (state->opts->schema_type == SDAP_SCHEMA_IPA_V1) {
+ /* req from ipa_sudo_refresh_send() */
+ attr_count = SDAP_OPTS_IPA_SUDO;
+ map = state->opts->ipa_sudorule_map;
+ } else {
+ /* req from sdap_sudo_refresh_send() */
+ attr_count = SDAP_OPTS_SUDO;
+ map = state->opts->sudorule_map;
+ }
+
subreq = sdap_get_generic_send(state,
state->ev,
state->opts,
@@ -367,8 +355,8 @@ static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req)
search_base->scope,
filter,
state->attrs,
- state->opts->sudorule_map,
- SDAP_OPTS_SUDO,
+ map,
+ attr_count,
state->timeout,
true);
if (subreq == NULL) {
@@ -390,6 +378,7 @@ static void sdap_sudo_load_sudoers_process(struct tevent_req *subreq)
int ret;
int i;
+ /* req from sdap_sudo_load_sudoers_send */
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_load_sudoers_state);
search_base = state->search_bases[state->base_iter];
@@ -438,10 +427,10 @@ static void sdap_sudo_load_sudoers_process(struct tevent_req *subreq)
tevent_req_done(req);
}
-static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
- TALLOC_CTX *mem_ctx,
- size_t *rules_count,
- struct sysdb_attrs ***rules)
+int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *rules_count,
+ struct sysdb_attrs ***rules)
{
struct sdap_sudo_load_sudoers_state *state;
@@ -455,7 +444,58 @@ static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
return EOK;
}
-static void sdap_sudo_refresh_load_done(struct tevent_req *subreq)
+static void sdap_sudo_refresh_load_done_ex(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ struct sdap_sudo_refresh_state *state;
+
+ /* req from sdap_sudo_refresh_send() */
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_sudo_refresh_state);
+
+ if (state->opts->schema_type == SDAP_SCHEMA_IPA_V1) {
+ /* req from ipa_sudo_refresh_send() */
+ sdap_sudo_refresh_load_done_ipa(subreq);
+ } else {
+ /* req from sdap_sudo_refresh_send() */
+ sdap_sudo_refresh_load_done_ldap(subreq);
+ }
+}
+
+static void sdap_sudo_refresh_load_done_ipa(struct tevent_req *subreq)
+{
+ struct sdap_sudo_refresh_state *state;
+ struct tevent_req *req;
+ int ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_sudo_refresh_state);
+
+ ret = sdap_sudo_load_sudoers_recv(subreq, state, &state->ldap_rules_count,
+ &state->ldap_rules);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Received %zu rules\n", state->ldap_rules_count);
+ DEBUG(SSSDBG_TRACE_FUNC, "Giving control back to IPA SUDO provider\n");
+
+ state->num_rules = state->ldap_rules_count;
+
+done:
+ /* req from ipa_sudo_refresh_send continue in ipa_sudo_sudoers_process */
+ state->error = ret;
+ if (ret == EOK) {
+ state->dp_error = DP_ERR_OK;
+ tevent_req_done(req);
+ } else {
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ret);
+ }
+}
+
+static void sdap_sudo_refresh_load_done_ldap(struct tevent_req *subreq)
{
struct tevent_req *req; /* req from sdap_sudo_refresh_send() */
struct sdap_sudo_refresh_state *state;
@@ -523,6 +563,7 @@ done:
}
}
+ /* finish sdap_sudo_refresh_send() */
state->error = ret;
if (ret == EOK) {
state->dp_error = DP_ERR_OK;
@@ -533,11 +574,11 @@ done:
}
}
-static int sdap_sudo_purge_sudoers(struct sss_domain_info *dom,
- const char *filter,
- struct sdap_attr_map *map,
- size_t rules_count,
- struct sysdb_attrs **rules)
+int sdap_sudo_purge_sudoers(struct sss_domain_info *dom,
+ const char *filter,
+ struct sdap_attr_map *map,
+ size_t rules_count,
+ struct sysdb_attrs **rules)
{
const char *name;
int i;
@@ -586,14 +627,14 @@ done:
return ret;
}
-static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- struct sdap_options *opts,
- size_t rules_count,
- struct sysdb_attrs **rules,
- int cache_timeout,
- time_t now,
- char **_usn)
+int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts,
+ size_t rules_count,
+ struct sysdb_attrs **rules,
+ int cache_timeout,
+ time_t now,
+ char **_usn)
{
errno_t ret;
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index edef44208..1e3bf5fa2 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -288,7 +288,7 @@ static int sdap_sudo_setup_periodical_refresh(struct sdap_sudo_ctx *sudo_ctx)
return EOK;
}
-static void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
+void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
{
unsigned int usn_number;
char *endptr = NULL;
@@ -621,7 +621,7 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
state = tevent_req_data(req, struct sdap_sudo_full_refresh_state);
ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error,
- &state->error, &highest_usn, NULL);
+ &state->error, &highest_usn, NULL, NULL);
talloc_zfree(subreq);
if (ret != EOK || state->dp_error != DP_ERR_OK || state->error != EOK) {
goto done;
@@ -795,7 +795,7 @@ static void sdap_sudo_rules_refresh_done(struct tevent_req *subreq)
state = tevent_req_data(req, struct sdap_sudo_rules_refresh_state);
ret = sdap_sudo_refresh_recv(state, subreq, &state->dp_error, &state->error,
- &highest_usn, &downloaded_rules_num);
+ &highest_usn, &downloaded_rules_num, NULL);
talloc_zfree(subreq);
if (ret != EOK || state->dp_error != DP_ERR_OK || state->error != EOK) {
goto done;
@@ -938,7 +938,7 @@ static void sdap_sudo_smart_refresh_done(struct tevent_req *subreq)
state = tevent_req_data(req, struct sdap_sudo_smart_refresh_state);
ret = sdap_sudo_refresh_recv(state, subreq, &dp_error, &error,
- &highest_usn, NULL);
+ &highest_usn, NULL, NULL);
if (ret != EOK || dp_error != DP_ERR_OK || error != EOK) {
goto done;
}
@@ -969,7 +969,7 @@ static int sdap_sudo_smart_refresh_recv(struct tevent_req *req,
TEVENT_REQ_RETURN_ON_ERROR(req);
return sdap_sudo_refresh_recv(state, state->subreq, dp_error, error,
- NULL, NULL);
+ NULL, NULL, NULL);
}
static void sdap_sudo_full_refresh_online_cb(void *pvt)
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index e2764b90c..2061de475 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -21,11 +21,17 @@
#ifndef _SDAP_SUDO_H_
#define _SDAP_SUDO_H_
+/* these two structures are used by both LDAP and IPA SUDO Providers */
struct sdap_sudo_ctx {
+ struct be_ctx *be_ctx;
struct sdap_id_ctx *id_ctx;
char **hostnames;
char **ip_addr;
+
+ char *ipa_hostname;
+ char **ipa_hostgroups;
+
bool include_netgroups;
bool include_regexp;
bool use_host_filter;
@@ -37,6 +43,26 @@ struct sdap_sudo_ctx {
struct tevent_req *first_refresh_timer;
};
+struct sdap_sudo_refresh_state {
+ struct be_ctx *be_ctx;
+ struct sdap_options *opts;
+ struct sdap_id_op *sdap_op;
+ struct sdap_id_conn_cache *sdap_conn_cache;
+ struct sysdb_ctx *sysdb;
+ struct sss_domain_info *domain;
+
+ const char *ldap_filter; /* search */
+ const char *sysdb_filter; /* delete */
+
+ struct sysdb_attrs **ldap_rules; /* search result will be stored here */
+ size_t ldap_rules_count;
+
+ int dp_error;
+ int error;
+ char *highest_usn;
+ size_t num_rules;
+};
+
enum sdap_sudo_refresh_type {
SDAP_SUDO_REFRESH_FULL,
SDAP_SUDO_REFRESH_SMART,
@@ -49,6 +75,7 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
struct sdap_id_ctx *id_ctx,
struct bet_ops **ops,
void **pvt_data);
+void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn);
/* sdap async interface */
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
@@ -58,14 +85,34 @@ struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
const char *ldap_filter,
const char *sysdb_filter);
+int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *rules_count,
+ struct sysdb_attrs ***rules);
+
int sdap_sudo_refresh_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
int *dp_error,
int *error,
char **usn,
- size_t *num_rules);
-
-/* timer */
+ size_t *num_rules,
+ struct sysdb_attrs ***rules);
+
+/* sysdb */
+int sdap_sudo_purge_sudoers(struct sss_domain_info *dom,
+ const char *filter,
+ struct sdap_attr_map *map,
+ size_t rules_count,
+ struct sysdb_attrs **rules);
+
+int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct sdap_options *opts,
+ size_t rules_count,
+ struct sysdb_attrs **rules,
+ int cache_timeout,
+ time_t now,
+ char **_usn);
typedef struct tevent_req * (*sdap_sudo_timer_fn_t)(TALLOC_CTX *mem_ctx,
struct sdap_sudo_ctx *sudo_ctx);