blob: fb8c266775c1ed83ba40bbc31da0695392d201b8 [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)) {
William Roberts0f520fa2015-10-22 12:26:01 -070089 free(rec->spec_file);
Stephen Smalleyf0740362012-01-04 12:30:47 -050090 free(rec);
91 rec = NULL;
92 }
93
94out:
95 return rec;
96}
97
98static struct selabel_lookup_rec *
Nick Kralevichb1ae15a2013-07-11 17:35:53 -070099selabel_lookup_common(struct selabel_handle *rec,
Stephen Smalleyf0740362012-01-04 12:30:47 -0500100 const char *key, int type)
101{
102 struct selabel_lookup_rec *lr;
103 lr = rec->func_lookup(rec, key, type);
104 if (!lr)
105 return NULL;
106
107 return lr;
108}
109
Stephen Smalleyab40ea92014-02-19 09:16:17 -0500110int selabel_lookup(struct selabel_handle *rec, char **con,
Stephen Smalleyf0740362012-01-04 12:30:47 -0500111 const char *key, int type)
112{
113 struct selabel_lookup_rec *lr;
114
Nick Kralevichb1ae15a2013-07-11 17:35:53 -0700115 lr = selabel_lookup_common(rec, key, type);
Stephen Smalleyf0740362012-01-04 12:30:47 -0500116 if (!lr)
117 return -1;
118
119 *con = strdup(lr->ctx_raw);
120 return *con ? 0 : -1;
121}
122
Stephen Smalley0e7340f2014-04-30 15:13:30 -0700123bool selabel_partial_match(struct selabel_handle *rec, const char *key)
124{
125 if (!rec->func_partial_match) {
126 /*
127 * If the label backend does not support partial matching,
128 * then assume a match is possible.
129 */
130 return true;
131 }
132 return rec->func_partial_match(rec, key);
133}
134
Stephen Smalleybe7f5e82014-06-12 12:21:13 -0400135int selabel_lookup_best_match(struct selabel_handle *rec, char **con,
136 const char *key, const char **aliases, int type)
137{
138 struct selabel_lookup_rec *lr;
139
140 if (!rec->func_lookup_best_match) {
141 errno = ENOTSUP;
142 return -1;
143 }
144
145 lr = rec->func_lookup_best_match(rec, key, aliases, type);
146 if (!lr)
147 return -1;
148
149 *con = strdup(lr->ctx_raw);
150 return *con ? 0 : -1;
151}
152
Stephen Smalley8b40b9c2015-08-05 11:35:23 -0400153enum selabel_cmp_result selabel_cmp(struct selabel_handle *h1,
154 struct selabel_handle *h2)
155{
156 if (!h1->func_cmp || h1->func_cmp != h2->func_cmp)
157 return SELABEL_INCOMPARABLE;
158
159 return h1->func_cmp(h1, h2);
160}
161
Stephen Smalleyf0740362012-01-04 12:30:47 -0500162void selabel_close(struct selabel_handle *rec)
163{
164 rec->func_close(rec);
William Roberts0f520fa2015-10-22 12:26:01 -0700165 free(rec->spec_file);
Stephen Smalleyf0740362012-01-04 12:30:47 -0500166 free(rec);
167}
168
169void selabel_stats(struct selabel_handle *rec)
170{
171 rec->func_stats(rec);
172}