summaryrefslogtreecommitdiffstats
path: root/src/util
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-04-19 16:11:47 -0400
committerJakub Hrozek <jhrozek@redhat.com>2014-04-28 21:57:01 +0200
commit9a592ee3fc195f20732c6b1f90894a0be25ccc19 (patch)
tree320d37f03789f3d938a51dae0aaec82c9ad5f9a4 /src/util
parent8e09148b68a3fd8b06fcb746054f3cfa250b40f8 (diff)
downloadsssd-9a592ee3fc195f20732c6b1f90894a0be25ccc19.tar.gz
sssd-9a592ee3fc195f20732c6b1f90894a0be25ccc19.tar.xz
sssd-9a592ee3fc195f20732c6b1f90894a0be25ccc19.zip
util: Change file check fns to use a mode mask
Instead of using a custom way to chck file type, use the system provided macros and a mode mask to decide when we want to check. Additionally a mask also allows us to selectively check permissions. Related: https://bugzilla.redhat.com/1089098 Resolves: https://fedorahosted.org/sssd/ticket/2321 Signed-off-by: Simo Sorce <simo@redhat.com> Reviewed-by: Pavel Reichl <preichl@redhat.com>
Diffstat (limited to 'src/util')
-rw-r--r--src/util/check_and_open.c85
-rw-r--r--src/util/sss_ini.c2
-rw-r--r--src/util/util.h26
3 files changed, 40 insertions, 73 deletions
diff --git a/src/util/check_and_open.c b/src/util/check_and_open.c
index 7bf7805dd..80ec00e10 100644
--- a/src/util/check_and_open.c
+++ b/src/util/check_and_open.c
@@ -30,11 +30,11 @@
#include "util/util.h"
static errno_t perform_checks(struct stat *stat_buf,
- const int uid, const int gid,
- const int mode, enum check_file_type type);
+ uid_t uid, gid_t gid,
+ mode_t mode, mode_t mask);
-errno_t check_file(const char *filename, const int uid, const int gid,
- const int mode, enum check_file_type type,
+errno_t check_file(const char *filename,
+ uid_t uid, uid_t gid, mode_t mode, mode_t mask,
struct stat *caller_stat_buf, bool follow_symlink)
{
int ret;
@@ -47,19 +47,22 @@ errno_t check_file(const char *filename, const int uid, const int gid,
stat_buf = caller_stat_buf;
}
- ret = follow_symlink ? stat(filename, stat_buf) : \
- lstat(filename, stat_buf);
+ if (follow_symlink) {
+ ret = stat(filename, stat_buf);
+ } else {
+ ret = lstat(filename, stat_buf);
+ }
if (ret == -1) {
- DEBUG(SSSDBG_TRACE_FUNC, "lstat for [%s] failed: [%d][%s].\n", filename, errno,
- strerror(errno));
+ DEBUG(SSSDBG_TRACE_FUNC, "lstat for [%s] failed: [%d][%s].\n",
+ filename, errno, strerror(errno));
return errno;
}
- return perform_checks(stat_buf, uid, gid, mode, type);
+ return perform_checks(stat_buf, uid, gid, mode, mask);
}
-errno_t check_fd(int fd, const int uid, const int gid,
- const int mode, enum check_file_type type,
+errno_t check_fd(int fd, uid_t uid, gid_t gid,
+ mode_t mode, mode_t mask,
struct stat *caller_stat_buf)
{
int ret;
@@ -80,63 +83,39 @@ errno_t check_fd(int fd, const int uid, const int gid,
return errno;
}
- return perform_checks(stat_buf, uid, gid, mode, type);
+ return perform_checks(stat_buf, uid, gid, mode, mask);
}
static errno_t perform_checks(struct stat *stat_buf,
- const int uid, const int gid,
- const int mode, enum check_file_type type)
+ uid_t uid, gid_t gid,
+ mode_t mode, mode_t mask)
{
- bool type_check;
-
- 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(SSSDBG_CRIT_FAILURE, "Unsupported file type.\n");
- return EINVAL;
+ mode_t st_mode;
+
+ if (mask) {
+ st_mode = stat_buf->st_mode & mask;
+ } else {
+ st_mode = stat_buf->st_mode & (S_IFMT|ALLPERMS);
}
- if (!type_check) {
+ if ((mode & S_IFMT) != (st_mode & S_IFMT)) {
DEBUG(SSSDBG_CRIT_FAILURE, "File is not the right type.\n");
return EINVAL;
}
- if (mode >= 0 && (stat_buf->st_mode & ~S_IFMT) != mode) {
+ if ((st_mode & ALLPERMS) != (mode & ALLPERMS)) {
DEBUG(SSSDBG_CRIT_FAILURE,
"File has the wrong mode [%.7o], expected [%.7o].\n",
- (stat_buf->st_mode & ~S_IFMT), mode);
+ (st_mode & ALLPERMS), (mode & ALLPERMS));
return EINVAL;
}
- if (uid >= 0 && stat_buf->st_uid != uid) {
+ if (uid != (uid_t)(-1) && stat_buf->st_uid != uid) {
DEBUG(SSSDBG_CRIT_FAILURE, "File must be owned by uid [%d].\n", uid);
return EINVAL;
}
- if (gid >= 0 && stat_buf->st_gid != gid) {
+ if (gid != (gid_t)(-1) && stat_buf->st_gid != gid) {
DEBUG(SSSDBG_CRIT_FAILURE, "File must be owned by gid [%d].\n", gid);
return EINVAL;
}
@@ -144,9 +123,9 @@ static errno_t perform_checks(struct stat *stat_buf,
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)
+errno_t check_and_open_readonly(const char *filename, int *fd,
+ uid_t uid, gid_t gid,
+ mode_t mode, mode_t mask)
{
int ret;
struct stat stat_buf;
@@ -159,7 +138,7 @@ errno_t check_and_open_readonly(const char *filename, int *fd, const uid_t uid,
return errno;
}
- ret = check_fd(*fd, uid, gid, mode, type, &stat_buf);
+ ret = check_fd(*fd, uid, gid, mode, mask, &stat_buf);
if (ret != EOK) {
close(*fd);
*fd = -1;
diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c
index 5293ae93b..89b133da0 100644
--- a/src/util/sss_ini.c
+++ b/src/util/sss_ini.c
@@ -120,7 +120,7 @@ int sss_ini_config_file_open(struct sss_ini_initdata *init_data,
&init_data->file);
#elif defined(HAVE_LIBINI_CONFIG_V0)
return check_and_open_readonly(config_file, &init_data->file, 0, 0,
- (S_IRUSR|S_IWUSR), CHECK_REG);
+ S_IFREG|S_IRUSR|S_IWUSR, 0);
#endif
}
diff --git a/src/util/util.h b/src/util/util.h
index c74ff5b56..54c6c6c78 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -329,18 +329,6 @@ sss_get_domain_name(TALLOC_CTX *mem_ctx, const char *orig_name,
/* from backup-file.c */
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
-};
-
/* check_file()
* Verify that a file has certain permissions and/or is of a certain
* file type. This function can be used to determine if a file is a
@@ -352,8 +340,8 @@ enum check_file_type {
* inode to minimize impact. Permission changes may have occurred,
* however.
*/
-errno_t check_file(const char *filename, const int uid, const int gid,
- const int mode, enum check_file_type type,
+errno_t check_file(const char *filename,
+ uid_t uid, gid_t gid, mode_t mode, mode_t mask,
struct stat *caller_stat_buf, bool follow_symlink);
/* check_fd()
@@ -363,8 +351,8 @@ errno_t check_file(const char *filename, const int uid, const int gid,
* is the safer way to perform file checks and should be preferred
* over check_file for nearly all situations.
*/
-errno_t check_fd(int fd, const int uid, const int gid,
- const int mode, enum check_file_type type,
+errno_t check_fd(int fd, uid_t uid, gid_t gid,
+ mode_t mode, mode_t mask,
struct stat *caller_stat_buf);
/* check_and_open_readonly()
@@ -372,9 +360,9 @@ errno_t check_fd(int fd, const int uid, const int gid,
* permissions and is of a certain file type. This function wraps
* check_fd(), and is considered race-condition safe.
*/
-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);
+errno_t check_and_open_readonly(const char *filename, int *fd,
+ uid_t uid, gid_t gid,
+ mode_t mode, mode_t mask);
/* from util.c */
#define SSS_NO_LINKLOCAL 0x01