diff options
author | Dmitri Pal <dpal@redhat.com> | 2012-03-18 14:54:37 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2012-04-05 11:20:09 -0700 |
commit | 31c43691242c234c1c9bca336eda6647b79d1442 (patch) | |
tree | c196fe9b22ce2541b0f8357e9a94eab95e341fd2 /ini | |
parent | 89bd6c4dbb49ed8e6a540bb934ac7ac1ded1940e (diff) | |
download | ding-libs-31c43691242c234c1c9bca336eda6647b79d1442.tar.gz ding-libs-31c43691242c234c1c9bca336eda6647b79d1442.tar.xz ding-libs-31c43691242c234c1c9bca336eda6647b79d1442.zip |
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
Diffstat (limited to 'ini')
-rw-r--r-- | ini/ini_configobj.h | 35 | ||||
-rw-r--r-- | ini/ini_fileobj.c | 75 |
2 files changed, 110 insertions, 0 deletions
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 @@ -104,6 +104,41 @@ */ /** + * @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 + +/** + * @} + */ + +/** * @defgroup collisionflags Flags that define collision resolution logic. * * @{ 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; + +} |