1 /* Copyright (C) 2005 Red Hat, Inc. */
2 
3 struct semanage_bool;
4 struct semanage_bool_key;
5 typedef struct semanage_bool record_t;
6 typedef struct semanage_bool_key record_key_t;
7 #define DBASE_RECORD_DEFINED
8 
9 struct dbase_activedb;
10 typedef struct dbase_activedb dbase_t;
11 #define DBASE_DEFINED
12 
13 #include <stdlib.h>
14 #include <string.h>
15 #include <selinux/selinux.h>
16 #include <semanage/handle.h>
17 #include "boolean_internal.h"
18 #include "database_activedb.h"
19 #include "parse_utils.h"
20 #include "debug.h"
21 
bool_read_list(semanage_handle_t * handle,semanage_bool_t *** booleans,unsigned int * count)22 static int bool_read_list(semanage_handle_t * handle,
23 			  semanage_bool_t *** booleans, unsigned int *count)
24 {
25 
26 	semanage_bool_t **tmp_booleans = NULL;
27 	unsigned int tmp_count = 0;
28 	int i;
29 
30 	char **names = NULL;
31 	int len = 0;
32 
33 	/* Fetch boolean names */
34 	if (security_get_boolean_names(&names, &len) < 0) {
35 		ERR(handle, "could not get list of boolean names");
36 		goto err;
37 	}
38 
39 	/* Allocate a sufficiently large array */
40 	tmp_booleans = malloc(sizeof(semanage_bool_t *) * len);
41 	if (tmp_booleans == NULL)
42 		goto omem;
43 
44 	/* Create records one by one */
45 	for (i = 0; i < len; i++) {
46 
47 		int value;
48 
49 		if (semanage_bool_create(handle, &tmp_booleans[i]) < 0)
50 			goto err;
51 		tmp_count++;
52 
53 		if (semanage_bool_set_name(handle,
54 					   tmp_booleans[i], names[i]) < 0)
55 			goto err;
56 
57 		value = security_get_boolean_active(names[i]);
58 		if (value < 0) {
59 			ERR(handle, "could not get the value "
60 			    "for boolean %s", names[i]);
61 			goto err;
62 		}
63 
64 		semanage_bool_set_value(tmp_booleans[i], value);
65 	}
66 
67 	/* Success */
68 	for (i = 0; i < len; i++)
69 		free(names[i]);
70 	free(names);
71 	*booleans = tmp_booleans;
72 	*count = tmp_count;
73 	return STATUS_SUCCESS;
74 
75 	/* Failure */
76       omem:
77 	ERR(handle, "out of memory");
78 
79       err:
80 	ERR(handle, "could not read boolean list");
81 	for (i = 0; i < len; i++)
82 		free(names[i]);
83 	free(names);
84 	for (i = 0; (unsigned int)i < tmp_count; i++)
85 		semanage_bool_free(tmp_booleans[i]);
86 	free(tmp_booleans);
87 	return STATUS_ERR;
88 }
89 
bool_commit_list(semanage_handle_t * handle,semanage_bool_t ** booleans,unsigned int count)90 static int bool_commit_list(semanage_handle_t * handle,
91 			    semanage_bool_t ** booleans, unsigned int count)
92 {
93 
94 	SELboolean *blist = NULL;
95 	const char *name;
96 	unsigned int bcount = 0;
97 	unsigned int i;
98 	int curvalue, newvalue;
99 
100 	/* Allocate a sufficiently large array */
101 	blist = malloc(sizeof(SELboolean) * count);
102 	if (blist == NULL)
103 		goto omem;
104 
105 	/* Populate array */
106 	for (i = 0; i < count; i++) {
107 		name = semanage_bool_get_name(booleans[i]);
108 		if (!name)
109 			goto omem;
110 		newvalue = semanage_bool_get_value(booleans[i]);
111 		curvalue = security_get_boolean_active(name);
112 		if (newvalue == curvalue)
113 			continue;
114 		blist[bcount].name = strdup(name);
115 		if (blist[bcount].name == NULL)
116 			goto omem;
117 		blist[bcount].value = newvalue;
118 		bcount++;
119 	}
120 
121 	/* Commit */
122 	if (security_set_boolean_list(bcount, blist, 0) < 0) {
123 		ERR(handle, "libselinux commit failed");
124 		goto err;
125 	}
126 
127 	for (i = 0; i < bcount; i++)
128 		free(blist[i].name);
129 	free(blist);
130 	return STATUS_SUCCESS;
131 
132       omem:
133 	ERR(handle, "out of memory");
134 
135       err:
136 	ERR(handle, "could not commit boolean list");
137 	for (i = 0; i < bcount; i++)
138 		free(blist[i].name);
139 	free(blist);
140 	return STATUS_ERR;
141 }
142 
143 /* BOOL RECORD: ACTIVEDB extension: method table */
144 record_activedb_table_t SEMANAGE_BOOL_ACTIVEDB_RTABLE = {
145 	.read_list = bool_read_list,
146 	.commit_list = bool_commit_list,
147 };
148 
bool_activedb_dbase_init(semanage_handle_t * handle,dbase_config_t * dconfig)149 int bool_activedb_dbase_init(semanage_handle_t * handle,
150 			     dbase_config_t * dconfig)
151 {
152 
153 	if (dbase_activedb_init(handle,
154 				&SEMANAGE_BOOL_RTABLE,
155 				&SEMANAGE_BOOL_ACTIVEDB_RTABLE,
156 				&dconfig->dbase) < 0)
157 		return STATUS_ERR;
158 
159 	dconfig->dtable = &SEMANAGE_ACTIVEDB_DTABLE;
160 	return STATUS_SUCCESS;
161 }
162 
bool_activedb_dbase_release(dbase_config_t * dconfig)163 void bool_activedb_dbase_release(dbase_config_t * dconfig)
164 {
165 
166 	dbase_activedb_release(dconfig->dbase);
167 }
168