label.c revision 35b01083fe5e34cbd318a78ef9b1a13432ae24d9
1/* 2 * Generalized labeling frontend for userspace object managers. 3 * 4 * Author : Eamon Walsh <ewalsh@epoch.ncsc.mil> 5 */ 6 7#include <sys/types.h> 8#include <ctype.h> 9#include <errno.h> 10#include <stdio.h> 11#include <stdlib.h> 12#include <string.h> 13#include <selinux/selinux.h> 14#include "callbacks.h" 15#include "label_internal.h" 16 17#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 18 19typedef int (*selabel_initfunc)(struct selabel_handle *rec, 20 struct selinux_opt *opts, unsigned nopts); 21 22static selabel_initfunc initfuncs[] = { 23 &selabel_file_init, 24 NULL, 25 NULL, 26 NULL, 27 &selabel_property_init, 28}; 29 30/* 31 * Validation functions 32 */ 33 34static inline int selabel_is_validate_set(struct selinux_opt *opts, unsigned n) 35{ 36 while (n--) 37 if (opts[n].type == SELABEL_OPT_VALIDATE) 38 return !!opts[n].value; 39 40 return 0; 41} 42 43int selabel_validate(struct selabel_handle *rec, 44 struct selabel_lookup_rec *contexts) 45{ 46 int rc = 0; 47 48 if (!rec->validating || contexts->validated) 49 goto out; 50 51 rc = selinux_validate(&contexts->ctx_raw); 52 if (rc < 0) 53 goto out; 54 55 contexts->validated = 1; 56out: 57 return rc; 58} 59 60/* 61 * Public API 62 */ 63 64struct selabel_handle *selabel_open(unsigned int backend, 65 struct selinux_opt *opts, unsigned nopts) 66{ 67 struct selabel_handle *rec = NULL; 68 69 if (backend >= ARRAY_SIZE(initfuncs)) { 70 errno = EINVAL; 71 goto out; 72 } 73 74 if (initfuncs[backend] == NULL) 75 goto out; 76 77 rec = (struct selabel_handle *)malloc(sizeof(*rec)); 78 if (!rec) 79 goto out; 80 81 memset(rec, 0, sizeof(*rec)); 82 rec->backend = backend; 83 rec->validating = selabel_is_validate_set(opts, nopts); 84 85 if ((*initfuncs[backend])(rec, opts, nopts)) { 86 free(rec); 87 rec = NULL; 88 } 89 90out: 91 return rec; 92} 93 94static struct selabel_lookup_rec * 95selabel_lookup_common(struct selabel_handle *rec, int translating, 96 const char *key, int type) 97{ 98 struct selabel_lookup_rec *lr; 99 lr = rec->func_lookup(rec, key, type); 100 if (!lr) 101 return NULL; 102 103 return lr; 104} 105 106int selabel_lookup(struct selabel_handle *rec, security_context_t *con, 107 const char *key, int type) 108{ 109 struct selabel_lookup_rec *lr; 110 111 lr = selabel_lookup_common(rec, 1, key, type); 112 if (!lr) 113 return -1; 114 115 *con = strdup(lr->ctx_raw); 116 return *con ? 0 : -1; 117} 118 119void selabel_close(struct selabel_handle *rec) 120{ 121 rec->func_close(rec); 122 free(rec); 123} 124 125void selabel_stats(struct selabel_handle *rec) 126{ 127 rec->func_stats(rec); 128} 129