Zbigniew Jędrzejewski-Szmek 35bb94
From b06ca097172783c89e04134abf16a00b5151032a Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 35bb94
From: Yu Watanabe <watanabe.yu+github@gmail.com>
Zbigniew Jędrzejewski-Szmek 35bb94
Date: Wed, 11 Oct 2017 14:41:13 +0900
Zbigniew Jędrzejewski-Szmek 35bb94
Subject: [PATCH] dynamic-user: permit the case static uid and gid are
Zbigniew Jędrzejewski-Szmek 35bb94
 different
Zbigniew Jędrzejewski-Szmek 35bb94
Zbigniew Jędrzejewski-Szmek 35bb94
This makes systemd supports the case that DynamicUser=yes and
Zbigniew Jędrzejewski-Szmek 35bb94
static user and group exist such that uid and gid of them are different.
Zbigniew Jędrzejewski-Szmek 35bb94
We only refuse the operation when user does not exist but the group
Zbigniew Jędrzejewski-Szmek 35bb94
with the same name exists.
Zbigniew Jędrzejewski-Szmek 35bb94
Zbigniew Jędrzejewski-Szmek 35bb94
Fixes #7013.
Zbigniew Jędrzejewski-Szmek 35bb94
Zbigniew Jędrzejewski-Szmek 35bb94
(cherry picked from commit 9ec655cbbd7505ef465e0444da0622e46099ce42)
Zbigniew Jędrzejewski-Szmek 35bb94
---
Zbigniew Jędrzejewski-Szmek 35bb94
 src/core/dynamic-user.c | 41 +++++++++++++++++++++++++----------------
Zbigniew Jędrzejewski-Szmek 35bb94
 1 file changed, 25 insertions(+), 16 deletions(-)
Zbigniew Jędrzejewski-Szmek 35bb94
Zbigniew Jędrzejewski-Szmek 35bb94
diff --git a/src/core/dynamic-user.c b/src/core/dynamic-user.c
Zbigniew Jędrzejewski-Szmek 35bb94
index a191341186..8f229d27ff 100644
Zbigniew Jędrzejewski-Szmek 35bb94
--- a/src/core/dynamic-user.c
Zbigniew Jędrzejewski-Szmek 35bb94
+++ b/src/core/dynamic-user.c
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -421,7 +421,7 @@ static void unlink_uid_lock(int lock_fd, uid_t uid, const char *name) {
Zbigniew Jędrzejewski-Szmek 35bb94
         (void) make_uid_symlinks(uid, name, false); /* remove direct lookup symlinks */
Zbigniew Jędrzejewski-Szmek 35bb94
 }
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
-static int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *ret) {
Zbigniew Jędrzejewski-Szmek 35bb94
+static int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *ret, bool is_user) {
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
         _cleanup_close_ int etc_passwd_lock_fd = -1, uid_lock_fd = -1;
Zbigniew Jędrzejewski-Szmek 35bb94
         uid_t uid = UID_INVALID;
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -460,19 +460,28 @@ static int dynamic_user_realize(DynamicUser *d, char **suggested_dirs, uid_t *re
Zbigniew Jędrzejewski-Szmek 35bb94
                         struct passwd *p;
Zbigniew Jędrzejewski-Szmek 35bb94
                         struct group *g;
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
-                        /* OK, this is not a numeric UID. Let's see if there's a user by this name */
Zbigniew Jędrzejewski-Szmek 35bb94
-                        p = getpwnam(d->name);
Zbigniew Jędrzejewski-Szmek 35bb94
-                        if (p)
Zbigniew Jędrzejewski-Szmek 35bb94
-                                uid = p->pw_uid;
Zbigniew Jędrzejewski-Szmek 35bb94
-
Zbigniew Jędrzejewski-Szmek 35bb94
-                        /* Let's see if there's a group by this name */
Zbigniew Jędrzejewski-Szmek 35bb94
-                        g = getgrnam(d->name);
Zbigniew Jędrzejewski-Szmek 35bb94
-                        if (g) {
Zbigniew Jędrzejewski-Szmek 35bb94
-                                /* If the UID/GID of the user/group of the same don't match, refuse operation */
Zbigniew Jędrzejewski-Szmek 35bb94
-                                if (uid != UID_INVALID && uid != (uid_t) g->gr_gid)
Zbigniew Jędrzejewski-Szmek 35bb94
-                                        return -EILSEQ;
Zbigniew Jędrzejewski-Szmek 35bb94
-
Zbigniew Jędrzejewski-Szmek 35bb94
-                                uid = (uid_t) g->gr_gid;
Zbigniew Jędrzejewski-Szmek 35bb94
+                        if (is_user) {
Zbigniew Jędrzejewski-Szmek 35bb94
+                                /* OK, this is not a numeric UID. Let's see if there's a user by this name */
Zbigniew Jędrzejewski-Szmek 35bb94
+                                p = getpwnam(d->name);
Zbigniew Jędrzejewski-Szmek 35bb94
+                                if (p)
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        uid = p->pw_uid;
Zbigniew Jędrzejewski-Szmek 35bb94
+                                else {
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        /* if the user does not exist but the group with the same name exists, refuse operation */
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        g = getgrnam(d->name);
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        if (g)
Zbigniew Jędrzejewski-Szmek 35bb94
+                                                return -EILSEQ;
Zbigniew Jędrzejewski-Szmek 35bb94
+                                }
Zbigniew Jędrzejewski-Szmek 35bb94
+                        } else {
Zbigniew Jędrzejewski-Szmek 35bb94
+                                /* Let's see if there's a group by this name */
Zbigniew Jędrzejewski-Szmek 35bb94
+                                g = getgrnam(d->name);
Zbigniew Jędrzejewski-Szmek 35bb94
+                                if (g)
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        uid = (uid_t) g->gr_gid;
Zbigniew Jędrzejewski-Szmek 35bb94
+                                else {
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        /* if the group does not exist but the user with the same name exists, refuse operation */
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        p = getpwnam(d->name);
Zbigniew Jędrzejewski-Szmek 35bb94
+                                        if (p)
Zbigniew Jędrzejewski-Szmek 35bb94
+                                                return -EILSEQ;
Zbigniew Jędrzejewski-Szmek 35bb94
+                                }
Zbigniew Jędrzejewski-Szmek 35bb94
                         }
Zbigniew Jędrzejewski-Szmek 35bb94
                 }
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
@@ -814,13 +823,13 @@ int dynamic_creds_realize(DynamicCreds *creds, char **suggested_paths, uid_t *ui
Zbigniew Jędrzejewski-Szmek 35bb94
         /* Realize both the referenced user and group */
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
         if (creds->user) {
Zbigniew Jędrzejewski-Szmek 35bb94
-                r = dynamic_user_realize(creds->user, suggested_paths, &u);
Zbigniew Jędrzejewski-Szmek 35bb94
+                r = dynamic_user_realize(creds->user, suggested_paths, &u, true);
Zbigniew Jędrzejewski-Szmek 35bb94
                 if (r < 0)
Zbigniew Jędrzejewski-Szmek 35bb94
                         return r;
Zbigniew Jędrzejewski-Szmek 35bb94
         }
Zbigniew Jędrzejewski-Szmek 35bb94
 
Zbigniew Jędrzejewski-Szmek 35bb94
         if (creds->group && creds->group != creds->user) {
Zbigniew Jędrzejewski-Szmek 35bb94
-                r = dynamic_user_realize(creds->group, suggested_paths, &g);
Zbigniew Jędrzejewski-Szmek 35bb94
+                r = dynamic_user_realize(creds->group, suggested_paths, &g, false);
Zbigniew Jędrzejewski-Szmek 35bb94
                 if (r < 0)
Zbigniew Jędrzejewski-Szmek 35bb94
                         return r;
Zbigniew Jędrzejewski-Szmek 35bb94
         } else