/*
 * security/tomoyo/domain.c
 *
 * Implementation of the Domain-Based Mandatory Access Control.
 *
 * Copyright (C) 2005-2009  NTT DATA CORPORATION
 *
 * Version: 2.2.0-pre   2009/02/01
 *
 */

#include "common.h"
#include "tomoyo.h"
#include "realpath.h"
#include <linux/binfmts.h>

/* Variables definitions.*/

/* The initial domain. */
struct tomoyo_domain_info tomoyo_kernel_domain;

/* The list for "struct tomoyo_domain_info". */
LIST_HEAD(tomoyo_domain_list);
DECLARE_RWSEM(tomoyo_domain_list_lock);

/* Structure for "initialize_domain" and "no_initialize_domain" keyword. */
struct tomoyo_domain_initializer_entry {
	struct list_head list;
	const struct tomoyo_path_info *domainname;    /* This may be NULL */
	const struct tomoyo_path_info *program;
	bool is_deleted;
	bool is_not;       /* True if this entry is "no_initialize_domain".  */
	/* True if the domainname is tomoyo_get_last_name(). */
	bool is_last_name;
};

/* Structure for "keep_domain" and "no_keep_domain" keyword. */
struct tomoyo_domain_keeper_entry {
	struct list_head list;
	const struct tomoyo_path_info *domainname;
	const struct tomoyo_path_info *program;       /* This may be NULL */
	bool is_deleted;
	bool is_not;       /* True if this entry is "no_keep_domain".        */
	/* True if the domainname is tomoyo_get_last_name(). */
	bool is_last_name;
};

/* Structure for "alias" keyword. */
struct tomoyo_alias_entry {
	struct list_head list;
	const struct tomoyo_path_info *original_name;
	const struct tomoyo_path_info *aliased_name;
	bool is_deleted;
};

/**
 * tomoyo_set_domain_flag - Set or clear domain's attribute flags.
 *
 * @domain:    Pointer to "struct tomoyo_domain_info".
 * @is_delete: True if it is a delete request.
 * @flags:     Flags to set or clear.
 *
 * Returns nothing.
 */
void tomoyo_set_domain_flag(struct tomoyo_domain_info *domain,
			    const bool is_delete, const u8 flags)
{
	/* We need to serialize because this is bitfield operation. */
	static DEFINE_SPINLOCK(lock);
	/***** CRITICAL SECTION START *****/
	spin_lock(&lock);
	if (!is_delete)
		domain->flags |= flags;
	else
		domain->flags &= ~flags;
	spin_unlock(&lock);
	/***** CRITICAL SECTION END *****/
}

/**
 * tomoyo_get_last_name - Get last component of a domainname.
 *
 * @domain: Pointer to "struct tomoyo_domain_info".
 *
 * Returns the last component of the domainname.
 */
const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain)
{
	const char *cp0 = domain->domainname->name;
	const char *cp1 = strrchr(cp0, ' ');

	if (cp1)
		return cp1 + 1;
	return cp0;
}

/* The list for "struct tomoyo_domain_initializer_entry". */
static LIST_HEAD(tomoyo_domain_initializer_list);
static DECLARE_RWSEM(tomoyo_domain_initializer_list_lock);

/**
 * tomoyo_update_domain_initializer_entry - Update "struct tomoyo_domain_initializer_entry" list.
 *
 * @domainname: The name of domain. May be NULL.
 * @program:    The name of program.
 * @is_not:     True if it is "no_initialize_domain" entry.
 * @is_delete:  True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_domain_initializer_entry(const char *domainname,
						  const char *program,
						  const bool is_not,
						  const bool is_delete)
{
	struct tomoyo_domain_initializer_entry *new_entry;
	struct tomoyo_domain_initializer_entry *ptr;
	const struct tomoyo_path_info *saved_program;
	const struct tomoyo_path_info *saved_domainname = NULL;
	int error = -ENOMEM;
	bool is_last_name = false;

	if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
		return -EINVAL; /* No patterns allowed. */
	if (domainname) {
		if (!tomoyo_is_domain_def(domainname) &&
		    tomoyo_is_correct_path(domainname, 1, -1, -1, __func__))
			is_last_name = true;
		else if (!tomoyo_is_correct_domain(domainname, __func__))
			return -EINVAL;
		saved_domainname = tomoyo_save_name(domainname);
		if (!saved_domainname)
			return -ENOMEM;
	}
	saved_program = tomoyo_save_name(program);
	if (!saved_program)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_domain_initializer_list_lock);
	list_for_each_entry(ptr, &tomoyo_domain_initializer_list, list) {
		if (ptr->is_not != is_not ||
		    ptr->domainname != saved_domainname ||
		    ptr->program != saved_program)
			continue;
		ptr->is_deleted = is_delete;
		error = 0;
		goto out;
	}
	if (is_delete) {
		error = -ENOENT;
		goto out;
	}
	new_entry = tomoyo_alloc_element(sizeof(*new_entry));
	if (!new_entry)
		goto out;
	new_entry->domainname = saved_domainname;
	new_entry->program = saved_program;
	new_entry->is_not = is_not;
	new_entry->is_last_name = is_last_name;
	list_add_tail(&new_entry->list, &tomoyo_domain_initializer_list);
	error = 0;
 out:
	up_write(&tomoyo_domain_initializer_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_read_domain_initializer_policy - Read "struct tomoyo_domain_initializer_entry" list.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns true on success, false otherwise.
 */
bool tomoyo_read_domain_initializer_policy(struct tomoyo_io_buffer *head)
{
	struct list_head *pos;
	bool done = true;

	down_read(&tomoyo_domain_initializer_list_lock);
	list_for_each_cookie(pos, head->read_var2,
			     &tomoyo_domain_initializer_list) {
		const char *no;
		const char *from = "";
		const char *domain = "";
		struct tomoyo_domain_initializer_entry *ptr;
		ptr = list_entry(pos, struct tomoyo_domain_initializer_entry,
				  list);
		if (ptr->is_deleted)
			continue;
		no = ptr->is_not ? "no_" : "";
		if (ptr->domainname) {
			from = " from ";
			domain = ptr->domainname->name;
		}
		if (!tomoyo_io_printf(head,
				      "%s" TOMOYO_KEYWORD_INITIALIZE_DOMAIN
				      "%s%s%s\n", no, ptr->program->name, from,
				      domain)) {
			done = false;
			break;
		}
	}
	up_read(&tomoyo_domain_initializer_list_lock);
	return done;
}

/**
 * tomoyo_write_domain_initializer_policy - Write "struct tomoyo_domain_initializer_entry" list.
 *
 * @data:      String to parse.
 * @is_not:    True if it is "no_initialize_domain" entry.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_domain_initializer_policy(char *data, const bool is_not,
					   const bool is_delete)
{
	char *cp = strstr(data, " from ");

	if (cp) {
		*cp = '\0';
		return tomoyo_update_domain_initializer_entry(cp + 6, data,
							      is_not,
							      is_delete);
	}
	return tomoyo_update_domain_initializer_entry(NULL, data, is_not,
						      is_delete);
}

/**
 * tomoyo_is_domain_initializer - Check whether the given program causes domainname reinitialization.
 *
 * @domainname: The name of domain.
 * @program:    The name of program.
 * @last_name:  The last component of @domainname.
 *
 * Returns true if executing @program reinitializes domain transition,
 * false otherwise.
 */
static bool tomoyo_is_domain_initializer(const struct tomoyo_path_info *
					 domainname,
					 const struct tomoyo_path_info *program,
					 const struct tomoyo_path_info *
					 last_name)
{
	struct tomoyo_domain_initializer_entry *ptr;
	bool flag = false;

	down_read(&tomoyo_domain_initializer_list_lock);
	list_for_each_entry(ptr,  &tomoyo_domain_initializer_list, list) {
		if (ptr->is_deleted)
			continue;
		if (ptr->domainname) {
			if (!ptr->is_last_name) {
				if (ptr->domainname != domainname)
					continue;
			} else {
				if (tomoyo_pathcmp(ptr->domainname, last_name))
					continue;
			}
		}
		if (tomoyo_pathcmp(ptr->program, program))
			continue;
		if (ptr->is_not) {
			flag = false;
			break;
		}
		flag = true;
	}
	up_read(&tomoyo_domain_initializer_list_lock);
	return flag;
}

/* The list for "struct tomoyo_domain_keeper_entry". */
static LIST_HEAD(tomoyo_domain_keeper_list);
static DECLARE_RWSEM(tomoyo_domain_keeper_list_lock);

/**
 * tomoyo_update_domain_keeper_entry - Update "struct tomoyo_domain_keeper_entry" list.
 *
 * @domainname: The name of domain.
 * @program:    The name of program. May be NULL.
 * @is_not:     True if it is "no_keep_domain" entry.
 * @is_delete:  True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_domain_keeper_entry(const char *domainname,
					     const char *program,
					     const bool is_not,
					     const bool is_delete)
{
	struct tomoyo_domain_keeper_entry *new_entry;
	struct tomoyo_domain_keeper_entry *ptr;
	const struct tomoyo_path_info *saved_domainname;
	const struct tomoyo_path_info *saved_program = NULL;
	static DEFINE_MUTEX(lock);
	int error = -ENOMEM;
	bool is_last_name = false;

	if (!tomoyo_is_domain_def(domainname) &&
	    tomoyo_is_correct_path(domainname, 1, -1, -1, __func__))
		is_last_name = true;
	else if (!tomoyo_is_correct_domain(domainname, __func__))
		return -EINVAL;
	if (program) {
		if (!tomoyo_is_correct_path(program, 1, -1, -1, __func__))
			return -EINVAL;
		saved_program = tomoyo_save_name(program);
		if (!saved_program)
			return -ENOMEM;
	}
	saved_domainname = tomoyo_save_name(domainname);
	if (!saved_domainname)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_domain_keeper_list_lock);
	list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
		if (ptr->is_not != is_not ||
		    ptr->domainname != saved_domainname ||
		    ptr->program != saved_program)
			continue;
		ptr->is_deleted = is_delete;
		error = 0;
		goto out;
	}
	if (is_delete) {
		error = -ENOENT;
		goto out;
	}
	new_entry = tomoyo_alloc_element(sizeof(*new_entry));
	if (!new_entry)
		goto out;
	new_entry->domainname = saved_domainname;
	new_entry->program = saved_program;
	new_entry->is_not = is_not;
	new_entry->is_last_name = is_last_name;
	list_add_tail(&new_entry->list, &tomoyo_domain_keeper_list);
	error = 0;
 out:
	up_write(&tomoyo_domain_keeper_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_write_domain_keeper_policy - Write "struct tomoyo_domain_keeper_entry" list.
 *
 * @data:      String to parse.
 * @is_not:    True if it is "no_keep_domain" entry.
 * @is_delete: True if it is a delete request.
 *
 */
int tomoyo_write_domain_keeper_policy(char *data, const bool is_not,
				      const bool is_delete)
{
	char *cp = strstr(data, " from ");

	if (cp) {
		*cp = '\0';
		return tomoyo_update_domain_keeper_entry(cp + 6, data, is_not,
							 is_delete);
	}
	return tomoyo_update_domain_keeper_entry(data, NULL, is_not, is_delete);
}

/**
 * tomoyo_read_domain_keeper_policy - Read "struct tomoyo_domain_keeper_entry" list.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns true on success, false otherwise.
 */
bool tomoyo_read_domain_keeper_policy(struct tomoyo_io_buffer *head)
{
	struct list_head *pos;
	bool done = true;

	down_read(&tomoyo_domain_keeper_list_lock);
	list_for_each_cookie(pos, head->read_var2,
			     &tomoyo_domain_keeper_list) {
		struct tomoyo_domain_keeper_entry *ptr;
		const char *no;
		const char *from = "";
		const char *program = "";

		ptr = list_entry(pos, struct tomoyo_domain_keeper_entry, list);
		if (ptr->is_deleted)
			continue;
		no = ptr->is_not ? "no_" : "";
		if (ptr->program) {
			from = " from ";
			program = ptr->program->name;
		}
		if (!tomoyo_io_printf(head,
				      "%s" TOMOYO_KEYWORD_KEEP_DOMAIN
				      "%s%s%s\n", no, program, from,
				      ptr->domainname->name)) {
			done = false;
			break;
		}
	}
	up_read(&tomoyo_domain_keeper_list_lock);
	return done;
}

/**
 * tomoyo_is_domain_keeper - Check whether the given program causes domain transition suppression.
 *
 * @domainname: The name of domain.
 * @program:    The name of program.
 * @last_name:  The last component of @domainname.
 *
 * Returns true if executing @program supresses domain transition,
 * false otherwise.
 */
static bool tomoyo_is_domain_keeper(const struct tomoyo_path_info *domainname,
				    const struct tomoyo_path_info *program,
				    const struct tomoyo_path_info *last_name)
{
	struct tomoyo_domain_keeper_entry *ptr;
	bool flag = false;

	down_read(&tomoyo_domain_keeper_list_lock);
	list_for_each_entry(ptr, &tomoyo_domain_keeper_list, list) {
		if (ptr->is_deleted)
			continue;
		if (!ptr->is_last_name) {
			if (ptr->domainname != domainname)
				continue;
		} else {
			if (tomoyo_pathcmp(ptr->domainname, last_name))
				continue;
		}
		if (ptr->program && tomoyo_pathcmp(ptr->program, program))
			continue;
		if (ptr->is_not) {
			flag = false;
			break;
		}
		flag = true;
	}
	up_read(&tomoyo_domain_keeper_list_lock);
	return flag;
}

/* The list for "struct tomoyo_alias_entry". */
static LIST_HEAD(tomoyo_alias_list);
static DECLARE_RWSEM(tomoyo_alias_list_lock);

/**
 * tomoyo_update_alias_entry - Update "struct tomoyo_alias_entry" list.
 *
 * @original_name: The original program's real name.
 * @aliased_name:  The symbolic program's symbolic link's name.
 * @is_delete:     True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
static int tomoyo_update_alias_entry(const char *original_name,
				     const char *aliased_name,
				     const bool is_delete)
{
	struct tomoyo_alias_entry *new_entry;
	struct tomoyo_alias_entry *ptr;
	const struct tomoyo_path_info *saved_original_name;
	const struct tomoyo_path_info *saved_aliased_name;
	int error = -ENOMEM;

	if (!tomoyo_is_correct_path(original_name, 1, -1, -1, __func__) ||
	    !tomoyo_is_correct_path(aliased_name, 1, -1, -1, __func__))
		return -EINVAL; /* No patterns allowed. */
	saved_original_name = tomoyo_save_name(original_name);
	saved_aliased_name = tomoyo_save_name(aliased_name);
	if (!saved_original_name || !saved_aliased_name)
		return -ENOMEM;
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_alias_list_lock);
	list_for_each_entry(ptr, &tomoyo_alias_list, list) {
		if (ptr->original_name != saved_original_name ||
		    ptr->aliased_name != saved_aliased_name)
			continue;
		ptr->is_deleted = is_delete;
		error = 0;
		goto out;
	}
	if (is_delete) {
		error = -ENOENT;
		goto out;
	}
	new_entry = tomoyo_alloc_element(sizeof(*new_entry));
	if (!new_entry)
		goto out;
	new_entry->original_name = saved_original_name;
	new_entry->aliased_name = saved_aliased_name;
	list_add_tail(&new_entry->list, &tomoyo_alias_list);
	error = 0;
 out:
	up_write(&tomoyo_alias_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return error;
}

/**
 * tomoyo_read_alias_policy - Read "struct tomoyo_alias_entry" list.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns true on success, false otherwise.
 */
bool tomoyo_read_alias_policy(struct tomoyo_io_buffer *head)
{
	struct list_head *pos;
	bool done = true;

	down_read(&tomoyo_alias_list_lock);
	list_for_each_cookie(pos, head->read_var2, &tomoyo_alias_list) {
		struct tomoyo_alias_entry *ptr;

		ptr = list_entry(pos, struct tomoyo_alias_entry, list);
		if (ptr->is_deleted)
			continue;
		if (!tomoyo_io_printf(head, TOMOYO_KEYWORD_ALIAS "%s %s\n",
				      ptr->original_name->name,
				      ptr->aliased_name->name)) {
			done = false;
			break;
		}
	}
	up_read(&tomoyo_alias_list_lock);
	return done;
}

/**
 * tomoyo_write_alias_policy - Write "struct tomoyo_alias_entry" list.
 *
 * @data:      String to parse.
 * @is_delete: True if it is a delete request.
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_write_alias_policy(char *data, const bool is_delete)
{
	char *cp = strchr(data, ' ');

	if (!cp)
		return -EINVAL;
	*cp++ = '\0';
	return tomoyo_update_alias_entry(data, cp, is_delete);
}

/* Domain create/delete handler. */

/**
 * tomoyo_delete_domain - Delete a domain.
 *
 * @domainname: The name of domain.
 *
 * Returns 0.
 */
int tomoyo_delete_domain(char *domainname)
{
	struct tomoyo_domain_info *domain;
	struct tomoyo_path_info name;

	name.name = domainname;
	tomoyo_fill_path_info(&name);
	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_domain_list_lock);
	/* Is there an active domain? */
	list_for_each_entry(domain, &tomoyo_domain_list, list) {
		/* Never delete tomoyo_kernel_domain */
		if (domain == &tomoyo_kernel_domain)
			continue;
		if (domain->is_deleted ||
		    tomoyo_pathcmp(domain->domainname, &name))
			continue;
		domain->is_deleted = true;
		break;
	}
	up_write(&tomoyo_domain_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return 0;
}

/**
 * tomoyo_find_or_assign_new_domain - Create a domain.
 *
 * @domainname: The name of domain.
 * @profile:    Profile number to assign if the domain was newly created.
 *
 * Returns pointer to "struct tomoyo_domain_info" on success, NULL otherwise.
 */
struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char *
							    domainname,
							    const u8 profile)
{
	struct tomoyo_domain_info *domain = NULL;
	const struct tomoyo_path_info *saved_domainname;

	/***** EXCLUSIVE SECTION START *****/
	down_write(&tomoyo_domain_list_lock);
	domain = tomoyo_find_domain(domainname);
	if (domain)
		goto out;
	if (!tomoyo_is_correct_domain(domainname, __func__))
		goto out;
	saved_domainname = tomoyo_save_name(domainname);
	if (!saved_domainname)
		goto out;
	/* Can I reuse memory of deleted domain? */
	list_for_each_entry(domain, &tomoyo_domain_list, list) {
		struct task_struct *p;
		struct tomoyo_acl_info *ptr;
		bool flag;
		if (!domain->is_deleted ||
		    domain->domainname != saved_domainname)
			continue;
		flag = false;
		/***** CRITICAL SECTION START *****/
		read_lock(&tasklist_lock);
		for_each_process(p) {
			if (tomoyo_real_domain(p) != domain)
				continue;
			flag = true;
			break;
		}
		read_unlock(&tasklist_lock);
		/***** CRITICAL SECTION END *****/
		if (flag)
			continue;
		list_for_each_entry(ptr, &domain->acl_info_list, list) {
			ptr->type |= TOMOYO_ACL_DELETED;
		}
		tomoyo_set_domain_flag(domain, true, domain->flags);
		domain->profile = profile;
		domain->quota_warned = false;
		mb(); /* Avoid out-of-order execution. */
		domain->is_deleted = false;
		goto out;
	}
	/* No memory reusable. Create using new memory. */
	domain = tomoyo_alloc_element(sizeof(*domain));
	if (domain) {
		INIT_LIST_HEAD(&domain->acl_info_list);
		domain->domainname = saved_domainname;
		domain->profile = profile;
		list_add_tail(&domain->list, &tomoyo_domain_list);
	}
 out:
	up_write(&tomoyo_domain_list_lock);
	/***** EXCLUSIVE SECTION END *****/
	return domain;
}

/**
 * tomoyo_find_next_domain - Find a domain.
 *
 * @bprm:           Pointer to "struct linux_binprm".
 * @next_domain:    Pointer to pointer to "struct tomoyo_domain_info".
 *
 * Returns 0 on success, negative value otherwise.
 */
int tomoyo_find_next_domain(struct linux_binprm *bprm,
			    struct tomoyo_domain_info **next_domain)
{
	/*
	 * This function assumes that the size of buffer returned by
	 * tomoyo_realpath() = TOMOYO_MAX_PATHNAME_LEN.
	 */
	struct tomoyo_page_buffer *tmp = tomoyo_alloc(sizeof(*tmp));
	struct tomoyo_domain_info *old_domain = tomoyo_domain();
	struct tomoyo_domain_info *domain = NULL;
	const char *old_domain_name = old_domain->domainname->name;
	const char *original_name = bprm->filename;
	char *new_domain_name = NULL;
	char *real_program_name = NULL;
	char *symlink_program_name = NULL;
	const u8 mode = tomoyo_check_flags(old_domain, TOMOYO_MAC_FOR_FILE);
	const bool is_enforce = (mode == 3);
	int retval = -ENOMEM;
	struct tomoyo_path_info r; /* real name */
	struct tomoyo_path_info s; /* symlink name */
	struct tomoyo_path_info l; /* last name */
	static bool initialized;

	if (!tmp)
		goto out;

	if (!initialized) {
		/*
		 * Built-in initializers. This is needed because policies are
		 * not loaded until starting /sbin/init.
		 */
		tomoyo_update_domain_initializer_entry(NULL, "/sbin/hotplug",
						       false, false);
		tomoyo_update_domain_initializer_entry(NULL, "/sbin/modprobe",
						       false, false);
		initialized = true;
	}

	/* Get tomoyo_realpath of program. */
	retval = -ENOENT;
	/* I hope tomoyo_realpath() won't fail with -ENOMEM. */
	real_program_name = tomoyo_realpath(original_name);
	if (!real_program_name)
		goto out;
	/* Get tomoyo_realpath of symbolic link. */
	symlink_program_name = tomoyo_realpath_nofollow(original_name);
	if (!symlink_program_name)
		goto out;

	r.name = real_program_name;
	tomoyo_fill_path_info(&r);
	s.name = symlink_program_name;
	tomoyo_fill_path_info(&s);
	l.name = tomoyo_get_last_name(old_domain);
	tomoyo_fill_path_info(&l);

	/* Check 'alias' directive. */
	if (tomoyo_pathcmp(&r, &s)) {
		struct tomoyo_alias_entry *ptr;
		/* Is this program allowed to be called via symbolic links? */
		down_read(&tomoyo_alias_list_lock);
		list_for_each_entry(ptr, &tomoyo_alias_list, list) {
			if (ptr->is_deleted ||
			    tomoyo_pathcmp(&r, ptr->original_name) ||
			    tomoyo_pathcmp(&s, ptr->aliased_name))
				continue;
			memset(real_program_name, 0, TOMOYO_MAX_PATHNAME_LEN);
			strncpy(real_program_name, ptr->aliased_name->name,
				TOMOYO_MAX_PATHNAME_LEN - 1);
			tomoyo_fill_path_info(&r);
			break;
		}
		up_read(&tomoyo_alias_list_lock);
	}

	/* Check execute permission. */
	retval = tomoyo_check_exec_perm(old_domain, &r, tmp);
	if (retval < 0)
		goto out;

	new_domain_name = tmp->buffer;
	if (tomoyo_is_domain_initializer(old_domain->domainname, &r, &l)) {
		/* Transit to the child of tomoyo_kernel_domain domain. */
		snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
			 TOMOYO_ROOT_NAME " " "%s", real_program_name);
	} else if (old_domain == &tomoyo_kernel_domain &&
		   !tomoyo_policy_loaded) {
		/*
		 * Needn't to transit from kernel domain before starting
		 * /sbin/init. But transit from kernel domain if executing
		 * initializers because they might start before /sbin/init.
		 */
		domain = old_domain;
	} else if (tomoyo_is_domain_keeper(old_domain->domainname, &r, &l)) {
		/* Keep current domain. */
		domain = old_domain;
	} else {
		/* Normal domain transition. */
		snprintf(new_domain_name, TOMOYO_MAX_PATHNAME_LEN + 1,
			 "%s %s", old_domain_name, real_program_name);
	}
	if (domain || strlen(new_domain_name) >= TOMOYO_MAX_PATHNAME_LEN)
		goto done;
	down_read(&tomoyo_domain_list_lock);
	domain = tomoyo_find_domain(new_domain_name);
	up_read(&tomoyo_domain_list_lock);
	if (domain)
		goto done;
	if (is_enforce)
		goto done;
	domain = tomoyo_find_or_assign_new_domain(new_domain_name,
						  old_domain->profile);
 done:
	if (domain)
		goto out;
	printk(KERN_WARNING "TOMOYO-ERROR: Domain '%s' not defined.\n",
	       new_domain_name);
	if (is_enforce)
		retval = -EPERM;
	else
		tomoyo_set_domain_flag(old_domain, false,
				       TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED);
 out:
	tomoyo_free(real_program_name);
	tomoyo_free(symlink_program_name);
	*next_domain = domain ? domain : old_domain;
	tomoyo_free(tmp);
	return retval;
}
