コード例 #1
0
int user_base_policydb_dbase_init(semanage_handle_t * handle,
				  dbase_config_t * dconfig)
{

	if (dbase_policydb_init(handle,
				semanage_path(SEMANAGE_ACTIVE, SEMANAGE_STORE_KERNEL),
				semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_KERNEL),
				&SEMANAGE_USER_BASE_RTABLE,
				&SEMANAGE_USER_BASE_POLICYDB_RTABLE,
				&dconfig->dbase) < 0)
		return STATUS_ERR;

	dconfig->dtable = &SEMANAGE_POLICYDB_DTABLE;
	return STATUS_SUCCESS;
}
コード例 #2
0
ファイル: direct_api.c プロジェクト: OpenDarwin-CVS/SEDarwin
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;
}
コード例 #3
0
ファイル: direct_api.c プロジェクト: OpenDarwin-CVS/SEDarwin
/* Writes a base module into a sandbox, overwriting any previous base
 * module.  Note that 'module_data' is not free()d by this function;
 * caller is responsible for deallocating it if necessary.  Returns 0
 * on success, -1 if out of memory, -2 if the data does not represent
 * a valid base module file, -3 if error while writing file.
 */
static int semanage_direct_install_base(semanage_handle_t *sh,
					char *base_data, size_t data_len) {
	int retval = -1;
	const char *filename = NULL;
	if ((retval = parse_base_headers(sh, base_data, data_len)) != 0) {
		goto cleanup;
	}
	if ((filename = semanage_path(SEMANAGE_TMP, SEMANAGE_BASE)) == NULL) {
		goto cleanup;
	}
	if (write_file(sh, filename, base_data, data_len) == -1) {
		retval = -3;
	}
	retval = 0;
 cleanup:
	return retval;
}
コード例 #4
0
ファイル: direct_api.c プロジェクト: OpenDarwin-CVS/SEDarwin
/* Takes a module stored in 'module_data' and parses its headers.
 * Sets reference variables 'filename' to module's fully qualified
 * path name into the sandbox, 'module_name' to module's name, and
 * 'version' to module's version.  The caller is responsible for
 * free()ing 'filename', 'module_name', and 'version'; they will be
 * set to NULL upon entering this function.  Returns 0 on success, -1
 * if out of memory, or -2 if data did not represent a module.
 */
static int parse_module_headers(semanage_handle_t *sh, char *module_data,
				size_t data_len, char **module_name,
				char **version, char **filename) {
	struct sepol_policy_file *pf;
	int file_type;
	const char *module_path;
	*module_name = *version = *filename = NULL;
	
	if (sepol_policy_file_create(&pf)) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	sepol_policy_file_set_mem(pf, module_data, data_len);
	sepol_policy_file_set_handle(pf, sh->sepolh);
	if (module_data == NULL ||
	    data_len == 0 ||
	    sepol_module_package_info(pf, &file_type, module_name,
				      version) == -1) {
		sepol_policy_file_free(pf);
		ERR(sh, "Could not parse module data.");
		return -2;
	}
	sepol_policy_file_free(pf);
	if (file_type != SEPOL_POLICY_MOD) {
		if (file_type == SEPOL_POLICY_BASE)
			ERR(sh, "Received a base module, expected a non-base module.");
		else
			ERR(sh, "Data did not represent a module.");
		return -2;
	}
	if ((module_path = semanage_path(SEMANAGE_TMP, SEMANAGE_MODULES)) == NULL) {
		return -1;
	}
	if (asprintf(filename, "%s/%s.pp", module_path, *module_name) == -1) {
		ERR(sh, "Out of memory!");
		return -1;
	}
	return 0;
}
コード例 #5
0
ファイル: direct_api.c プロジェクト: OpenDarwin-CVS/SEDarwin
/* 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;
}