From 1f3868e797b3d75e0154499ca45bfd6d09577576 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Wed, 8 Sep 2021 14:18:35 +0200
Subject: [PATCH 1/2] CONFDB: Change ownership of config.ldb

Config database is owned by root. This prevents our socket
activated services to start because they are started under
the sssd user. Changing the ownership to sssd fixes the issue.

Resolves: https://github.com/SSSD/sssd/issues/5781
---
 src/confdb/confdb.c    |  3 ++
 src/monitor/monitor.c  |  2 +-
 src/tests/cwrap/group  |  1 +
 src/tests/cwrap/passwd |  1 +
 src/util/usertools.c   | 63 ++++++++++++++++++++++++++++++++++++++++++
 src/util/util.h        |  4 +++
 6 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index b7a73d97b3..7a718cc628 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -673,8 +673,11 @@ int confdb_init(TALLOC_CTX *mem_ctx,
     }
 
     old_umask = umask(SSS_DFL_UMASK);
+    sss_set_sssd_user_eid();
 
     ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL);
+
+    sss_restore_sssd_user_eid();
     umask(old_umask);
     if (ret != LDB_SUCCESS) {
         DEBUG(SSSDBG_FATAL_FAILURE, "Unable to open config database [%s]\n",
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 60a9658642..a213b2fb47 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1603,7 +1603,7 @@ errno_t load_configuration(TALLOC_CTX *mem_ctx,
 
     /* Allow configuration database to be accessible
      * when SSSD runs as nonroot */
-    ret = chown(cdb_file, ctx->uid, ctx->gid);
+    ret = chown(cdb_file, sss_sssd_user_uid(), sss_sssd_user_gid());
     if (ret != 0) {
         ret = errno;
         DEBUG(SSSDBG_FATAL_FAILURE,
diff --git a/src/tests/cwrap/group b/src/tests/cwrap/group
index d0cea659ea..1a3766e630 100644
--- a/src/tests/cwrap/group
+++ b/src/tests/cwrap/group
@@ -1,2 +1,3 @@
+root:x:0:
 sssd:x:123:
 foogroup:x:10001:
diff --git a/src/tests/cwrap/passwd b/src/tests/cwrap/passwd
index 862ccfe03e..0511a91bcb 100644
--- a/src/tests/cwrap/passwd
+++ b/src/tests/cwrap/passwd
@@ -1,2 +1,3 @@
+root:x:0:0:root:/root:/bin/bash
 sssd:x:123:456:sssd unprivileged user:/:/sbin/nologin
 foobar:x:10001:10001:User for SSSD testing:/home/foobar:/bin/bash
diff --git a/src/util/usertools.c b/src/util/usertools.c
index 8c2ed4e2de..8871ba7b51 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -835,3 +835,66 @@ int sss_output_fqname(TALLOC_CTX *mem_ctx,
     talloc_zfree(tmp_ctx);
     return ret;
 }
+
+static void sss_sssd_user_uid_and_gid(uid_t *uid, gid_t *gid)
+{
+    static uid_t sssd_uid;
+    static uid_t sssd_gid;
+    static bool resolved = false;
+
+    errno_t ret;
+
+    if (! resolved) {
+        ret = sss_user_by_name_or_uid(SSSD_USER, &sssd_uid, &sssd_gid);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_CRIT_FAILURE, "failed to get sssd user (" SSSD_USER ") uid/gid, using root\n");
+            if (uid != NULL) {
+                *uid = 0;
+            }
+            if (gid != NULL) {
+                *gid = 0;
+            }
+            return;
+        } else {
+            resolved = true;
+        }
+    }
+
+    if (uid != NULL) {
+        *uid = sssd_uid;
+    }
+
+    if (gid != NULL) {
+        *gid = sssd_gid;
+    }
+}
+
+uid_t sss_sssd_user_uid(void)
+{
+    uid_t uid;
+    sss_sssd_user_uid_and_gid(&uid, NULL);
+    return uid;
+}
+
+gid_t sss_sssd_user_gid(void)
+{
+    gid_t gid;
+    sss_sssd_user_uid_and_gid(NULL, &gid);
+    return gid;
+}
+
+void sss_set_sssd_user_eid(void)
+{
+    if (geteuid() == 0) {
+        seteuid(sss_sssd_user_uid());
+        setegid(sss_sssd_user_gid());
+    }
+}
+
+void sss_restore_sssd_user_eid(void)
+{
+    if (getuid() == 0) {
+        seteuid(getuid());
+        setegid(getgid());
+    }
+}
diff --git a/src/util/util.h b/src/util/util.h
index bcbb9ac72f..94df2a8b99 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -383,6 +383,10 @@ errno_t sss_canonicalize_ip_address(TALLOC_CTX *mem_ctx,
 const char * const * get_known_services(void);
 
 errno_t sss_user_by_name_or_uid(const char *input, uid_t *_uid, gid_t *_gid);
+uid_t sss_sssd_user_uid(void);
+gid_t sss_sssd_user_gid(void);
+void sss_set_sssd_user_eid(void);
+void sss_restore_sssd_user_eid(void);
 
 int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
                        const char sep, bool trim, bool skip_empty,

From 52ffabf89ebcdc4be947798748d47eb7804635d7 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Mon, 20 Sep 2021 13:05:14 +0000
Subject: [PATCH 2/2] CONFDB: Change ownership before dropping privileges

From previous SSSD version, config file can exist and can be
owned by root. To allow smooth transition we can change
the ownership.

This commit can be reverted later.

Resolves: https://github.com/SSSD/sssd/issues/5781
---
 src/confdb/confdb.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 7a718cc628..76528bb4d9 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -673,6 +673,8 @@ int confdb_init(TALLOC_CTX *mem_ctx,
     }
 
     old_umask = umask(SSS_DFL_UMASK);
+    /* file may exists and could be owned by root from previous version */
+    chown(confdb_location, sss_sssd_user_uid(), sss_sssd_user_gid());
     sss_set_sssd_user_eid();
 
     ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL);
