summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/responder/common/responder.h8
-rw-r--r--src/responder/common/responder_common.c57
-rw-r--r--src/responder/pam/pamsrv_cmd.c23
-rw-r--r--src/tests/cwrap/Makefile.am1
-rw-r--r--src/util/util_creds.h82
6 files changed, 139 insertions, 34 deletions
diff --git a/Makefile.am b/Makefile.am
index 148c16be8..8ff3322cd 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -495,6 +495,7 @@ SSSD_LIBS = \
$(COLLECTION_LIBS) \
$(DHASH_LIBS) \
$(OPENLDAP_LIBS) \
+ $(SELINUX_LIBS) \
$(TDB_LIBS)
PYTHON_BINDINGS_LIBS = \
@@ -555,6 +556,7 @@ dist_noinst_HEADERS = \
src/util/authtok-utils.h \
src/util/util_safealign.h \
src/util/util_sss_idmap.h \
+ src/util/util_creds.h \
src/monitor/monitor.h \
src/monitor/monitor_interfaces.h \
src/monitor/monitor_iface_generated.h \
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");
}
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index b9fd35325..bfc534f57 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -985,14 +985,14 @@ static int pam_auth_req_destructor(struct pam_auth_req *preq)
return 0;
}
-static bool is_uid_trusted(uint32_t uid,
+static bool is_uid_trusted(struct cli_creds *creds,
size_t trusted_uids_count,
uid_t *trusted_uids)
{
- size_t i;
+ errno_t ret;
/* root is always trusted */
- if (uid == 0) {
+ if (client_euid(creds) == 0) {
return true;
}
@@ -1001,11 +1001,8 @@ static bool is_uid_trusted(uint32_t uid,
return true;
}
- for(i = 0; i < trusted_uids_count; i++) {
- if (trusted_uids[i] == uid) {
- return true;
- }
- }
+ ret = check_allowed_uids(client_euid(creds), trusted_uids_count, trusted_uids);
+ if (ret == EOK) return true;
return false;
}
@@ -1094,13 +1091,13 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
}
pd = preq->pd;
- preq->is_uid_trusted = is_uid_trusted(cctx->client_euid,
+ preq->is_uid_trusted = is_uid_trusted(cctx->creds,
pctx->trusted_uids_count,
pctx->trusted_uids);
if (!preq->is_uid_trusted) {
- DEBUG(SSSDBG_MINOR_FAILURE, "uid %"PRIu32" is not trusted.\n",
- cctx->client_euid);
+ DEBUG(SSSDBG_MINOR_FAILURE, "uid %"SPRIuid" is not trusted.\n",
+ client_euid(cctx->creds));
}
@@ -1779,8 +1776,8 @@ static void pam_dom_forwarder(struct pam_auth_req *preq)
!is_domain_public(preq->pd->domain, pctx->public_domains,
pctx->public_domains_count)) {
DEBUG(SSSDBG_MINOR_FAILURE,
- "Untrusted user %"PRIu32" cannot access non-public domain %s.\n",
- preq->cctx->client_euid, preq->pd->domain);
+ "Untrusted user %"SPRIuid" cannot access non-public domain %s.\n",
+ client_euid(preq->cctx->creds), preq->pd->domain);
preq->pd->pam_status = PAM_PERM_DENIED;
pam_reply(preq);
return;
diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am
index ca4a941da..67f57e14e 100644
--- a/src/tests/cwrap/Makefile.am
+++ b/src/tests/cwrap/Makefile.am
@@ -157,6 +157,7 @@ responder_common_tests_CFLAGS = \
responder_common_tests_LDADD = \
$(CMOCKA_LIBS) \
$(SSSD_LIBS) \
+ $(SELINUX_LIBS) \
$(abs_top_builddir)/libsss_util.la \
$(abs_top_builddir)/libsss_debug.la \
$(abs_top_builddir)/libsss_test_common.la \
diff --git a/src/util/util_creds.h b/src/util/util_creds.h
new file mode 100644
index 000000000..65468fa12
--- /dev/null
+++ b/src/util/util_creds.h
@@ -0,0 +1,82 @@
+/*
+ Authors:
+ Simo Sorce <simo@redhat.com>
+
+ Copyright (C) 2016 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __SSSD_UTIL_CREDS_H__
+#define __SSSD_UTIL_CREDS_H__
+
+/* following code comes from gss-proxy's gp_selinux.h file */
+#ifdef HAVE_SELINUX
+
+#include <selinux/context.h>
+#define SELINUX_CTX context_t
+#include <selinux/selinux.h>
+#define SEC_CTX security_context_t
+
+#define SELINUX_context_new context_new
+#define SELINUX_context_free context_free
+#define SELINUX_context_str context_str
+#define SELINUX_context_type_get context_type_get
+#define SELINUX_context_user_get context_user_get
+#define SELINUX_context_role_get context_role_get
+#define SELINUX_context_range_get context_range_get
+#define SELINUX_getpeercon getpeercon
+#define SELINUX_freecon freecon
+
+#else /* not HAVE_SELINUX */
+
+#define SELINUX_CTX void *
+#define SEC_CTX void *
+
+#define SELINUX_context_new(x) NULL
+#define SELINUX_context_free(x) (x) = NULL
+#define SELINUX_context_dummy_get(x) "<SELinux not compiled in>"
+#define SELINUX_context_str SELINUX_context_dummy_get
+#define SELINUX_context_type_get SELINUX_context_dummy_get
+#define SELINUX_context_user_get SELINUX_context_dummy_get
+#define SELINUX_context_role_get SELINUX_context_dummy_get
+#define SELINUX_context_range_get SELINUX_context_dummy_get
+
+#include <errno.h>
+#define SELINUX_getpeercon(x, y) -1; do { \
+ *(y) = NULL; \
+ errno = ENOTSUP; \
+} while(0)
+
+#define SELINUX_freecon(x) (x) = NULL
+
+#endif /* done HAVE_SELINUX */
+
+#ifdef HAVE_UCRED
+#include <sys/socket.h>
+struct cli_creds {
+ struct ucred ucred;
+ SELINUX_CTX selinux_ctx;
+};
+
+#define cli_creds_get_uid(x) x->ucred.uid
+
+#else /* not HAVE_UCRED */
+struct cli_creds {
+ SELINUX_CTX selinux_ctx;
+};
+#define cli_creds_get_uid(x) -1
+#endif /* done HAVE_UCRED */
+
+#endif /* __SSSD_UTIL_CREDS_H__ */