summaryrefslogtreecommitdiffstats
path: root/src/responder/common
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2016-01-20 09:12:47 +0100
committerLukas Slebodnik <lslebodn@redhat.com>2016-01-28 09:46:26 +0100
commit6499d0b915209b670f8e337c4fe76a8be9fa6576 (patch)
tree58d43008239501773d31c9bcaa1c8474c3e5219b /src/responder/common
parent1b8858b1611db5048592f477059ca5ad66d7ceb1 (diff)
downloadsssd-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.h8
-rw-r--r--src/responder/common/responder_common.c57
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");
}