summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2015-11-10 12:32:16 +0100
committerLukas Slebodnik <lslebodn@redhat.com>2015-12-15 16:27:16 +0100
commitcb235ec146f1ba81c211f8506736edea436be28a (patch)
treeccded943dac3df926f7c3a15c3327abedd49f7c5
parent556801ec367543a8d534e55ecd11a977642bcee6 (diff)
downloadsssd-cb235ec146f1ba81c211f8506736edea436be28a.tar.gz
sssd-cb235ec146f1ba81c211f8506736edea436be28a.tar.xz
sssd-cb235ec146f1ba81c211f8506736edea436be28a.zip
SUDO: obtain host information when going online
Resolves: https://fedorahosted.org/sssd/ticket/2672 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
-rw-r--r--src/providers/ldap/sdap_async_sudo.c75
-rw-r--r--src/providers/ldap/sdap_sudo.c79
-rw-r--r--src/providers/ldap/sdap_sudo.h2
3 files changed, 101 insertions, 55 deletions
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index b8310275b..c2ac6988d 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -497,6 +497,8 @@ struct sdap_sudo_refresh_state {
static errno_t sdap_sudo_refresh_retry(struct tevent_req *req);
static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq);
+static void sdap_sudo_refresh_hostinfo_done(struct tevent_req *subreq);
+static errno_t sdap_sudo_refresh_sudoers(struct tevent_req *req);
static void sdap_sudo_refresh_done(struct tevent_req *subreq);
struct tevent_req *sdap_sudo_refresh_send(TALLOC_CTX *mem_ctx,
@@ -588,7 +590,6 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq)
{
struct tevent_req *req;
struct sdap_sudo_refresh_state *state;
- char *filter;
int dp_error;
int ret;
@@ -608,15 +609,74 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n");
+ /* Renew host information if needed. */
+ if (state->sudo_ctx->run_hostinfo) {
+ subreq = sdap_sudo_get_hostinfo_send(state, state->opts,
+ state->sudo_ctx->id_ctx->be);
+ if (subreq == NULL) {
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ tevent_req_set_callback(subreq, sdap_sudo_refresh_hostinfo_done, req);
+ state->sudo_ctx->run_hostinfo = false;
+ return;
+ }
+
+ ret = sdap_sudo_refresh_sudoers(req);
+ if (ret != EAGAIN) {
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ret);
+ }
+}
+
+static void sdap_sudo_refresh_hostinfo_done(struct tevent_req *subreq)
+{
+ struct sdap_sudo_ctx *sudo_ctx;
+ struct sdap_sudo_refresh_state *state;
+ struct tevent_req *req;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_sudo_refresh_state);
+
+ sudo_ctx = state->sudo_ctx;
+
+ ret = sdap_sudo_get_hostinfo_recv(sudo_ctx, subreq, &sudo_ctx->hostnames,
+ &sudo_ctx->ip_addr);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve host information, "
+ "host filter will be disabled [%d]: %s\n",
+ ret, sss_strerror(ret));
+ sudo_ctx->use_host_filter = false;
+ } else {
+ sudo_ctx->use_host_filter = true;
+ }
+
+ ret = sdap_sudo_refresh_sudoers(req);
+ if (ret != EAGAIN) {
+ state->dp_error = DP_ERR_FATAL;
+ tevent_req_error(req, ret);
+ }
+}
+
+static errno_t sdap_sudo_refresh_sudoers(struct tevent_req *req)
+{
+ struct sdap_sudo_refresh_state *state;
+ struct tevent_req *subreq;
+ char *filter;
+
+ state = tevent_req_data(req, struct sdap_sudo_refresh_state);
+
/* We are connected. Host information may have changed during transition
* from offline to online state. At this point we can combine search
* and host filter. */
filter = sdap_sudo_get_filter(state, state->opts->sudorule_map,
state->sudo_ctx, state->search_filter);
if (filter == NULL) {
- state->dp_error = DP_ERR_FATAL;
- tevent_req_error(req, ENOMEM);
- return;
+ return ENOMEM;
}
subreq = sdap_sudo_load_sudoers_send(state, state->ev,
@@ -624,14 +684,13 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq)
sdap_id_op_handle(state->sdap_op),
filter);
if (subreq == NULL) {
- state->dp_error = DP_ERR_FATAL;
- tevent_req_error(req, ENOMEM);
- return;
+ talloc_free(filter);
+ return ENOMEM;
}
tevent_req_set_callback(subreq, sdap_sudo_refresh_done, req);
- return;
+ return EAGAIN;
}
static void sdap_sudo_refresh_done(struct tevent_req *subreq)
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index ed4ecc674..76cc41050 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -41,7 +41,20 @@ struct bet_ops sdap_sudo_ops = {
.finalize = sdap_sudo_shutdown
};
-static void sdap_sudo_get_hostinfo_done(struct tevent_req *req);
+static void sdap_sudo_online_cb(void *pvt)
+{
+ struct sdap_sudo_ctx *sudo_ctx;
+
+ sudo_ctx = talloc_get_type(pvt, struct sdap_sudo_ctx);
+ if (sudo_ctx == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, "BUG: sudo_ctx is NULL\n");
+ return;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "We are back online. SUDO host information will "
+ "be renewed on next refresh.\n");
+ sudo_ctx->run_hostinfo = true;
+}
int sdap_sudo_init(struct be_ctx *be_ctx,
struct sdap_id_ctx *id_ctx,
@@ -49,7 +62,6 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
void **pvt_data)
{
struct sdap_sudo_ctx *sudo_ctx = NULL;
- struct tevent_req *req = NULL;
int ret;
DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing sudo LDAP back end\n");
@@ -79,23 +91,26 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
goto done;
}
- req = sdap_sudo_get_hostinfo_send(sudo_ctx, id_ctx->opts, be_ctx);
- if (req == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve host information - "
- "(host filter will be disabled)\n");
-
- sudo_ctx->use_host_filter = false;
-
- ret = sdap_sudo_ptask_setup(sudo_ctx->id_ctx->be, sudo_ctx);
+ if (sudo_ctx->use_host_filter) {
+ ret = be_add_online_cb(sudo_ctx, sudo_ctx->id_ctx->be,
+ sdap_sudo_online_cb, sudo_ctx, NULL);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE,
- "Unable to setup periodical refresh"
- "of sudo rules [%d]: %s\n", ret, strerror(ret));
- /* periodical updates will not work, but specific-rule update
- * is no affected by this, therefore we don't have to fail here */
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to install online callback "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
}
- } else {
- tevent_req_set_callback(req, sdap_sudo_get_hostinfo_done, sudo_ctx);
+
+ /* Obtain hostinfo with the first refresh. */
+ sudo_ctx->run_hostinfo = true;
+ }
+
+ ret = sdap_sudo_ptask_setup(sudo_ctx->id_ctx->be, sudo_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Unable to setup periodical refresh of sudo rules [%d]: %s\n",
+ ret, strerror(ret));
+ /* periodical updates will not work, but specific-rule update
+ * is no affected by this, therefore we don't have to fail here */
}
ret = EOK;
@@ -108,36 +123,6 @@ done:
return ret;
}
-static void sdap_sudo_get_hostinfo_done(struct tevent_req *req)
-{
- struct sdap_sudo_ctx *sudo_ctx = NULL;
- char **hostnames = NULL;
- char **ip_addr = NULL;
- int ret;
-
- sudo_ctx = tevent_req_callback_data(req, struct sdap_sudo_ctx);
-
- ret = sdap_sudo_get_hostinfo_recv(sudo_ctx, req, &hostnames, &ip_addr);
- talloc_zfree(req);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve host information - "
- "(host filter will be disabled) [%d]: %s\n", ret, strerror(ret));
- sudo_ctx->use_host_filter = false;
- }
-
- talloc_zfree(sudo_ctx->hostnames);
- talloc_zfree(sudo_ctx->ip_addr);
-
- sudo_ctx->hostnames = talloc_move(sudo_ctx, &hostnames);
- sudo_ctx->ip_addr = talloc_move(sudo_ctx, &ip_addr);
-
- ret = sdap_sudo_ptask_setup(sudo_ctx->id_ctx->be, sudo_ctx);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Unable to setup periodical refresh"
- "of sudo rules [%d]: %s\n", ret, strerror(ret));
- }
-}
-
static void sdap_sudo_reply(struct tevent_req *req)
{
struct be_req *be_req = NULL;
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index c3222b211..6b4d249a8 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -35,6 +35,8 @@ struct sdap_sudo_ctx {
bool full_refresh_done;
bool full_refresh_in_progress;
+
+ bool run_hostinfo;
};
/* Common functions from ldap_sudo.c */