1 #include <netinet/in.h> 2 #include <stdlib.h> 3 4 #include "debug.h" 5 #include "context.h" 6 #include "handle.h" 7 8 #include <sepol/policydb/policydb.h> 9 #include "ibendport_internal.h" 10 11 /* Create a low level ibendport structure from 12 * a high level representation 13 */ 14 static int ibendport_from_record(sepol_handle_t *handle, 15 const policydb_t *policydb, 16 ocontext_t **ibendport, 17 const sepol_ibendport_t *data) 18 { 19 ocontext_t *tmp_ibendport = NULL; 20 context_struct_t *tmp_con = NULL; 21 char *ibdev_name = NULL; 22 int port = sepol_ibendport_get_port(data); 23 24 tmp_ibendport = (ocontext_t *)calloc(1, sizeof(ocontext_t)); 25 if (!tmp_ibendport) 26 goto omem; 27 28 if (sepol_ibendport_alloc_ibdev_name(handle, 29 &tmp_ibendport->u.ibendport.dev_name) < 0) 30 goto omem; 31 32 if (sepol_ibendport_get_ibdev_name(handle, 33 data, 34 &ibdev_name) < 0) 35 goto err; 36 37 strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX); 38 39 free(ibdev_name); 40 ibdev_name = NULL; 41 42 tmp_ibendport->u.ibendport.port = port; 43 44 /* Context */ 45 if (context_from_record(handle, policydb, &tmp_con, 46 sepol_ibendport_get_con(data)) < 0) 47 goto err; 48 context_cpy(&tmp_ibendport->context[0], tmp_con); 49 context_destroy(tmp_con); 50 free(tmp_con); 51 tmp_con = NULL; 52 53 *ibendport = tmp_ibendport; 54 return STATUS_SUCCESS; 55 56 omem: 57 ERR(handle, "out of memory"); 58 59 err: 60 if (tmp_ibendport) { 61 context_destroy(&tmp_ibendport->context[0]); 62 free(tmp_ibendport); 63 } 64 context_destroy(tmp_con); 65 free(tmp_con); 66 free(ibdev_name); 67 ERR(handle, "could not create ibendport structure"); 68 return STATUS_ERR; 69 } 70 71 static int ibendport_to_record(sepol_handle_t *handle, 72 const policydb_t *policydb, 73 ocontext_t *ibendport, 74 sepol_ibendport_t **record) 75 { 76 int port = ibendport->u.ibendport.port; 77 context_struct_t *con = &ibendport->context[0]; 78 79 sepol_context_t *tmp_con = NULL; 80 sepol_ibendport_t *tmp_record = NULL; 81 82 if (sepol_ibendport_create(handle, &tmp_record) < 0) 83 goto err; 84 85 if (sepol_ibendport_set_ibdev_name(handle, tmp_record, 86 ibendport->u.ibendport.dev_name) < 0) 87 goto err; 88 89 sepol_ibendport_set_port(tmp_record, port); 90 91 if (context_to_record(handle, policydb, con, &tmp_con) < 0) 92 goto err; 93 94 if (sepol_ibendport_set_con(handle, tmp_record, tmp_con) < 0) 95 goto err; 96 97 sepol_context_free(tmp_con); 98 *record = tmp_record; 99 return STATUS_SUCCESS; 100 101 err: 102 ERR(handle, "could not convert ibendport to record"); 103 sepol_context_free(tmp_con); 104 sepol_ibendport_free(tmp_record); 105 return STATUS_ERR; 106 } 107 108 /* Return the number of ibendports */ 109 extern int sepol_ibendport_count(sepol_handle_t *handle __attribute__ ((unused)), 110 const sepol_policydb_t *p, unsigned int *response) 111 { 112 unsigned int count = 0; 113 ocontext_t *c, *head; 114 const policydb_t *policydb = &p->p; 115 116 head = policydb->ocontexts[OCON_IBENDPORT]; 117 for (c = head; c; c = c->next) 118 count++; 119 120 *response = count; 121 122 return STATUS_SUCCESS; 123 } 124 125 /* Check if a ibendport exists */ 126 int sepol_ibendport_exists(sepol_handle_t *handle __attribute__ ((unused)), 127 const sepol_policydb_t *p, 128 const sepol_ibendport_key_t *key, int *response) 129 { 130 const policydb_t *policydb = &p->p; 131 ocontext_t *c, *head; 132 int port; 133 const char *ibdev_name; 134 135 sepol_ibendport_key_unpack(key, &ibdev_name, &port); 136 137 head = policydb->ocontexts[OCON_IBENDPORT]; 138 for (c = head; c; c = c->next) { 139 const char *ibdev_name2 = c->u.ibendport.dev_name; 140 int port2 = c->u.ibendport.port; 141 142 if (port2 == port && 143 (!strcmp(ibdev_name, ibdev_name2))) { 144 *response = 1; 145 return STATUS_SUCCESS; 146 } 147 } 148 149 *response = 0; 150 return STATUS_SUCCESS; 151 } 152 153 int sepol_ibendport_query(sepol_handle_t *handle, 154 const sepol_policydb_t *p, 155 const sepol_ibendport_key_t *key, 156 sepol_ibendport_t **response) 157 { 158 const policydb_t *policydb = &p->p; 159 ocontext_t *c, *head; 160 int port; 161 const char *ibdev_name; 162 163 sepol_ibendport_key_unpack(key, &ibdev_name, &port); 164 165 head = policydb->ocontexts[OCON_IBENDPORT]; 166 for (c = head; c; c = c->next) { 167 const char *ibdev_name2 = c->u.ibendport.dev_name; 168 int port2 = c->u.ibendport.port; 169 170 if (port2 == port && 171 (!strcmp(ibdev_name, ibdev_name2))) { 172 if (ibendport_to_record(handle, policydb, c, response) < 0) 173 goto err; 174 return STATUS_SUCCESS; 175 } 176 } 177 178 *response = NULL; 179 return STATUS_SUCCESS; 180 181 err: 182 ERR(handle, "could not query ibendport, IB device: %s port %u", 183 ibdev_name, port); 184 return STATUS_ERR; 185 } 186 187 /* Load a ibendport into policy */ 188 int sepol_ibendport_modify(sepol_handle_t *handle, 189 sepol_policydb_t *p, 190 const sepol_ibendport_key_t *key, 191 const sepol_ibendport_t *data) 192 { 193 policydb_t *policydb = &p->p; 194 ocontext_t *ibendport = NULL; 195 int port; 196 const char *ibdev_name; 197 198 sepol_ibendport_key_unpack(key, &ibdev_name, &port); 199 200 if (ibendport_from_record(handle, policydb, &ibendport, data) < 0) 201 goto err; 202 203 /* Attach to context list */ 204 ibendport->next = policydb->ocontexts[OCON_IBENDPORT]; 205 policydb->ocontexts[OCON_IBENDPORT] = ibendport; 206 207 return STATUS_SUCCESS; 208 209 err: 210 ERR(handle, "could not load ibendport %s/%d", 211 ibdev_name, port); 212 if (ibendport) { 213 context_destroy(&ibendport->context[0]); 214 free(ibendport); 215 } 216 return STATUS_ERR; 217 } 218 219 int sepol_ibendport_iterate(sepol_handle_t *handle, 220 const sepol_policydb_t *p, 221 int (*fn)(const sepol_ibendport_t *ibendport, 222 void *fn_arg), void *arg) 223 { 224 const policydb_t *policydb = &p->p; 225 ocontext_t *c, *head; 226 sepol_ibendport_t *ibendport = NULL; 227 228 head = policydb->ocontexts[OCON_IBENDPORT]; 229 for (c = head; c; c = c->next) { 230 int status; 231 232 if (ibendport_to_record(handle, policydb, c, &ibendport) < 0) 233 goto err; 234 235 /* Invoke handler */ 236 status = fn(ibendport, arg); 237 if (status < 0) 238 goto err; 239 240 sepol_ibendport_free(ibendport); 241 ibendport = NULL; 242 243 /* Handler requested exit */ 244 if (status > 0) 245 break; 246 } 247 248 return STATUS_SUCCESS; 249 250 err: 251 ERR(handle, "could not iterate over ibendports"); 252 sepol_ibendport_free(ibendport); 253 return STATUS_ERR; 254 } 255