2 * This file is part of buxton.
4 * Copyright (C) 2013 Intel Corporation
6 * buxton is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
19 #include <sys/inotify.h>
22 #include "buxtonkey.h"
23 #include "configurator.h"
30 static Hashmap *_smackrules = NULL;
31 /* set to true unless Smack support is not detected by the daemon */
32 static bool have_smack = true;
34 #define smack_check() do { if (!have_smack) { return true; } } while (0);
37 bool buxton_smack_enabled(void)
42 bool buxton_cache_smack_rules(void)
46 FILE *load_file = NULL;
47 char *rule_pair = NULL;
49 bool have_rules = false;
53 hashmap_free(_smackrules);
56 _smackrules = hashmap_new(string_hash_func, string_compare_func);
62 /* FIXME: should check for a proper mount point instead */
63 if ((stat(SMACK_MOUNT_DIR, &buf) == -1) || !S_ISDIR(buf.st_mode)) {
64 buxton_log("Smack filesystem not detected; disabling Smack checks\n");
69 load_file = fopen(buxton_smack_load_file(), "r");
74 buxton_log("Smackfs load2 file not found; disabling Smack checks\n");
78 buxton_log("fopen(): %m\n");
87 BuxtonKeyAccessType *accesstype;
89 char subject[SMACK_LABEL_LEN+1] = { 0, };
90 char object[SMACK_LABEL_LEN+1] = { 0, };
91 char access[ACC_LEN] = { 0, };
93 /* read contents from load2 */
94 chars = fscanf(load_file, "%s %s %s\n", subject, object, access);
96 if (ferror(load_file)) {
97 buxton_log("fscanf(): %m\n");
102 if (!have_rules && chars == EOF && feof(load_file)) {
103 buxton_debug("No loaded Smack rules found\n");
108 buxton_log("Corrupt load file detected\n");
115 r = asprintf(&rule_pair, "%s %s", subject, object);
120 accesstype = malloc0(sizeof(BuxtonKeyAccessType));
125 *accesstype = ACCESS_NONE;
127 if (strchr(access, 'r')) {
128 *accesstype |= ACCESS_READ;
131 if (strchr(access, 'w')) {
132 *accesstype |= ACCESS_WRITE;
135 hashmap_put(_smackrules, rule_pair, accesstype);
137 } while (!feof(load_file));
147 bool buxton_check_smack_access(BuxtonString *subject, BuxtonString *object, BuxtonKeyAccessType request)
151 _cleanup_free_ char *key = NULL;
153 BuxtonKeyAccessType *access;
157 assert((request == ACCESS_READ) || (request == ACCESS_WRITE));
160 buxton_debug("Subject: %s\n", subject->value);
161 buxton_debug("Object: %s\n", object->value);
163 /* check the builtin Smack rules first */
164 if (streq(subject->value, "*")) {
168 if (streq(object->value, "@") || streq(subject->value, "@")) {
172 if (streq(object->value, "*")) {
176 if (streq(subject->value, object->value)) {
180 if (request == ACCESS_READ) {
181 if (streq(object->value, "_")) {
184 if (streq(subject->value, "^")) {
189 /* finally, check the loaded rules */
190 r = asprintf(&key, "%s %s", subject->value, object->value);
195 buxton_debug("Key: %s\n", key);
197 access = hashmap_get(_smackrules, key);
199 /* A null value is not an error, since clients may try to
200 * read/write keys with labels that are not in the loaded
201 * rule set. In this situation, access is simply denied,
202 * because there are no further rules to consider.
204 buxton_debug("Value of key '%s' is NULL\n", key);
208 /* After debugging, change this code to: */
209 /* return ((*access) & request); */
211 buxton_debug("Value: %x\n", *access);
214 if (request == ACCESS_READ && (*access) & request) {
215 buxton_debug("Read access granted!\n");
219 if (request == ACCESS_WRITE && ((*access) & ACCESS_READ && (*access) & ACCESS_WRITE)) {
220 buxton_debug("Write access granted!\n");
224 buxton_debug("Access denied!\n");
228 int buxton_watch_smack_rules(void)
237 fd = inotify_init1(IN_NONBLOCK);
239 buxton_log("inotify_init(): %m\n");
242 if (inotify_add_watch(fd, buxton_smack_load_file(), IN_CLOSE_WRITE) < 0) {
243 buxton_log("inotify_add_watch(): %m\n");
250 * Editor modelines - http://www.wireshark.org/tools/modelines.html
255 * indent-tabs-mode: t
258 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
259 * :indentSize=8:tabSize=8:noTabs=false: