- struct tomoyo_domain_initializer_entry *ptr;
- bool flag = false;
-
- list_for_each_entry_rcu(ptr, &tomoyo_policy_list
- [TOMOYO_ID_DOMAIN_INITIALIZER], head.list) {
- if (ptr->head.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;
- }
- return flag;
-}
-
-static bool tomoyo_same_domain_keeper_entry(const struct tomoyo_acl_head *a,
- const struct tomoyo_acl_head *b)
-{
- const struct tomoyo_domain_keeper_entry *p1 =
- container_of(a, typeof(*p1), head);
- const struct tomoyo_domain_keeper_entry *p2 =
- container_of(b, typeof(*p2), head);
- return p1->is_not == p2->is_not && p1->is_last_name == p2->is_last_name
- && p1->domainname == p2->domainname
- && p1->program == p2->program;
-}
-
-/**
- * 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.
- *
- * Caller holds tomoyo_read_lock().
- */
-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 e = { .is_not = is_not };
- int error = is_delete ? -ENOENT : -ENOMEM;
-
- if (!tomoyo_domain_def(domainname) &&
- tomoyo_correct_path(domainname))
- e.is_last_name = true;
- else if (!tomoyo_correct_domain(domainname))
- return -EINVAL;
- if (program) {
- if (!tomoyo_correct_path(program))
- return -EINVAL;
- e.program = tomoyo_get_name(program);
- if (!e.program)
- goto out;
- }
- e.domainname = tomoyo_get_name(domainname);
- if (!e.domainname)
- goto out;
- error = tomoyo_update_policy(&e.head, sizeof(e), is_delete,
- &tomoyo_policy_list
- [TOMOYO_ID_DOMAIN_KEEPER],
- tomoyo_same_domain_keeper_entry);
- out:
- tomoyo_put_name(e.domainname);
- tomoyo_put_name(e.program);
- 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.
- *
- * Caller holds tomoyo_read_lock().
- */
-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_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.
- *
- * Caller holds tomoyo_read_lock().
- */
-static bool tomoyo_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;
-
- list_for_each_entry_rcu(ptr,
- &tomoyo_policy_list[TOMOYO_ID_DOMAIN_KEEPER],
- head.list) {
- if (ptr->head.is_deleted)
- continue;
- if (!ptr->is_last_name) {
- if (ptr->domainname != domainname)