diff options
Diffstat (limited to 'common/ini/ini_metadata.c')
-rw-r--r-- | common/ini/ini_metadata.c | 510 |
1 files changed, 0 insertions, 510 deletions
diff --git a/common/ini/ini_metadata.c b/common/ini/ini_metadata.c deleted file mode 100644 index f6d35453e..000000000 --- a/common/ini/ini_metadata.c +++ /dev/null @@ -1,510 +0,0 @@ -/* - INI LIBRARY - - Functions to process metadata. - - Copyright (C) Dmitri Pal <dpal@redhat.com> 2010 - - INI Library is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - INI Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with INI Library. If not, see <http://www.gnu.org/licenses/>. -*/ - -#define _GNU_SOURCE -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include "config.h" -#include "collection.h" -#include "collection_tools.h" -#include "trace.h" -#include "ini_config.h" -#include "ini_metadata.h" - -#define INI_METADATA "meta" - -/* Beffer length used for int to string conversions */ -#define CONVERSION_BUFFER 80 - -/* Invalid file mode */ -#define WRONG_FMODE 0x80000000 - -/* Prepare metadata */ -int prepare_metadata(uint32_t metaflags, - struct collection_item **metadata, - int *save_error) -{ - int error = EOK; - struct collection_item *metasec = NULL; - - TRACE_FLOW_STRING("prepare_metadata", "Entry"); - - /* Are we supposed to collect or process meta data ? */ - if (!metadata) { - TRACE_FLOW_STRING("No meta data", "Exit"); - return EOK; - } - - /* Allocate metadata */ - error = col_create_collection(metadata, - INI_METADATA, - COL_CLASS_INI_META); - if (error) { - TRACE_ERROR_NUMBER("Failed to create meta data", error); - return error; - } - - /* Check and create section for file error if needed */ - if (metaflags & INI_META_SEC_ERROR_FLAG) { - /* Create ERROR collection */ - if ((error = col_create_collection(&metasec, - INI_META_SEC_ERROR, - COL_CLASS_INI_SECTION)) || - (error = col_add_collection_to_collection( - *metadata, - NULL, - NULL, - metasec, - COL_ADD_MODE_REFERENCE))) { - TRACE_ERROR_NUMBER("Failed to create error section", error); - col_destroy_collection(metasec); - col_destroy_collection(*metadata); - *metadata = NULL; - return error; - } - /* If we are here we would have to save file open error */ - *save_error = 1; - col_destroy_collection(metasec); - } - - TRACE_FLOW_STRING("prepare_metadata", "Exit"); - return error; -} - - - -/* Collect metadata for the file */ -int collect_metadata(uint32_t metaflags, - struct collection_item **metadata, - FILE *config_file, - const char *config_filename) -{ - int error = EOK; - struct collection_item *metasec = NULL; - int filedes; - struct stat file_stats; - char buff[CONVERSION_BUFFER]; - - TRACE_FLOW_STRING("collect_metadata", "Entry"); - /* Check and create section for file error if needed */ - if (metaflags & INI_META_SEC_ACCESS_FLAG) { - /* Create ACCESS collection */ - error = col_create_collection(&metasec, - INI_META_SEC_ACCESS, - COL_CLASS_INI_SECTION); - if (error) { - TRACE_ERROR_NUMBER("Failed to create access section.", error); - col_destroy_collection(metasec); - return error; - } - - filedes = fileno(config_file); - - /* Collect statistics */ - errno = 0; - if (fstat(filedes, &file_stats) < 0) { - error = errno; - TRACE_ERROR_NUMBER("Failed to get statistics.", error); - col_destroy_collection(metasec); - return error; - } - - /* Record statistics */ - /* UID */ - snprintf(buff, CONVERSION_BUFFER, "%lu", - (unsigned long)file_stats.st_uid); - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_UID, - buff, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save uid", error); - col_destroy_collection(metasec); - return error; - } - - /* GID */ - snprintf(buff, CONVERSION_BUFFER, "%lu", - (unsigned long)file_stats.st_gid); - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_GID, - buff, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save gid", error); - col_destroy_collection(metasec); - return error; - } - - /* PERMISSIONS */ - snprintf(buff, CONVERSION_BUFFER, "%lu", - (unsigned long)file_stats.st_mode); - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_PERM, - buff, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save permissions", error); - col_destroy_collection(metasec); - return error; - } - - /* Modification time stamp */ - snprintf(buff, CONVERSION_BUFFER, "%ld", - (long int)file_stats.st_mtime); - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_MODIFIED, - buff, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save modification time", error); - col_destroy_collection(metasec); - return error; - } - - /* Name */ - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_NAME, - config_filename, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save file name", error); - col_destroy_collection(metasec); - return error; - } - - /* The device ID can actualy be bigger than - * 32-bits according to the type sizes. - * However it is probaly not going to happen - * on a real system. - * Add a check for this case. - */ - if (file_stats.st_dev > ULONG_MAX) { - TRACE_ERROR_NUMBER("Device is out of range", ERANGE); - col_destroy_collection(metasec); - return ERANGE; - } - - /* Device ID */ - TRACE_INFO_LNUMBER("Device ID", file_stats.st_dev); - - snprintf(buff, CONVERSION_BUFFER, "%lu", - (unsigned long)file_stats.st_dev); - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_DEV, - buff, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save inode", error); - col_destroy_collection(metasec); - return error; - } - - /* i-node */ - snprintf(buff, CONVERSION_BUFFER, "%lu", - (unsigned long)file_stats.st_ino); - error = col_add_str_property(metasec, - NULL, - INI_META_KEY_INODE, - buff, - 0); - if (error) { - TRACE_ERROR_NUMBER("Failed to save inode", error); - col_destroy_collection(metasec); - return error; - } - - /* Add section to metadata */ - error = col_add_collection_to_collection( - *metadata, - NULL, - NULL, - metasec, - COL_ADD_MODE_REFERENCE); - - col_destroy_collection(metasec); - - if (error) { - TRACE_ERROR_NUMBER("Failed to save file name", error); - return error; - } - } - - TRACE_FLOW_STRING("collect_metadata", "Exit"); - return error; -} - -/* Function to free metadata */ -void free_ini_config_metadata(struct collection_item *metadata) -{ - TRACE_FLOW_STRING("free_ini_config_metadata", "Entry"); - col_destroy_collection(metadata); - TRACE_FLOW_STRING("free_ini_config_metadata", "Exit"); -} - -/* Function to check uid or gid */ -static int check_id(struct collection_item *metadata, - unsigned long id, - const char *key) -{ - int error = EOK; - struct collection_item *item = NULL; - unsigned long fid; - - TRACE_FLOW_STRING("check_id", "Entry"); - TRACE_INFO_STRING("Key", key); - - error = get_config_item(INI_META_SEC_ACCESS, - key, - metadata, - &item); - if (error) { - TRACE_ERROR_NUMBER("Internal collection error.", error); - return error; - } - - /* Entry is supposed to be there so it is an error - * is the item is not found. - */ - if (item == NULL) { - TRACE_ERROR_NUMBER("Expected item is not found.", ENOENT); - return ENOENT; - } - - fid = get_ulong_config_value(item, 1, -1, &error); - if ((error) || (fid == -1)) { - TRACE_ERROR_NUMBER("Conversion failed", EINVAL); - return EINVAL; - } - - if (id != fid) { - TRACE_ERROR_NUMBER("File ID:", fid); - TRACE_ERROR_NUMBER("ID passed in.", id); - TRACE_ERROR_NUMBER("Access denied.", EACCES); - return EACCES; - } - - TRACE_FLOW_STRING("check_id", "Exit"); - return EOK; -} - -/* Function to check access */ -int config_access_check(struct collection_item *metadata, - uint32_t flags, - uid_t uid, - gid_t gid, - mode_t mode, - mode_t mask) -{ - int error = EOK; - struct collection_item *item = NULL; - mode_t f_mode; - - TRACE_FLOW_STRING("config_access_check", "Entry"); - - flags &= INI_ACCESS_CHECK_MODE | - INI_ACCESS_CHECK_GID | - INI_ACCESS_CHECK_UID; - - if ((metadata == NULL) || (flags == 0)) { - TRACE_ERROR_NUMBER("Invalid parameter.", EINVAL); - return EINVAL; - - } - - /* Check that metadata is actually metadata */ - if(!col_is_of_class(metadata, COL_CLASS_INI_META)) { - TRACE_ERROR_NUMBER("Invalid collection.", EINVAL); - return EINVAL; - } - - /* Check mode */ - if (flags & INI_ACCESS_CHECK_MODE) { - - error = get_config_item(INI_META_SEC_ACCESS, - INI_META_KEY_PERM, - metadata, - &item); - if (error) { - TRACE_ERROR_NUMBER("Internal collection error.", error); - return error; - } - - /* Entry is supposed to be there so it is an error - * is the item is not found. - */ - if (item == NULL) { - TRACE_ERROR_NUMBER("Expected item is not found.", ENOENT); - return ENOENT; - } - - f_mode = (mode_t)get_ulong_config_value(item, 1, WRONG_FMODE, &error); - if ((error) || (f_mode == WRONG_FMODE)) { - TRACE_ERROR_NUMBER("Conversion failed", error); - return ENOENT; - } - - TRACE_INFO_NUMBER("File mode as saved.", f_mode); - f_mode &= S_IRWXU | S_IRWXG | S_IRWXO; - TRACE_INFO_NUMBER("File mode adjusted.", f_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) != (f_mode & mask)) { - TRACE_INFO_NUMBER("File mode:", (mode & mask)); - TRACE_INFO_NUMBER("Mode adjusted.", (f_mode & mask)); - TRACE_ERROR_NUMBER("Access denied.", EACCES); - return EACCES; - } - } - - /* Check uid */ - if (flags & INI_ACCESS_CHECK_UID) { - - error = check_id(metadata, (unsigned long)uid, INI_META_KEY_UID); - if (error) { - TRACE_ERROR_NUMBER("Check for UID failed.", error); - return error; - } - } - - /* Check gid */ - if (flags & INI_ACCESS_CHECK_GID) { - - error = check_id(metadata, (unsigned long)gid, INI_META_KEY_GID); - if (error) { - TRACE_ERROR_NUMBER("Check for UID failed.", error); - return error; - } - } - - TRACE_FLOW_STRING("config_access_check", "Exit"); - return error; - -} - -static unsigned long get_checked_value(struct collection_item *metadata, - const char *key, - int *err) -{ - - int error = EOK; - struct collection_item *item = NULL; - unsigned long value; - - TRACE_FLOW_STRING("get_checked_value", "Entry"); - TRACE_INFO_STRING("Key", key); - - error = get_config_item(INI_META_SEC_ACCESS, - key, - metadata, - &item); - if (error) { - TRACE_ERROR_NUMBER("Internal collection error.", error); - *err = error; - return 0; - } - - /* Entry is supposed to be there so it is an error - * is the item is not found. - */ - if (item == NULL) { - TRACE_ERROR_NUMBER("Expected item is not found.", ENOENT); - *err = ENOENT; - return 0; - } - - value = get_ulong_config_value(item, 1, -1, &error); - if ((error) || (value == -1)) { - TRACE_ERROR_NUMBER("Conversion failed", EINVAL); - *err = EINVAL; - return 0; - } - - *err = 0; - - TRACE_FLOW_NUMBER("get_checked_value Returning", value); - return value; - -} - - -/* Function to check whether the configuration is different */ -int config_changed(struct collection_item *metadata, - struct collection_item *saved_metadata, - int *changed) -{ - int error = EOK; - struct collection_item *md[2]; - unsigned long value[3][2]; - const char *key[] = { INI_META_KEY_MODIFIED, - INI_META_KEY_DEV, - INI_META_KEY_INODE }; - int i, j; - - - TRACE_FLOW_STRING("config_changed", "Entry"); - - if ((!metadata) || - (!saved_metadata) || - (!changed) || - (!col_is_of_class(metadata, COL_CLASS_INI_META)) || - (!col_is_of_class(saved_metadata, COL_CLASS_INI_META))) { - TRACE_ERROR_NUMBER("Invalid argument.", EINVAL); - return EINVAL; - } - - md[0] = metadata; - md[1] = saved_metadata; - - /* Get three values from each collection and compare them */ - for (i = 0; i < 3; i++) { - for (j = 0; j < 2; j++) { - value[i][j] = get_checked_value(md[j], key[i] , &error); - if (error) { - TRACE_ERROR_NUMBER("Failed to get section.", error); - return error; - } - } - if (value[i][0] != value[i][1]) { - *changed = 1; - break; - } - } - - TRACE_FLOW_STRING("config_changed", "Exit"); - return error; - -} |