1/* Copyright (C) 2005 Red Hat, Inc. */
2
3struct semanage_node;
4struct semanage_node_key;
5typedef struct semanage_node record_t;
6typedef struct semanage_node_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 <strings.h>
16#include <semanage/handle.h>
17#include "node_internal.h"
18#include "context_internal.h"
19#include "database_file.h"
20#include "parse_utils.h"
21#include "debug.h"
22
23static int node_print(semanage_handle_t * handle,
24		      semanage_node_t * node, FILE * str)
25{
26
27	char *con_str = NULL;
28	char *addr = NULL;
29	char *mask = NULL;
30
31	int proto = semanage_node_get_proto(node);
32	const char *proto_str = semanage_node_get_proto_str(proto);
33	semanage_context_t *con = semanage_node_get_con(node);
34
35	if (semanage_node_get_addr(handle, node, &addr) < 0)
36		goto err;
37
38	if (semanage_node_get_mask(handle, node, &mask) < 0)
39		goto err;
40
41	if (semanage_context_to_string(handle, con, &con_str) < 0)
42		goto err;
43
44	if (fprintf
45	    (str, "nodecon %s %s %s %s\n", proto_str, addr, mask, con_str) < 0)
46		goto err;
47
48	free(addr);
49	free(mask);
50	free(con_str);
51	return STATUS_SUCCESS;
52
53      err:
54	free(addr);
55	free(mask);
56	free(con_str);
57	ERR(handle, "could not print node to stream");
58	return STATUS_ERR;
59}
60
61static int node_parse(semanage_handle_t * handle,
62		      parse_info_t * info, semanage_node_t * node)
63{
64
65	int proto;
66	char *str = NULL;
67	semanage_context_t *con = NULL;
68
69	if (parse_skip_space(handle, info) < 0)
70		goto err;
71	if (!info->ptr)
72		goto last;
73
74	/* Header */
75	if (parse_assert_str(handle, info, "nodecon") < 0)
76		goto err;
77	if (parse_assert_space(handle, info) < 0)
78		goto err;
79
80	/* Protocol */
81	if (parse_fetch_string(handle, info, &str, ' ') < 0)
82		goto err;
83	if (!strcasecmp(str, "ipv4"))
84		proto = SEMANAGE_PROTO_IP4;
85	else if (!strcasecmp(str, "ipv6"))
86		proto = SEMANAGE_PROTO_IP6;
87	else {
88		ERR(handle, "invalid protocol \"%s\" (%s: %u):\n%s", str,
89		    info->filename, info->lineno, info->orig_line);
90		goto err;
91	}
92	free(str);
93	str = NULL;
94
95	semanage_node_set_proto(node, proto);
96
97	/* Address */
98	if (parse_assert_space(handle, info) < 0)
99		goto err;
100	if (parse_fetch_string(handle, info, &str, ' ') < 0)
101		goto err;
102	if (semanage_node_set_addr(handle, node, proto, str) < 0)
103		goto err;
104	if (parse_assert_space(handle, info) < 0)
105		goto err;
106	free(str);
107	str = NULL;
108
109	/* Netmask */
110	if (parse_fetch_string(handle, info, &str, ' ') < 0)
111		goto err;
112	if (semanage_node_set_mask(handle, node, proto, str) < 0)
113		goto err;
114	if (parse_assert_space(handle, info) < 0)
115		goto err;
116	free(str);
117	str = NULL;
118
119	/* Port context */
120	if (parse_fetch_string(handle, info, &str, ' ') < 0)
121		goto err;
122	if (semanage_context_from_string(handle, str, &con) < 0) {
123		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
124		    str, info->filename, info->lineno, info->orig_line);
125		goto err;
126	}
127	if (con == NULL) {
128		ERR(handle, "<<none>> context is not valid "
129		    "for nodes (%s: %u):\n%s", info->filename,
130		    info->lineno, info->orig_line);
131		goto err;
132	}
133	free(str);
134	str = NULL;
135
136	if (semanage_node_set_con(handle, node, con) < 0)
137		goto err;
138
139	if (parse_assert_space(handle, info) < 0)
140		goto err;
141
142	semanage_context_free(con);
143	return STATUS_SUCCESS;
144
145      last:
146	parse_dispose_line(info);
147	return STATUS_NODATA;
148
149      err:
150	ERR(handle, "could not parse node record");
151	free(str);
152	semanage_context_free(con);
153	parse_dispose_line(info);
154	return STATUS_ERR;
155}
156
157/* NODE RECORD: FILE extension: method table */
158record_file_table_t SEMANAGE_NODE_FILE_RTABLE = {
159	.parse = node_parse,
160	.print = node_print,
161};
162
163int node_file_dbase_init(semanage_handle_t * handle,
164			 const char *path_ro,
165			 const char *path_rw,
166			 dbase_config_t * dconfig)
167{
168
169	if (dbase_file_init(handle,
170			    path_ro,
171			    path_rw,
172			    &SEMANAGE_NODE_RTABLE,
173			    &SEMANAGE_NODE_FILE_RTABLE, &dconfig->dbase) < 0)
174		return STATUS_ERR;
175
176	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
177	return STATUS_SUCCESS;
178}
179
180void node_file_dbase_release(dbase_config_t * dconfig)
181{
182
183	dbase_file_release(dconfig->dbase);
184}
185