• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 typedef int (*selabel_initfunc)(struct selabel_handle *rec,
20 				struct selinux_opt *opts, unsigned nopts);
21 
22 static 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 
selabel_is_validate_set(struct selinux_opt * opts,unsigned n)34 static 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 
selabel_validate(struct selabel_handle * rec,struct selabel_lookup_rec * contexts)43 int 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;
56 out:
57 	return rc;
58 }
59 
60 /*
61  * Public API
62  */
63 
selabel_open(unsigned int backend,struct selinux_opt * opts,unsigned nopts)64 struct 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 
90 out:
91 	return rec;
92 }
93 
94 static struct selabel_lookup_rec *
selabel_lookup_common(struct selabel_handle * rec,int translating,const char * key,int type)95 selabel_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 
selabel_lookup(struct selabel_handle * rec,security_context_t * con,const char * key,int type)106 int 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 
selabel_close(struct selabel_handle * rec)119 void selabel_close(struct selabel_handle *rec)
120 {
121 	rec->func_close(rec);
122 	free(rec);
123 }
124 
selabel_stats(struct selabel_handle * rec)125 void selabel_stats(struct selabel_handle *rec)
126 {
127 	rec->func_stats(rec);
128 }
129