handle.c revision a401a8762294d90e17fcaf83f4447ac6f246ba70
1/* Author: Joshua Brindle <jbrindle@tresys.co
2 *	   Jason Tang	  <jtang@tresys.com>
3 *
4 * Copyright (C) 2004-2005 Tresys Technology, LLC
5 * Copyright (C) 2005 Red Hat, Inc.
6 *
7 *  This library is free software; you can redistribute it and/or
8 *  modify it under the terms of the GNU Lesser General Public
9 *  License as published by the Free Software Foundation; either
10 *  version 2.1 of the License, or (at your option) any later version.
11 *
12 *  This library is distributed in the hope that it will be useful,
13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 *  Lesser General Public License for more details.
16 *
17 *  You should have received a copy of the GNU Lesser General Public
18 *  License along with this library; if not, write to the Free Software
19 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22/* This file implements only the publicly-visible handle functions to libsemanage. */
23
24#include <selinux/selinux.h>
25
26#include <stdarg.h>
27#include <assert.h>
28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
31#include <sys/time.h>
32
33#include "direct_api.h"
34#include "handle.h"
35#include "debug.h"
36#include "semanage_conf.h"
37#include "semanage_store.h"
38
39#define SEMANAGE_COMMIT_READ_WAIT 5
40
41semanage_handle_t *semanage_handle_create(void)
42{
43	semanage_handle_t *sh = NULL;
44	const char *conf_name = NULL;
45
46	/* Allocate handle */
47	if ((sh = calloc(1, sizeof(semanage_handle_t))) == NULL)
48		goto err;
49
50	if ((conf_name = semanage_conf_path()) == NULL)
51		goto err;
52
53	if ((sh->conf = semanage_conf_parse(conf_name)) == NULL)
54		goto err;
55
56	/* Link to sepol handle */
57	sh->sepolh = sepol_handle_create();
58	if (!sh->sepolh)
59		goto err;
60	sepol_msg_set_callback(sh->sepolh, semanage_msg_relay_handler, sh);
61
62	/* By default do not rebuild the policy on commit
63	 * If any changes are made, this flag is ignored */
64	sh->do_rebuild = 0;
65
66	/* By default always reload policy after commit if SELinux is enabled. */
67	sh->do_reload = (is_selinux_enabled() > 0);
68
69	/* By default do not create store */
70	sh->create_store = 0;
71
72	/* Set timeout: some default value for now, later use config */
73	sh->timeout = SEMANAGE_COMMIT_READ_WAIT;
74
75	/* Set callback */
76	sh->msg_callback = semanage_msg_default_handler;
77	sh->msg_callback_arg = NULL;
78
79	return sh;
80
81      err:
82	semanage_handle_destroy(sh);
83	return NULL;
84}
85
86void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild)
87{
88
89	assert(sh != NULL);
90
91	sh->do_rebuild = do_rebuild;
92	return;
93}
94
95void semanage_set_reload(semanage_handle_t * sh, int do_reload)
96{
97
98	assert(sh != NULL);
99
100	sh->do_reload = do_reload;
101	return;
102}
103
104void semanage_set_create_store(semanage_handle_t * sh, int create_store)
105{
106
107	assert(sh != NULL);
108
109	sh->create_store = create_store;
110	return;
111}
112
113void semanage_set_disable_dontaudit(semanage_handle_t * sh, int disable_dontaudit)
114{
115	assert(sh != NULL);
116
117	sepol_set_disable_dontaudit(sh->sepolh, disable_dontaudit);
118	return;
119}
120
121int semanage_is_connected(semanage_handle_t * sh)
122{
123	assert(sh != NULL);
124	return sh->is_connected;
125}
126
127void semanage_select_store(semanage_handle_t * sh, char *storename,
128			   enum semanage_connect_type storetype)
129{
130
131	assert(sh != NULL);
132
133	/* This just sets the storename to what the user requests, no
134	   verification of existance will be done until connect */
135	sh->conf->store_path = strdup(storename);
136	assert(sh->conf->store_path); /* no way to return failure */
137	sh->conf->store_type = storetype;
138
139	return;
140}
141
142int semanage_is_managed(semanage_handle_t * sh)
143{
144	assert(sh != NULL);
145	if (sh->is_connected) {
146		ERR(sh, "Already connected.");
147		return -1;
148	}
149	switch (sh->conf->store_type) {
150	case SEMANAGE_CON_DIRECT:
151		return semanage_direct_is_managed(sh);
152	default:
153		ERR(sh,
154		    "The connection type specified within your semanage.conf file has not been implemented yet.");
155		/* fall through */
156	}
157	return -1;
158}
159
160int semanage_mls_enabled(semanage_handle_t * sh)
161{
162	assert(sh != NULL);
163	switch (sh->conf->store_type) {
164	case SEMANAGE_CON_DIRECT:
165		return semanage_direct_mls_enabled(sh);
166	default:
167		ERR(sh,
168		    "The connection type specified within your semanage.conf file has not been implemented yet.");
169		/* fall through */
170	}
171	return -1;
172}
173
174int semanage_connect(semanage_handle_t * sh)
175{
176	assert(sh != NULL);
177	switch (sh->conf->store_type) {
178	case SEMANAGE_CON_DIRECT:{
179			if (semanage_direct_connect(sh) < 0) {
180				return -1;
181			}
182			break;
183		}
184	default:{
185			ERR(sh,
186			    "The connection type specified within your semanage.conf file has not been implemented yet.");
187			return -1;
188		}
189	}
190	sh->is_connected = 1;
191	return 0;
192}
193
194int semanage_access_check(semanage_handle_t * sh)
195{
196	assert(sh != NULL);
197	switch (sh->conf->store_type) {
198	case SEMANAGE_CON_DIRECT:
199		return semanage_direct_access_check(sh);
200	default:
201		return -1;
202	}
203
204	return -1;		/* unreachable */
205}
206
207hidden_def(semanage_access_check)
208
209int semanage_disconnect(semanage_handle_t * sh)
210{
211	assert(sh != NULL && sh->funcs != NULL
212	       && sh->funcs->disconnect != NULL);
213	if (!sh->is_connected) {
214		return 0;
215	}
216	if (sh->funcs->disconnect(sh) < 0) {
217		return -1;
218	}
219	sh->is_in_transaction = 0;
220	sh->is_connected = 0;
221	sh->modules_modified = 0;
222	return 0;
223}
224
225void semanage_handle_destroy(semanage_handle_t * sh)
226{
227	if (sh == NULL)
228		return;
229
230	if (sh->funcs != NULL && sh->funcs->destroy != NULL)
231		sh->funcs->destroy(sh);
232	semanage_conf_destroy(sh->conf);
233	sepol_handle_destroy(sh->sepolh);
234	free(sh);
235}
236
237hidden_def(semanage_handle_destroy)
238
239/********************* public transaction functions *********************/
240int semanage_begin_transaction(semanage_handle_t * sh)
241{
242	assert(sh != NULL && sh->funcs != NULL
243	       && sh->funcs->begin_trans != NULL);
244	if (!sh->is_connected) {
245		ERR(sh, "Not connected.");
246		return -1;
247	}
248	if (sh->is_in_transaction) {
249		return 0;
250	}
251
252	if (sh->funcs->begin_trans(sh) < 0) {
253		return -1;
254	}
255	sh->is_in_transaction = 1;
256	return 0;
257}
258
259hidden_def(semanage_begin_transaction)
260
261int semanage_commit(semanage_handle_t * sh)
262{
263	int retval;
264	assert(sh != NULL && sh->funcs != NULL && sh->funcs->commit != NULL);
265	if (!sh->is_in_transaction) {
266		ERR(sh,
267		    "Will not commit because caller does not have a transaction lock yet.");
268		return -1;
269	}
270	retval = sh->funcs->commit(sh);
271	sh->is_in_transaction = 0;
272	sh->modules_modified = 0;
273	return retval;
274}
275