From dbfc54be75b6d00879189e6f7ab82f65b17c1b9d Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Wed, 5 Oct 2011 17:52:06 +0200 Subject: Add option to follow symlinks to check_file() --- src/monitor/monitor.c | 2 +- src/sbus/sbus_client.c | 2 +- src/sbus/sssd_dbus_server.c | 2 +- src/tests/check_and_open-tests.c | 29 ++++++++++++++++++++++++++++- src/util/check_and_open.c | 5 +++-- src/util/util.h | 2 +- 6 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 333b24a8..87f7a172 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -2420,7 +2420,7 @@ int main(int argc, const char *argv[]) } /* Warn if nscd seems to be running */ - ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL); + ret = check_file(NSCD_SOCKET_PATH, -1, -1, -1, CHECK_SOCK, NULL, false); if (ret == EOK) { sss_log(SSS_LOG_NOTICE, "nscd socket was detected. Nscd caching capabilities " diff --git a/src/sbus/sbus_client.c b/src/sbus/sbus_client.c index 1c5c1b24..5b15ef3e 100644 --- a/src/sbus/sbus_client.c +++ b/src/sbus/sbus_client.c @@ -46,7 +46,7 @@ int sbus_client_init(TALLOC_CTX *mem_ctx, return EIO; } - ret = check_file(filename, 0, 0, 0600, CHECK_SOCK, NULL); + ret = check_file(filename, 0, 0, 0600, CHECK_SOCK, NULL, false); if (ret != EOK) { DEBUG(1, ("check_file failed for [%s].\n", filename)); return EIO; diff --git a/src/sbus/sssd_dbus_server.c b/src/sbus/sssd_dbus_server.c index 1bb58d49..fdcbc4ff 100644 --- a/src/sbus/sssd_dbus_server.c +++ b/src/sbus/sssd_dbus_server.c @@ -120,7 +120,7 @@ int sbus_new_server(TALLOC_CTX *mem_ctx, return EIO; } - ret = check_file(filename, 0, 0, -1, CHECK_SOCK, &stat_buf); + ret = check_file(filename, 0, 0, -1, CHECK_SOCK, &stat_buf, false); if (ret != EOK) { DEBUG(1, ("check_file failed for [%s].\n", filename)); return EIO; diff --git a/src/tests/check_and_open-tests.c b/src/tests/check_and_open-tests.c index 59879cc9..8e1bc988 100644 --- a/src/tests/check_and_open-tests.c +++ b/src/tests/check_and_open-tests.c @@ -100,7 +100,7 @@ START_TEST(test_symlink) ret = symlink(filename, newpath); fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno)); - ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL); + ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL, false); unlink(newpath); fail_unless(ret == EINVAL, @@ -108,6 +108,32 @@ START_TEST(test_symlink) } END_TEST +START_TEST(test_follow_symlink) +{ + int ret; + char *newpath; + size_t newpath_length; + + newpath_length = strlen(filename) + strlen(SUFFIX) + 1; + newpath = malloc((newpath_length) * sizeof(char)); + fail_unless(newpath != NULL, "malloc failed"); + + ret = snprintf(newpath, newpath_length, "%s%s", filename, SUFFIX); + fail_unless(ret == newpath_length - 1, + "snprintf failed: expected [%d] got [%d]", newpath_length -1, + ret); + + ret = symlink(filename, newpath); + fail_unless(ret == 0, "symlink failed [%d][%s]", ret, strerror(errno)); + + ret = check_file(newpath, uid, gid, mode, CHECK_REG, NULL, true); + unlink(newpath); + + fail_unless(ret == EOK, + "check_and_open_readonly failed on symlink with follow=true"); +} +END_TEST + START_TEST(test_not_regular_file) { int ret; @@ -196,6 +222,7 @@ Suite *check_and_open_suite (void) tcase_add_test (tc_check_and_open_readonly, test_wrong_filename); tcase_add_test (tc_check_and_open_readonly, test_not_regular_file); tcase_add_test (tc_check_and_open_readonly, test_symlink); + tcase_add_test (tc_check_and_open_readonly, test_follow_symlink); tcase_add_test (tc_check_and_open_readonly, test_wrong_uid); tcase_add_test (tc_check_and_open_readonly, test_wrong_gid); tcase_add_test (tc_check_and_open_readonly, test_wrong_permission); diff --git a/src/util/check_and_open.c b/src/util/check_and_open.c index db926f10..27ef1c88 100644 --- a/src/util/check_and_open.c +++ b/src/util/check_and_open.c @@ -35,7 +35,7 @@ static errno_t perform_checks(struct stat *stat_buf, 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) + struct stat *caller_stat_buf, bool follow_symlink) { int ret; struct stat local_stat_buf; @@ -47,7 +47,8 @@ errno_t check_file(const char *filename, const int uid, const int gid, stat_buf = caller_stat_buf; } - ret = lstat(filename, stat_buf); + ret = follow_symlink ? stat(filename, stat_buf) : \ + lstat(filename, stat_buf); if (ret == -1) { DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n", filename, errno, strerror(errno))); diff --git a/src/util/util.h b/src/util/util.h index a59603d0..b267a0f6 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -335,7 +335,7 @@ enum check_file_type { */ 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); + struct stat *caller_stat_buf, bool follow_symlink); /* check_fd() * Verify that an open file descriptor has certain permissions and/or -- cgit