int semanage_bool_list(semanage_handle_t * handle, semanage_bool_t *** records, unsigned int *count) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_list(handle, dconfig, records, count); }
int semanage_bool_exists(semanage_handle_t * handle, const semanage_bool_key_t * key, int *response) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_exists(handle, dconfig, key, response); }
int semanage_bool_iterate(semanage_handle_t * handle, int (*handler) (const semanage_bool_t * record, void *varg), void *handler_arg) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_iterate(handle, dconfig, handler, handler_arg); }
int semanage_bool_query(semanage_handle_t * handle, const semanage_bool_key_t * key, semanage_bool_t ** response) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_query(handle, dconfig, key, response); }
static int semanage_direct_disconnect(semanage_handle_t *sh) { /* destroy transaction */ if (sh->is_in_transaction) { /* destroy sandbox */ if (semanage_remove_directory(semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)) < 0) { ERR(sh, "Could not cleanly remove sandbox %s.", semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); return -1; } semanage_release_trans_lock(sh); } /* Release object databases: local modifications */ user_base_file_dbase_release(semanage_user_base_dbase_local(sh)); user_extra_file_dbase_release(semanage_user_extra_dbase_local(sh)); user_join_dbase_release(semanage_user_dbase_local(sh)); port_file_dbase_release(semanage_port_dbase_local(sh)); iface_file_dbase_release(semanage_iface_dbase_local(sh)); bool_file_dbase_release(semanage_bool_dbase_local(sh)); fcontext_file_dbase_release(semanage_fcontext_dbase_local(sh)); seuser_file_dbase_release(semanage_seuser_dbase_local(sh)); node_file_dbase_release(semanage_node_dbase_local(sh)); /* Release object databases: local modifications + policy */ user_base_policydb_dbase_release(semanage_user_base_dbase_policy(sh)); user_extra_file_dbase_release(semanage_user_extra_dbase_policy(sh)); user_join_dbase_release(semanage_user_dbase_policy(sh)); port_policydb_dbase_release(semanage_port_dbase_policy(sh)); iface_policydb_dbase_release(semanage_iface_dbase_policy(sh)); bool_policydb_dbase_release(semanage_bool_dbase_policy(sh)); fcontext_file_dbase_release(semanage_fcontext_dbase_policy(sh)); seuser_file_dbase_release(semanage_seuser_dbase_policy(sh)); node_policydb_dbase_release(semanage_node_dbase_policy(sh)); /* Release object databases: active kernel policy */ bool_activedb_dbase_release(semanage_bool_dbase_active(sh)); return 0; }
int semanage_base_merge_components( semanage_handle_t* handle) { unsigned int i,j; int rc = STATUS_SUCCESS; /* Order is important here - change things carefully. * System components first, local next. Verify runs with * mutual dependencies are ran after everything is merged */ load_table_t components[] = { { semanage_user_base_dbase_local(handle), semanage_user_base_dbase_policy(handle), MODE_MODIFY }, { semanage_user_extra_dbase_local(handle), semanage_user_extra_dbase_policy(handle), MODE_MODIFY }, { semanage_port_dbase_local(handle), semanage_port_dbase_policy(handle), MODE_MODIFY }, { semanage_iface_dbase_local(handle), semanage_iface_dbase_policy(handle), MODE_MODIFY }, { semanage_bool_dbase_local(handle), semanage_bool_dbase_policy(handle), MODE_SET }, { semanage_fcontext_dbase_local(handle), semanage_fcontext_dbase_policy(handle), MODE_MODIFY }, { semanage_seuser_dbase_local(handle), semanage_seuser_dbase_policy(handle), MODE_MODIFY }, { semanage_node_dbase_local(handle), semanage_node_dbase_policy(handle), MODE_MODIFY | MODE_SORT }, }; const unsigned int CCOUNT = sizeof(components)/sizeof(components[0]); /* Merge components into policy (and validate) */ for (i = 0; i < CCOUNT; i++) { record_t** records = NULL; unsigned int nrecords = 0; dbase_config_t* src = components[i].src; dbase_config_t* dst = components[i].dst; int mode = components[i].mode; record_table_t* rtable = src->dtable->get_rtable(src->dbase); /* Must invoke cache function first */ if (src->dtable->cache(handle, src->dbase) < 0) goto err; if (dst->dtable->cache(handle, dst->dbase) < 0) goto err; /* List all records */ if (src->dtable->list(handle, src->dbase, &records, &nrecords) < 0) goto err; /* Sort records on MODE_SORT */ if (mode & MODE_SORT) { qsort(records, nrecords, sizeof(record_t*), (int (*) (const void*, const void*)) rtable->compare2_qsort); } /* Clear obsolete ones for MODE_SET */ if (mode & MODE_SET && clear_obsolete(handle, records, nrecords, src, dst) < 0) { rc = STATUS_ERR; goto dbase_exit; } /* Load records */ if (load_records(handle, dst, records, nrecords, mode) < 0) { rc = STATUS_ERR; goto dbase_exit; } /* Cleanup */ dbase_exit: for (j = 0; j < nrecords; j++) rtable->free(records[j]); free(records); /* Abort on error */ if (rc < 0) goto err; } return rc; err: ERR(handle, "could not merge local modifications into policy"); return STATUS_ERR; }
int semanage_bool_count(semanage_handle_t * handle, unsigned int *response) { dbase_config_t *dconfig = semanage_bool_dbase_policy(handle); return dbase_count(handle, dconfig, response); }
/* Check that the module store exists, creating it if necessary. */ int semanage_direct_connect(semanage_handle_t *sh) { char polpath[PATH_MAX]; snprintf(polpath, PATH_MAX, "%s%s", selinux_path(), sh->conf->store_path); if (semanage_check_init(polpath)) goto err; if (sh->create_store) if (semanage_create_store(sh, 1)) goto err; if (semanage_access_check(sh) < SEMANAGE_CAN_READ) goto err; sh->u.direct.translock_file_fd = -1; sh->u.direct.activelock_file_fd = -1; /* set up function pointers */ sh->funcs = &direct_funcs; /* Object databases: local modifications */ if (user_base_file_dbase_init(sh, semanage_fname(SEMANAGE_USERS_BASE_LOCAL), semanage_user_base_dbase_local(sh)) < 0) goto err; if (user_extra_file_dbase_init(sh, semanage_fname(SEMANAGE_USERS_EXTRA_LOCAL), semanage_user_extra_dbase_local(sh)) < 0) goto err; if (user_join_dbase_init(sh, semanage_user_base_dbase_local(sh), semanage_user_extra_dbase_local(sh), semanage_user_dbase_local(sh)) < 0) goto err; if (port_file_dbase_init(sh, semanage_fname(SEMANAGE_PORTS_LOCAL), semanage_port_dbase_local(sh)) < 0) goto err; if (iface_file_dbase_init(sh, semanage_fname(SEMANAGE_INTERFACES_LOCAL), semanage_iface_dbase_local(sh)) < 0) goto err; if (bool_file_dbase_init(sh, semanage_fname(SEMANAGE_BOOLEANS_LOCAL), semanage_bool_dbase_local(sh)) < 0) goto err; if (fcontext_file_dbase_init(sh, semanage_fname(SEMANAGE_FC_LOCAL), semanage_fcontext_dbase_local(sh)) < 0) goto err; if (seuser_file_dbase_init(sh, semanage_fname(SEMANAGE_SEUSERS_LOCAL), semanage_seuser_dbase_local(sh)) < 0) goto err; if (node_file_dbase_init(sh, semanage_fname(SEMANAGE_NODES_LOCAL), semanage_node_dbase_local(sh)) < 0) goto err; /* Object databases: local modifications + policy */ if (user_base_policydb_dbase_init(sh, semanage_user_base_dbase_policy(sh)) < 0) goto err; if (user_extra_file_dbase_init(sh, semanage_fname(SEMANAGE_USERS_EXTRA), semanage_user_extra_dbase_policy(sh)) < 0) goto err; if (user_join_dbase_init(sh, semanage_user_base_dbase_policy(sh), semanage_user_extra_dbase_policy(sh), semanage_user_dbase_policy(sh)) < 0) goto err; if (port_policydb_dbase_init(sh, semanage_port_dbase_policy(sh)) < 0) goto err; if (iface_policydb_dbase_init(sh, semanage_iface_dbase_policy(sh)) < 0) goto err; if (bool_policydb_dbase_init(sh, semanage_bool_dbase_policy(sh)) < 0) goto err; if (fcontext_file_dbase_init(sh, semanage_fname(SEMANAGE_FC), semanage_fcontext_dbase_policy(sh)) < 0) goto err; if (seuser_file_dbase_init(sh, semanage_fname(SEMANAGE_SEUSERS), semanage_seuser_dbase_policy(sh)) < 0) goto err; if (node_policydb_dbase_init(sh, semanage_node_dbase_policy(sh)) < 0) goto err; /* Active kernel policy */ if (bool_activedb_dbase_init(sh, semanage_bool_dbase_active(sh)) < 0) goto err; return STATUS_SUCCESS; err: ERR(sh, "could not establish direct connection"); sepol_handle_destroy(sh->sepolh); return STATUS_ERR; }
/* Commits all changes in sandbox to the actual kernel policy. * Returns commit number on success, -1 on error. */ static int semanage_direct_commit(semanage_handle_t *sh) { char **mod_filenames = NULL; const char *linked_filename = NULL, *ofilename = NULL; sepol_module_package_t *base = NULL; int retval = -1, num_modfiles = 0, i; sepol_policydb_t* out = NULL; /* Declare some variables */ int modified, fcontexts_modified, ports_modified, seusers_modified, users_extra_modified; dbase_config_t* users = semanage_user_dbase_local(sh); dbase_config_t* users_base = semanage_user_base_dbase_local(sh); dbase_config_t* pusers_base = semanage_user_base_dbase_policy(sh); dbase_config_t* users_extra = semanage_user_extra_dbase_local(sh); dbase_config_t* pusers_extra = semanage_user_extra_dbase_policy(sh); dbase_config_t* ports = semanage_port_dbase_local(sh); dbase_config_t* pports = semanage_port_dbase_policy(sh); dbase_config_t* bools = semanage_bool_dbase_local(sh); dbase_config_t* pbools = semanage_bool_dbase_policy(sh); dbase_config_t* ifaces = semanage_iface_dbase_local(sh); dbase_config_t* pifaces = semanage_iface_dbase_policy(sh); dbase_config_t* nodes = semanage_node_dbase_local(sh); dbase_config_t* pnodes = semanage_node_dbase_policy(sh); dbase_config_t* fcontexts = semanage_fcontext_dbase_local(sh); dbase_config_t* pfcontexts = semanage_fcontext_dbase_policy(sh); dbase_config_t* seusers = semanage_seuser_dbase_local(sh); dbase_config_t* pseusers = semanage_seuser_dbase_policy(sh); /* Before we do anything else, flush the join to its component parts. * This *does not* flush to disk automatically */ if (users->dtable->is_modified(users->dbase) && users->dtable->flush(sh, users->dbase) < 0) goto cleanup; /* Decide if anything was modified */ fcontexts_modified = fcontexts->dtable->is_modified(fcontexts->dbase); seusers_modified = seusers->dtable->is_modified(seusers->dbase); users_extra_modified = users_extra->dtable->is_modified(users_extra->dbase); ports_modified = ports->dtable->is_modified(ports->dbase); modified = sh->modules_modified; modified |= ports_modified; modified |= users->dtable->is_modified(users_base->dbase); modified |= bools->dtable->is_modified(bools->dbase); modified |= ifaces->dtable->is_modified(ifaces->dbase); modified |= nodes->dtable->is_modified(nodes->dbase); /* FIXME: get rid of these, once we support loading the existing policy, * instead of rebuilding it */ modified |= seusers_modified; modified |= fcontexts_modified; modified |= users_extra_modified; /* If there were policy changes, or explicitly requested, rebuild the policy */ if (sh->do_rebuild || modified) { /* =================== Module expansion =============== */ /* link all modules in the sandbox to the base module */ if (semanage_get_modules_names(sh, &mod_filenames, &num_modfiles) != 0 || semanage_verify_modules(sh, mod_filenames, num_modfiles) == -1 || semanage_link_sandbox(sh, &base) < 0) { goto cleanup; } /* write the linked base */ if ((linked_filename = semanage_path(SEMANAGE_TMP, SEMANAGE_LINKED)) == NULL || semanage_write_module(sh, linked_filename, base) == -1 || semanage_verify_linked(sh) != 0) { goto cleanup; } /* ==================== File-backed ================== */ /* File Contexts */ if ((ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_FC_TMPL)) == NULL || write_file(sh, ofilename, sepol_module_package_get_file_contexts(base), sepol_module_package_get_file_contexts_len(base)) == -1) { goto cleanup; } if (semanage_split_fc(sh)) goto cleanup; pfcontexts->dtable->drop_cache(pfcontexts->dbase); /* Seusers */ if (sepol_module_package_get_seusers_len(base)) { if ((ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_SEUSERS)) == NULL || write_file(sh, ofilename, sepol_module_package_get_seusers(base), sepol_module_package_get_seusers_len(base)) == -1) { goto cleanup; } pseusers->dtable->drop_cache(pseusers->dbase); } else { if (pseusers->dtable->clear(sh, pseusers->dbase) < 0) goto cleanup; } /* Users_extra */ if (sepol_module_package_get_user_extra_len(base)) { if ((ofilename = semanage_path(SEMANAGE_TMP, SEMANAGE_USERS_EXTRA)) == NULL || write_file(sh, ofilename, sepol_module_package_get_user_extra(base), sepol_module_package_get_user_extra_len(base)) == -1) { goto cleanup; } pusers_extra->dtable->drop_cache(pusers_extra->dbase); } else { if (pusers_extra->dtable->clear(sh, pusers_extra->dbase) < 0) goto cleanup; } /* ==================== Policydb-backed ================ */ /* Create new policy object, then attach to policy databases * that work with a policydb */ if (semanage_expand_sandbox(sh, base, &out) < 0) goto cleanup; dbase_policydb_attach((dbase_policydb_t*) pusers_base->dbase, out); dbase_policydb_attach((dbase_policydb_t*) pports->dbase, out); dbase_policydb_attach((dbase_policydb_t*) pifaces->dbase, out); dbase_policydb_attach((dbase_policydb_t*) pbools->dbase, out); dbase_policydb_attach((dbase_policydb_t*) pnodes->dbase, out); /* ============= Apply changes, and verify =============== */ if (semanage_base_merge_components(sh) < 0) goto cleanup; if (semanage_write_policydb(sh, out) < 0) goto cleanup; if (semanage_verify_kernel(sh) != 0) goto cleanup; } /* FIXME: else if !modified, but seusers_modified, * load the existing policy instead of rebuilding */ /* ======= Post-process: Validate non-policydb components ===== */ /* Validate local modifications to file contexts. * Note: those are still cached, even though they've been * merged into the main file_contexts. We won't check the * large file_contexts - checked at compile time */ if (sh->do_rebuild || modified || fcontexts_modified) { if (semanage_fcontext_validate_local(sh, out) < 0) goto cleanup; } /* Validate local seusers against policy */ if (sh->do_rebuild || modified || seusers_modified) { if (semanage_seuser_validate_local(sh, out) < 0) goto cleanup; } /* Validate local ports for overlap */ if (sh->do_rebuild || ports_modified) { if (semanage_port_validate_local(sh) < 0) goto cleanup; } /* ================== Write non-policydb components ========= */ /* Commit changes to components */ if (semanage_commit_components(sh) < 0) goto cleanup; retval = semanage_install_sandbox(sh); cleanup: for (i = 0; mod_filenames != NULL && i < num_modfiles; i++) { free(mod_filenames[i]); } /* Detach from policydb, so it can be freed */ dbase_policydb_detach((dbase_policydb_t*) pusers_base->dbase); dbase_policydb_detach((dbase_policydb_t*) pports->dbase); dbase_policydb_detach((dbase_policydb_t*) pifaces->dbase); dbase_policydb_detach((dbase_policydb_t*) pnodes->dbase); dbase_policydb_detach((dbase_policydb_t*) pbools->dbase); free(mod_filenames); sepol_module_package_free(base); sepol_policydb_free(out); semanage_release_trans_lock(sh); /* regardless if the commit was successful or not, remove the sandbox if it is still there */ semanage_remove_directory(semanage_path(SEMANAGE_TMP, SEMANAGE_TOPLEVEL)); return retval; }