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 handle = NULL; 130 return STATUS_SUCCESS; 131 } 132 133 /* Query an interface */ 134 int sepol_iface_query(sepol_handle_t * handle, 135 const sepol_policydb_t * p, 136 const sepol_iface_key_t * key, sepol_iface_t ** response) 137 { 138 139 const policydb_t *policydb = &p->p; 140 ocontext_t *c, *head; 141 142 const char *name; 143 sepol_iface_key_unpack(key, &name); 144 145 head = policydb->ocontexts[OCON_NETIF]; 146 for (c = head; c; c = c->next) { 147 if (!strcmp(name, c->u.name)) { 148 149 if (iface_to_record(handle, policydb, c, response) < 0) 150 goto err; 151 152 return STATUS_SUCCESS; 153 } 154 } 155 156 *response = NULL; 157 return STATUS_SUCCESS; 158 159 err: 160 ERR(handle, "could not query interface %s", name); 161 return STATUS_ERR; 162 } 163 164 /* Load an interface into policy */ 165 int sepol_iface_modify(sepol_handle_t * handle, 166 sepol_policydb_t * p, 167 const sepol_iface_key_t * key, 168 const sepol_iface_t * data) 169 { 170 171 policydb_t *policydb = &p->p; 172 ocontext_t *head, *prev, *c, *iface = NULL; 173 174 const char *name; 175 sepol_iface_key_unpack(key, &name); 176 177 if (iface_from_record(handle, policydb, &iface, data) < 0) 178 goto err; 179 180 prev = NULL; 181 head = policydb->ocontexts[OCON_NETIF]; 182 for (c = head; c; c = c->next) { 183 if (!strcmp(name, c->u.name)) { 184 185 /* Replace */ 186 iface->next = c->next; 187 if (prev == NULL) 188 policydb->ocontexts[OCON_NETIF] = iface; 189 else 190 prev->next = iface; 191 free(c->u.name); 192 context_destroy(&c->context[0]); 193 context_destroy(&c->context[1]); 194 free(c); 195 196 return STATUS_SUCCESS; 197 } 198 prev = c; 199 } 200 201 /* Attach to context list */ 202 iface->next = policydb->ocontexts[OCON_NETIF]; 203 policydb->ocontexts[OCON_NETIF] = iface; 204 return STATUS_SUCCESS; 205 206 err: 207 ERR(handle, "error while loading interface %s", name); 208 209 if (iface != NULL) { 210 free(iface->u.name); 211 context_destroy(&iface->context[0]); 212 context_destroy(&iface->context[1]); 213 free(iface); 214 } 215 return STATUS_ERR; 216 } 217 218 /* Return the number of interfaces */ 219 extern int sepol_iface_count(sepol_handle_t * handle __attribute__ ((unused)), 220 const sepol_policydb_t * p, unsigned int *response) 221 { 222 223 unsigned int count = 0; 224 ocontext_t *c, *head; 225 const policydb_t *policydb = &p->p; 226 227 head = policydb->ocontexts[OCON_NETIF]; 228 for (c = head; c != NULL; c = c->next) 229 count++; 230 231 *response = count; 232 233 handle = NULL; 234 return STATUS_SUCCESS; 235 } 236 237 int sepol_iface_iterate(sepol_handle_t * handle, 238 const sepol_policydb_t * p, 239 int (*fn) (const sepol_iface_t * iface, 240 void *fn_arg), void *arg) 241 { 242 243 const policydb_t *policydb = &p->p; 244 ocontext_t *c, *head; 245 sepol_iface_t *iface = NULL; 246 247 head = policydb->ocontexts[OCON_NETIF]; 248 for (c = head; c; c = c->next) { 249 int status; 250 251 if (iface_to_record(handle, policydb, c, &iface) < 0) 252 goto err; 253 254 /* Invoke handler */ 255 status = fn(iface, arg); 256 if (status < 0) 257 goto err; 258 259 sepol_iface_free(iface); 260 iface = NULL; 261 262 /* Handler requested exit */ 263 if (status > 0) 264 break; 265 } 266 267 return STATUS_SUCCESS; 268 269 err: 270 ERR(handle, "could not iterate over interfaces"); 271 sepol_iface_free(iface); 272 return STATUS_ERR; 273 } 274