selinux-access.c revision 8fd00193803fd20bed163832ec4d0d5ba2958b87
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering/***
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering This file is part of systemd.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Copyright 2012 Dan Walsh
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is free software; you can redistribute it and/or modify it
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering under the terms of the GNU Lesser General Public License as published by
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering (at your option) any later version.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering systemd is distributed in the hope that it will be useful, but
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering Lesser General Public License for more details.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering You should have received a copy of the GNU Lesser General Public License
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering***/
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include "selinux-access.h"
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#ifdef HAVE_SELINUX
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek#include <stdio.h>
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering#include <string.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include <errno.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include <limits.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include <selinux/selinux.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include <selinux/avc.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include <sys/socket.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#ifdef HAVE_AUDIT
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include <libaudit.h>
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#endif
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "sd-bus.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "bus-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "log.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "audit.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "selinux-util.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "audit-fd.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#include "strv.h"
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic bool initialized = false;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstruct audit_info {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_bus_creds *creds;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *path;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *cmdline;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering};
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering/*
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Any time an access gets denied this callback will be called
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering with the audit data. We then need to just copy the audit data into the msgbuf.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering*/
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int audit_callback(
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering void *auditdata,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering security_class_t cls,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char *msgbuf,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering size_t msgbufsize) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const struct audit_info *audit = auditdata;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering uid_t uid = 0, login_uid = 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering gid_t gid = 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char login_uid_buf[DECIMAL_STR_MAX(uid_t)] = "n/a";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char uid_buf[DECIMAL_STR_MAX(uid_t)] = "n/a";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char gid_buf[DECIMAL_STR_MAX(gid_t)] = "n/a";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid) >= 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering snprintf(login_uid_buf, sizeof(login_uid_buf), UID_FMT, login_uid);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (sd_bus_creds_get_uid(audit->creds, &uid) >= 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering snprintf(uid_buf, sizeof(uid_buf), UID_FMT, uid);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (sd_bus_creds_get_gid(audit->creds, &gid) >= 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering snprintf(gid_buf, sizeof(gid_buf), GID_FMT, gid);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering snprintf(msgbuf, msgbufsize,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering "auid=%s uid=%s gid=%s%s%s%s%s%s%s",
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering login_uid_buf, uid_buf, gid_buf,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering audit->path ? " path=\"" : "", strempty(audit->path), audit->path ? "\"" : "",
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering audit->cmdline ? " cmdline=\"" : "", strempty(audit->cmdline), audit->cmdline ? "\"" : "");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering msgbuf[msgbufsize-1] = 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering/*
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Any time an access gets denied this callback will be called
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering code copied from dbus. If audit is turned on the messages will go as
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering user_avc's into the /var/log/audit/audit.log, otherwise they will be
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sent to syslog.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering*/
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering_printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering va_list ap;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#ifdef HAVE_AUDIT
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (get_audit_fd() >= 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering _cleanup_free_ char *buf = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering va_start(ap, fmt);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = vasprintf(&buf, fmt, ap);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering va_end(ap);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r >= 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#endif
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering va_start(ap, fmt);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering va_end(ap);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering/*
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Function must be called once to initialize the SELinux AVC environment.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering Sets up callbacks.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering If you want to cleanup memory you should need to call selinux_access_finish.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering*/
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int access_init(void) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int r = 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (avc_open(NULL, 0)) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering log_error("avc_open() failed: %m");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return -errno;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback) audit_callback);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) log_callback);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (security_getenforce() < 0){
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = -errno;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering avc_destroy();
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringstatic int mac_selinux_access_init(sd_bus_error *error) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int r;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (initialized)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!mac_selinux_use())
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = access_init();
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to initialize SELinux.");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering initialized = true;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#endif
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringvoid mac_selinux_access_free(void) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#ifdef HAVE_SELINUX
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (!initialized)
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering avc_destroy();
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering initialized = false;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#endif
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering/*
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering This function communicates with the kernel to check whether or not it should
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering allow the access.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering If the machine is in permissive mode it will return ok. Audit messages will
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering still be generated if the access would be denied in enforcing mode.
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering*/
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poetteringint mac_selinux_generic_access_check(
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_bus_message *message,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *path,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *permission,
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_bus_error *error) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#ifdef HAVE_SELINUX
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering const char *tclass = NULL, *scon = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering struct audit_info audit_info = {};
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering _cleanup_free_ char *cl = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering security_context_t fcon = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering char **cmdline = NULL;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering int r = 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering assert(message);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek assert(permission);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek assert(error);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (!mac_selinux_use())
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return 0;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering r = mac_selinux_access_init(error);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (r < 0)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return r;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering r = sd_bus_query_sender_creds(
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering message,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_AUDIT_LOGIN_UID|
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SD_BUS_CREDS_SELINUX_CONTEXT|
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering SD_BUS_CREDS_AUGMENT /* get more bits from /proc */,
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering &creds);
ef5bfcf668e6029faa78534dfeb2591df854cdefLennart Poettering if (r < 0)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering goto finish;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = sd_bus_creds_get_selinux_context(creds, &scon);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (r < 0)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering goto finish;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (path) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek /* Get the file context of the unit file */
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering r = getfilecon(path, &fcon);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get file context on %s.", path);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering goto finish;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering tclass = "service";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering } else {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = getcon(&fcon);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0) {
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Failed to get current context.");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering goto finish;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering tclass = "system";
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering sd_bus_creds_get_cmdline(creds, &cmdline);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering cl = strv_join(cmdline, " ");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering audit_info.creds = creds;
875c6e1b48f37a07dfbb80d6653c73f205e94260Lennart Poettering audit_info.path = path;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering audit_info.cmdline = cl;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = selinux_check_access((security_context_t) scon, fcon, tclass, permission, &audit_info);
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering if (r < 0)
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, cl, r);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poetteringfinish:
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering freecon(fcon);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering if (r < 0 && security_getenforce() != 1) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering sd_bus_error_free(error);
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering r = 0;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering }
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return r;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering#else
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering return 0;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering#endif
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering}
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poetteringint mac_selinux_unit_access_check_strv(char **units,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering sd_bus_message *message,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering Manager *m,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering const char *permission,
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering sd_bus_error *error) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering#ifdef HAVE_SELINUX
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering char **i;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering Unit *u;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering int r;
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering STRV_FOREACH(i, units) {
be3f52f4ed02a9256b1577719677b32a17b525acLennart Poettering u = manager_get_unit(m, *i);
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering if (u) {
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek r = mac_selinux_unit_access_check(u, message, permission, error);
1ca208fb4f93e5869704af1812cbff7130a2fc03Zbigniew Jędrzejewski-Szmek if (r < 0)
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering return r;
3731acf1acfb4a6eb68374a5b137f3b368f63381Lennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering }
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering#endif
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering return 0;
0f4ba83c397e807939a4eb0b2cbd04ad4ab548ccLennart Poettering}
73e231abde39f22097df50542c745e01de879836Jan Engelhardt