diff -Naur libsepol/include/sepol/booleans.h libsepol.new/include/sepol/booleans.h --- libsepol/include/sepol/booleans.h 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/include/sepol/booleans.h 2005-09-30 18:59:14.000000000 -0400 @@ -16,4 +16,17 @@ sepol_bool_t** bool_arr, size_t bool_arr_len); +/* Iterate the booleans + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_bool_iterate( + policydb_t* policydb, + int (*fn)( + sepol_bool_t* boolean, + void* fn_arg), + void* arg); + #endif diff -Naur libsepol/include/sepol/interfaces.h libsepol.new/include/sepol/interfaces.h --- libsepol/include/sepol/interfaces.h 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/include/sepol/interfaces.h 2005-09-30 18:47:14.000000000 -0400 @@ -17,4 +17,17 @@ policydb_t* policydb, sepol_iface_t* data); +/* Iterate the interfaces + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_iface_iterate( + policydb_t* policydb, + int (*fn)( + sepol_iface_t* iface, + void* fn_arg), + void* arg); + #endif diff -Naur libsepol/include/sepol/ports.h libsepol.new/include/sepol/ports.h --- libsepol/include/sepol/ports.h 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/include/sepol/ports.h 2005-09-30 18:57:14.000000000 -0400 @@ -19,4 +19,17 @@ policydb_t* policydb, sepol_port_t* data); +/* Iterate the ports + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_port_iterate( + policydb_t* policydb, + int (*fn)( + sepol_port_t* port, + void* fn_arg), + void* arg); + #endif diff -Naur libsepol/include/sepol/users.h libsepol.new/include/sepol/users.h --- libsepol/include/sepol/users.h 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/include/sepol/users.h 2005-09-30 18:47:00.000000000 -0400 @@ -32,11 +32,18 @@ policydb_t* policydb, const char* role); -/* Obtain the user list */ -extern int sepol_user_list( +/* Iterate the users + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue */ + +extern int sepol_user_iterate( policydb_t* policydb, - sepol_user_t*** users, - size_t* nusers); + int (*fn)( + sepol_user_t* user, + void* fn_arg), + void* arg); extern int sepol_get_valid_roles( policydb_t* policydb, diff -Naur libsepol/src/booleans.c libsepol.new/src/booleans.c --- libsepol/src/booleans.c 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/src/booleans.c 2005-09-30 19:28:56.000000000 -0400 @@ -93,3 +93,51 @@ DEBUG(__FUNCTION__, "error while loading booleans\n"); return STATUS_ERR; } + +int sepol_bool_iterate( + policydb_t* policydb, + int (*fn)( + sepol_bool_t* boolean, + void* fn_arg), + void* arg) { + + size_t nbools = policydb->p_bools.nprim; + sepol_bool_t* boolean = NULL; + size_t i; + + /* For each boolean */ + for (i = 0; i < nbools; i++) { + + int status; + const char* name = policydb->p_bool_val_to_name[i]; + cond_bool_datum_t* booldatum = policydb->bool_val_to_struct[i]; + int value = booldatum->state; + + if (sepol_bool_create(&boolean) < 0) + goto err; + + if (sepol_bool_set_name(boolean, name) < 0) + goto err; + + sepol_bool_set_value(boolean, value); + + /* Invoke handler */ + status = fn(boolean, arg); + if (status < 0) + goto err; + + sepol_bool_free(boolean); + boolean = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + DEBUG(__FUNCTION__, "could not iterate over booleans\n"); + sepol_bool_free(boolean); + return STATUS_ERR; +} diff -Naur libsepol/src/interfaces.c libsepol.new/src/interfaces.c --- libsepol/src/interfaces.c 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/src/interfaces.c 2005-09-30 19:01:12.000000000 -0400 @@ -131,3 +131,82 @@ free(iface); return STATUS_ERR; } + +int sepol_iface_iterate( + policydb_t* policydb, + int (*fn)( + sepol_iface_t* iface, + void* fn_arg), + void* arg) { + + ocontext_t *c, *l, *head; + sepol_iface_t* iface = NULL; + char* tmp_con_str = NULL; + size_t tmp_con_ssize; + sepol_context_t* tmp_con = NULL; + + head = policydb->ocontexts[OCON_NETIF]; + for (l = NULL, c = head; c; l = c, c = c->next) { + + int status; + char* name = c->u.name; + context_struct_t* ifcon = &c->context[0]; + context_struct_t* msgcon = &c->context[1]; + + if (sepol_iface_create(&iface) < 0) + goto err; + + if (sepol_iface_set_name(iface, name) < 0) + goto err; + + /* Interface context */ + if (sepol_ctx_struct_to_string(policydb, ifcon, + &tmp_con_str, &tmp_con_ssize) < 0) + goto err; + + if (sepol_context_from_string(tmp_con_str, &tmp_con) < 0) + goto err; + free(tmp_con_str); + tmp_con_str = NULL; + + if (sepol_iface_set_ifcon(iface, tmp_con) < 0) + goto err; + tmp_con = NULL; + + /* Message context */ + if (sepol_ctx_struct_to_string(policydb, msgcon, + &tmp_con_str, &tmp_con_ssize) < 0) + goto err; + + if (sepol_context_from_string(tmp_con_str, &tmp_con) < 0) + goto err; + free(tmp_con_str); + tmp_con_str = NULL; + + if (sepol_iface_set_msgcon(iface, tmp_con) < 0) + goto err; + tmp_con = NULL; + + /* Invoke handler */ + status = fn(iface, arg); + if (status < 0) + goto err; + + sepol_iface_free(iface); + iface = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + + err: + DEBUG(__FUNCTION__, "could not iterate over interfaces\n"); + free(tmp_con_str); + sepol_context_free(tmp_con); + sepol_iface_free(iface); + return STATUS_ERR; +} + diff -Naur libsepol/src/ports.c libsepol.new/src/ports.c --- libsepol/src/ports.c 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/src/ports.c 2005-09-30 19:01:22.000000000 -0400 @@ -19,7 +19,20 @@ default: DEBUG(__FUNCTION__, "unsupported protocol %d\n", proto); - return -1; + return STATUS_ERR; + } +} + +static int ipproto2sepol(int proto) { + switch(proto) { + case IPPROTO_TCP: + return SEPOL_PROTO_TCP; + case IPPROTO_UDP: + return SEPOL_PROTO_UDP; + default: + DEBUG(__FUNCTION__, "invalid protocol %d " + "found in policy\n", proto); + return STATUS_ERR; } } @@ -158,3 +171,71 @@ free(port); return STATUS_ERR; } + +int sepol_port_iterate( + policydb_t* policydb, + int (*fn)( + sepol_port_t* port, + void* fn_arg), + void* arg) { + + ocontext_t *c, *l, *head; + sepol_port_t* port = NULL; + char* tmp_con_str = NULL; + size_t tmp_con_ssize; + sepol_context_t* tmp_con = NULL; + + head = policydb->ocontexts[OCON_PORT]; + for (l = NULL, c = head; c; l = c, c = c->next) { + + int status; + int proto = c->u.port.protocol; + int low = c->u.port.low_port; + int high = c->u.port.high_port; + context_struct_t* con = &c->context[0]; + + if (sepol_port_create(&port) < 0) + goto err; + + if (sepol_port_set_proto(port, ipproto2sepol(proto)) < 0) + goto err; + + if (sepol_port_set_range(port, low, high) < 0) + goto err; + + if (sepol_ctx_struct_to_string(policydb, con, + &tmp_con_str, &tmp_con_ssize) < 0) + goto err; + + if (sepol_context_from_string(tmp_con_str, &tmp_con) < 0) + goto err; + free(tmp_con_str); + tmp_con_str = NULL; + + if (sepol_port_set_con(port, tmp_con) < 0) + goto err; + tmp_con = NULL; + + /* Invoke handler */ + status = fn(port, arg); + if (status < 0) + goto err; + + sepol_port_free(port); + port = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + + return STATUS_SUCCESS; + + err: + DEBUG(__FUNCTION__, "could not iterate over ports\n"); + free(tmp_con_str); + sepol_context_free(tmp_con); + sepol_port_free(port); + return STATUS_ERR; +} diff -Naur libsepol/src/users.c libsepol.new/src/users.c --- libsepol/src/users.c 2005-09-30 16:19:08.000000000 -0400 +++ libsepol.new/src/users.c 2005-09-30 18:57:34.000000000 -0400 @@ -365,40 +365,38 @@ /* Fill an array with all valid users */ -int sepol_user_list( +int sepol_user_iterate( policydb_t* policydb, - sepol_user_t*** users, - size_t* nusers) { + int (*fn)( + sepol_user_t* user, + void* fn_arg), + void* arg) { - size_t tmp_nusers = policydb->p_users.nprim; - sepol_user_t** tmp_users = - (sepol_user_t**) calloc(tmp_nusers, sizeof(sepol_user_t*)); - - sepol_user_t** ptr; + size_t nusers = policydb->p_users.nprim; + sepol_user_t* user = NULL; size_t i; - if (!tmp_users) - goto omem; /* For each user */ - for (i = 0; i < tmp_nusers; i++) { - + for (i = 0; i < nusers; i++) { + + int status; const char* name = policydb->p_user_val_to_name[i]; user_datum_t* usrdatum = policydb->user_val_to_struct[i]; ebitmap_t* roles = &(usrdatum->roles.roles); ebitmap_node_t* rnode; unsigned bit; - if (sepol_user_create(&tmp_users[i]) < 0) + if (sepol_user_create(&user) < 0) goto err; - if (sepol_user_set_name(tmp_users[i], name) < 0) + if (sepol_user_set_name(user, name) < 0) goto err; /* Extract roles */ ebitmap_for_each_bit(roles, rnode, bit) { if (ebitmap_node_get_bit(rnode, bit)) { char* role = policydb->p_role_val_to_name[bit]; - if (sepol_user_add_role(tmp_users[i], role) < 0) + if (sepol_user_add_role(user, role) < 0) goto err; } } @@ -417,7 +415,7 @@ if (mls_struct_to_string(policydb, &context, &str) < 0) goto err; - if (sepol_user_set_mlslevel(tmp_users[i], str) < 0 ) { + if (sepol_user_set_mlslevel(user, str) < 0 ) { free(str); goto err; } @@ -429,29 +427,31 @@ if (mls_struct_to_string(policydb, &context, &str) < 0) goto err; - if (sepol_user_set_mlsrange(tmp_users[i], str) < 0) { + if (sepol_user_set_mlsrange(user, str) < 0) { free(str); goto err; } free(str); } - } - *nusers = tmp_nusers; - *users = tmp_users; + /* Invoke handler */ + status = fn(user, arg); + if (status < 0) + goto err; - return STATUS_SUCCESS; + sepol_user_free(user); + user = NULL; - omem: - DEBUG(__FUNCTION__, "out of memory\n"); + /* Handler requested exit */ + if (status > 0) + break; + } - err: - DEBUG(__FUNCTION__, "could not enumerate users\n"); + return STATUS_SUCCESS; - ptr = tmp_users; - while (ptr && (*ptr != NULL)) - sepol_user_free(*ptr++); - free(tmp_users); + err: + DEBUG(__FUNCTION__, "could not iterate over users\n"); + sepol_user_free(user); return STATUS_ERR; }