From 31c43691242c234c1c9bca336eda6647b79d1442 Mon Sep 17 00:00:00 2001 From: Dmitri Pal Date: Sun, 18 Mar 2012 14:54:37 -0400 Subject: Check access function Added check access constants and the check access function. The function is effectively copied from ini_metadata.c The flags are copied from ini_config.h --- ini/ini_configobj.h | 35 +++++++++++++++++++++++++ ini/ini_fileobj.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/ini/ini_configobj.h b/ini/ini_configobj.h index 8984402..eccad71 100644 --- a/ini/ini_configobj.h +++ b/ini/ini_configobj.h @@ -99,6 +99,41 @@ /** @brief Collect file stats. */ #define INI_META_STATS 1 +/** + * @} + */ + +/** + * @defgroup accesscheck Access control check flags + * + * @{ + */ + +/** + * @brief Validate access mode + * + * If this flag is specified the mode parameter + * will be matched against the permissions set on the file + * using the provided mask. + */ +#define INI_ACCESS_CHECK_MODE 0x00000001 + +/** + * @brief Validate uid + * + * Provided uid will be checked against uid + * of the file. + */ +#define INI_ACCESS_CHECK_UID 0x00000002 + +/** + * @brief Validate gid + * + * Provided gid will be checked against gid + * of the file. + */ +#define INI_ACCESS_CHECK_GID 0x00000004 + /** * @} */ diff --git a/ini/ini_fileobj.c b/ini/ini_fileobj.c index 48730fc..5764933 100644 --- a/ini/ini_fileobj.c +++ b/ini/ini_fileobj.c @@ -409,3 +409,78 @@ const char *ini_config_get_filename(struct ini_cfgfile *file_ctx) TRACE_FLOW_EXIT(); return ret; } + + +/* Check access */ +int ini_config_access_check(struct ini_cfgfile *file_ctx, + uint32_t flags, + uid_t uid, + gid_t gid, + mode_t mode, + mode_t mask) +{ + mode_t st_mode; + + TRACE_FLOW_ENTRY(); + + flags &= INI_ACCESS_CHECK_MODE | + INI_ACCESS_CHECK_GID | + INI_ACCESS_CHECK_UID; + + if ((file_ctx == NULL) || (flags == 0)) { + TRACE_ERROR_NUMBER("Invalid parameter.", EINVAL); + return EINVAL; + + } + + /* Check mode */ + if (flags & INI_ACCESS_CHECK_MODE) { + + TRACE_INFO_NUMBER("File mode as saved.", + file_ctx->file_stats.st_mode); + + st_mode = file_ctx->file_stats.st_mode; + st_mode &= S_IRWXU | S_IRWXG | S_IRWXO; + TRACE_INFO_NUMBER("File mode adjusted.", st_mode); + + TRACE_INFO_NUMBER("Mode as provided.", mode); + mode &= S_IRWXU | S_IRWXG | S_IRWXO; + TRACE_INFO_NUMBER("Mode adjusted.", mode); + + /* Adjust mask */ + if (mask == 0) mask = S_IRWXU | S_IRWXG | S_IRWXO; + else mask &= S_IRWXU | S_IRWXG | S_IRWXO; + + if ((mode & mask) != (st_mode & mask)) { + TRACE_INFO_NUMBER("File mode:", (mode & mask)); + TRACE_INFO_NUMBER("Mode adjusted.", + (st_mode & mask)); + TRACE_ERROR_NUMBER("Access denied.", EACCES); + return EACCES; + } + } + + /* Check uid */ + if (flags & INI_ACCESS_CHECK_UID) { + if (file_ctx->file_stats.st_uid != uid) { + TRACE_ERROR_NUMBER("GID:", file_ctx->file_stats.st_uid); + TRACE_ERROR_NUMBER("GID passed in.", uid); + TRACE_ERROR_NUMBER("Access denied.", EACCES); + return EACCES; + } + } + + /* Check gid */ + if (flags & INI_ACCESS_CHECK_GID) { + if (file_ctx->file_stats.st_gid != gid) { + TRACE_ERROR_NUMBER("GID:", file_ctx->file_stats.st_gid); + TRACE_ERROR_NUMBER("GID passed in.", gid); + TRACE_ERROR_NUMBER("Access denied.", EACCES); + return EACCES; + } + } + + TRACE_FLOW_EXIT(); + return EOK; + +} -- cgit