diff options
author | Michal Sekletar <msekleta@redhat.com> | 2014-07-24 10:40:28 +0200 |
---|---|---|
committer | Michal Sekletar <msekleta@redhat.com> | 2014-08-19 18:57:12 +0200 |
commit | cf8bd44339b00330fdbc91041d6731ba8aba9fec (patch) | |
tree | 50131a58cdb8e65adc849c0971ff832ec208d6ec /src/shared | |
parent | 6c3e68e7c1adc6176526e69769bf2eba86cdd257 (diff) |
socket: introduce SELinuxLabelViaNet option
This makes possible to spawn service instances triggered by socket with
MLS/MCS SELinux labels which are created based on information provided by
connected peer.
Implementation of label_get_child_label derived from xinetd.
Reviewed-by: Paul Moore <pmoore@redhat.com>
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/label.c | 69 | ||||
-rw-r--r-- | src/shared/label.h | 1 |
2 files changed, 70 insertions, 0 deletions
diff --git a/src/shared/label.c b/src/shared/label.c index 25a8b361b7..dd89bec6e8 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -31,6 +31,7 @@ #ifdef HAVE_SELINUX #include <selinux/selinux.h> #include <selinux/label.h> +#include <selinux/context.h> #endif #include "label.h" @@ -243,6 +244,74 @@ fail: return r; } +int label_get_child_label(int socket_fd, const char *exe, char **label) { + int r = 0; + +#ifdef HAVE_SELINUX + + security_context_t mycon = NULL, peercon = NULL, fcon = NULL, ret = NULL; + security_class_t sclass; + context_t pcon = NULL, bcon = NULL; + const char *range = NULL; + + assert(socket_fd >= 0); + assert(exe); + assert(label); + + r = getcon(&mycon); + if (r < 0) + goto out; + + r = getpeercon(socket_fd, &peercon); + if (r < 0) + goto out; + + r = getfilecon(exe, &fcon); + if (r < 0) + goto out; + + bcon = context_new(mycon); + if (!bcon) + goto out; + + pcon = context_new(peercon); + if (!pcon) + goto out; + + range = context_range_get(pcon); + if (!range) + goto out; + + r = context_range_set(bcon, range); + if (r) + goto out; + + freecon(mycon); + mycon = context_str(bcon); + if (!mycon) + goto out; + + sclass = string_to_security_class("process"); + r = security_compute_create(mycon, fcon, sclass, &ret); + if (r < 0) + goto out; + + *label = ret; + +out: + if (r && security_getenforce() == 1) + r = -errno; + + freecon(mycon); + freecon(peercon); + freecon(fcon); + context_free(pcon); + context_free(bcon); + +#endif + return r; +} + int label_context_set(const char *path, mode_t mode) { int r = 0; diff --git a/src/shared/label.h b/src/shared/label.h index 72948205f6..4163f7f98c 100644 --- a/src/shared/label.h +++ b/src/shared/label.h @@ -39,6 +39,7 @@ void label_context_clear(void); void label_free(const char *label); int label_get_create_label_from_exe(const char *exe, char **label); +int label_get_child_label(int socket_fd, const char *exec, char **label); int label_mkdir(const char *path, mode_t mode); |