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