From 47be9ff57e72906660bb62a515222f482131e1fb Mon Sep 17 00:00:00 2001 From: Miroslav Grepl Date: Fri, 11 Apr 2014 09:37:53 +0200 Subject: Create setools-3.3.7 git repo --- libsefs/tests/attic/fuse_non_mls.c | 195 +++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 libsefs/tests/attic/fuse_non_mls.c (limited to 'libsefs/tests/attic/fuse_non_mls.c') diff --git a/libsefs/tests/attic/fuse_non_mls.c b/libsefs/tests/attic/fuse_non_mls.c new file mode 100644 index 0000000..30b3df4 --- /dev/null +++ b/libsefs/tests/attic/fuse_non_mls.c @@ -0,0 +1,195 @@ +/* + * The approach described below does not actually work. Apparantly, + * SELinux will assign a context based upond the underlying policy + * (typically from a fs_use statement); the operating system will not + * invoke this file's fuse_getxattr() function at all. Thus it is + * not possible to use FUSE to create a virtual filesystem with + * arbitrary file contexts. + */ + +/** + * @file + * + * Use the FUSE (filesystem in userspace) to create a virtual + * filesystem for libsefs tests. This particular filesystem will not + * contain MLS contexts. + * + * @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 + +#define FUSE_USE_VERSION 25 + +#define XATTR_NAME_SELINUX "security.selinux" + +#include +#include + +#include +#include +#include +#include + +/*************** definition of the virtual filesystem ***************/ + +static apol_bst_t *bst = NULL; + +struct fuse_entry +{ + const char *path; + mode_t mode; + const char *context; +}; + +static struct fuse_entry fs[] = { + {"/", S_IFDIR, "user_r:object_r:system_t"}, + {"/foo", S_IFREG, "user_r:object_r:system_t"}, + {NULL, 0, NULL} +}; + +static int fuse_comp(const void *a, const void *b, void *data __attribute__ ((unused))) +{ + const struct fuse_entry *f1 = (const struct fuse_entry *)a; + const struct fuse_entry *f2 = (const struct fuse_entry *)b; + return strcmp(f1->path, f2->path); +} + +/*************** required fuse functions ***************/ + +static int fuse_getattr(const char *path, struct stat *stbuf) +{ + struct fuse_entry key = { path, 0, NULL }; + struct fuse_entry *e; + memset(stbuf, 0, sizeof(*stbuf)); + if (apol_bst_get_element(bst, &key, NULL, (void **)&e) < 0) { + return -ENOENT; + } + if (e->mode == S_IFDIR) { + stbuf->st_mode = S_IFDIR | 0755; + stbuf->st_nlink = 2; + } else { + stbuf->st_mode = e->mode | 0444; + stbuf->st_nlink = 1; + } + return 0; +} + +static int fuse_getxattr(const char *path, const char *attrib_name, char *buf, size_t buflen) +{ + struct fuse_entry key = { path, 0, NULL }; + struct fuse_entry *e; + if (apol_bst_get_element(bst, &key, NULL, (void **)&e) < 0) { + return -ENOENT; + } + if (strcmp(attrib_name, XATTR_NAME_SELINUX) != 0) { + return -ENOSYS; + } + strncpy(buf, e->context, buflen); + return strlen(e->context) + 1; +} + +static int fuse_open(const char *path, struct fuse_file_info *fi __attribute__ ((unused))) +{ + struct fuse_entry key = { path, 0, NULL }; + struct fuse_entry *e; + if (apol_bst_get_element(bst, &key, NULL, (void **)&e) < 0) { + return -ENOENT; + } + + return -EACCES; +} + +static int fuse_read(const char *path, char *buf __attribute__ ((unused)), size_t size, off_t offset __attribute__ ((unused)), + struct fuse_file_info *fi __attribute__ ((unused))) +{ + struct fuse_entry key = { path, 0, NULL }; + struct fuse_entry *e; + if (apol_bst_get_element(bst, &key, NULL, (void **)&e) < 0) { + return -ENOENT; + } + return size; +} + +struct stem_data +{ + const char *stem; + void *buf; + fuse_fill_dir_t filler; +}; + +static int fuse_stem_match(void *a, void *data) +{ + const struct fuse_entry *e = (const struct fuse_entry *)a; + struct stem_data *sd = (struct stem_data *)data; + + size_t e_len = strlen(e->path); + size_t stem_len = strlen(sd->stem); + if (e_len <= stem_len) { + /* entry's path is too longer than the requested path */ + return 0; + } + if (strncmp(e->path, sd->stem, stem_len) != 0) { + /* stem is not the beginning of entry's path */ + return 0; + } + const char *file = e->path + 1; + if (strchr(file, '/') != NULL) { + /* member of a subdirectory of stem */ + return 0; + } + return -sd->filler(sd->buf, file, NULL, 0); +} + +static int fuse_readdir(const char *path, void *buf, fuse_fill_dir_t filler, + off_t offset __attribute__ ((unused)), struct fuse_file_info *fi __attribute__ ((unused))) +{ + struct fuse_entry key = { path, 0, NULL }; + struct fuse_entry *e; + if (apol_bst_get_element(bst, &key, NULL, (void **)&e) < 0) { + return -ENOENT; + } + + filler(buf, ".", NULL, 0); + filler(buf, "..", NULL, 0); + struct stem_data sd = { path, buf, filler }; + return -apol_bst_inorder_map(bst, fuse_stem_match, &sd); +} + +int main(int argc, char *argv[]) +{ + if ((bst = apol_bst_create(fuse_comp, NULL)) < 0) { + return 1; + } + for (size_t i = 0; fs[i].path != NULL; i++) { + if (apol_bst_insert(bst, &fs[i], NULL) < 0) { + return 1; + } + } + + struct fuse_operations non_mls_oper = { + .getattr = fuse_getattr, + .getxattr = fuse_getxattr, + .open = fuse_open, + .read = fuse_read, + .readdir = fuse_readdir, + }; + return fuse_main(argc, argv, &non_mls_oper); +} -- cgit