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