diff options
Diffstat (limited to 'libsefs/src/query.cc')
-rw-r--r-- | libsefs/src/query.cc | 431 |
1 files changed, 431 insertions, 0 deletions
diff --git a/libsefs/src/query.cc b/libsefs/src/query.cc new file mode 100644 index 0000000..64c4e6b --- /dev/null +++ b/libsefs/src/query.cc @@ -0,0 +1,431 @@ +/** + * @file + * Implementation of the sefs_query class. + * + * @author Jeremy A. Mowery jmowery@tresys.com + * @author Jason Tang jtang@tresys.com + * + * Copyright (C) 2007 Tresys Technology, LLC + * + * This 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 2.1 of the License, or (at your option) any later version. + * + * This 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 this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <config.h> + +#include "sefs_internal.hh" + +#include <sefs/query.hh> +#include <apol/util.h> +#include <qpol/genfscon_query.h> + +#include <assert.h> +#include <errno.h> + +/******************** public functions below ********************/ + +sefs_query::sefs_query() +{ + _user = _role = _type = _range = NULL; + _path = _dev = NULL; + _objclass = QPOL_CLASS_ALL; + _indirect = _regex = _recursive = false; + _inode = 0; + _recompiled = false; + _reuser = _rerole = _retype = _rerange = _repath = _redev = NULL; +} + +sefs_query::~sefs_query() +{ + free(_user); + free(_role); + free(_type); + free(_range); + free(_path); + free(_dev); + if (_recompiled) + { + regfree(_reuser); + free(_reuser); + regfree(_rerole); + free(_rerole); + regfree(_retype); + free(_retype); + regfree(_rerange); + free(_rerange); + regfree(_repath); + free(_repath); + regfree(_redev); + free(_redev); + } +} + +void sefs_query::user(const char *name) throw(std::bad_alloc) +{ + if (name != _user) + { + free(_user); + _user = NULL; + if (name != NULL && *name != '\0' && (_user = strdup(name)) == NULL) + { + throw std::bad_alloc(); + } + } +} + +void sefs_query::role(const char *name) throw(std::bad_alloc) +{ + if (name != _role) + { + free(_role); + _role = NULL; + if (name != NULL && *name != '\0' && (_role = strdup(name)) == NULL) + { + throw std::bad_alloc(); + } + } +} + +void sefs_query::type(const char *name, bool indirect) throw(std::bad_alloc) +{ + if (name != _type) + { + free(_type); + _type = NULL; + if (name != NULL && *name != '\0') + { + if ((_type = strdup(name)) == NULL) + { + throw std::bad_alloc(); + } + _indirect = indirect; + } + } +} + +void sefs_query::range(const char *name, int match) throw(std::bad_alloc) +{ + if (name != _range) + { + free(_range); + _range = NULL; + if (name != NULL && *name != '\0') + { + if ((_range = strdup(name)) == NULL) + { + throw std::bad_alloc(); + } + _rangeMatch = match; + } + } +} + +void sefs_query::objectClass(uint32_t objclass) +{ + _objclass = objclass; +} + +void sefs_query::objectClass(const char *name) +{ + if (name == NULL || *name == '\0' || strcmp(name, "any") == 0) + { + _objclass = QPOL_CLASS_ALL; + } + else + { + uint32_t o = apol_str_to_objclass(name); + if (o != QPOL_CLASS_ALL) + { + _objclass = o; + } + } +} + +void sefs_query::path(const char *str) throw(std::bad_alloc) +{ + if (str != _path) + { + free(_path); + _path = NULL; + if (str != NULL && *str != '\0' && (_path = strdup(str)) == NULL) + { + throw std::bad_alloc(); + } + } +} + +void sefs_query::inode(ino64_t ino) +{ + _inode = ino; +} + +void sefs_query::dev(const char *str) throw(std::bad_alloc) +{ + if (str != _dev) + { + free(_dev); + _dev = NULL; + if (str != NULL && *str != '\0' && (_dev = strdup(str)) == NULL) + { + throw std::bad_alloc(); + } + } +} + +void sefs_query::regex(bool r) +{ + _regex = r; +} + +/******************** private functions below ********************/ + +void sefs_query::compile() throw(std::bad_alloc, std::invalid_argument) +{ + if (_recompiled) + { + regfree(_reuser); + regfree(_rerole); + regfree(_retype); + regfree(_rerange); + regfree(_repath); + regfree(_redev); + } + else + { + if ((_reuser = static_cast < regex_t * >(malloc(sizeof(*_reuser)))) == NULL) + { + throw std::bad_alloc(); + } + if ((_rerole = static_cast < regex_t * >(malloc(sizeof(*_rerole)))) == NULL) + { + throw std::bad_alloc(); + } + if ((_retype = static_cast < regex_t * >(malloc(sizeof(*_retype)))) == NULL) + { + throw std::bad_alloc(); + } + if ((_rerange = static_cast < regex_t * >(malloc(sizeof(*_rerange)))) == NULL) + { + throw std::bad_alloc(); + } + if ((_repath = static_cast < regex_t * >(malloc(sizeof(*_repath)))) == NULL) + { + throw std::bad_alloc(); + } + if ((_redev = static_cast < regex_t * >(malloc(sizeof(*_redev)))) == NULL) + { + throw std::bad_alloc(); + } + } + char errbuf[1024] = { '\0' }; + int regretv; + const char *s = (_user == NULL ? "" : _user); + if ((regretv = regcomp(_reuser, s, REG_EXTENDED | REG_NOSUB))) + { + regerror(regretv, _reuser, errbuf, 1024); + throw std::invalid_argument(errbuf); + } + s = (_role == NULL ? "" : _role); + if ((regretv = regcomp(_rerole, s, REG_EXTENDED | REG_NOSUB))) + { + regerror(regretv, _reuser, errbuf, 1024); + throw std::invalid_argument(errbuf); + } + s = (_type == NULL ? "" : _type); + if ((regretv = regcomp(_retype, s, REG_EXTENDED | REG_NOSUB))) + { + regerror(regretv, _reuser, errbuf, 1024); + throw std::invalid_argument(errbuf); + } + s = (_range == NULL ? "" : _range); + if ((regretv = regcomp(_rerange, s, REG_EXTENDED | REG_NOSUB))) + { + regerror(regretv, _reuser, errbuf, 1024); + throw std::invalid_argument(errbuf); + } + s = (_path == NULL ? "" : _path); + if ((regretv = regcomp(_repath, s, REG_EXTENDED | REG_NOSUB))) + { + regerror(regretv, _reuser, errbuf, 1024); + throw std::invalid_argument(errbuf); + } + s = (_dev == NULL ? "" : _dev); + if ((regretv = regcomp(_redev, s, REG_EXTENDED | REG_NOSUB))) + { + regerror(regretv, _reuser, errbuf, 1024); + throw std::invalid_argument(errbuf); + } + _recompiled = true; +} + +/******************** C functions below ********************/ + +sefs_query_t *sefs_query_create() +{ + return new sefs_query(); +} + +void sefs_query_destroy(sefs_query_t ** query) +{ + if (query != NULL && *query != NULL) + { + delete(*query); + *query = NULL; + } +} + +int sefs_query_set_user(sefs_query_t * query, const char *name) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + try + { + query->user(name); + } + catch(...) + { + return -1; + } + return 0; +} + +int sefs_query_set_role(sefs_query_t * query, const char *name) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + try + { + query->role(name); + } + catch(...) + { + return -1; + } + return 0; +} + +int sefs_query_set_type(sefs_query_t * query, const char *name, bool indirect) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + try + { + query->type(name, indirect); + } + catch(...) + { + return -1; + } + return 0; +} + +int sefs_query_set_range(sefs_query_t * query, const char *range, int match) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + query->range(range, match); + return 0; +} + +int sefs_query_set_object_class(sefs_query_t * query, uint32_t objclass) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + query->objectClass(objclass); + return 0; +} + +int sefs_query_set_object_class_str(sefs_query_t * query, const char *name) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + query->objectClass(name); + return 0; +} + +int sefs_query_set_path(sefs_query_t * query, const char *path) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + try + { + query->path(path); + } + catch(...) + { + return -1; + } + return 0; +} + +int sefs_query_set_inode(sefs_query_t * query, ino64_t inode) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + query->inode(inode); + return 0; +} + +int sefs_query_set_dev(sefs_query_t * query, const char *dev) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + try + { + query->dev(dev); + } + catch(...) + { + return -1; + } + return 0; +} + +int sefs_query_set_regex(sefs_query_t * query, bool regex) +{ + if (query == NULL) + { + errno = EINVAL; + return -1; + } + query->regex(regex); + return 0; +} |