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