1#include <stdlib.h>
2
3#include "debug.h"
4#include <sepol/policydb/policydb.h>
5#include "policydb_internal.h"
6
7/* Policy file interfaces. */
8
9int sepol_policy_file_create(sepol_policy_file_t ** pf)
10{
11	*pf = calloc(1, sizeof(sepol_policy_file_t));
12	if (!(*pf))
13		return -1;
14	return 0;
15}
16
17void sepol_policy_file_set_mem(sepol_policy_file_t * spf,
18			       char *data, size_t len)
19{
20	struct policy_file *pf = &spf->pf;
21	if (!len) {
22		pf->type = PF_LEN;
23		return;
24	}
25	pf->type = PF_USE_MEMORY;
26	pf->data = data;
27	pf->len = len;
28	pf->size = len;
29	return;
30}
31
32void sepol_policy_file_set_fp(sepol_policy_file_t * spf, FILE * fp)
33{
34	struct policy_file *pf = &spf->pf;
35	pf->type = PF_USE_STDIO;
36	pf->fp = fp;
37	return;
38}
39
40int sepol_policy_file_get_len(sepol_policy_file_t * spf, size_t * len)
41{
42	struct policy_file *pf = &spf->pf;
43	if (pf->type != PF_LEN)
44		return -1;
45	*len = pf->len;
46	return 0;
47}
48
49void sepol_policy_file_set_handle(sepol_policy_file_t * pf,
50				  sepol_handle_t * handle)
51{
52	pf->pf.handle = handle;
53}
54
55void sepol_policy_file_free(sepol_policy_file_t * pf)
56{
57	free(pf);
58}
59
60/* Policydb interfaces. */
61
62int sepol_policydb_create(sepol_policydb_t ** sp)
63{
64	policydb_t *p;
65	*sp = malloc(sizeof(sepol_policydb_t));
66	if (!(*sp))
67		return -1;
68	p = &(*sp)->p;
69	if (policydb_init(p)) {
70		free(*sp);
71		return -1;
72	}
73	return 0;
74}
75
76hidden_def(sepol_policydb_create)
77
78void sepol_policydb_free(sepol_policydb_t * p)
79{
80	if (!p)
81		return;
82	policydb_destroy(&p->p);
83	free(p);
84}
85
86hidden_def(sepol_policydb_free)
87
88int sepol_policy_kern_vers_min(void)
89{
90	return POLICYDB_VERSION_MIN;
91}
92
93int sepol_policy_kern_vers_max(void)
94{
95	return POLICYDB_VERSION_MAX;
96}
97
98int sepol_policydb_set_typevers(sepol_policydb_t * sp, unsigned int type)
99{
100	struct policydb *p = &sp->p;
101	switch (type) {
102	case POLICY_KERN:
103		p->policyvers = POLICYDB_VERSION_MAX;
104		break;
105	case POLICY_BASE:
106	case POLICY_MOD:
107		p->policyvers = MOD_POLICYDB_VERSION_MAX;
108		break;
109	default:
110		return -1;
111	}
112	p->policy_type = type;
113	return 0;
114}
115
116int sepol_policydb_set_vers(sepol_policydb_t * sp, unsigned int vers)
117{
118	struct policydb *p = &sp->p;
119	switch (p->policy_type) {
120	case POLICY_KERN:
121		if (vers < POLICYDB_VERSION_MIN || vers > POLICYDB_VERSION_MAX)
122			return -1;
123		break;
124	case POLICY_BASE:
125	case POLICY_MOD:
126		if (vers < MOD_POLICYDB_VERSION_MIN
127		    || vers > MOD_POLICYDB_VERSION_MAX)
128			return -1;
129		break;
130	default:
131		return -1;
132	}
133	p->policyvers = vers;
134	return 0;
135}
136
137int sepol_policydb_set_handle_unknown(sepol_policydb_t * sp,
138				      unsigned int handle_unknown)
139{
140	struct policydb *p = &sp->p;
141
142	switch (handle_unknown) {
143	case SEPOL_DENY_UNKNOWN:
144	case SEPOL_REJECT_UNKNOWN:
145	case SEPOL_ALLOW_UNKNOWN:
146		break;
147	default:
148		return -1;
149	}
150
151	p->handle_unknown = handle_unknown;
152	return 0;
153}
154
155int sepol_policydb_set_target_platform(sepol_policydb_t * sp,
156				      int target_platform)
157{
158	struct policydb *p = &sp->p;
159
160	switch (target_platform) {
161	case SEPOL_TARGET_SELINUX:
162	case SEPOL_TARGET_XEN:
163		break;
164	default:
165		return -1;
166	}
167
168	p->target_platform = target_platform;
169	return 0;
170}
171
172int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf)
173{
174	return policydb_read(&p->p, &pf->pf, 0);
175}
176
177int sepol_policydb_write(sepol_policydb_t * p, sepol_policy_file_t * pf)
178{
179	return policydb_write(&p->p, &pf->pf);
180}
181
182int sepol_policydb_from_image(sepol_handle_t * handle,
183			      void *data, size_t len, sepol_policydb_t * p)
184{
185	return policydb_from_image(handle, data, len, &p->p);
186}
187
188int sepol_policydb_to_image(sepol_handle_t * handle,
189			    sepol_policydb_t * p, void **newdata,
190			    size_t * newlen)
191{
192	return policydb_to_image(handle, &p->p, newdata, newlen);
193}
194
195int sepol_policydb_mls_enabled(const sepol_policydb_t * p)
196{
197
198	return p->p.mls;
199}
200
201/*
202 * Enable compatibility mode for SELinux network checks iff
203 * the packet class is not defined in the policy.
204 */
205#define PACKET_CLASS_NAME "packet"
206int sepol_policydb_compat_net(const sepol_policydb_t * p)
207{
208	return (hashtab_search(p->p.p_classes.table, PACKET_CLASS_NAME) ==
209		NULL);
210}
211