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