From 05305d205f5e0c1d7a6c994d23aacc24ef3f1c01 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  |  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 60a9658642..d02f54650a 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1563,6 +1563,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) {
@@ -1603,7 +1605,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..333e92dffc 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 bcbb9ac72f..0a7d4d84c0 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 dda16ec143debc56c9356ea59846b4eb89a03993 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 | 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);
