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