blob: 82d25d0aec5bd9e654b1d98b01b9d1bda0400f4f [file] [log] [blame]
Stephen Smalleyf0740362012-01-04 12:30:47 -05001/*
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,
Stephen Smalleya2e47cd2012-06-11 13:35:34 -040020 const struct selinux_opt *opts,
21 unsigned nopts);
Stephen Smalleyf0740362012-01-04 12:30:47 -050022
23static selabel_initfunc initfuncs[] = {
24 &selabel_file_init,
Stephen Smalley35b01082012-04-04 10:06:13 -040025 NULL,
26 NULL,
27 NULL,
28 &selabel_property_init,
Stephen Smalleyf0740362012-01-04 12:30:47 -050029};
30
31/*
32 * Validation functions
33 */
34
Stephen Smalleya2e47cd2012-06-11 13:35:34 -040035static inline int selabel_is_validate_set(const struct selinux_opt *opts,
36 unsigned n)
Stephen Smalleyf0740362012-01-04 12:30:47 -050037{
38 while (n--)
39 if (opts[n].type == SELABEL_OPT_VALIDATE)
40 return !!opts[n].value;
41
42 return 0;
43}
44
45int 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;
58out:
59 return rc;
60}
61
62/*
63 * Public API
64 */
65
66struct selabel_handle *selabel_open(unsigned int backend,
Stephen Smalleya2e47cd2012-06-11 13:35:34 -040067 const struct selinux_opt *opts,
68 unsigned nopts)
Stephen Smalleyf0740362012-01-04 12:30:47 -050069{
70 struct selabel_handle *rec = NULL;
71
72 if (backend >= ARRAY_SIZE(initfuncs)) {
73 errno = EINVAL;
74 goto out;
75 }
76
Stephen Smalley35b01082012-04-04 10:06:13 -040077 if (initfuncs[backend] == NULL)
78 goto out;
79
Stephen Smalleyf0740362012-01-04 12:30:47 -050080 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
93out:
94 return rec;
95}
96
97static struct selabel_lookup_rec *
98selabel_lookup_common(struct selabel_handle *rec, int translating,
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
109int 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, 1, key, type);
115 if (!lr)
116 return -1;
117
118 *con = strdup(lr->ctx_raw);
119 return *con ? 0 : -1;
120}
121
122void selabel_close(struct selabel_handle *rec)
123{
124 rec->func_close(rec);
125 free(rec);
126}
127
128void selabel_stats(struct selabel_handle *rec)
129{
130 rec->func_stats(rec);
131}