From eb73035b35eade285c61d90c921ebef22e228ae3 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Fri, 15 Oct 2021 11:03:19 +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  |  5 ++++-
 src/tests/cwrap/group  |  1 +
 src/tests/cwrap/passwd |  1 +
 src/util/usertools.c   | 42 ++++++++++++++++++++++++++++++++++++++++++
 src/util/util.h        |  3 +++
 6 files changed, 54 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 b5fee7e7a7..c7610cb69b 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1551,6 +1551,8 @@ errno_t load_configuration(TALLOC_CTX *mem_ctx,
     errno_t ret;
     struct mt_ctx *ctx;
     char *cdb_file = NULL;
+    uid_t sssd_uid;
+    gid_t sssd_gid;
 
     ctx = talloc_zero(mem_ctx, struct mt_ctx);
     if(!ctx) {
@@ -1591,7 +1593,8 @@ 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);
+    sss_sssd_user_uid_and_gid(&sssd_uid, &sssd_gid);
+    ret = chown(cdb_file, sssd_uid, sssd_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..6f93a4cef2 100644
--- a/src/util/usertools.c
+++ b/src/util/usertools.c
@@ -835,3 +835,45 @@ int sss_output_fqname(TALLOC_CTX *mem_ctx,
     talloc_zfree(tmp_ctx);
     return ret;
 }
+
+void sss_sssd_user_uid_and_gid(uid_t *_uid, gid_t *_gid)
+{
+    uid_t sssd_uid;
+    gid_t sssd_gid;
+    errno_t ret;
+
+    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");
+        sssd_uid = 0;
+        sssd_gid = 0;
+    }
+
+    if (_uid != NULL) {
+        *_uid = sssd_uid;
+    }
+
+    if (_gid != NULL) {
+        *_gid = sssd_gid;
+    }
+}
+
+void sss_set_sssd_user_eid(void)
+{
+    uid_t uid;
+    gid_t gid;
+
+    if (geteuid() == 0) {
+        sss_sssd_user_uid_and_gid(&uid, &gid);
+        seteuid(uid);
+        setegid(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 e85cd12022..6dfd2540cc 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -383,6 +383,9 @@ 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);
+void sss_sssd_user_uid_and_gid(uid_t *_uid, gid_t *_gid);
+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 9d30b6e991e2d3aee1ba75e89252594096b2c798 Mon Sep 17 00:00:00 2001
From: Tomas Halman <thalman@redhat.com>
Date: Fri, 15 Oct 2021 11:04:05 +0200
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 | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 7a718cc628..80203c0f64 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -641,6 +641,8 @@ int confdb_init(TALLOC_CTX *mem_ctx,
     struct confdb_ctx *cdb;
     int ret = EOK;
     mode_t old_umask;
+    uid_t sssd_uid;
+    gid_t sssd_gid;
 
     cdb = talloc_zero(mem_ctx, struct confdb_ctx);
     if (!cdb)
@@ -673,6 +675,9 @@ 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 */
+    sss_sssd_user_uid_and_gid(&sssd_uid, &sssd_gid);
+    chown(confdb_location, sssd_uid, sssd_gid);
     sss_set_sssd_user_eid();
 
     ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL);
