summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-02-16 15:53:56 +0100
committerStephen Gallagher <sgallagh@redhat.com>2010-02-23 16:16:23 -0500
commit978bea5902ece9b9f01d1d6525dbe0889a410ffc (patch)
treed83a94851cb6e3fe10fdbfcee1757190c15ab4eb
parente0bb119bdc1549d731f371202428c0cb667d3388 (diff)
downloadsssd-978bea5902ece9b9f01d1d6525dbe0889a410ffc.tar.gz
sssd-978bea5902ece9b9f01d1d6525dbe0889a410ffc.tar.xz
sssd-978bea5902ece9b9f01d1d6525dbe0889a410ffc.zip
Check and set permissions on SBUS sockets
-rw-r--r--src/confdb/confdb_setup.c3
-rw-r--r--src/sbus/sbus_client.c13
-rw-r--r--src/sbus/sssd_dbus_server.c27
-rw-r--r--src/tests/check_and_open-tests.c17
-rw-r--r--src/tests/files-tests.c2
-rw-r--r--src/util/check_and_open.c87
-rw-r--r--src/util/util.h17
7 files changed, 141 insertions, 25 deletions
diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c
index 3c10c06c9..77cd5f938 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 df5c07120..1c5c1b24a 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 a859cbabc..98c308e65 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,9 @@ int sbus_new_server(TALLOC_CTX *mem_ctx,
DBusError dbus_error;
dbus_bool_t dbret;
char *tmp;
+ int ret;
+ char *filename;
+ struct stat stat_buf;
*_server = NULL;
@@ -108,6 +114,27 @@ 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, -1, CHECK_SOCK, &stat_buf);
+ if (ret != EOK) {
+ DEBUG(1, ("check_file failed for [%s].\n", filename));
+ return EIO;
+ }
+
+ if ((stat_buf.st_mode & ~S_IFMT) != 0600) {
+ 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 b0d638b55..32cf09f33 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 90b971779..2ebe659da 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 5d5b57993..d010670ba 100644
--- a/src/util/check_and_open.c
+++ b/src/util/check_and_open.c
@@ -29,39 +29,98 @@
#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 int uid, const int gid,
+ const int 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_DONT_CHECK_FILE_TYPE:
+ type_check = true;
+ break;
+ 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 (mode >= 0 && (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 (uid >= 0 && stat_buf->st_uid != uid) {
+ DEBUG(1, ("File [%s] must be owned by uid [%d].\n", filename, uid));
return EINVAL;
}
- 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));
+ if (gid >= 0 && stat_buf->st_gid != gid) {
+ DEBUG(1, ("File [%s] must be owned by gid [%d].\n", filename, 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 945e20d00..5d2dff28f 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,22 @@ 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_DONT_CHECK_FILE_TYPE = -1,
+ CHECK_REG,
+ CHECK_DIR,
+ CHECK_CHR,
+ CHECK_BLK,
+ CHECK_FIFO,
+ CHECK_LNK,
+ CHECK_SOCK
+};
+errno_t check_file(const char *filename, const int uid, const int gid,
+ const int 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,