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