1 #include <stdlib.h> 2 #include <string.h> 3 #include <netinet/in.h> 4 #include <arpa/inet.h> 5 #include <errno.h> 6 7 #include "sepol/policydb/policydb.h" 8 #include "ibendport_internal.h" 9 #include "context_internal.h" 10 #include "debug.h" 11 12 struct sepol_ibendport { 13 /* Device Name */ 14 char *ibdev_name; 15 16 /* Port number */ 17 int port; 18 19 /* Context */ 20 sepol_context_t *con; 21 }; 22 23 struct sepol_ibendport_key { 24 /* Device Name */ 25 char *ibdev_name; 26 27 /* Port number */ 28 int port; 29 }; 30 31 /* Allocates a sufficiently large string (ibdev_name) */ 32 int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle, 33 char **ibdev_name) 34 { 35 char *tmp_ibdev_name = NULL; 36 37 tmp_ibdev_name = calloc(1, IB_DEVICE_NAME_MAX); 38 39 if (!tmp_ibdev_name) 40 goto omem; 41 42 *ibdev_name = tmp_ibdev_name; 43 return STATUS_SUCCESS; 44 45 omem: 46 ERR(handle, "out of memory"); 47 ERR(handle, "could not allocate string buffer for ibdev_name"); 48 return STATUS_ERR; 49 } 50 51 /* Key */ 52 int sepol_ibendport_key_create(sepol_handle_t *handle, 53 const char *ibdev_name, 54 int port, 55 sepol_ibendport_key_t **key_ptr) 56 { 57 sepol_ibendport_key_t *tmp_key = 58 (sepol_ibendport_key_t *)malloc(sizeof(sepol_ibendport_key_t)); 59 60 if (!tmp_key) { 61 ERR(handle, "out of memory, could not create ibendport key"); 62 goto omem; 63 } 64 65 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0) 66 goto err; 67 68 strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX); 69 tmp_key->port = port; 70 71 *key_ptr = tmp_key; 72 return STATUS_SUCCESS; 73 74 omem: 75 ERR(handle, "out of memory"); 76 77 err: 78 sepol_ibendport_key_free(tmp_key); 79 ERR(handle, "could not create ibendport key for IB device %s, port %u", 80 ibdev_name, port); 81 return STATUS_ERR; 82 } 83 84 hidden_def(sepol_ibendport_key_create) 85 86 void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, 87 const char **ibdev_name, int *port) 88 { 89 *ibdev_name = key->ibdev_name; 90 *port = key->port; 91 } 92 93 hidden_def(sepol_ibendport_key_unpack) 94 95 int sepol_ibendport_key_extract(sepol_handle_t *handle, 96 const sepol_ibendport_t *ibendport, 97 sepol_ibendport_key_t **key_ptr) 98 { 99 if (sepol_ibendport_key_create 100 (handle, ibendport->ibdev_name, ibendport->port, key_ptr) < 0) { 101 ERR(handle, "could not extract key from ibendport device %s port %d", 102 ibendport->ibdev_name, 103 ibendport->port); 104 105 return STATUS_ERR; 106 } 107 108 return STATUS_SUCCESS; 109 } 110 111 void sepol_ibendport_key_free(sepol_ibendport_key_t *key) 112 { 113 if (!key) 114 return; 115 free(key->ibdev_name); 116 free(key); 117 } 118 119 int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, const sepol_ibendport_key_t *key) 120 { 121 int rc; 122 123 rc = strcmp(ibendport->ibdev_name, key->ibdev_name); 124 125 if ((ibendport->port == key->port) && !rc) 126 return 0; 127 128 if (ibendport->port < key->port) 129 return -1; 130 else if (key->port < ibendport->port) 131 return 1; 132 else 133 return rc; 134 } 135 136 int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, const sepol_ibendport_t *ibendport2) 137 { 138 int rc; 139 140 rc = strcmp(ibendport->ibdev_name, ibendport2->ibdev_name); 141 142 if ((ibendport->port == ibendport2->port) && !rc) 143 return 0; 144 145 if (ibendport->port < ibendport2->port) 146 return -1; 147 else if (ibendport2->port < ibendport->port) 148 return 1; 149 else 150 return rc; 151 } 152 153 int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport) 154 { 155 return ibendport->port; 156 } 157 158 hidden_def(sepol_ibendport_get_port) 159 160 void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port) 161 { 162 ibendport->port = port; 163 } 164 165 hidden_def(sepol_ibendport_set_port) 166 167 int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, 168 const sepol_ibendport_t *ibendport, 169 char **ibdev_name) 170 { 171 char *tmp_ibdev_name = NULL; 172 173 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0) 174 goto err; 175 176 strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX); 177 *ibdev_name = tmp_ibdev_name; 178 return STATUS_SUCCESS; 179 180 err: 181 free(tmp_ibdev_name); 182 ERR(handle, "could not get ibendport ibdev_name"); 183 return STATUS_ERR; 184 } 185 186 hidden_def(sepol_ibendport_get_ibdev_name) 187 188 int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, 189 sepol_ibendport_t *ibendport, 190 const char *ibdev_name) 191 { 192 char *tmp = NULL; 193 194 if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0) 195 goto err; 196 197 strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX); 198 free(ibendport->ibdev_name); 199 ibendport->ibdev_name = tmp; 200 return STATUS_SUCCESS; 201 202 err: 203 free(tmp); 204 ERR(handle, "could not set ibendport subnet prefix to %s", ibdev_name); 205 return STATUS_ERR; 206 } 207 208 hidden_def(sepol_ibendport_set_ibdev_name) 209 210 /* Create */ 211 int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport) 212 { 213 sepol_ibendport_t *tmp_ibendport = (sepol_ibendport_t *)malloc(sizeof(sepol_ibendport_t)); 214 215 if (!tmp_ibendport) { 216 ERR(handle, "out of memory, could not create ibendport record"); 217 return STATUS_ERR; 218 } 219 220 tmp_ibendport->ibdev_name = NULL; 221 tmp_ibendport->port = 0; 222 tmp_ibendport->con = NULL; 223 *ibendport = tmp_ibendport; 224 225 return STATUS_SUCCESS; 226 } 227 228 hidden_def(sepol_ibendport_create) 229 230 /* Deep copy clone */ 231 int sepol_ibendport_clone(sepol_handle_t *handle, 232 const sepol_ibendport_t *ibendport, 233 sepol_ibendport_t **ibendport_ptr) 234 { 235 sepol_ibendport_t *new_ibendport = NULL; 236 237 if (sepol_ibendport_create(handle, &new_ibendport) < 0) 238 goto err; 239 240 if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0) 241 goto omem; 242 243 strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX); 244 new_ibendport->port = ibendport->port; 245 246 if (ibendport->con && 247 (sepol_context_clone(handle, ibendport->con, &new_ibendport->con) < 0)) 248 goto err; 249 250 *ibendport_ptr = new_ibendport; 251 return STATUS_SUCCESS; 252 253 omem: 254 ERR(handle, "out of memory"); 255 256 err: 257 ERR(handle, "could not clone ibendport record"); 258 sepol_ibendport_free(new_ibendport); 259 return STATUS_ERR; 260 } 261 262 /* Destroy */ 263 void sepol_ibendport_free(sepol_ibendport_t *ibendport) 264 { 265 if (!ibendport) 266 return; 267 268 free(ibendport->ibdev_name); 269 sepol_context_free(ibendport->con); 270 free(ibendport); 271 } 272 273 hidden_def(sepol_ibendport_free) 274 275 /* Context */ 276 sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport) 277 { 278 return ibendport->con; 279 } 280 281 hidden_def(sepol_ibendport_get_con) 282 283 int sepol_ibendport_set_con(sepol_handle_t *handle, 284 sepol_ibendport_t *ibendport, sepol_context_t *con) 285 { 286 sepol_context_t *newcon; 287 288 if (sepol_context_clone(handle, con, &newcon) < 0) { 289 ERR(handle, "out of memory, could not set ibendport context"); 290 return STATUS_ERR; 291 } 292 293 sepol_context_free(ibendport->con); 294 ibendport->con = newcon; 295 return STATUS_SUCCESS; 296 } 297 298 hidden_def(sepol_ibendport_set_con) 299