[SSSD] [PATCH] Check and set permissions on SBUS sockets

Sumit Bose sbose at redhat.com
Fri Feb 19 13:49:27 UTC 2010


Hi,

this patch should fix #403.

libdbus is so nice to call chmod(0777) explicitly on a newly created
socket so we have to call chmod() explicitly too to change the
permissions. I would prefer the call fchmod(), but I didn't found a way
to get the file descriptor of the socket out of libdbus. If anyone knows
a way I would be happy to update the patch.

bye,
Sumit
-------------- next part --------------
From 745d5069da29e61d6beb6027a87a81672a48b153 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 16 Feb 2010 15:53:56 +0100
Subject: [PATCH 1/2] Check and set permissions on SBUS sockets

---
 src/confdb/confdb_setup.c        |    3 +-
 src/sbus/sbus_client.c           |   13 ++++++
 src/sbus/sssd_dbus_server.c      |   24 ++++++++++++
 src/tests/check_and_open-tests.c |   17 ++++----
 src/tests/files-tests.c          |    2 +-
 src/util/check_and_open.c        |   76 ++++++++++++++++++++++++++++++++------
 src/util/util.h                  |   16 +++++++-
 7 files changed, 128 insertions(+), 23 deletions(-)

diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c
index 3c10c06..77cd5f9 100644
--- a/src/confdb/confdb_setup.c
+++ b/src/confdb/confdb_setup.c
@@ -285,7 +285,8 @@ int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
     tmp_ctx = talloc_new(cdb);
     if (tmp_ctx == NULL) return ENOMEM;
 
-    ret = check_and_open_readonly(config_file, &fd, 0, 0, (S_IRUSR|S_IWUSR));
+    ret = check_and_open_readonly(config_file, &fd, 0, 0, (S_IRUSR|S_IWUSR),
+                                  CHECK_REG);
     if (ret != EOK) {
         DEBUG(1, ("Permission check on config file failed.\n"));
         talloc_zfree(tmp_ctx);
diff --git a/src/sbus/sbus_client.c b/src/sbus/sbus_client.c
index df5c071..1c5c1b2 100644
--- a/src/sbus/sbus_client.c
+++ b/src/sbus/sbus_client.c
@@ -33,12 +33,25 @@ int sbus_client_init(TALLOC_CTX *mem_ctx,
 {
     struct sbus_connection *conn = NULL;
     int ret;
+    char *filename;
 
     /* Validate input */
     if (server_address == NULL) {
         return EINVAL;
     }
 
+    filename = strchr(server_address, '/');
+    if (filename == NULL) {
+        DEBUG(1, ("Unexpected dbus address [%s].\n", server_address));
+        return EIO;
+    }
+
+    ret = check_file(filename, 0, 0, 0600, CHECK_SOCK, NULL);
+    if (ret != EOK) {
+        DEBUG(1, ("check_file failed for [%s].\n", filename));
+        return EIO;
+    }
+
     ret = sbus_new_connection(mem_ctx, ev, server_address, intf, &conn);
     if (ret != EOK) {
         goto fail;
diff --git a/src/sbus/sssd_dbus_server.c b/src/sbus/sssd_dbus_server.c
index a859cba..b4b8894 100644
--- a/src/sbus/sssd_dbus_server.c
+++ b/src/sbus/sssd_dbus_server.c
@@ -19,6 +19,9 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include "tevent.h"
 #include "util/util.h"
 #include "dbus/dbus.h"
@@ -95,6 +98,8 @@ int sbus_new_server(TALLOC_CTX *mem_ctx,
     DBusError dbus_error;
     dbus_bool_t dbret;
     char *tmp;
+    int ret;
+    char *filename;
 
     *_server = NULL;
 
@@ -108,6 +113,25 @@ int sbus_new_server(TALLOC_CTX *mem_ctx,
         return EIO;
     }
 
+    filename = strchr(address, '/');
+    if (filename == NULL) {
+        DEBUG(1, ("Unexpected dbus address [%s].\n", address));
+        return EIO;
+    }
+
+    ret = check_file(filename, 0, 0, 0777, CHECK_SOCK, NULL);
+    if (ret != EOK) {
+        DEBUG(1, ("check_file failed for [%s].\n", filename));
+        return EIO;
+    }
+
+    ret = chmod(filename, 0600);
+    if (ret != EOK) {
+        DEBUG(1, ("chmod failed for [%s]: [%d][%s].\n", filename, errno,
+                                                     strerror(errno)));
+        return EIO;
+    }
+
     tmp = dbus_server_get_address(dbus_server);
     DEBUG(3, ("D-BUS Server listening on %s\n", tmp));
     free(tmp);
diff --git a/src/tests/check_and_open-tests.c b/src/tests/check_and_open-tests.c
index b0d638b..32cf09f 100644
--- a/src/tests/check_and_open-tests.c
+++ b/src/tests/check_and_open-tests.c
@@ -74,7 +74,7 @@ START_TEST(test_wrong_filename)
 {
     int ret;
 
-    ret = check_and_open_readonly("/bla/bla/bla", &fd, uid, gid, mode);
+    ret = check_and_open_readonly("/bla/bla/bla", &fd, uid, gid, mode, CHECK_REG);
     fail_unless(ret == ENOENT,
                 "check_and_open_readonly succeeded on non-existing file");
     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
@@ -99,7 +99,7 @@ START_TEST(test_symlink)
     ret = symlink(filename, newpath);
     fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(ret));
 
-    ret = check_and_open_readonly(newpath, &fd, uid, gid, mode);
+    ret = check_and_open_readonly(newpath, &fd, uid, gid, mode, CHECK_REG);
     unlink(newpath);
     fail_unless(ret == EINVAL,
                 "check_and_open_readonly succeeded on symlink");
@@ -111,7 +111,7 @@ START_TEST(test_not_regular_file)
 {
     int ret;
 
-    ret = check_and_open_readonly("/dev/null", &fd, uid, gid, mode);
+    ret = check_and_open_readonly("/dev/null", &fd, uid, gid, mode, CHECK_REG);
     fail_unless(ret == EINVAL,
                 "check_and_open_readonly succeeded on non-regular file");
     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
@@ -122,7 +122,7 @@ START_TEST(test_wrong_uid)
 {
     int ret;
 
-    ret = check_and_open_readonly(filename, &fd, uid+1, gid, mode);
+    ret = check_and_open_readonly(filename, &fd, uid+1, gid, mode, CHECK_REG);
     fail_unless(ret == EINVAL,
                 "check_and_open_readonly succeeded with wrong uid");
     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
@@ -133,7 +133,7 @@ START_TEST(test_wrong_gid)
 {
     int ret;
 
-    ret = check_and_open_readonly(filename, &fd, uid, gid+1, mode);
+    ret = check_and_open_readonly(filename, &fd, uid, gid+1, mode, CHECK_REG);
     fail_unless(ret == EINVAL,
                 "check_and_open_readonly succeeded with wrong gid");
     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
@@ -144,7 +144,8 @@ START_TEST(test_wrong_permission)
 {
     int ret;
 
-    ret = check_and_open_readonly(filename, &fd, uid, gid, (mode|S_IWOTH));
+    ret = check_and_open_readonly(filename, &fd, uid, gid, (mode|S_IWOTH),
+                                  CHECK_REG);
     fail_unless(ret == EINVAL,
                 "check_and_open_readonly succeeded with wrong mode");
     fail_unless(fd == -1, "check_and_open_readonly file descriptor not -1");
@@ -155,7 +156,7 @@ START_TEST(test_ok)
 {
     int ret;
 
-    ret = check_and_open_readonly(filename, &fd, uid, gid, mode);
+    ret = check_and_open_readonly(filename, &fd, uid, gid, mode, CHECK_REG);
     fail_unless(ret == EOK,
                 "check_and_open_readonly failed");
     fail_unless(fd >= 0,
@@ -169,7 +170,7 @@ START_TEST(test_write)
     ssize_t size;
     errno_t my_errno;
 
-    ret = check_and_open_readonly(filename, &fd, uid, gid, mode);
+    ret = check_and_open_readonly(filename, &fd, uid, gid, mode, CHECK_REG);
     fail_unless(ret == EOK,
                 "check_and_open_readonly failed");
     fail_unless(fd >= 0,
diff --git a/src/tests/files-tests.c b/src/tests/files-tests.c
index 90b9717..2ebe659 100644
--- a/src/tests/files-tests.c
+++ b/src/tests/files-tests.c
@@ -183,7 +183,7 @@ START_TEST(test_simple_copy)
     fail_unless(ret == 0, "destination directory not there\n");
 
     tmp = talloc_asprintf(test_ctx, "%s/bar", dst_path);
-    ret = check_and_open_readonly(tmp, &fd, uid, gid, 0700);
+    ret = check_and_open_readonly(tmp, &fd, uid, gid, 0700, CHECK_REG);
     fail_unless(ret == EOK, "Cannot open %s\n");
     close(fd);
     talloc_free(tmp);
diff --git a/src/util/check_and_open.c b/src/util/check_and_open.c
index 5d5b579..2b745be 100644
--- a/src/util/check_and_open.c
+++ b/src/util/check_and_open.c
@@ -29,39 +29,91 @@
 
 #include "util/util.h"
 
-errno_t check_and_open_readonly(const char *filename, int *fd, const uid_t uid,
-                               const gid_t gid, const mode_t mode)
+errno_t check_file(const char *filename, const uid_t uid, const gid_t gid,
+                   const mode_t mode, enum check_file_type type,
+                   struct stat *caller_stat_buf)
 {
     int ret;
-    struct stat stat_buf;
-    struct stat fd_stat_buf;
-
-    *fd = -1;
+    struct stat local_stat_buf;
+    struct stat *stat_buf;
+    bool type_check;
+
+    if (caller_stat_buf == NULL) {
+        stat_buf = &local_stat_buf;
+    } else {
+        stat_buf = caller_stat_buf;
+    }
 
-    ret = lstat(filename, &stat_buf);
+    ret = lstat(filename, stat_buf);
     if (ret == -1) {
         DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n", filename, errno,
                                                         strerror(errno)));
         return errno;
     }
 
-    if (!S_ISREG(stat_buf.st_mode)) {
-        DEBUG(1, ("File [%s] is not a regular file.\n", filename));
+    switch (type) {
+        case CHECK_REG:
+            type_check = S_ISREG(stat_buf->st_mode);
+            break;
+        case CHECK_DIR:
+            type_check = S_ISDIR(stat_buf->st_mode);
+            break;
+        case CHECK_CHR:
+            type_check = S_ISCHR(stat_buf->st_mode);
+            break;
+        case CHECK_BLK:
+            type_check = S_ISBLK(stat_buf->st_mode);
+            break;
+        case CHECK_FIFO:
+            type_check = S_ISFIFO(stat_buf->st_mode);
+            break;
+        case CHECK_LNK:
+            type_check = S_ISLNK(stat_buf->st_mode);
+            break;
+        case CHECK_SOCK:
+            type_check = S_ISSOCK(stat_buf->st_mode);
+            break;
+        default:
+            DEBUG(1, ("Unsupprted file type.\n"));
+            return EINVAL;
+    }
+
+    if (!type_check) {
+        DEBUG(1, ("File [%s] is not the right type.\n", filename));
         return EINVAL;
     }
 
-    if ((stat_buf.st_mode & ~S_IFMT) != mode) {
+    if ((stat_buf->st_mode & ~S_IFMT) != mode) {
         DEBUG(1, ("File [%s] has the wrong mode [%.7o], expected [%.7o].\n",
-                  filename, (stat_buf.st_mode & ~S_IFMT), mode));
+                  filename, (stat_buf->st_mode & ~S_IFMT), mode));
         return EINVAL;
     }
 
-    if (stat_buf.st_uid != uid || stat_buf.st_gid != gid) {
+    if (stat_buf->st_uid != uid || stat_buf->st_gid != gid) {
         DEBUG(1, ("File [%s] must be owned by uid [%d] and gid [%d].\n",
                   filename, uid, gid));
         return EINVAL;
     }
 
+    return EOK;
+}
+
+errno_t check_and_open_readonly(const char *filename, int *fd, const uid_t uid,
+                               const gid_t gid, const mode_t mode,
+                               enum check_file_type type)
+{
+    int ret;
+    struct stat stat_buf;
+    struct stat fd_stat_buf;
+
+    *fd = -1;
+
+    ret = check_file(filename, uid, gid, mode, type, &stat_buf);
+    if (ret != EOK) {
+        DEBUG(1, ("check_file failed.\n"));
+        return ret;
+    }
+
     *fd = open(filename, O_RDONLY);
     if (*fd == -1) {
         DEBUG(1, ("open [%s] failed: [%d][%s].\n", filename, errno,
diff --git a/src/util/util.h b/src/util/util.h
index 945e20d..02febf8 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -33,6 +33,7 @@
 #include <time.h>
 #include <pcre.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 
 #include "config.h"
 
@@ -247,8 +248,21 @@ int sss_parse_name(TALLOC_CTX *memctx,
 int backup_file(const char *src, int dbglvl);
 
 /* from check_and_open.c */
+enum check_file_type {
+    CHECK_REG,
+    CHECK_DIR,
+    CHECK_CHR,
+    CHECK_BLK,
+    CHECK_FIFO,
+    CHECK_LNK,
+    CHECK_SOCK
+};
+errno_t check_file(const char *filename, const uid_t uid, const gid_t gid,
+                   const mode_t mode, enum check_file_type type,
+                   struct stat *caller_stat_buf);
 errno_t check_and_open_readonly(const char *filename, int *fd, const uid_t uid,
-                               const gid_t gid, const mode_t mode);
+                               const gid_t gid, const mode_t mode,
+                               enum check_file_type type);
 
 /* from util.c */
 int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
-- 
1.6.6

-------------- next part --------------
From 6d7b1f5972c267370b979cdc2c95a0c9ba4a1183 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 19 Feb 2010 14:41:10 +0100
Subject: [PATCH 2/2] Fix file permissions of config.ldb

---
 src/confdb/confdb.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index 6981baa..64653b1 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -521,6 +521,7 @@ int confdb_init(TALLOC_CTX *mem_ctx,
 {
     struct confdb_ctx *cdb;
     int ret = EOK;
+    mode_t old_umask;
 
     cdb = talloc_zero(mem_ctx, struct confdb_ctx);
     if (!cdb)
@@ -552,7 +553,10 @@ int confdb_init(TALLOC_CTX *mem_ctx,
         return EIO;
     }
 
+    old_umask = umask(0177);
+
     ret = ldb_connect(cdb->ldb, confdb_location, 0, NULL);
+    umask(old_umask);
     if (ret != LDB_SUCCESS) {
         DEBUG(0, ("Unable to open config database [%s]\n",
                   confdb_location));
-- 
1.6.6



More information about the sssd-devel mailing list