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