21255d
From 40dff18947fa198810db4cd3e5291349fc84a0e8 Mon Sep 17 00:00:00 2001
21255d
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
21255d
Date: Thu, 1 Aug 2019 10:02:14 +0200
21255d
Subject: [PATCH] shared/user-util: allow usernames with dots in specific
21255d
 fields
21255d
21255d
People do have usernames with dots, and it makes them very unhappy that systemd
21255d
doesn't like their that. It seems that there is no actual problem with allowing
21255d
dots in the username. In particular chown declares ":" as the official
21255d
separator, and internally in systemd we never rely on "." as the seperator
21255d
between user and group (nor do we call chown directly). Using dots in the name
21255d
is probably not a very good idea, but we don't need to care. Debian tools
21255d
(adduser) do not allow users with dots to be created.
21255d
21255d
This patch allows *existing* names with dots to be used in User, Group,
21255d
SupplementaryGroups, SocketUser, SocketGroup fields, both in unit files and on
21255d
the command line. DynamicUsers and sysusers still follow the strict policy.
21255d
user@.service and tmpfiles already allowed arbitrary user names, and this
21255d
remains unchanged.
21255d
21255d
Fixes #12754.
21255d
21255d
(cherry picked from commit ae480f0b09aec815b64579bb1828ea935d8ee236)
21255d
21255d
Related: #1848373
21255d
---
21255d
 src/core/dbus-execute.c               | 12 ++++++------
21255d
 src/core/dbus-socket.c                |  4 ++--
21255d
 src/core/dbus-util.c                  |  2 +-
21255d
 src/core/dbus-util.h                  |  2 +-
21255d
 src/core/load-fragment-gperf.gperf.m4 | 10 +++++-----
21255d
 src/core/load-fragment.c              |  8 ++++----
21255d
 src/core/load-fragment.h              |  4 ++--
21255d
 7 files changed, 21 insertions(+), 21 deletions(-)
21255d
21255d
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
21255d
index 0fe4c14e48..e004fb55c9 100644
21255d
--- a/src/core/dbus-execute.c
21255d
+++ b/src/core/dbus-execute.c
21255d
@@ -1113,10 +1113,10 @@ int bus_exec_context_set_transient_property(
21255d
         flags |= UNIT_PRIVATE;
21255d
 
21255d
         if (streq(name, "User"))
21255d
-                return bus_set_transient_user(u, name, &c->user, message, flags, error);
21255d
+                return bus_set_transient_user_compat(u, name, &c->user, message, flags, error);
21255d
 
21255d
         if (streq(name, "Group"))
21255d
-                return bus_set_transient_user(u, name, &c->group, message, flags, error);
21255d
+                return bus_set_transient_user_compat(u, name, &c->group, message, flags, error);
21255d
 
21255d
         if (streq(name, "TTYPath"))
21255d
                 return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
21255d
@@ -1297,10 +1297,10 @@ int bus_exec_context_set_transient_property(
21255d
                 if (r < 0)
21255d
                         return r;
21255d
 
21255d
-                STRV_FOREACH(p, l) {
21255d
-                        if (!isempty(*p) && !valid_user_group_name_or_id(*p))
21255d
-                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
21255d
-                }
21255d
+                STRV_FOREACH(p, l)
21255d
+                        if (!isempty(*p) && !valid_user_group_name_or_id_compat(*p))
21255d
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
21255d
+                                                         "Invalid supplementary group names");
21255d
 
21255d
                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
21255d
                         if (strv_isempty(l)) {
21255d
diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c
21255d
index bb77539030..8fdbc05409 100644
21255d
--- a/src/core/dbus-socket.c
21255d
+++ b/src/core/dbus-socket.c
21255d
@@ -281,10 +281,10 @@ static int bus_socket_set_transient_property(
21255d
                 return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error);
21255d
 
21255d
         if (streq(name, "SocketUser"))
21255d
-                return bus_set_transient_user(u, name, &s->user, message, flags, error);
21255d
+                return bus_set_transient_user_compat(u, name, &s->user, message, flags, error);
21255d
 
21255d
         if (streq(name, "SocketGroup"))
21255d
-                return bus_set_transient_user(u, name, &s->group, message, flags, error);
21255d
+                return bus_set_transient_user_compat(u, name, &s->group, message, flags, error);
21255d
 
21255d
         if (streq(name, "BindIPv6Only"))
21255d
                 return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error);
21255d
diff --git a/src/core/dbus-util.c b/src/core/dbus-util.c
21255d
index f4fbb72cb9..7862beaacb 100644
21255d
--- a/src/core/dbus-util.c
21255d
+++ b/src/core/dbus-util.c
21255d
@@ -30,7 +30,7 @@ int bus_property_get_triggered_unit(
21255d
 
21255d
 BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
21255d
 BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
21255d
-BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user, valid_user_group_name_or_id);
21255d
+BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user_compat, valid_user_group_name_or_id_compat);
21255d
 BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute);
21255d
 
21255d
 int bus_set_transient_string(
21255d
diff --git a/src/core/dbus-util.h b/src/core/dbus-util.h
21255d
index 12b055e4ac..a3316c6701 100644
21255d
--- a/src/core/dbus-util.h
21255d
+++ b/src/core/dbus-util.h
21255d
@@ -235,7 +235,7 @@ int bus_property_get_triggered_unit(sd_bus *bus, const char *path, const char *i
21255d
 
21255d
 int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
 int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
-int bus_set_transient_user(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
+int bus_set_transient_user_compat(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
 int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
 int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
 int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
21255d
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
21255d
index 24ee5ae6fe..156a4d0a6d 100644
21255d
--- a/src/core/load-fragment-gperf.gperf.m4
21255d
+++ b/src/core/load-fragment-gperf.gperf.m4
21255d
@@ -25,9 +25,9 @@ m4_define(`EXEC_CONTEXT_CONFIG_ITEMS',
21255d
 `$1.WorkingDirectory,            config_parse_working_directory,     0,                             offsetof($1, exec_context)
21255d
 $1.RootDirectory,                config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_directory)
21255d
 $1.RootImage,                    config_parse_unit_path_printf,      true,                          offsetof($1, exec_context.root_image)
21255d
-$1.User,                         config_parse_user_group,            0,                             offsetof($1, exec_context.user)
21255d
-$1.Group,                        config_parse_user_group,            0,                             offsetof($1, exec_context.group)
21255d
-$1.SupplementaryGroups,          config_parse_user_group_strv,       0,                             offsetof($1, exec_context.supplementary_groups)
21255d
+$1.User,                         config_parse_user_group_compat,     0,                             offsetof($1, exec_context.user)
21255d
+$1.Group,                        config_parse_user_group_compat,     0,                             offsetof($1, exec_context.group)
21255d
+$1.SupplementaryGroups,          config_parse_user_group_strv_compat, 0,                            offsetof($1, exec_context.supplementary_groups)
21255d
 $1.Nice,                         config_parse_exec_nice,             0,                             offsetof($1, exec_context)
21255d
 $1.OOMScoreAdjust,               config_parse_exec_oom_score_adjust, 0,                             offsetof($1, exec_context)
21255d
 $1.IOSchedulingClass,            config_parse_exec_io_class,         0,                             offsetof($1, exec_context)
21255d
@@ -354,8 +354,8 @@ Socket.ExecStartPost,            config_parse_exec,                  SOCKET_EXEC
21255d
 Socket.ExecStopPre,              config_parse_exec,                  SOCKET_EXEC_STOP_PRE,          offsetof(Socket, exec_command)
21255d
 Socket.ExecStopPost,             config_parse_exec,                  SOCKET_EXEC_STOP_POST,         offsetof(Socket, exec_command)
21255d
 Socket.TimeoutSec,               config_parse_sec_fix_0,             0,                             offsetof(Socket, timeout_usec)
21255d
-Socket.SocketUser,               config_parse_user_group,            0,                             offsetof(Socket, user)
21255d
-Socket.SocketGroup,              config_parse_user_group,            0,                             offsetof(Socket, group)
21255d
+Socket.SocketUser,               config_parse_user_group_compat,     0,                             offsetof(Socket, user)
21255d
+Socket.SocketGroup,              config_parse_user_group_compat,     0,                             offsetof(Socket, group)
21255d
 Socket.SocketMode,               config_parse_mode,                  0,                             offsetof(Socket, socket_mode)
21255d
 Socket.DirectoryMode,            config_parse_mode,                  0,                             offsetof(Socket, directory_mode)
21255d
 Socket.Accept,                   config_parse_bool,                  0,                             offsetof(Socket, accept)
21255d
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
21255d
index 740401a582..ba81d94504 100644
21255d
--- a/src/core/load-fragment.c
21255d
+++ b/src/core/load-fragment.c
21255d
@@ -1899,7 +1899,7 @@ int config_parse_sec_fix_0(
21255d
         return 0;
21255d
 }
21255d
 
21255d
-int config_parse_user_group(
21255d
+int config_parse_user_group_compat(
21255d
                 const char *unit,
21255d
                 const char *filename,
21255d
                 unsigned line,
21255d
@@ -1932,7 +1932,7 @@ int config_parse_user_group(
21255d
                 return -ENOEXEC;
21255d
         }
21255d
 
21255d
-        if (!valid_user_group_name_or_id(k)) {
21255d
+        if (!valid_user_group_name_or_id_compat(k)) {
21255d
                 log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
21255d
                 return -ENOEXEC;
21255d
         }
21255d
@@ -1940,7 +1940,7 @@ int config_parse_user_group(
21255d
         return free_and_replace(*user, k);
21255d
 }
21255d
 
21255d
-int config_parse_user_group_strv(
21255d
+int config_parse_user_group_strv_compat(
21255d
                 const char *unit,
21255d
                 const char *filename,
21255d
                 unsigned line,
21255d
@@ -1986,7 +1986,7 @@ int config_parse_user_group_strv(
21255d
                         return -ENOEXEC;
21255d
                 }
21255d
 
21255d
-                if (!valid_user_group_name_or_id(k)) {
21255d
+                if (!valid_user_group_name_or_id_compat(k)) {
21255d
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid user/group name or numeric ID: %s", k);
21255d
                         return -ENOEXEC;
21255d
                 }
21255d
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
21255d
index 65a94d53cc..f9d34d484d 100644
21255d
--- a/src/core/load-fragment.h
21255d
+++ b/src/core/load-fragment.h
21255d
@@ -96,8 +96,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_utmp_mode);
21255d
 CONFIG_PARSER_PROTOTYPE(config_parse_working_directory);
21255d
 CONFIG_PARSER_PROTOTYPE(config_parse_fdname);
21255d
 CONFIG_PARSER_PROTOTYPE(config_parse_sec_fix_0);
21255d
-CONFIG_PARSER_PROTOTYPE(config_parse_user_group);
21255d
-CONFIG_PARSER_PROTOTYPE(config_parse_user_group_strv);
21255d
+CONFIG_PARSER_PROTOTYPE(config_parse_user_group_compat);
21255d
+CONFIG_PARSER_PROTOTYPE(config_parse_user_group_strv_compat);
21255d
 CONFIG_PARSER_PROTOTYPE(config_parse_restrict_namespaces);
21255d
 CONFIG_PARSER_PROTOTYPE(config_parse_bind_paths);
21255d
 CONFIG_PARSER_PROTOTYPE(config_parse_exec_keyring_mode);