1*2d543d20SAndroid Build Coastguard Worker /* Copyright (C) 2005 Red Hat, Inc. */
2*2d543d20SAndroid Build Coastguard Worker
3*2d543d20SAndroid Build Coastguard Worker struct semanage_user_base;
4*2d543d20SAndroid Build Coastguard Worker struct semanage_user_key;
5*2d543d20SAndroid Build Coastguard Worker typedef struct semanage_user_base record_t;
6*2d543d20SAndroid Build Coastguard Worker typedef struct semanage_user_key record_key_t;
7*2d543d20SAndroid Build Coastguard Worker #define DBASE_RECORD_DEFINED
8*2d543d20SAndroid Build Coastguard Worker
9*2d543d20SAndroid Build Coastguard Worker struct dbase_file;
10*2d543d20SAndroid Build Coastguard Worker typedef struct dbase_file dbase_t;
11*2d543d20SAndroid Build Coastguard Worker #define DBASE_DEFINED
12*2d543d20SAndroid Build Coastguard Worker
13*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
14*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
15*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
16*2d543d20SAndroid Build Coastguard Worker #include <string.h>
17*2d543d20SAndroid Build Coastguard Worker #include <semanage/handle.h>
18*2d543d20SAndroid Build Coastguard Worker #include "user_internal.h"
19*2d543d20SAndroid Build Coastguard Worker #include "database_file.h"
20*2d543d20SAndroid Build Coastguard Worker #include "parse_utils.h"
21*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
22*2d543d20SAndroid Build Coastguard Worker
user_base_print(semanage_handle_t * handle,semanage_user_base_t * user,FILE * str)23*2d543d20SAndroid Build Coastguard Worker static int user_base_print(semanage_handle_t * handle,
24*2d543d20SAndroid Build Coastguard Worker semanage_user_base_t * user, FILE * str)
25*2d543d20SAndroid Build Coastguard Worker {
26*2d543d20SAndroid Build Coastguard Worker
27*2d543d20SAndroid Build Coastguard Worker const char **roles = NULL;
28*2d543d20SAndroid Build Coastguard Worker unsigned int i, nroles;
29*2d543d20SAndroid Build Coastguard Worker
30*2d543d20SAndroid Build Coastguard Worker const char *name = semanage_user_base_get_name(user);
31*2d543d20SAndroid Build Coastguard Worker const char *mls_level = semanage_user_base_get_mlslevel(user);
32*2d543d20SAndroid Build Coastguard Worker const char *mls_range = semanage_user_base_get_mlsrange(user);
33*2d543d20SAndroid Build Coastguard Worker
34*2d543d20SAndroid Build Coastguard Worker if (fprintf(str, "user %s roles { ", name) < 0)
35*2d543d20SAndroid Build Coastguard Worker goto err;
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker if (semanage_user_base_get_roles(handle, user, &roles, &nroles) < 0)
38*2d543d20SAndroid Build Coastguard Worker goto err;
39*2d543d20SAndroid Build Coastguard Worker
40*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < nroles; i++) {
41*2d543d20SAndroid Build Coastguard Worker if (fprintf(str, "%s ", roles[i]) < 0)
42*2d543d20SAndroid Build Coastguard Worker goto err;
43*2d543d20SAndroid Build Coastguard Worker }
44*2d543d20SAndroid Build Coastguard Worker
45*2d543d20SAndroid Build Coastguard Worker if (fprintf(str, "} ") < 0)
46*2d543d20SAndroid Build Coastguard Worker goto err;
47*2d543d20SAndroid Build Coastguard Worker
48*2d543d20SAndroid Build Coastguard Worker /* MLS */
49*2d543d20SAndroid Build Coastguard Worker if (mls_level != NULL && mls_range != NULL)
50*2d543d20SAndroid Build Coastguard Worker if (fprintf(str, "level %s range %s", mls_level, mls_range) < 0)
51*2d543d20SAndroid Build Coastguard Worker goto err;
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker if (fprintf(str, ";\n") < 0)
54*2d543d20SAndroid Build Coastguard Worker goto err;
55*2d543d20SAndroid Build Coastguard Worker
56*2d543d20SAndroid Build Coastguard Worker free(roles);
57*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
58*2d543d20SAndroid Build Coastguard Worker
59*2d543d20SAndroid Build Coastguard Worker err:
60*2d543d20SAndroid Build Coastguard Worker free(roles);
61*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not print user %s to stream", name);
62*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
63*2d543d20SAndroid Build Coastguard Worker }
64*2d543d20SAndroid Build Coastguard Worker
user_base_parse(semanage_handle_t * handle,parse_info_t * info,semanage_user_base_t * user)65*2d543d20SAndroid Build Coastguard Worker static int user_base_parse(semanage_handle_t * handle,
66*2d543d20SAndroid Build Coastguard Worker parse_info_t * info, semanage_user_base_t * user)
67*2d543d20SAndroid Build Coastguard Worker {
68*2d543d20SAndroid Build Coastguard Worker
69*2d543d20SAndroid Build Coastguard Worker int islist = 0;
70*2d543d20SAndroid Build Coastguard Worker char *str = NULL;
71*2d543d20SAndroid Build Coastguard Worker char *start;
72*2d543d20SAndroid Build Coastguard Worker char *name_str = NULL;
73*2d543d20SAndroid Build Coastguard Worker
74*2d543d20SAndroid Build Coastguard Worker if (parse_skip_space(handle, info) < 0)
75*2d543d20SAndroid Build Coastguard Worker goto err;
76*2d543d20SAndroid Build Coastguard Worker if (!info->ptr)
77*2d543d20SAndroid Build Coastguard Worker goto last;
78*2d543d20SAndroid Build Coastguard Worker
79*2d543d20SAndroid Build Coastguard Worker /* Parse user header */
80*2d543d20SAndroid Build Coastguard Worker if (parse_assert_str(handle, info, "user") < 0)
81*2d543d20SAndroid Build Coastguard Worker goto err;
82*2d543d20SAndroid Build Coastguard Worker if (parse_assert_space(handle, info) < 0)
83*2d543d20SAndroid Build Coastguard Worker goto err;
84*2d543d20SAndroid Build Coastguard Worker
85*2d543d20SAndroid Build Coastguard Worker /* Parse user name */
86*2d543d20SAndroid Build Coastguard Worker if (parse_fetch_string(handle, info, &name_str, ' ', 0) < 0)
87*2d543d20SAndroid Build Coastguard Worker goto err;
88*2d543d20SAndroid Build Coastguard Worker
89*2d543d20SAndroid Build Coastguard Worker if (semanage_user_base_set_name(handle, user, name_str) < 0) {
90*2d543d20SAndroid Build Coastguard Worker free(name_str);
91*2d543d20SAndroid Build Coastguard Worker goto err;
92*2d543d20SAndroid Build Coastguard Worker }
93*2d543d20SAndroid Build Coastguard Worker free(name_str);
94*2d543d20SAndroid Build Coastguard Worker
95*2d543d20SAndroid Build Coastguard Worker if (parse_assert_space(handle, info) < 0)
96*2d543d20SAndroid Build Coastguard Worker goto err;
97*2d543d20SAndroid Build Coastguard Worker if (parse_assert_str(handle, info, "roles") < 0)
98*2d543d20SAndroid Build Coastguard Worker goto err;
99*2d543d20SAndroid Build Coastguard Worker if (parse_assert_space(handle, info) < 0)
100*2d543d20SAndroid Build Coastguard Worker goto err;
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker islist = (parse_optional_ch(info, '{') != STATUS_NODATA);
103*2d543d20SAndroid Build Coastguard Worker
104*2d543d20SAndroid Build Coastguard Worker /* For each role, loop */
105*2d543d20SAndroid Build Coastguard Worker do {
106*2d543d20SAndroid Build Coastguard Worker char delim;
107*2d543d20SAndroid Build Coastguard Worker
108*2d543d20SAndroid Build Coastguard Worker if (parse_skip_space(handle, info) < 0)
109*2d543d20SAndroid Build Coastguard Worker goto err;
110*2d543d20SAndroid Build Coastguard Worker if (parse_assert_noeof(handle, info) < 0)
111*2d543d20SAndroid Build Coastguard Worker goto err;
112*2d543d20SAndroid Build Coastguard Worker
113*2d543d20SAndroid Build Coastguard Worker start = info->ptr;
114*2d543d20SAndroid Build Coastguard Worker while (*(info->ptr) &&
115*2d543d20SAndroid Build Coastguard Worker *(info->ptr) != ';' &&
116*2d543d20SAndroid Build Coastguard Worker *(info->ptr) != '}' && !isspace(*(info->ptr)))
117*2d543d20SAndroid Build Coastguard Worker info->ptr++;
118*2d543d20SAndroid Build Coastguard Worker
119*2d543d20SAndroid Build Coastguard Worker delim = *(info->ptr);
120*2d543d20SAndroid Build Coastguard Worker *(info->ptr)++ = '\0';
121*2d543d20SAndroid Build Coastguard Worker
122*2d543d20SAndroid Build Coastguard Worker if (semanage_user_base_add_role(handle, user, start) < 0)
123*2d543d20SAndroid Build Coastguard Worker goto err;
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker if (delim && !isspace(delim)) {
126*2d543d20SAndroid Build Coastguard Worker if (islist && delim == '}')
127*2d543d20SAndroid Build Coastguard Worker break;
128*2d543d20SAndroid Build Coastguard Worker else if (!islist && delim == ';')
129*2d543d20SAndroid Build Coastguard Worker goto skip_semicolon;
130*2d543d20SAndroid Build Coastguard Worker else
131*2d543d20SAndroid Build Coastguard Worker goto err;
132*2d543d20SAndroid Build Coastguard Worker }
133*2d543d20SAndroid Build Coastguard Worker
134*2d543d20SAndroid Build Coastguard Worker if (parse_skip_space(handle, info) < 0)
135*2d543d20SAndroid Build Coastguard Worker goto err;
136*2d543d20SAndroid Build Coastguard Worker if (parse_optional_ch(info, ';') != STATUS_NODATA)
137*2d543d20SAndroid Build Coastguard Worker goto skip_semicolon;
138*2d543d20SAndroid Build Coastguard Worker if (parse_optional_ch(info, '}') != STATUS_NODATA)
139*2d543d20SAndroid Build Coastguard Worker islist = 0;
140*2d543d20SAndroid Build Coastguard Worker
141*2d543d20SAndroid Build Coastguard Worker } while (islist);
142*2d543d20SAndroid Build Coastguard Worker
143*2d543d20SAndroid Build Coastguard Worker /* Handle mls */
144*2d543d20SAndroid Build Coastguard Worker /* Parse level header */
145*2d543d20SAndroid Build Coastguard Worker if (parse_skip_space(handle, info) < 0)
146*2d543d20SAndroid Build Coastguard Worker goto err;
147*2d543d20SAndroid Build Coastguard Worker if (parse_optional_str(info, "level") == STATUS_NODATA)
148*2d543d20SAndroid Build Coastguard Worker goto semicolon;
149*2d543d20SAndroid Build Coastguard Worker if (parse_assert_space(handle, info) < 0)
150*2d543d20SAndroid Build Coastguard Worker goto err;
151*2d543d20SAndroid Build Coastguard Worker
152*2d543d20SAndroid Build Coastguard Worker /* NOTE: does not allow spaces/multiline */
153*2d543d20SAndroid Build Coastguard Worker if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
154*2d543d20SAndroid Build Coastguard Worker goto err;
155*2d543d20SAndroid Build Coastguard Worker if (semanage_user_base_set_mlslevel(handle, user, str) < 0)
156*2d543d20SAndroid Build Coastguard Worker goto err;
157*2d543d20SAndroid Build Coastguard Worker free(str);
158*2d543d20SAndroid Build Coastguard Worker str = NULL;
159*2d543d20SAndroid Build Coastguard Worker
160*2d543d20SAndroid Build Coastguard Worker /* Parse range header */
161*2d543d20SAndroid Build Coastguard Worker if (parse_assert_space(handle, info) < 0)
162*2d543d20SAndroid Build Coastguard Worker goto err;
163*2d543d20SAndroid Build Coastguard Worker if (parse_assert_str(handle, info, "range") < 0)
164*2d543d20SAndroid Build Coastguard Worker goto err;
165*2d543d20SAndroid Build Coastguard Worker if (parse_assert_space(handle, info) < 0)
166*2d543d20SAndroid Build Coastguard Worker goto err;
167*2d543d20SAndroid Build Coastguard Worker
168*2d543d20SAndroid Build Coastguard Worker if (parse_fetch_string(handle, info, &str, ';', 1) < 0)
169*2d543d20SAndroid Build Coastguard Worker goto err;
170*2d543d20SAndroid Build Coastguard Worker if (semanage_user_base_set_mlsrange(handle, user, str) < 0)
171*2d543d20SAndroid Build Coastguard Worker goto err;
172*2d543d20SAndroid Build Coastguard Worker
173*2d543d20SAndroid Build Coastguard Worker free(str);
174*2d543d20SAndroid Build Coastguard Worker str = NULL;
175*2d543d20SAndroid Build Coastguard Worker
176*2d543d20SAndroid Build Coastguard Worker /* Check for semicolon */
177*2d543d20SAndroid Build Coastguard Worker semicolon:
178*2d543d20SAndroid Build Coastguard Worker if (parse_skip_space(handle, info) < 0)
179*2d543d20SAndroid Build Coastguard Worker goto err;
180*2d543d20SAndroid Build Coastguard Worker if (parse_assert_ch(handle, info, ';') < 0)
181*2d543d20SAndroid Build Coastguard Worker goto err;
182*2d543d20SAndroid Build Coastguard Worker
183*2d543d20SAndroid Build Coastguard Worker skip_semicolon:
184*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
185*2d543d20SAndroid Build Coastguard Worker
186*2d543d20SAndroid Build Coastguard Worker last:
187*2d543d20SAndroid Build Coastguard Worker parse_dispose_line(info);
188*2d543d20SAndroid Build Coastguard Worker return STATUS_NODATA;
189*2d543d20SAndroid Build Coastguard Worker
190*2d543d20SAndroid Build Coastguard Worker err:
191*2d543d20SAndroid Build Coastguard Worker ERR(handle, "could not parse user record");
192*2d543d20SAndroid Build Coastguard Worker free(str);
193*2d543d20SAndroid Build Coastguard Worker parse_dispose_line(info);
194*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
195*2d543d20SAndroid Build Coastguard Worker }
196*2d543d20SAndroid Build Coastguard Worker
197*2d543d20SAndroid Build Coastguard Worker /* USER BASE record: FILE extension: method table */
198*2d543d20SAndroid Build Coastguard Worker record_file_table_t SEMANAGE_USER_BASE_FILE_RTABLE = {
199*2d543d20SAndroid Build Coastguard Worker .parse = user_base_parse,
200*2d543d20SAndroid Build Coastguard Worker .print = user_base_print,
201*2d543d20SAndroid Build Coastguard Worker };
202*2d543d20SAndroid Build Coastguard Worker
user_base_file_dbase_init(semanage_handle_t * handle,const char * path_ro,const char * path_rw,dbase_config_t * dconfig)203*2d543d20SAndroid Build Coastguard Worker int user_base_file_dbase_init(semanage_handle_t * handle,
204*2d543d20SAndroid Build Coastguard Worker const char *path_ro,
205*2d543d20SAndroid Build Coastguard Worker const char *path_rw,
206*2d543d20SAndroid Build Coastguard Worker dbase_config_t * dconfig)
207*2d543d20SAndroid Build Coastguard Worker {
208*2d543d20SAndroid Build Coastguard Worker
209*2d543d20SAndroid Build Coastguard Worker if (dbase_file_init(handle,
210*2d543d20SAndroid Build Coastguard Worker path_ro,
211*2d543d20SAndroid Build Coastguard Worker path_rw,
212*2d543d20SAndroid Build Coastguard Worker &SEMANAGE_USER_BASE_RTABLE,
213*2d543d20SAndroid Build Coastguard Worker &SEMANAGE_USER_BASE_FILE_RTABLE,
214*2d543d20SAndroid Build Coastguard Worker &dconfig->dbase) < 0)
215*2d543d20SAndroid Build Coastguard Worker return STATUS_ERR;
216*2d543d20SAndroid Build Coastguard Worker
217*2d543d20SAndroid Build Coastguard Worker dconfig->dtable = &SEMANAGE_FILE_DTABLE;
218*2d543d20SAndroid Build Coastguard Worker return STATUS_SUCCESS;
219*2d543d20SAndroid Build Coastguard Worker }
220*2d543d20SAndroid Build Coastguard Worker
user_base_file_dbase_release(dbase_config_t * dconfig)221*2d543d20SAndroid Build Coastguard Worker void user_base_file_dbase_release(dbase_config_t * dconfig)
222*2d543d20SAndroid Build Coastguard Worker {
223*2d543d20SAndroid Build Coastguard Worker
224*2d543d20SAndroid Build Coastguard Worker dbase_file_release(dconfig->dbase);
225*2d543d20SAndroid Build Coastguard Worker }
226