xref: /aosp_15_r20/external/selinux/libsemanage/src/ibpkeys_file.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 /* Copyright (C) 2017 Mellanox Technologies Inc. */
2 
3 struct semanage_ibpkey;
4 struct semanage_ibpkey_key;
5 typedef struct semanage_ibpkey record_t;
6 typedef struct semanage_ibpkey_key record_key_t;
7 #define DBASE_RECORD_DEFINED
8 
9 struct dbase_file;
10 typedef 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 "ibpkey_internal.h"
18 #include "database_file.h"
19 #include "parse_utils.h"
20 #include "debug.h"
21 
ibpkey_print(semanage_handle_t * handle,semanage_ibpkey_t * ibpkey,FILE * str)22 static int ibpkey_print(semanage_handle_t *handle,
23 			semanage_ibpkey_t *ibpkey, FILE *str)
24 {
25 	char *con_str = NULL;
26 	char *subnet_prefix_str = NULL;
27 
28 	int low = semanage_ibpkey_get_low(ibpkey);
29 	int high = semanage_ibpkey_get_high(ibpkey);
30 
31 	if (semanage_ibpkey_get_subnet_prefix(handle, ibpkey, &subnet_prefix_str) != 0)
32 		goto err;
33 
34 	semanage_context_t *con = semanage_ibpkey_get_con(ibpkey);
35 
36 	if (fprintf(str, "ibpkeycon %s ", subnet_prefix_str) < 0)
37 		goto err;
38 
39 	if (low == high) {
40 		if (fprintf(str, "%d ", low) < 0)
41 			goto err;
42 	} else {
43 		if (fprintf(str, "%d - %d ", low, high) < 0)
44 			goto err;
45 	}
46 
47 	if (semanage_context_to_string(handle, con, &con_str) < 0)
48 		goto err;
49 	if (fprintf(str, "%s\n", con_str) < 0)
50 		goto err;
51 
52 	free(subnet_prefix_str);
53 	free(con_str);
54 	return STATUS_SUCCESS;
55 
56 err:
57 	ERR(handle, "could not print ibpkey range (%s) %u - %u to stream",
58 	    subnet_prefix_str, low, high);
59 	free(subnet_prefix_str);
60 	free(con_str);
61 	return STATUS_ERR;
62 }
63 
ibpkey_parse(semanage_handle_t * handle,parse_info_t * info,semanage_ibpkey_t * ibpkey)64 static int ibpkey_parse(semanage_handle_t *handle,
65 			parse_info_t *info, semanage_ibpkey_t *ibpkey)
66 {
67 	int low, high;
68 	char *str = NULL;
69 	semanage_context_t *con = NULL;
70 
71 	if (parse_skip_space(handle, info) < 0)
72 		goto err;
73 	if (!info->ptr)
74 		goto last;
75 
76 	/* Header */
77 	if (parse_assert_str(handle, info, "ibpkeycon") < 0)
78 		goto err;
79 	if (parse_assert_space(handle, info) < 0)
80 		goto err;
81 
82 	/* Subnet Prefix */
83 	if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
84 		goto err;
85 	if (semanage_ibpkey_set_subnet_prefix(handle, ibpkey, str) < 0)
86 		goto err;
87 	free(str);
88 	str = NULL;
89 
90 	/* Range/Pkey */
91 	if (parse_assert_space(handle, info) < 0)
92 		goto err;
93 	if (parse_fetch_int(handle, info, &low, '-') < 0)
94 		goto err;
95 
96 	/* If range (-) does not follow immediately, require a space
97 	 * In other words, the space here is optional, but only
98 	 * in the ranged case, not in the single ibpkey case,
99 	 * so do a custom test
100 	 */
101 	if (*info->ptr && *info->ptr != '-') {
102 		if (parse_assert_space(handle, info) < 0)
103 			goto err;
104 	}
105 
106 	if (parse_optional_ch(info, '-') != STATUS_NODATA) {
107 		if (parse_skip_space(handle, info) < 0)
108 			goto err;
109 		if (parse_fetch_int(handle, info, &high, ' ') < 0)
110 			goto err;
111 		if (parse_assert_space(handle, info) < 0)
112 			goto err;
113 		semanage_ibpkey_set_range(ibpkey, low, high);
114 	} else {
115 		semanage_ibpkey_set_pkey(ibpkey, low);
116 	}
117 	/* Pkey context */
118 	if (parse_fetch_string(handle, info, &str, ' ', 0) < 0)
119 		goto err;
120 	if (semanage_context_from_string(handle, str, &con) < 0) {
121 		ERR(handle, "invalid security context \"%s\" (%s: %u)\n%s",
122 		    str, info->filename, info->lineno, info->orig_line);
123 		goto err;
124 	}
125 	if (!con) {
126 		ERR(handle, "<<none>> context is not valid for ibpkeys (%s: %u):\n%s",
127 		    info->filename,
128 		    info->lineno, info->orig_line);
129 		goto err;
130 	}
131 	free(str);
132 	str = NULL;
133 
134 	if (semanage_ibpkey_set_con(handle, ibpkey, con) < 0)
135 		goto err;
136 
137 	if (parse_assert_space(handle, info) < 0)
138 		goto err;
139 
140 	semanage_context_free(con);
141 	return STATUS_SUCCESS;
142 
143 last:
144 	parse_dispose_line(info);
145 	return STATUS_NODATA;
146 
147 err:
148 	ERR(handle, "could not parse ibpkey record");
149 	free(str);
150 	semanage_context_free(con);
151 	parse_dispose_line(info);
152 	return STATUS_ERR;
153 }
154 
155 /* IBPKEY RECORD: FILE extension: method table */
156 record_file_table_t SEMANAGE_IBPKEY_FILE_RTABLE = {
157 	.parse = ibpkey_parse,
158 	.print = ibpkey_print,
159 };
160 
ibpkey_file_dbase_init(semanage_handle_t * handle,const char * path_ro,const char * path_rw,dbase_config_t * dconfig)161 int ibpkey_file_dbase_init(semanage_handle_t *handle,
162 			   const char *path_ro,
163 			   const char *path_rw,
164 			   dbase_config_t *dconfig)
165 {
166 	if (dbase_file_init(handle,
167 			    path_ro,
168 			    path_rw,
169 			    &SEMANAGE_IBPKEY_RTABLE,
170 			    &SEMANAGE_IBPKEY_FILE_RTABLE, &dconfig->dbase) < 0)
171 		return STATUS_ERR;
172 
173 	dconfig->dtable = &SEMANAGE_FILE_DTABLE;
174 	return STATUS_SUCCESS;
175 }
176 
ibpkey_file_dbase_release(dbase_config_t * dconfig)177 void ibpkey_file_dbase_release(dbase_config_t *dconfig)
178 {
179 	dbase_file_release(dconfig->dbase);
180 }
181