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