1 #include <stdlib.h> 2 3 #include "debug.h" 4 #include "context.h" 5 #include "handle.h" 6 7 #include <sepol/policydb/policydb.h> 8 #include <sepol/interfaces.h> 9 #include "iface_internal.h" 10 11 /* Create a low level structure from record */ 12 static int iface_from_record(sepol_handle_t * handle, 13 const policydb_t * policydb, 14 ocontext_t ** iface, const sepol_iface_t * record) 15 { 16 17 ocontext_t *tmp_iface = NULL; 18 context_struct_t *tmp_con = NULL; 19 20 tmp_iface = (ocontext_t *) calloc(1, sizeof(ocontext_t)); 21 if (!tmp_iface) 22 goto omem; 23 24 /* Name */ 25 tmp_iface->u.name = strdup(sepol_iface_get_name(record)); 26 if (!tmp_iface->u.name) 27 goto omem; 28 29 /* Interface Context */ 30 if (context_from_record(handle, policydb, 31 &tmp_con, sepol_iface_get_ifcon(record)) < 0) 32 goto err; 33 context_cpy(&tmp_iface->context[0], tmp_con); 34 context_destroy(tmp_con); 35 free(tmp_con); 36 tmp_con = NULL; 37 38 /* Message Context */ 39 if (context_from_record(handle, policydb, 40 &tmp_con, sepol_iface_get_msgcon(record)) < 0) 41 goto err; 42 context_cpy(&tmp_iface->context[1], tmp_con); 43 context_destroy(tmp_con); 44 free(tmp_con); 45 tmp_con = NULL; 46 47 *iface = tmp_iface; 48 return STATUS_SUCCESS; 49 50 omem: 51 ERR(handle, "out of memory"); 52 53 err: 54 if (tmp_iface != NULL) { 55 free(tmp_iface->u.name); 56 context_destroy(&tmp_iface->context[0]); 57 context_destroy(&tmp_iface->context[1]); 58 free(tmp_iface); 59 } 60 context_destroy(tmp_con); 61 free(tmp_con); 62 ERR(handle, "error creating interface structure"); 63 return STATUS_ERR; 64 } 65 66 static int iface_to_record(sepol_handle_t * handle, 67 const policydb_t * policydb, 68 ocontext_t * iface, sepol_iface_t ** record) 69 { 70 71 char *name = iface->u.name; 72 context_struct_t *ifcon = &iface->context[0]; 73 context_struct_t *msgcon = &iface->context[1]; 74 75 sepol_context_t *tmp_con = NULL; 76 sepol_iface_t *tmp_record = NULL; 77 78 if (sepol_iface_create(handle, &tmp_record) < 0) 79 goto err; 80 81 if (sepol_iface_set_name(handle, tmp_record, name) < 0) 82 goto err; 83 84 if (context_to_record(handle, policydb, ifcon, &tmp_con) < 0) 85 goto err; 86 if (sepol_iface_set_ifcon(handle, tmp_record, tmp_con) < 0) 87 goto err; 88 sepol_context_free(tmp_con); 89 tmp_con = NULL; 90 91 if (context_to_record(handle, policydb, msgcon, &tmp_con) < 0) 92 goto err; 93 if (sepol_iface_set_msgcon(handle, tmp_record, tmp_con) < 0) 94 goto err; 95 sepol_context_free(tmp_con); 96 tmp_con = NULL; 97 98 *record = tmp_record; 99 return STATUS_SUCCESS; 100 101 err: 102 ERR(handle, "could not convert interface %s to record", name); 103 sepol_context_free(tmp_con); 104 sepol_iface_free(tmp_record); 105 return STATUS_ERR; 106 } 107 108 /* Check if an interface exists */ 109 int sepol_iface_exists(sepol_handle_t * handle __attribute__ ((unused)), 110 const sepol_policydb_t * p, 111 const sepol_iface_key_t * key, int *response) 112 { 113 114 const policydb_t *policydb = &p->p; 115 ocontext_t *c, *head; 116 117 const char *name; 118 sepol_iface_key_unpack(key, &name); 119 120 head = policydb->ocontexts[OCON_NETIF]; 121 for (c = head; c; c = c->next) { 122 if (!strcmp(name, c->u.name)) { 123 *response = 1; 124 return STATUS_SUCCESS; 125 } 126 } 127 *response = 0; 128 129 return STATUS_SUCCESS; 130 } 131 132 /* Query an interface */ 133 int sepol_iface_query(sepol_handle_t * handle, 134 const sepol_policydb_t * p, 135 const sepol_iface_key_t * key, sepol_iface_t ** response) 136 { 137 138 const policydb_t *policydb = &p->p; 139 ocontext_t *c, *head; 140 141 const char *name; 142 sepol_iface_key_unpack(key, &name); 143 144 head = policydb->ocontexts[OCON_NETIF]; 145 for (c = head; c; c = c->next) { 146 if (!strcmp(name, c->u.name)) { 147 148 if (iface_to_record(handle, policydb, c, response) < 0) 149 goto err; 150 151 return STATUS_SUCCESS; 152 } 153 } 154 155 *response = NULL; 156 return STATUS_SUCCESS; 157 158 err: 159 ERR(handle, "could not query interface %s", name); 160 return STATUS_ERR; 161 } 162 163 /* Load an interface into policy */ 164 int sepol_iface_modify(sepol_handle_t * handle, 165 sepol_policydb_t * p, 166 const sepol_iface_key_t * key, 167 const sepol_iface_t * data) 168 { 169 170 policydb_t *policydb = &p->p; 171 ocontext_t *head, *prev, *c, *iface = NULL; 172 173 const char *name; 174 sepol_iface_key_unpack(key, &name); 175 176 if (iface_from_record(handle, policydb, &iface, data) < 0) 177 goto err; 178 179 prev = NULL; 180 head = policydb->ocontexts[OCON_NETIF]; 181 for (c = head; c; c = c->next) { 182 if (!strcmp(name, c->u.name)) { 183 184 /* Replace */ 185 iface->next = c->next; 186 if (prev == NULL) 187 policydb->ocontexts[OCON_NETIF] = iface; 188 else 189 prev->next = iface; 190 free(c->u.name); 191 context_destroy(&c->context[0]); 192 context_destroy(&c->context[1]); 193 free(c); 194 195 return STATUS_SUCCESS; 196 } 197 prev = c; 198 } 199 200 /* Attach to context list */ 201 iface->next = policydb->ocontexts[OCON_NETIF]; 202 policydb->ocontexts[OCON_NETIF] = iface; 203 return STATUS_SUCCESS; 204 205 err: 206 ERR(handle, "error while loading interface %s", name); 207 208 if (iface != NULL) { 209 free(iface->u.name); 210 context_destroy(&iface->context[0]); 211 context_destroy(&iface->context[1]); 212 free(iface); 213 } 214 return STATUS_ERR; 215 } 216 217 /* Return the number of interfaces */ 218 extern int sepol_iface_count(sepol_handle_t * handle __attribute__ ((unused)), 219 const sepol_policydb_t * p, unsigned int *response) 220 { 221 222 unsigned int count = 0; 223 ocontext_t *c, *head; 224 const policydb_t *policydb = &p->p; 225 226 head = policydb->ocontexts[OCON_NETIF]; 227 for (c = head; c != NULL; c = c->next) 228 count++; 229 230 *response = count; 231 232 return STATUS_SUCCESS; 233 } 234 235 int sepol_iface_iterate(sepol_handle_t * handle, 236 const sepol_policydb_t * p, 237 int (*fn) (const sepol_iface_t * iface, 238 void *fn_arg), void *arg) 239 { 240 241 const policydb_t *policydb = &p->p; 242 ocontext_t *c, *head; 243 sepol_iface_t *iface = NULL; 244 245 head = policydb->ocontexts[OCON_NETIF]; 246 for (c = head; c; c = c->next) { 247 int status; 248 249 if (iface_to_record(handle, policydb, c, &iface) < 0) 250 goto err; 251 252 /* Invoke handler */ 253 status = fn(iface, arg); 254 if (status < 0) 255 goto err; 256 257 sepol_iface_free(iface); 258 iface = NULL; 259 260 /* Handler requested exit */ 261 if (status > 0) 262 break; 263 } 264 265 return STATUS_SUCCESS; 266 267 err: 268 ERR(handle, "could not iterate over interfaces"); 269 sepol_iface_free(iface); 270 return STATUS_ERR; 271 } 272