int semanage_fcontext_del_local(
	semanage_handle_t* handle,
	const semanage_fcontext_key_t* key) {

	dbase_config_t* dconfig = semanage_fcontext_dbase_local(handle);
	return dbase_del(handle, dconfig, key);
}
int semanage_fcontext_count_local(
	semanage_handle_t* handle,
	unsigned int* response) {

	dbase_config_t* dconfig = semanage_fcontext_dbase_local(handle);
	return dbase_count(handle, dconfig, response);
}
int semanage_fcontext_list_local(
	semanage_handle_t* handle,
	semanage_fcontext_t*** records,
	unsigned int* count) {

	dbase_config_t* dconfig = semanage_fcontext_dbase_local(handle);
	return dbase_list(handle, dconfig, records, count);
}
int semanage_fcontext_exists_local(
	semanage_handle_t* handle,
	const semanage_fcontext_key_t* key,
	int* response) {

	dbase_config_t* dconfig = semanage_fcontext_dbase_local(handle);
	return dbase_exists(handle, dconfig, key, response);
}
int semanage_fcontext_query_local(
	semanage_handle_t* handle,
	const semanage_fcontext_key_t* key,
	semanage_fcontext_t** response) {

	dbase_config_t* dconfig = semanage_fcontext_dbase_local(handle);
	return dbase_query(handle, dconfig, key, response);
}
int semanage_fcontext_modify_local(
	semanage_handle_t* handle,
	const semanage_fcontext_key_t* key,
	const semanage_fcontext_t* data) {

	dbase_config_t* dconfig = semanage_fcontext_dbase_local(handle);	
	return dbase_modify(handle, dconfig, key, data);
}
Example #7
0
int semanage_fcontext_iterate_local(semanage_handle_t * handle,
				    int (*handler) (const semanage_fcontext_t *
						    record, void *varg),
				    void *handler_arg)
{

	dbase_config_t *dconfig = semanage_fcontext_dbase_local(handle);
	return dbase_iterate(handle, dconfig, handler, handler_arg);
}
Example #8
0
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_commit_components(
	semanage_handle_t* handle) {

	int i;
	dbase_config_t* components[] = {
		semanage_iface_dbase_local(handle),
		semanage_bool_dbase_local(handle),
		semanage_user_base_dbase_local(handle),
		semanage_user_extra_dbase_local(handle),
		semanage_user_extra_dbase_policy(handle),
		semanage_port_dbase_local(handle),
		semanage_fcontext_dbase_local(handle),
		semanage_fcontext_dbase_policy(handle),
		semanage_seuser_dbase_local(handle),
		semanage_seuser_dbase_policy(handle),
		semanage_bool_dbase_active(handle),
		semanage_node_dbase_local(handle),
	};
	const int CCOUNT = sizeof(components)/sizeof(components[0]);

	for (i = 0; i < CCOUNT; i++) {
		/* Flush to disk */
		if (components[i]->dtable->flush(
			handle, components[i]->dbase) < 0)
			goto err;
	}

	return STATUS_SUCCESS;

	err:
	ERR(handle, "could not commit local/active modifications");

	for (i=0; i < CCOUNT; i++) 
		components[i]->dtable->drop_cache(components[i]->dbase);
	return STATUS_ERR;
}
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;
}
Example #11
0
/* 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;
}
Example #12
0
/* 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;
}