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