]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/condition.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / shared / condition.c
index 0b77d2c22dc3ce8f16d0f4fa63f52880e5fdc88d..11555b474cec72a7ad4635f0f127df18407ee8a3 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -24,6 +25,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <time.h>
 #include <unistd.h>
 
 #include "parse-util.h"
 #include "path-util.h"
 #include "proc-cmdline.h"
+#include "process-util.h"
 #include "selinux-util.h"
 #include "smack-util.h"
 #include "stat-util.h"
 #include "string-table.h"
 #include "string-util.h"
+#include "tomoyo-util.h"
+#include "user-util.h"
 #include "util.h"
 #include "virt.h"
 
@@ -128,7 +133,7 @@ static int condition_test_kernel_command_line(Condition *c) {
                         const char *f;
 
                         f = startswith(word, c->parameter);
-                        found = f && (*f == '=' || *f == 0);
+                        found = f && IN_SET(*f, 0, '=');
                 }
 
                 if (found)
@@ -138,6 +143,60 @@ static int condition_test_kernel_command_line(Condition *c) {
         return false;
 }
 
+static int condition_test_user(Condition *c) {
+        uid_t id;
+        int r;
+        _cleanup_free_ char *username = NULL;
+        const char *u;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_USER);
+
+        r = parse_uid(c->parameter, &id);
+        if (r >= 0)
+                return id == getuid() || id == geteuid();
+
+        if (streq("@system", c->parameter))
+                return getuid() <= SYSTEM_UID_MAX || geteuid() <= SYSTEM_UID_MAX;
+
+        username = getusername_malloc();
+        if (!username)
+                return -ENOMEM;
+
+        if (streq(username, c->parameter))
+                return 1;
+
+        if (getpid_cached() == 1)
+                return streq(c->parameter, "root");
+
+        u = c->parameter;
+        r = get_user_creds(&u, &id, NULL, NULL, NULL);
+        if (r < 0)
+                return 0;
+
+        return id == getuid() || id == geteuid();
+}
+
+static int condition_test_group(Condition *c) {
+        gid_t id;
+        int r;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_GROUP);
+
+        r = parse_gid(c->parameter, &id);
+        if (r >= 0)
+                return in_gid(id);
+
+        /* Avoid any NSS lookups if we are PID1 */
+        if (getpid_cached() == 1)
+                return streq(c->parameter, "root");
+
+        return in_group(c->parameter) > 0;
+}
+
 static int condition_test_virtualization(Condition *c) {
         int b, v;
 
@@ -235,7 +294,7 @@ static int condition_test_security(Condition *c) {
         assert(c->type == CONDITION_SECURITY);
 
         if (streq(c->parameter, "selinux"))
-                return mac_selinux_have();
+                return mac_selinux_use();
         if (streq(c->parameter, "smack"))
                 return mac_smack_use();
         if (streq(c->parameter, "apparmor"))
@@ -244,6 +303,8 @@ static int condition_test_security(Condition *c) {
                 return use_audit();
         if (streq(c->parameter, "ima"))
                 return use_ima();
+        if (streq(c->parameter, "tomoyo"))
+                return mac_tomoyo_use();
 
         return false;
 }
@@ -475,6 +536,8 @@ int condition_test(Condition *c) {
                 [CONDITION_ARCHITECTURE] = condition_test_architecture,
                 [CONDITION_NEEDS_UPDATE] = condition_test_needs_update,
                 [CONDITION_FIRST_BOOT] = condition_test_first_boot,
+                [CONDITION_USER] = condition_test_user,
+                [CONDITION_GROUP] = condition_test_group,
                 [CONDITION_NULL] = condition_test_null,
         };
 
@@ -538,6 +601,8 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_DIRECTORY_NOT_EMPTY] = "ConditionDirectoryNotEmpty",
         [CONDITION_FILE_NOT_EMPTY] = "ConditionFileNotEmpty",
         [CONDITION_FILE_IS_EXECUTABLE] = "ConditionFileIsExecutable",
+        [CONDITION_USER] = "ConditionUser",
+        [CONDITION_GROUP] = "ConditionGroup",
         [CONDITION_NULL] = "ConditionNull"
 };
 
@@ -562,6 +627,8 @@ static const char* const assert_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_DIRECTORY_NOT_EMPTY] = "AssertDirectoryNotEmpty",
         [CONDITION_FILE_NOT_EMPTY] = "AssertFileNotEmpty",
         [CONDITION_FILE_IS_EXECUTABLE] = "AssertFileIsExecutable",
+        [CONDITION_USER] = "AssertUser",
+        [CONDITION_GROUP] = "AssertGroup",
         [CONDITION_NULL] = "AssertNull"
 };