diff options
author | Simo Sorce <simo@redhat.com> | 2016-01-20 09:12:47 +0100 |
---|---|---|
committer | Lukas Slebodnik <lslebodn@redhat.com> | 2016-01-28 09:46:26 +0100 |
commit | 6499d0b915209b670f8e337c4fe76a8be9fa6576 (patch) | |
tree | 58d43008239501773d31c9bcaa1c8474c3e5219b /src/responder/common | |
parent | 1b8858b1611db5048592f477059ca5ad66d7ceb1 (diff) | |
download | sssd-6499d0b915209b670f8e337c4fe76a8be9fa6576.tar.gz sssd-6499d0b915209b670f8e337c4fe76a8be9fa6576.tar.xz sssd-6499d0b915209b670f8e337c4fe76a8be9fa6576.zip |
Util: Improve code to get connection credentials
Adds support to get SELINUX context and make code more abstract so
that struct ucred (if availale) can be used w/o redefining uid,gid,pid to
int32. Also gives a layer of indirection that may come handy if we want
to improve the code further in the future.
Signed-off-by: Lukas Slebodnik <lslebodn@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
Diffstat (limited to 'src/responder/common')
-rw-r--r-- | src/responder/common/responder.h | 8 | ||||
-rw-r--r-- | src/responder/common/responder_common.c | 57 |
2 files changed, 44 insertions, 21 deletions
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index f363c2074..3b70b69e4 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -118,6 +118,8 @@ struct resp_ctx { bool shutting_down; }; +struct cli_creds; + struct cli_ctx { struct tevent_context *ev; struct resp_ctx *rctx; @@ -127,9 +129,8 @@ struct cli_ctx { struct cli_request *creq; struct cli_protocol_version *cli_protocol_version; int priv; - int32_t client_euid; - int32_t client_egid; - int32_t client_pid; + + struct cli_creds *creds; int pwent_dom_idx; int pwent_cur; @@ -329,6 +330,7 @@ errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *csv_string, bool allow_sss_loop, size_t *_uid_count, uid_t **_uids); +uid_t client_euid(struct cli_creds *creds); errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count, uid_t *allowed_uids); diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c index a7e198cc5..6ac1ea222 100644 --- a/src/responder/common/responder_common.c +++ b/src/responder/common/responder_common.c @@ -42,6 +42,7 @@ #include "providers/data_provider.h" #include "monitor/monitor_interfaces.h" #include "sbus/sbus_client.h" +#include "util/util_creds.h" static errno_t set_close_on_exec(int fd) { @@ -84,16 +85,20 @@ static int client_destructor(struct cli_ctx *ctx) static errno_t get_client_cred(struct cli_ctx *cctx) { - cctx->client_euid = -1; - cctx->client_egid = -1; - cctx->client_pid = -1; + SEC_CTX secctx; + int ret; + + cctx->creds = talloc(cctx, struct cli_creds); + if (!cctx->creds) return ENOMEM; #ifdef HAVE_UCRED - int ret; - struct ucred client_cred; - socklen_t client_cred_len = sizeof(client_cred); + socklen_t client_cred_len = sizeof(struct ucred); + + cctx->creds->ucred.uid = -1; + cctx->creds->ucred.gid = -1; + cctx->creds->ucred.pid = -1; - ret = getsockopt(cctx->cfd, SOL_SOCKET, SO_PEERCRED, &client_cred, + ret = getsockopt(cctx->cfd, SOL_SOCKET, SO_PEERCRED, &cctx->creds->ucred, &client_cred_len); if (ret != EOK) { ret = errno; @@ -107,15 +112,30 @@ static errno_t get_client_cred(struct cli_ctx *cctx) return ENOMSG; } - cctx->client_euid = client_cred.uid; - cctx->client_egid = client_cred.gid; - cctx->client_pid = client_cred.pid; - - DEBUG(SSSDBG_TRACE_ALL, "Client creds: euid[%d] egid[%d] pid[%d].\n", - cctx->client_euid, cctx->client_egid, cctx->client_pid); + DEBUG(SSSDBG_TRACE_ALL, + "Client creds: euid[%d] egid[%d] pid[%d].\n", + cctx->creds->ucred.uid, cctx->creds->ucred.gid, + cctx->creds->ucred.pid); #endif - return EOK; + ret = SELINUX_getpeercon(cctx->cfd, &secctx); + if (ret != 0) { + DEBUG(SSSDBG_CRIT_FAILURE, + "SELINUX_getpeercon failed [%d][%s].\n", ret, strerror(ret)); + /* This is not fatal, as SELinux may simply be disabled */ + ret = EOK; + } else { + cctx->creds->selinux_ctx = SELINUX_context_new(secctx); + SELINUX_freecon(secctx); + } + + return ret; +} + +uid_t client_euid(struct cli_creds *creds) +{ + if (!creds) return -1; + return cli_creds_get_uid(creds); } errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count, @@ -418,7 +438,7 @@ static void accept_fd_handler(struct tevent_context *ev, } if (rctx->allowed_uids_count != 0) { - if (cctx->client_euid == -1) { + if (client_euid(cctx->creds) == -1) { DEBUG(SSSDBG_CRIT_FAILURE, "allowed_uids configured, " \ "but platform does not support " \ "reading peer credential from the " \ @@ -428,12 +448,13 @@ static void accept_fd_handler(struct tevent_context *ev, return; } - ret = check_allowed_uids(cctx->client_euid, rctx->allowed_uids_count, + ret = check_allowed_uids(client_euid(cctx->creds), rctx->allowed_uids_count, rctx->allowed_uids); if (ret != EOK) { if (ret == EACCES) { - DEBUG(SSSDBG_CRIT_FAILURE, "Access denied for uid [%d].\n", - cctx->client_euid); + DEBUG(SSSDBG_CRIT_FAILURE, + "Access denied for uid [%"SPRIuid"].\n", + client_euid(cctx->creds)); } else { DEBUG(SSSDBG_OP_FAILURE, "check_allowed_uids failed.\n"); } |