diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/providers/ipa/ipa_selinux.c | 31 | ||||
-rw-r--r-- | src/providers/ipa/ipa_selinux.h | 1 |
2 files changed, 29 insertions, 3 deletions
diff --git a/src/providers/ipa/ipa_selinux.c b/src/providers/ipa/ipa_selinux.c index 0e65a377..489c203d 100644 --- a/src/providers/ipa/ipa_selinux.c +++ b/src/providers/ipa/ipa_selinux.c @@ -58,7 +58,8 @@ static struct ipa_selinux_op_ctx * ipa_selinux_create_op_ctx(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct be_req *be_req, const char *username, - const char *hostname); + const char *hostname, + struct ipa_selinux_ctx *selinux_ctx); static void ipa_selinux_handler_done(struct tevent_req *subreq); static void ipa_get_selinux_connect_done(struct tevent_req *subreq); @@ -79,6 +80,7 @@ static errno_t ipa_selinux_process_maps(TALLOC_CTX *mem_ctx, struct ipa_selinux_op_ctx { struct be_req *be_req; struct sss_domain_info *domain; + struct ipa_selinux_ctx *selinux_ctx; struct sysdb_attrs *user; struct sysdb_attrs *host; @@ -107,7 +109,8 @@ void ipa_selinux_handler(struct be_req *be_req) op_ctx = ipa_selinux_create_op_ctx(be_req, be_ctx->domain->sysdb, be_ctx->domain, - be_req, pd->user, hostname); + be_req, pd->user, hostname, + selinux_ctx); if (op_ctx == NULL) { DEBUG(SSSDBG_OP_FAILURE, ("Cannot create op context\n")); goto fail; @@ -131,7 +134,8 @@ static struct ipa_selinux_op_ctx * ipa_selinux_create_op_ctx(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, struct sss_domain_info *domain, struct be_req *be_req, const char *username, - const char *hostname) + const char *hostname, + struct ipa_selinux_ctx *selinux_ctx) { struct ipa_selinux_op_ctx *op_ctx; struct ldb_dn *host_dn; @@ -149,6 +153,7 @@ ipa_selinux_create_op_ctx(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, } op_ctx->be_req = be_req; op_ctx->domain = domain; + op_ctx->selinux_ctx = selinux_ctx; ret = sss_selinux_extract_user(op_ctx, sysdb, domain, username, &op_ctx->user); if (ret != EOK) { @@ -200,6 +205,7 @@ static void ipa_selinux_handler_done(struct tevent_req *req) { struct ipa_selinux_op_ctx *op_ctx = tevent_req_callback_data(req, struct ipa_selinux_op_ctx); struct be_req *breq = op_ctx->be_req; + struct be_ctx *be_ctx = be_req_get_be_ctx(breq); struct sysdb_ctx *sysdb = op_ctx->domain->sysdb; errno_t ret, sret; size_t map_count = 0; @@ -284,6 +290,11 @@ static void ipa_selinux_handler_done(struct tevent_req *req) } in_transaction = false; + /* If we got here in online mode, set last_update to current time */ + if (!be_is_offline(be_ctx)) { + op_ctx->selinux_ctx->last_update = time(NULL); + } + pd->pam_status = PAM_SUCCESS; be_req_terminate(breq, DP_ERR_OK, EOK, "Success"); return; @@ -798,6 +809,8 @@ ipa_get_selinux_send(TALLOC_CTX *mem_ctx, struct ipa_get_selinux_state *state; bool offline; int ret = EOK; + time_t now; + time_t refresh_interval; DEBUG(SSSDBG_TRACE_FUNC, ("Retrieving SELinux user mapping\n")); req = tevent_req_create(mem_ctx, &state, struct ipa_get_selinux_state); @@ -815,6 +828,18 @@ ipa_get_selinux_send(TALLOC_CTX *mem_ctx, offline ? "offline" : "online")); if (!offline) { + /* FIXME: Make the interval configurable */ + refresh_interval = 5; + now = time(NULL); + if (now < selinux_ctx->last_update + refresh_interval) { + /* SELinux maps were recently updated -> force offline */ + DEBUG(SSSDBG_TRACE_INTERNAL, + ("Performing cached SELinux processing\n")); + offline = true; + } + } + + if (!offline) { state->op = sdap_id_op_create(state, selinux_ctx->id_ctx->sdap_id_ctx->conn_cache); if (!state->op) { DEBUG(SSSDBG_OP_FAILURE, ("sdap_id_op_create failed\n")); diff --git a/src/providers/ipa/ipa_selinux.h b/src/providers/ipa/ipa_selinux.h index 0f3fadd3..e8fd4a06 100644 --- a/src/providers/ipa/ipa_selinux.h +++ b/src/providers/ipa/ipa_selinux.h @@ -36,6 +36,7 @@ struct ipa_selinux_ctx { struct ipa_id_ctx *id_ctx; + time_t last_update; struct sdap_search_base **selinux_search_bases; struct sdap_search_base **host_search_bases; |