diff options
author | Michal Šrubař <xsruba03@stud.fit.vutbr.cz> | 2014-09-18 19:29:38 +0200 |
---|---|---|
committer | Lukas Slebodnik <lslebodn@redhat.com> | 2015-10-09 11:43:10 +0200 |
commit | b326061a4af321c3bea9e96bc071d52c9d9d16f4 (patch) | |
tree | 720740b9c3d6941672c623110b3d406ef08b23de | |
parent | c65de71bc38753320b9fd6f6fe1386244a2ff54a (diff) | |
download | sssd-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.c | 171 | ||||
-rw-r--r-- | src/providers/ldap/sdap_sudo.c | 10 | ||||
-rw-r--r-- | src/providers/ldap/sdap_sudo.h | 53 |
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); |