chiark / gitweb /
core/smack: downgrade info to debug
[elogind.git] / src / core / selinux-access.c
index 9ddc042eca1475fcaafbde49f61f852944c3ab07..bc195f3c56e746746bd03d3a5cb2edc0baeb9f34 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include "util.h"
-#include "job.h"
-#include "manager.h"
 #include "selinux-access.h"
 
 #ifdef HAVE_SELINUX
-#include "dbus.h"
-#include "log.h"
-#include "dbus-unit.h"
-#include "bus-errors.h"
-#include "dbus-common.h"
-#include "audit.h"
-#include "selinux-util.h"
-#include "audit-fd.h"
 
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <limits.h>
 #include <selinux/selinux.h>
 #include <selinux/avc.h>
 #ifdef HAVE_AUDIT
 #include <libaudit.h>
 #endif
-#include <limits.h>
+#include <dbus.h>
+
+#include "util.h"
+#include "log.h"
+#include "bus-errors.h"
+#include "dbus-common.h"
+#include "audit.h"
+#include "selinux-util.h"
+#include "audit-fd.h"
 
 static bool initialized = false;
 
@@ -61,6 +59,10 @@ static int bus_get_selinux_security_context(
                 DBusError *error) {
 
         _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL;
+        DBusMessageIter iter, sub;
+        const char *bytes;
+        char *b;
+        int nbytes;
 
         m = dbus_message_new_method_call(
                         DBUS_SERVICE_DBUS,
@@ -87,12 +89,21 @@ static int bus_get_selinux_security_context(
         if (dbus_set_error_from_message(error, reply))
                 return -EIO;
 
-        if (!dbus_message_get_args(
-                            reply, error,
-                            DBUS_TYPE_STRING, scon,
-                            DBUS_TYPE_INVALID))
+        if (!dbus_message_iter_init(reply, &iter))
                 return -EIO;
 
+        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY)
+                return -EIO;
+
+        dbus_message_iter_recurse(&iter, &sub);
+        dbus_message_iter_get_fixed_array(&sub, &bytes, &nbytes);
+
+        b = strndup(bytes, nbytes);
+        if (!b)
+                return -ENOMEM;
+
+        *scon = b;
+
         return 0;
 }
 
@@ -121,7 +132,7 @@ static int bus_get_audit_data(
         if (r < 0)
                 return r;
 
-        r = get_process_cmdline(pid, LINE_MAX, true, &audit->cmdline);
+        r = get_process_cmdline(pid, 0, true, &audit->cmdline);
         if (r < 0)
                 return r;
 
@@ -170,13 +181,18 @@ static int log_callback(int type, const char *fmt, ...) {
 
 #ifdef HAVE_AUDIT
         if (get_audit_fd() >= 0) {
-                char buf[LINE_MAX];
+                _cleanup_free_ char *buf = NULL;
+                int r;
 
-                vsnprintf(buf, sizeof(buf), fmt, ap);
-                audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
+                r = vasprintf(&buf, fmt, ap);
                 va_end(ap);
 
-                return 0;
+                if (r >= 0) {
+                        audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
+                        return 0;
+                }
+
+                va_start(ap, fmt);
         }
 #endif
         log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
@@ -210,7 +226,7 @@ static int access_init(void) {
         return r;
 }
 
-static int selinux_init(DBusError *error) {
+static int selinux_access_init(DBusError *error) {
         int r;
 
         if (initialized)
@@ -228,6 +244,14 @@ static int selinux_init(DBusError *error) {
         return 0;
 }
 
+void selinux_access_free(void) {
+        if (!initialized)
+                return;
+
+        avc_destroy();
+        initialized = false;
+}
+
 static int get_audit_data(
                 DBusConnection *connection,
                 DBusMessage *message,
@@ -237,7 +261,7 @@ static int get_audit_data(
         const char *sender;
         int r, fd;
         struct ucred ucred;
-        socklen_t len;
+        socklen_t len = sizeof(ucred);
 
         sender = dbus_message_get_sender(message);
         if (sender)
@@ -259,7 +283,7 @@ static int get_audit_data(
         if (r < 0)
                 return r;
 
-        r = get_process_cmdline(ucred.pid, LINE_MAX, true, &audit->cmdline);
+        r = get_process_cmdline(ucred.pid, 0, true, &audit->cmdline);
         if (r < 0)
                 return r;
 
@@ -291,7 +315,8 @@ static int get_calling_context(
                 if (r >= 0)
                         return r;
 
-                log_debug("bus_get_selinux_security_context failed %m");
+                log_error("bus_get_selinux_security_context failed: %m");
+                return r;
         }
 
         if (!dbus_connection_get_unix_fd(connection, &fd)) {
@@ -314,7 +339,7 @@ static int get_calling_context(
    If the machine is in permissive mode it will return ok.  Audit messages will
    still be generated if the access would be denied in enforcing mode.
 */
-static int selinux_access_check(
+int selinux_access_check(
                 DBusConnection *connection,
                 DBusMessage *message,
                 const char *path,
@@ -331,14 +356,12 @@ static int selinux_access_check(
         assert(permission);
         assert(error);
 
-        r = selinux_init(error);
-        if (r < 0)
-                return r;
-
         if (!use_selinux())
                 return 0;
 
-        log_debug("SELinux access check for path=%s permission=%s", strna(path), permission);
+        r = selinux_access_init(error);
+        if (r < 0)
+                return r;
 
         audit.uid = audit.loginuid = (uid_t) -1;
         audit.gid = (gid_t) -1;
@@ -398,69 +421,19 @@ finish:
         return r;
 }
 
-int selinux_unit_access_check(
-                Unit *u,
-                DBusConnection *connection,
-                DBusMessage *message,
-                const char *permission,
-                DBusError *error) {
-
-        assert(u);
-        assert(connection);
-        assert(message);
-        assert(permission);
-        assert(error);
-
-        return selinux_access_check(connection, message, u->source_path ? u->source_path : u->fragment_path, permission, error);
-}
-
-int selinux_manager_access_check(
-                Manager *m,
-                DBusConnection *connection,
-                DBusMessage *message,
-                const char *permission,
-                DBusError *error) {
-
-        assert(m);
-        assert(connection);
-        assert(message);
-        assert(permission);
-        assert(error);
-
-        return selinux_access_check(connection, message, NULL, permission, error);
-}
-
-void selinux_access_finish(void) {
-        if (!initialized)
-                return;
-
-        avc_destroy();
-        initialized = false;
-}
-
 #else
 
-int selinux_unit_access_check(
-                Unit *u,
-                DBusConnection *connection,
-                DBusMessage *message,
-                const char *permission,
-                DBusError *error) {
-
-        return 0;
-}
-
-int selinux_manager_access_check(
-                Manager *m,
+int selinux_access_check(
                 DBusConnection *connection,
                 DBusMessage *message,
+                const char *path,
                 const char *permission,
                 DBusError *error) {
 
         return 0;
 }
 
-void selinux_access_finish(void) {
+void selinux_access_free(void) {
 }
 
 #endif