Index: trunk/1.8.x/ccs-patch/include/linux/ccsecurity.h
===================================================================
--- trunk/1.8.x/ccs-patch/include/linux/ccsecurity.h	(revision 5696)
+++ trunk/1.8.x/ccs-patch/include/linux/ccsecurity.h	(working copy)
@@ -77,7 +77,6 @@
 				 void *data_page);
 #endif
 	int (*umount_permission) (struct vfsmount *mnt, int flags);
-	_Bool (*lport_reserved) (const u16 port);
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
 	void (*save_open_mode) (int mode);
 	void (*clear_open_mode) (void);
@@ -115,9 +114,6 @@
 #endif
 	int (*fcntl_permission) (struct file *file, unsigned int cmd,
 				 unsigned long arg);
-	int (*kill_permission) (pid_t pid, int sig);
-	int (*tgkill_permission) (pid_t tgid, pid_t pid, int sig);
-	int (*tkill_permission) (pid_t pid, int sig);
 	int (*socket_create_permission) (int family, int type, int protocol);
 	int (*socket_listen_permission) (struct socket *sock);
 	int (*socket_connect_permission) (struct socket *sock,
@@ -136,8 +132,6 @@
 				 mode_t mode);
 	int (*getattr_permission) (struct vfsmount *mnt,
 				   struct dentry *dentry);
-	int (*sigqueue_permission) (pid_t pid, int sig);
-	int (*tgsigqueue_permission) (pid_t tgid, pid_t pid, int sig);
 	int (*search_binary_handler) (struct linux_binprm *bprm,
 				      struct pt_regs *regs);
 #ifdef CONFIG_CCSECURITY_USE_EXTERNAL_TASK_SECURITY
@@ -710,23 +704,11 @@
 
 #endif
 
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-
 static inline _Bool ccs_lport_reserved(const u16 port)
 {
-	_Bool (*func) (const u16) = ccsecurity_ops.lport_reserved;
-	return func ? func(port) : 0;
-}
-
-#else
-
-static inline _Bool ccs_lport_reserved(const u16 port)
-{
 	return 0;
 }
 
-#endif
-
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 
 static inline _Bool ccs_capable(const u8 operation)
@@ -768,42 +750,8 @@
 
 #endif
 
-#ifdef CONFIG_CCSECURITY_IPC
-
 static inline int ccs_kill_permission(pid_t pid, int sig)
 {
-	int (*func) (pid_t, int) = ccsecurity_ops.kill_permission;
-	return func ? func(pid, sig) : 0;
-}
-
-static inline int ccs_tgkill_permission(pid_t tgid, pid_t pid, int sig)
-{
-	int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgkill_permission;
-	return func ? func(tgid, pid, sig) : 0;
-}
-
-static inline int ccs_tkill_permission(pid_t pid, int sig)
-{
-	int (*func) (pid_t, int) = ccsecurity_ops.tkill_permission;
-	return func ? func(pid, sig) : 0;
-}
-
-static inline int ccs_sigqueue_permission(pid_t pid, int sig)
-{
-	int (*func) (pid_t, int) = ccsecurity_ops.sigqueue_permission;
-	return func ? func(pid, sig) : 0;
-}
-
-static inline int ccs_tgsigqueue_permission(pid_t tgid, pid_t pid, int sig)
-{
-	int (*func) (pid_t, pid_t, int) = ccsecurity_ops.tgsigqueue_permission;
-	return func ? func(tgid, pid, sig) : 0;
-}
-
-#else
-
-static inline int ccs_kill_permission(pid_t pid, int sig)
-{
 	return 0;
 }
 
@@ -827,8 +775,6 @@
 	return 0;
 }
 
-#endif
-
 /* Index numbers for Capability Controls. */
 enum ccs_capability_acl_index {
 	/* socket(PF_ROUTE, *, *)                                      */
@@ -849,8 +795,6 @@
 	CCS_USE_KERNEL_MODULE,
 	/* sys_kexec_load()                                            */
 	CCS_SYS_KEXEC_LOAD,
-	/* sys_ptrace()                                                */
-	CCS_SYS_PTRACE,
 	CCS_MAX_CAPABILITY_INDEX
 };
 
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/Kconfig
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/Kconfig	(revision 5696)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/Kconfig	(working copy)
@@ -177,14 +177,5 @@
 	  Say Y here if you want to enable domain transition without involving
 	  program execution request.
 
-config CCSECURITY_PORTRESERVE
-       bool "Enable local port reserver."
-       default y
-       depends on NET
-       depends on CCSECURITY
-       ---help---
-	 Say Y here if you want to implement
-	 /proc/sys/net/ipv4/ip_local_reserved_ports as a MAC policy.
-
 config CCSECURITY_NETWORK_RECVMSG
 	def_bool CCSECURITY_NETWORK
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/realpath.c
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/realpath.c	(revision 5696)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/realpath.c	(working copy)
@@ -28,6 +28,7 @@
 char *ccs_encode(const char *str);
 char *ccs_encode2(const char *str, int str_len);
 char *ccs_realpath(struct path *path);
+char *ccs_realpath2(struct path *path, bool force_no_fsname);
 const char *ccs_get_exe(void);
 void ccs_fill_path_info(struct ccs_path_info *ptr);
 
@@ -492,16 +493,18 @@
 #define SOCKFS_MAGIC 0x534F434B
 
 /**
- * ccs_realpath - Returns realpath(3) of the given pathname but ignores chroot'ed root.
+ * ccs_realpath2 - Returns realpath(3) of the given pathname but ignores chroot'ed root.
  *
- * @path: Pointer to "struct path".
+ * @path:            Pointer to "struct path".
+ * @force_no_fsname: Force use of normal pathname if true, may use fsname
+ *                   otherwise.
  *
  * Returns the realpath of the given @path on success, NULL otherwise.
  *
  * This function uses kzalloc(), so caller must kfree() if this function
  * didn't return NULL.
  */
-char *ccs_realpath(struct path *path)
+char *ccs_realpath2(struct path *path, bool force_no_fsname)
 {
 	char *buf = NULL;
 	char *name = NULL;
@@ -521,6 +524,8 @@
 			break;
 		/* To make sure that pos is '\0' terminated. */
 		buf[buf_len - 1] = '\0';
+		if (force_no_fsname)
+			goto absolute_path;
 		/* Get better name for socket. */
 		if (sb->s_magic == SOCKFS_MAGIC) {
 			pos = ccs_get_socket_name(path, buf, buf_len - 1);
@@ -542,6 +547,7 @@
 		if (!path->mnt || (inode->i_op && !inode->i_op->rename))
 			pos = ERR_PTR(-EINVAL);
 		else {
+absolute_path:
 			/* Get absolute name for the rest. */
 			ccs_realpath_lock();
 			pos = ccs_get_absolute_path(path, buf, buf_len - 1);
@@ -563,6 +569,21 @@
 }
 
 /**
+ * ccs_realpath - Returns realpath(3) of the given pathname but ignores chroot'ed root.
+ *
+ * @path: Pointer to "struct path".
+ *
+ * Returns the realpath of the given @path on success, NULL otherwise.
+ *
+ * This function uses kzalloc(), so caller must kfree() if this function
+ * didn't return NULL.
+ */
+char *ccs_realpath(struct path *path)
+{
+	return ccs_realpath2(path, false);
+}
+
+/**
  * ccs_encode2 - Encode binary string to ascii string.
  *
  * @str:     String in binary format.
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/internal.h
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/internal.h	(revision 5696)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/internal.h	(working copy)
@@ -386,6 +386,7 @@
 
 /* Index numbers for Access Controls. */
 enum ccs_acl_entry_type_index {
+	CCS_TYPE_EXECUTE_ACL,
 	CCS_TYPE_PATH_ACL,
 	CCS_TYPE_PATH2_ACL,
 	CCS_TYPE_PATH_NUMBER_ACL,
@@ -402,7 +403,7 @@
 	CCS_TYPE_UNIX_ACL,
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	CCS_TYPE_SIGNAL_ACL,
+	CCS_TYPE_PTRACE_ACL,
 #endif
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	CCS_TYPE_AUTO_EXECUTE_HANDLER,
@@ -412,6 +413,7 @@
 	CCS_TYPE_AUTO_TASK_ACL,
 	CCS_TYPE_MANUAL_TASK_ACL,
 #endif
+	CCS_TYPE_USE_GROUP_ACL,
 };
 
 /* Index numbers for "struct ccs_condition". */
@@ -451,7 +453,6 @@
 				     CCS_TASK_IS_EXECUTE_HANDLER */
 	CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
 	CCS_EXEC_REALPATH,
-	CCS_SYMLINK_TARGET,
 	CCS_PATH1_UID,
 	CCS_PATH1_GID,
 	CCS_PATH1_INO,
@@ -485,20 +486,6 @@
 	CCS_ENVP_ENTRY,
 };
 
-/* Index numbers for domain's attributes. */
-enum ccs_domain_info_flags_index {
-	/* Quota warnning flag.   */
-	CCS_DIF_QUOTA_WARNED,
-	/*
-	 * This domain was unable to create a new domain at
-	 * ccs_find_next_domain() because the name of the domain to be created
-	 * was too long or it could not allocate memory.
-	 * More than one process continued execve() without domain transition.
-	 */
-	CCS_DIF_TRANSITION_FAILED,
-	CCS_MAX_DOMAIN_INFO_FLAGS
-};
-
 /* Index numbers for audit type. */
 enum ccs_grant_log {
 	/* Follow profile's configuration. */
@@ -513,6 +500,7 @@
 enum ccs_group_id {
 	CCS_PATH_GROUP,
 	CCS_NUMBER_GROUP,
+	CCS_ACL_GROUP,
 #ifdef CONFIG_CCSECURITY_NETWORK
 	CCS_ADDRESS_GROUP,
 #endif
@@ -540,7 +528,9 @@
 /* Index numbers for functionality. */
 enum ccs_mac_index {
 	CCS_MAC_FILE_EXECUTE,
-	CCS_MAC_FILE_OPEN,
+	CCS_MAC_FILE_READ,
+	CCS_MAC_FILE_WRITE,
+	CCS_MAC_FILE_APPEND,
 	CCS_MAC_FILE_CREATE,
 	CCS_MAC_FILE_UNLINK,
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
@@ -597,7 +587,7 @@
 	CCS_MAC_ENVIRON,
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	CCS_MAC_SIGNAL,
+	CCS_MAC_PTRACE,
 #endif
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
@@ -609,7 +599,6 @@
 	CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
 	CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
 	CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
-	CCS_MAC_CAPABILITY_SYS_PTRACE,
 #endif
 	CCS_MAX_MAC_INDEX
 };
@@ -659,12 +648,12 @@
 	CCS_TYPE_LINK,
 	CCS_TYPE_RENAME,
 	CCS_TYPE_PIVOT_ROOT,
+	CCS_TYPE_SYMLINK,
 	CCS_MAX_PATH2_OPERATION
 };
 
 /* Index numbers for access controls with one pathname. */
 enum ccs_path_acl_index {
-	CCS_TYPE_EXECUTE,
 	CCS_TYPE_READ,
 	CCS_TYPE_WRITE,
 	CCS_TYPE_APPEND,
@@ -674,7 +663,6 @@
 #endif
 	CCS_TYPE_RMDIR,
 	CCS_TYPE_TRUNCATE,
-	CCS_TYPE_SYMLINK,
 	CCS_TYPE_CHROOT,
 	CCS_TYPE_UMOUNT,
 	CCS_MAX_PATH_OPERATION
@@ -705,17 +693,12 @@
 
 /* Index numbers for entry type. */
 enum ccs_policy_id {
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-	CCS_ID_RESERVEDPORT,
-#endif
 	CCS_ID_GROUP,
 #ifdef CONFIG_CCSECURITY_NETWORK
 	CCS_ID_ADDRESS_GROUP,
 #endif
 	CCS_ID_PATH_GROUP,
 	CCS_ID_NUMBER_GROUP,
-	CCS_ID_AGGREGATOR,
-	CCS_ID_TRANSITION_CONTROL,
 	CCS_ID_MANAGER,
 	CCS_ID_CONDITION,
 	CCS_ID_NAME,
@@ -756,6 +739,7 @@
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	CCS_EXECUTE_HANDLER,
 #endif
+	CCS_ACL_POLICY,
 };
 
 /* Index numbers for special mount operations. */
@@ -770,18 +754,6 @@
 	CCS_MAX_SPECIAL_MOUNT
 };
 
-/* Index numbers for domain transition control keywords. */
-enum ccs_transition_type {
-	/* Do not change this order, */
-	CCS_TRANSITION_CONTROL_NO_RESET,
-	CCS_TRANSITION_CONTROL_RESET,
-	CCS_TRANSITION_CONTROL_NO_INITIALIZE,
-	CCS_TRANSITION_CONTROL_INITIALIZE,
-	CCS_TRANSITION_CONTROL_NO_KEEP,
-	CCS_TRANSITION_CONTROL_KEEP,
-	CCS_MAX_TRANSITION_TYPE
-};
-
 /* Index numbers for type of numeric values. */
 enum ccs_value_type {
 	CCS_VALUE_TYPE_INVALID,
@@ -815,9 +787,6 @@
 /* Profile number is an integer between 0 and 255. */
 #define CCS_MAX_PROFILES 256
 
-/* Group number is an integer between 0 and 255. */
-#define CCS_MAX_ACL_GROUPS 256
-
 /* Current thread is doing open(O_RDONLY | O_TRUNC) ? */
 #define CCS_OPEN_FOR_READ_TRUNCATE        1
 /* Current thread is doing open(3) ? */
@@ -876,9 +845,11 @@
 /* Common header for individual entries. */
 struct ccs_acl_info {
 	struct list_head list;
+	struct list_head domain_list; /* Used by inverse mode. */
 	struct ccs_condition *cond; /* Maybe NULL. */
 	s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
 	u8 type; /* One of values in "enum ccs_acl_entry_type_index". */
+	u8 mode; /* Used by inverse mode. */
 	u16 perm;
 } __packed;
 
@@ -887,6 +858,7 @@
 	/* Either @filename or @group is NULL. */
 	const struct ccs_path_info *filename;
 	struct ccs_group *group;
+	bool is_not;
 };
 
 /* Structure for holding a number. */
@@ -895,6 +867,7 @@
 	struct ccs_group *group; /* Maybe NULL. */
 	/* One of values in "enum ccs_value_type". */
 	u8 value_type[2];
+	bool is_not;
 };
 
 /* Structure for holding an IP address. */
@@ -902,12 +875,13 @@
 	struct in6_addr ip[2]; /* Big endian. */
 	struct ccs_group *group; /* Pointer to address group. */
 	bool is_ipv6; /* Valid only if @group == NULL. */
+	bool is_not;
 };
 
 /* Structure for "path_group"/"number_group"/"address_group" directive. */
 struct ccs_group {
 	struct ccs_shared_acl_head head;
-	/* Name of group (without leading '@'). */
+	/* Name of group (without leading "\\=" or "\\!"). */
 	const struct ccs_path_info *group_name;
 	/*
 	 * List of "struct ccs_path_group" or "struct ccs_number_group" or
@@ -933,6 +907,7 @@
 	struct ccs_acl_head head;
 	/* Structure for holding an IP address. */
 	struct ccs_ipaddr_union address;
+	bool is_not;
 };
 
 /* Subset of "struct stat". Used by conditional ACL and audit logs. */
@@ -966,11 +941,6 @@
 	 * parent directory.
 	 */
 	struct ccs_mini_stat stat[CCS_MAX_PATH_STAT];
-	/*
-	 * Content of symbolic link to be created. NULL for operations other
-	 * than symlink().
-	 */
-	struct ccs_path_info *symlink_target;
 };
 
 /* Structure for entries which follows "struct ccs_condition". */
@@ -1001,8 +971,6 @@
 	u16 argc; /* Number of "struct ccs_argv". */
 	u16 envc; /* Number of "struct ccs_envp". */
 	u8 grant_log; /* One of values in "enum ccs_grant_log". */
-	bool exec_transit; /* True if transit is for "file execute". */
-	const struct ccs_path_info *transit; /* Maybe NULL. */
 	/*
 	 * struct ccs_condition_element condition[condc];
 	 * struct ccs_number_union values[numbers_count];
@@ -1027,22 +995,13 @@
 	 * NULL if not dealing do_execve().
 	 */
 	struct ccs_execve *ee;
-	/*
-	 * For holding parameters.
-	 * Pointers in this union are not NULL except path->matched_path.
-	 */
+	/* For holding parameters. Pointers in this union are not NULL. */
 	union {
 		struct {
+			const struct ccs_path_info *program;
+		} execute;
+		struct {
 			const struct ccs_path_info *filename;
-			/*
-			 * For using wildcards at ccs_find_next_domain().
-			 *
-			 * The matched_acl cannot be used because it may refer
-			 * a "struct ccs_path_acl" with ->is_group == true.
-			 * We want to use exact "struct ccs_path_info" rather
-			 * than "struct ccs_path_acl".
-			 */
-			const struct ccs_path_info *matched_path;
 			/* One of values in "enum ccs_path_acl_index". */
 			u8 operation;
 		} path;
@@ -1099,9 +1058,9 @@
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
 		struct {
-			const char *dest_pattern;
-			int sig;
-		} signal;
+			const char *domainname;
+			unsigned long request;
+		} ptrace;
 #endif
 		struct {
 			const struct ccs_path_info *type;
@@ -1117,14 +1076,14 @@
 #endif
 	} param;
 	/*
-	 * For updating current->ccs_domain_info at ccs_update_task_domain().
-	 * Initialized to NULL at ccs_init_request_info().
 	 * Matching "struct ccs_acl_info" is copied if access request was
-	 * granted. Re-initialized to NULL at ccs_update_task_domain().
+	 * granted.
 	 */
 	struct ccs_acl_info *matched_acl;
 	u8 param_type; /* One of values in "enum ccs_acl_entry_type_index". */
 	bool granted; /* True if granted, false otherwise. */
+	/* True if rejected by inverse mode match, false otherwise. */
+	bool inversed;
 	/* True if current thread should not be carried sleep penalty. */
 	bool dont_sleep_on_enforce_error;
 	/*
@@ -1146,8 +1105,7 @@
 	u8 mode;
 	/*
 	 * For holding operation index used for this request.
-	 * Used by ccs_init_request_info() / ccs_get_mode() /
-	 * ccs_write_log(). One of values in "enum ccs_mac_index".
+	 * One of values in "enum ccs_mac_index".
 	 */
 	u8 type;
 };
@@ -1186,37 +1144,14 @@
 	const struct ccs_path_info *domainname;
 	/* Namespace for this domain. Never NULL. */
 	struct ccs_policy_namespace *ns;
+	/* Default domain transition. Never NULL. */
+	const struct ccs_path_info *default_transition;
 	u8 profile;        /* Profile number to use. */
-	u8 group;          /* Group number to use.   */
-	bool is_deleted;   /* Delete flag.           */
-	bool flags[CCS_MAX_DOMAIN_INFO_FLAGS];
+	bool quota_exceeded;
+	s8 is_deleted;     /* Delete flag.           */
+	struct ccs_condition *cond; /* Used by inverse mode. */
 };
 
-/*
- * Structure for "reset_domain"/"no_reset_domain"/"initialize_domain"/
- * "no_initialize_domain"/"keep_domain"/"no_keep_domain" keyword.
- */
-struct ccs_transition_control {
-	struct ccs_acl_head head;
-	u8 type; /* One of values in "enum ccs_transition_type" */
-	bool is_last_name; /* True if the domainname is ccs_last_word(). */
-	const struct ccs_path_info *domainname; /* Maybe NULL */
-	const struct ccs_path_info *program;    /* Maybe NULL */
-};
-
-/* Structure for "aggregator" keyword. */
-struct ccs_aggregator {
-	struct ccs_acl_head head;
-	const struct ccs_path_info *original_name;
-	const struct ccs_path_info *aggregated_name;
-};
-
-/* Structure for "deny_autobind" keyword. */
-struct ccs_reserved {
-	struct ccs_acl_head head;
-	struct ccs_number_union port;
-};
-
 /* Structure for policy manager. */
 struct ccs_manager {
 	struct ccs_acl_head head;
@@ -1260,6 +1195,7 @@
 struct ccs_handler_acl {
 	struct ccs_acl_info head;       /* type = CCS_TYPE_*_EXECUTE_HANDLER */
 	const struct ccs_path_info *handler; /* Pointer to single pathname.  */
+	const struct ccs_path_info *transit; /* Maybe NULL. */
 };
 
 /*
@@ -1272,10 +1208,17 @@
 	const struct ccs_path_info *domainname;
 };
 
+/* Structure for "file execute" directive. */
+struct ccs_execute_acl {
+	struct ccs_acl_info head; /* type = CCS_TYPE_EXECUTE_ACL */
+	struct ccs_name_union program;
+	const struct ccs_path_info *transit; /* Maybe NULL. */
+};
+
 /*
- * Structure for "file execute", "file read", "file write", "file append",
- * "file unlink", "file getattr", "file rmdir", "file truncate",
- * "file symlink", "file chroot" and "file unmount" directive.
+ * Structure for "file read", "file write", "file append", "file unlink",
+ * "file getattr", "file rmdir", "file truncate", "file chroot" and
+ * "file unmount" directive.
  */
 struct ccs_path_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
@@ -1283,7 +1226,8 @@
 };
 
 /*
- * Structure for "file rename", "file link" and "file pivot_root" directive.
+ * Structure for "file rename", "file link", "file pivot_root" and
+ * "file symlink" directive.
  */
 struct ccs_path2_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
@@ -1321,8 +1265,8 @@
 
 /* Structure for "misc env" directive in domain policy. */
 struct ccs_env_acl {
-	struct ccs_acl_info head;        /* type = CCS_TYPE_ENV_ACL  */
-	const struct ccs_path_info *env; /* environment variable */
+	struct ccs_acl_info head;  /* type = CCS_TYPE_ENV_ACL  */
+	struct ccs_name_union env; /* environment variable */
 };
 
 /* Structure for "capability" directive. */
@@ -1331,11 +1275,10 @@
 	u8 operation; /* One of values in "enum ccs_capability_acl_index". */
 };
 
-/* Structure for "ipc signal" directive. */
-struct ccs_signal_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */
-	struct ccs_number_union sig;
-	/* Pointer to destination pattern. */
+/* Structure for "ipc ptrace" directive. */
+struct ccs_ptrace_acl {
+	struct ccs_acl_info head; /* type = CCS_TYPE_PTRACE_ACL */
+	struct ccs_number_union request;
 	const struct ccs_path_info *domainname;
 };
 
@@ -1354,6 +1297,13 @@
 	struct ccs_name_union name;
 };
 
+/* Structure for "use_group" directive. */
+struct ccs_use_group_acl {
+	struct ccs_acl_info head; /* type = CCS_TYPE_USE_GROUP_ACL */
+	struct ccs_group *group;
+	bool is_not;
+};
+
 /* Structure for holding string data. */
 struct ccs_name {
 	struct ccs_shared_acl_head head;
@@ -1371,6 +1321,7 @@
 		struct ccs_acl_info acl_info;
 		struct ccs_handler_acl handler_acl;
 		struct ccs_task_acl task_acl;
+		struct ccs_execute_acl execute_acl;
 		struct ccs_path_acl path_acl;
 		struct ccs_path2_acl path2_acl;
 		struct ccs_path_number_acl path_number_acl;
@@ -1378,19 +1329,18 @@
 		struct ccs_mount_acl mount_acl;
 		struct ccs_env_acl env_acl;
 		struct ccs_capability_acl capability_acl;
-		struct ccs_signal_acl signal_acl;
+		struct ccs_ptrace_acl ptrace_acl;
 		struct ccs_inet_acl inet_acl;
 		struct ccs_unix_acl unix_acl;
+		struct ccs_use_group_acl use_group_acl;
 		/**/
 		struct ccs_acl_head acl_head;
-		struct ccs_transition_control transition_control;
-		struct ccs_aggregator aggregator;
-		struct ccs_reserved reserved;
 		struct ccs_manager manager;
 		struct ccs_path_group path_group;
 		struct ccs_number_group number_group;
 		struct ccs_address_group address_group;
 	} e;
+	struct ccs_acl_info *matched_entry; /* Used by inverse mode. */
 };
 
 /* Structure for reading/writing policy via /proc/ccs/ interfaces. */
@@ -1404,12 +1354,12 @@
 		struct list_head *domain;
 		struct list_head *group;
 		struct list_head *acl;
+		const struct ccs_path_info *acl_group_name;
 		size_t avail;
 		unsigned int step;
 		unsigned int query_index;
 		u16 index;
 		u16 cond_index;
-		u8 acl_group_index;
 		u8 cond_step;
 		u8 bit;
 		u8 w_pos;
@@ -1417,11 +1367,13 @@
 		bool print_this_domain_only;
 		bool print_transition_related_only;
 		bool print_cond_part;
+		bool print_default_transition;
 		const char *w[CCS_MAX_IO_READ_QUEUE];
 	} r;
 	struct {
 		struct ccs_policy_namespace *ns;
 		struct ccs_domain_info *domain;
+		struct ccs_acl_info *acl; /* Used by inverse mode. */
 		size_t avail;
 		bool is_delete;
 	} w;
@@ -1465,10 +1417,8 @@
 	struct ccs_profile *profile_ptr[CCS_MAX_PROFILES];
 	/* List of "struct ccs_group". */
 	struct list_head group_list[CCS_MAX_GROUP];
-	/* List of policy. */
-	struct list_head policy_list[CCS_MAX_POLICY];
-	/* The global ACL referred by "use_group" keyword. */
-	struct list_head acl_group[CCS_MAX_ACL_GROUPS];
+	/* List of default transition pattern. */
+	struct list_head default_transition_list;
 	/* List for connecting to ccs_namespace_list list. */
 	struct list_head namespace_list;
 	/* Profile version. Currently only 20100903 is defined. */
@@ -1490,14 +1440,13 @@
 char *ccs_encode(const char *str);
 char *ccs_encode2(const char *str, int str_len);
 char *ccs_realpath(struct path *path);
+char *ccs_realpath2(struct path *path, bool force_no_fsname);
 const char *ccs_get_exe(void);
 const struct ccs_path_info *ccs_get_name(const char *name);
 int ccs_audit_log(struct ccs_request_info *r);
 int ccs_check_acl(struct ccs_request_info *r);
-int ccs_init_request_info(struct ccs_request_info *r, const u8 index);
 struct ccs_domain_info *ccs_assign_domain(const char *domainname,
 					  const bool transit);
-u8 ccs_get_config(const u8 profile, const u8 index);
 void *ccs_commit_ok(void *data, const unsigned int size);
 void ccs_del_acl(struct list_head *element);
 void ccs_del_condition(struct list_head *element);
@@ -1506,22 +1455,23 @@
 void ccs_notify_gc(struct ccs_io_buffer *head, const bool is_register);
 void ccs_transition_failed(const char *domainname);
 void ccs_warn_oom(const char *function);
-void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...)
-	__printf(2, 3);
 
 /* Variable definition for internal use. */
 
 extern bool ccs_policy_loaded;
-extern const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS];
 extern const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX];
+extern const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION];
 extern const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION];
 extern const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION];
 extern const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION];
 extern struct ccs_domain_info ccs_kernel_domain;
+extern struct ccs_group ccs_group_any;
 extern struct list_head ccs_condition_list;
 extern struct list_head ccs_domain_list;
+extern struct list_head ccs_inversed_acl_list;
 extern struct list_head ccs_name_list[CCS_MAX_HASH];
 extern struct list_head ccs_namespace_list;
+extern struct list_head ccs_manager_list;
 extern struct mutex ccs_policy_lock;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
 extern struct srcu_struct ccs_ss;
@@ -1742,19 +1692,6 @@
 
 #endif
 
-/**
- * ccs_get_mode - Get mode for specified functionality.
- *
- * @profile: Profile number.
- * @index:   Functionality number.
- *
- * Returns mode.
- */
-static inline u8 ccs_get_mode(const u8 profile, const u8 index)
-{
-	return ccs_get_config(profile, index) & (CCS_CONFIG_MAX_MODE - 1);
-}
-
 #if defined(CONFIG_SLOB)
 
 /**
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c	(revision 5698)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/policy_io.c	(working copy)
@@ -23,7 +23,9 @@
 static const u8 ccs_index2category[CCS_MAX_MAC_INDEX] = {
 	/* CONFIG::file group */
 	[CCS_MAC_FILE_EXECUTE]    = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_OPEN]       = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_READ]       = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_WRITE]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_APPEND]     = CCS_MAC_CATEGORY_FILE,
 	[CCS_MAC_FILE_CREATE]     = CCS_MAC_CATEGORY_FILE,
 	[CCS_MAC_FILE_UNLINK]     = CCS_MAC_CATEGORY_FILE,
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
@@ -83,7 +85,7 @@
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
 	/* CONFIG::ipc group */
-	[CCS_MAC_SIGNAL]          = CCS_MAC_CATEGORY_IPC,
+	[CCS_MAC_PTRACE]          = CCS_MAC_CATEGORY_IPC,
 #endif
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	/* CONFIG::capability group */
@@ -96,7 +98,6 @@
 	[CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = CCS_MAC_CATEGORY_CAPABILITY,
 	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = CCS_MAC_CATEGORY_CAPABILITY,
 	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_PTRACE]        = CCS_MAC_CATEGORY_CAPABILITY,
 #endif
 };
 
@@ -113,7 +114,9 @@
 					   + CCS_MAX_MAC_CATEGORY_INDEX] = {
 	/* CONFIG::file group */
 	[CCS_MAC_FILE_EXECUTE]    = "execute",
-	[CCS_MAC_FILE_OPEN]       = "open",
+	[CCS_MAC_FILE_READ]       = "read",
+	[CCS_MAC_FILE_WRITE]      = "write",
+	[CCS_MAC_FILE_APPEND]     = "append",
 	[CCS_MAC_FILE_CREATE]     = "create",
 	[CCS_MAC_FILE_UNLINK]     = "unlink",
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
@@ -173,7 +176,7 @@
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
 	/* CONFIG::ipc group */
-	[CCS_MAC_SIGNAL] = "signal",
+	[CCS_MAC_PTRACE] = "ptrace",
 #endif
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	/* CONFIG::capability group */
@@ -186,7 +189,6 @@
 	[CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = "SYS_SETHOSTNAME",
 	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module",
 	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = "SYS_KEXEC_LOAD",
-	[CCS_MAC_CAPABILITY_SYS_PTRACE]        = "SYS_PTRACE",
 #endif
 	/* CONFIG group */
 	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE]       = "file",
@@ -204,23 +206,6 @@
 #endif
 };
 
-/* String table for path operation. */
-static const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION] = {
-	[CCS_TYPE_EXECUTE]    = "execute",
-	[CCS_TYPE_READ]       = "read",
-	[CCS_TYPE_WRITE]      = "write",
-	[CCS_TYPE_APPEND]     = "append",
-	[CCS_TYPE_UNLINK]     = "unlink",
-#ifdef CONFIG_CCSECURITY_FILE_GETATTR
-	[CCS_TYPE_GETATTR]    = "getattr",
-#endif
-	[CCS_TYPE_RMDIR]      = "rmdir",
-	[CCS_TYPE_TRUNCATE]   = "truncate",
-	[CCS_TYPE_SYMLINK]    = "symlink",
-	[CCS_TYPE_CHROOT]     = "chroot",
-	[CCS_TYPE_UMOUNT]     = "unmount",
-};
-
 #ifdef CONFIG_CCSECURITY_NETWORK
 
 /* String table for socket's operation. */
@@ -300,7 +285,6 @@
 	[CCS_TASK_TYPE]            = "task.type",
 	[CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
 	[CCS_EXEC_REALPATH]        = "exec.realpath",
-	[CCS_SYMLINK_TARGET]       = "symlink.target",
 	[CCS_PATH1_UID]            = "path1.uid",
 	[CCS_PATH1_GID]            = "path1.gid",
 	[CCS_PATH1_INO]            = "path1.ino",
@@ -337,25 +321,13 @@
 };
 
 /* String table for domain flags. */
-const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
-	[CCS_DIF_QUOTA_WARNED]      = "quota_exceeded\n",
-	[CCS_DIF_TRANSITION_FAILED] = "transition_failed\n",
-};
+#define CCS_QUOTA_EXCEEDED "quota_exceeded\n"
 
-/* String table for domain transition control keywords. */
-static const char * const ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
-	[CCS_TRANSITION_CONTROL_NO_RESET]      = "no_reset_domain ",
-	[CCS_TRANSITION_CONTROL_RESET]         = "reset_domain ",
-	[CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
-	[CCS_TRANSITION_CONTROL_INITIALIZE]    = "initialize_domain ",
-	[CCS_TRANSITION_CONTROL_NO_KEEP]       = "no_keep_domain ",
-	[CCS_TRANSITION_CONTROL_KEEP]          = "keep_domain ",
-};
-
 /* String table for grouping keywords. */
 static const char * const ccs_group_name[CCS_MAX_GROUP] = {
 	[CCS_PATH_GROUP]    = "path_group ",
 	[CCS_NUMBER_GROUP]  = "number_group ",
+	[CCS_ACL_GROUP]     = "acl_group ",
 #ifdef CONFIG_CCSECURITY_NETWORK
 	[CCS_ADDRESS_GROUP] = "address_group ",
 #endif
@@ -404,9 +376,6 @@
 int ccs_audit_log(struct ccs_request_info *r);
 struct ccs_domain_info *ccs_assign_domain(const char *domainname,
 					  const bool transit);
-u8 ccs_get_config(const u8 profile, const u8 index);
-void ccs_transition_failed(const char *domainname);
-void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...);
 
 static bool ccs_correct_domain(const unsigned char *domainname);
 static bool ccs_correct_path(const char *filename);
@@ -432,18 +401,17 @@
 				const struct ccs_condition *cond);
 static bool ccs_print_entry(struct ccs_io_buffer *head,
 			    const struct ccs_acl_info *acl);
-static bool ccs_print_group(struct ccs_io_buffer *head,
+static bool ccs_print_group(struct ccs_io_buffer *head, const bool is_not,
 			    const struct ccs_group *group);
 static bool ccs_read_acl(struct ccs_io_buffer *head, struct list_head *list);
 static bool ccs_read_group(struct ccs_io_buffer *head, const int idx);
-static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx);
 static bool ccs_same_condition(const struct ccs_condition *a,
 			       const struct ccs_condition *b);
 static bool ccs_select_domain(struct ccs_io_buffer *head, const char *data);
 static bool ccs_set_lf(struct ccs_io_buffer *head);
 static bool ccs_str_starts(char **src, const char *find);
 static char *ccs_get_transit_preference(struct ccs_acl_param *param,
-					struct ccs_condition *e);
+					struct ccs_execute_acl *e);
 static char *ccs_init_log(struct ccs_request_info *r, int len, const char *fmt,
 			  va_list args);
 static char *ccs_print_bprm(struct linux_binprm *bprm,
@@ -465,14 +433,16 @@
 			struct ccs_profile *profile);
 static int ccs_supervisor(struct ccs_request_info *r, const char *fmt, ...)
 	__printf(2, 3);
-static int ccs_truncate(char *str);
 static int ccs_update_acl(const int size, struct ccs_acl_param *param);
+static int ccs_update_inverse_list(struct ccs_acl_info *new_entry,
+				   const int size,
+				   struct ccs_acl_param *param);
 static int ccs_update_manager_entry(const char *manager, const bool is_delete);
 static int ccs_update_policy(const int size, struct ccs_acl_param *param);
 static int ccs_write_acl(struct ccs_policy_namespace *ns,
 			 struct list_head *list, char *data,
 			 const bool is_delete);
-static int ccs_write_aggregator(struct ccs_acl_param *param);
+static int ccs_write_acl_policy(struct ccs_io_buffer *head);
 static int ccs_write_answer(struct ccs_io_buffer *head);
 static int ccs_write_domain(struct ccs_io_buffer *head);
 static int ccs_write_exception(struct ccs_io_buffer *head);
@@ -483,8 +453,8 @@
 static int ccs_write_profile(struct ccs_io_buffer *head);
 static int ccs_write_stat(struct ccs_io_buffer *head);
 static int ccs_write_task(struct ccs_acl_param *param);
-static int ccs_write_transition_control(struct ccs_acl_param *param,
-					const u8 type);
+static int ccs_write_transition_control(struct ccs_acl_param *param);
+static int ccs_write_use_group_acl(struct ccs_acl_param *param);
 static s8 ccs_find_yesno(const char *string, const char *find);
 static ssize_t ccs_read(struct file *file, char __user *buf, size_t count,
 			loff_t *ppos);
@@ -506,6 +476,8 @@
 					      const unsigned int profile);
 static struct ccs_profile *ccs_profile(const u8 profile);
 static u8 ccs_condition_type(const char *word);
+static u8 ccs_get_config(const u8 profile, const u8 index);
+static u8 ccs_group_type(char **src);
 static u8 ccs_make_byte(const u8 c1, const u8 c2, const u8 c3);
 static u8 ccs_parse_ulong(unsigned long *result, char **str);
 static unsigned int ccs_poll(struct file *file, poll_table *wait);
@@ -537,6 +509,7 @@
 					   const struct ccs_number_union *ptr);
 static void ccs_read_domain(struct ccs_io_buffer *head);
 static void ccs_read_exception(struct ccs_io_buffer *head);
+static void ccs_read_inverse_policy(struct ccs_io_buffer *head);
 static void ccs_read_log(struct ccs_io_buffer *head);
 static void ccs_read_manager(struct ccs_io_buffer *head);
 static void ccs_read_pid(struct ccs_io_buffer *head);
@@ -552,14 +525,11 @@
 static void ccs_set_uint(unsigned int *i, const char *string,
 			 const char *find);
 static void ccs_update_stat(const u8 index);
-static void ccs_update_task_domain(struct ccs_request_info *r);
+static void ccs_write_log(struct ccs_request_info *r, const char *fmt, ...)
+	__printf(2, 3);
 static void ccs_write_log2(struct ccs_request_info *r, int len,
 			   const char *fmt, va_list args);
 
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-static bool __ccs_lport_reserved(const u16 port);
-static int ccs_write_reserved_port(struct ccs_acl_param *param);
-#endif
 
 #ifdef CONFIG_CCSECURITY_NETWORK
 static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
@@ -1202,14 +1172,15 @@
 
 /* Initial namespace.*/
 static struct ccs_policy_namespace ccs_kernel_namespace;
+static struct ccs_path_info ccs_kernel_transition;
 
+struct ccs_group ccs_group_any;
+
 /* List of "struct ccs_condition". */
 LIST_HEAD(ccs_condition_list);
 
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-/* Bitmap for reserved local port numbers.*/
-static u8 ccs_reserved_port_map[8192];
-#endif
+/* List of "struct ccs_manager". */
+LIST_HEAD(ccs_manager_list);
 
 /* Wait queue for kernel -> userspace notification. */
 static DECLARE_WAIT_QUEUE_HEAD(ccs_query_wait);
@@ -1431,6 +1402,8 @@
 	struct list_head *list;
 	const char *group_name = ccs_read_token(param);
 	bool found = false;
+	if (!strcmp(group_name, "any"))
+		return &ccs_group_any;
 	if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
 		return NULL;
 	e.group_name = ccs_get_name(group_name);
@@ -1475,8 +1448,11 @@
 				 struct ccs_name_union *ptr)
 {
 	char *filename;
-	if (param->data[0] == '@') {
-		param->data++;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		ptr->is_not = true;
+		/* fall through */
+	case 1:
 		ptr->group = ccs_get_group(param, CCS_PATH_GROUP);
 		return ptr->group != NULL;
 	}
@@ -1542,8 +1518,11 @@
 	u8 type;
 	unsigned long v;
 	memset(ptr, 0, sizeof(*ptr));
-	if (param->data[0] == '@') {
-		param->data++;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		ptr->is_not = true;
+		/* fall through */
+	case 1:
 		ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP);
 		return ptr->group != NULL;
 	}
@@ -1583,8 +1562,17 @@
 {
 	u8 * const min = ptr->ip[0].in6_u.u6_addr8;
 	u8 * const max = ptr->ip[1].in6_u.u6_addr8;
-	char *address = ccs_read_token(param);
+	char *address;
 	const char *end;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		ptr->is_not = true;
+		/* fall through */
+	case 1:
+		ptr->group = ccs_get_group(param, CCS_ADDRESS_GROUP);
+		return ptr->group != NULL;
+	}
+	address = ccs_read_token(param);
 	if (!strchr(address, ':') &&
 	    ccs_in4_pton(address, -1, min, '-', &end) > 0) {
 		ptr->is_ipv6 = false;
@@ -1639,7 +1627,7 @@
 					struct ccs_name_union *ptr)
 {
 	char *filename = param->data;
-	if (*filename == '@')
+	if (ccs_group_type(&filename))
 		return ccs_parse_name_union(param, ptr);
 	ptr->filename = ccs_get_dqword(filename);
 	return ptr->filename != NULL;
@@ -1717,8 +1705,7 @@
 		a->names_count == b->names_count &&
 		a->argc == b->argc && a->envc == b->envc &&
 		a->grant_log == b->grant_log &&
-		a->exec_transit == b->exec_transit && a->transit == b->transit
-		&& !memcmp(a + 1, b + 1, a->size - sizeof(*a));
+		!memcmp(a + 1, b + 1, a->size - sizeof(*a));
 }
 
 /**
@@ -1911,7 +1898,7 @@
  * Returns the condition string part.
  */
 static char *ccs_get_transit_preference(struct ccs_acl_param *param,
-					struct ccs_condition *e)
+					struct ccs_execute_acl *e)
 {
 	char * const pos = param->data;
 	bool flag;
@@ -1924,8 +1911,7 @@
 		if (cp)
 			*cp = '\0';
 		flag = ccs_correct_path(pos) || !strcmp(pos, "keep") ||
-			!strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
-			!strcmp(pos, "child") || !strcmp(pos, "parent");
+			!strcmp(pos, "child");
 		if (cp)
 			*cp = ' ';
 	}
@@ -1933,15 +1919,9 @@
 		return pos;
 	e->transit = ccs_get_name(ccs_read_token(param));
 done:
-	if (e->transit) {
-		e->exec_transit = true;
+	if (e->transit)
 		return param->data;
-	}
-	/*
-	 * Return a bad read-only condition string that will let
-	 * ccs_get_condition() return NULL.
-	 */
-	return "/";
+	return NULL;
 }
 
 /**
@@ -1960,7 +1940,7 @@
 	struct ccs_argv *argv = NULL;
 	struct ccs_envp *envp = NULL;
 	struct ccs_condition e = { };
-	char * const start_of_string = ccs_get_transit_preference(param, &e);
+	char * const start_of_string = param->data;
 	char * const end_of_string = start_of_string + strlen(start_of_string);
 	char *pos;
 rerun:
@@ -2017,18 +1997,6 @@
 			}
 			continue;
 		}
-		if (!strcmp(left_word, "auto_domain_transition")) {
-			if (entry) {
-				if (is_not || entry->transit)
-					goto out;
-				entry->transit = ccs_get_dqword(right_word);
-				if (!entry->transit ||
-				    (entry->transit->name[0] != '/' &&
-				     !ccs_domain_def(entry->transit->name)))
-					goto out;
-			}
-			continue;
-		}
 		if (!strncmp(left_word, "exec.argv[", 10)) {
 			if (!argv) {
 				e.argc++;
@@ -2069,7 +2037,7 @@
 				e.numbers_count--;
 				left = CCS_NUMBER_UNION;
 				param->data = left_word;
-				if (*left_word == '@' ||
+				if (ccs_group_type(&left_word) ||
 				    !ccs_parse_number_union(param,
 							    numbers_p++))
 					goto out;
@@ -2079,7 +2047,7 @@
 			e.condc++;
 		else
 			e.condc--;
-		if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) {
+		if (left == CCS_EXEC_REALPATH) {
 			if (!names_p) {
 				e.names_count++;
 			} else {
@@ -2135,9 +2103,8 @@
 		+ e.envc * sizeof(struct ccs_envp);
 	entry = kzalloc(e.size, CCS_GFP_FLAGS);
 	if (!entry)
-		goto out2;
+		return NULL;
 	*entry = e;
-	e.transit = NULL;
 	condp = (struct ccs_condition_element *) (entry + 1);
 	numbers_p = (struct ccs_number_union *) (condp + e.condc);
 	names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count);
@@ -2164,8 +2131,6 @@
 		ccs_del_condition(&entry->head.list);
 		kfree(entry);
 	}
-out2:
-	ccs_put_name(e.transit);
 	return NULL;
 }
 
@@ -2306,7 +2271,7 @@
  *
  * @head: Pointer to "struct ccs_io_buffer".
  *
- * Returns true if all data was flushed, false otherwise.
+ * Returns nothing.
  */
 static bool ccs_set_lf(struct ccs_io_buffer *head)
 {
@@ -2336,12 +2301,9 @@
 static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns)
 {
 	unsigned int idx;
-	for (idx = 0; idx < CCS_MAX_ACL_GROUPS; idx++)
-		INIT_LIST_HEAD(&ns->acl_group[idx]);
 	for (idx = 0; idx < CCS_MAX_GROUP; idx++)
 		INIT_LIST_HEAD(&ns->group_list[idx]);
-	for (idx = 0; idx < CCS_MAX_POLICY; idx++)
-		INIT_LIST_HEAD(&ns->policy_list[idx]);
+	INIT_LIST_HEAD(&ns->default_transition_list);
 	ns->profile_version = 20100903;
 	ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
 	list_add_tail_rcu(&ns->namespace_list, &ccs_namespace_list);
@@ -2471,7 +2433,7 @@
  * CONFIG::category. If CONFIG::category is set to use default, then use
  * CONFIG. CONFIG cannot be set to use default.
  */
-u8 ccs_get_config(const u8 profile, const u8 index)
+static u8 ccs_get_config(const u8 profile, const u8 index)
 {
 	u8 config;
 	const struct ccs_profile *p;
@@ -2547,18 +2509,39 @@
 }
 
 /**
+ * ccs_group_type - Check whether the given string refers group or not.
+ *
+ * @src:  Pointer to pointer to the string.
+ *
+ * Returns 1 if @src refers a group in positive match, 2 if psrc refers a group
+ * in negative match, 0 otherwise.
+ *
+ * The @src is updated to point the first character of a group name if @src
+ * refers a group.
+ */
+static u8 ccs_group_type(char **src)
+{
+	if (ccs_str_starts(src, "\\="))
+		return 1;
+	if (ccs_str_starts(src, "\\!"))
+		return 2;
+	return 0;
+}
+
+/**
  * ccs_print_group - Print group's name.
  *
- * @head:  Pointer to "struct ccs_io_buffer".
- * @group: Pointer to "struct ccsgroup". Maybe NULL.
+ * @head:   Pointer to "struct ccs_io_buffer".
+ * @is_not: True if @group is negative match, false otherwise.
+ * @group:  Pointer to "struct ccsgroup". Maybe NULL.
  *
  * Returns true if @group is not NULL. false otherwise.
  */
-static bool ccs_print_group(struct ccs_io_buffer *head,
+static bool ccs_print_group(struct ccs_io_buffer *head, const bool is_not,
 			    const struct ccs_group *group)
 {
 	if (group) {
-		ccs_set_string(head, "@");
+		ccs_set_string(head, is_not ? "\\!" : "\\=");
 		ccs_set_string(head, group->group_name->name);
 		return true;
 	}
@@ -2856,7 +2839,7 @@
 	struct ccs_acl_param param = {
 		/* .ns = &ccs_kernel_namespace, */
 		.is_delete = is_delete,
-		.list = &ccs_kernel_namespace.policy_list[CCS_ID_MANAGER],
+		.list = &ccs_manager_list,
 	};
 	struct ccs_manager *e = &param.e.manager;
 	int error = is_delete ? -ENOENT : -ENOMEM;
@@ -2908,8 +2891,7 @@
 {
 	if (head->r.eof)
 		return;
-	list_for_each_cookie(head->r.acl, &ccs_kernel_namespace.
-			     policy_list[CCS_ID_MANAGER]) {
+	list_for_each_cookie(head->r.acl, &ccs_manager_list) {
 		struct ccs_manager *ptr =
 			list_entry(head->r.acl, typeof(*ptr), head.list);
 		if (ptr->head.is_deleted)
@@ -2945,9 +2927,7 @@
 	if (!ccs_manage_by_non_root && (current_uid() || current_euid()))
 		return false;
 	exe = ccs_get_exe();
-	list_for_each_entry_srcu(ptr, &ccs_kernel_namespace.
-				 policy_list[CCS_ID_MANAGER], head.list,
-				 &ccs_ss) {
+	list_for_each_entry_srcu(ptr, &ccs_manager_list, head.list, &ccs_ss) {
 		if (ptr->head.is_deleted)
 			continue;
 		if (ptr->is_domain) {
@@ -3056,6 +3036,45 @@
 }
 
 /**
+ * ccs_update_inverse_list - Update an entry for domain policy.
+ *
+ * @new_entry: Pointer to "struct ccs_acl_info".
+ * @size:      Size of @new_entry in bytes.
+ * @param:     Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_update_inverse_list(struct ccs_acl_info *new_entry,
+				   const int size, struct ccs_acl_param *param)
+{
+	const bool is_delete = param->is_delete;
+	struct ccs_acl_info *entry;
+	list_for_each_entry_srcu(entry, &ccs_inversed_acl_list, list,
+				 &ccs_ss) {
+		if (entry->is_deleted == CCS_GC_IN_PROGRESS ||
+		    entry->perm != new_entry->perm ||
+		    entry->type != new_entry->type ||
+		    entry->cond != new_entry->cond ||
+		    memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
+			continue;
+		entry->is_deleted = is_delete;
+		param->matched_entry = entry;
+		return 0;
+	}
+	if (is_delete)
+		return -ENOENT;
+	entry = ccs_commit_ok(new_entry, size);
+	if (!entry)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&entry->domain_list);
+	list_add_tail_rcu(&entry->list, &ccs_inversed_acl_list);
+	param->matched_entry = entry;
+	return 0;
+}
+
+/**
  * ccs_update_acl - Update "struct ccs_acl_info" entry.
  *
  * @size:  Size of new entry in bytes.
@@ -3077,23 +3096,13 @@
 		new_entry->cond = ccs_get_condition(param);
 		if (!new_entry->cond)
 			return -EINVAL;
-		/*
-		 * Domain transition preference is allowed for only
-		 * "file execute"/"task auto_execute_handler"/
-		 * "task denied_auto_execute_handler" entries.
-		 */
-		if (new_entry->cond->exec_transit &&
-		    !(new_entry->type == CCS_TYPE_PATH_ACL &&
-		      new_entry->perm == 1 << CCS_TYPE_EXECUTE)
-#ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
-		    && new_entry->type != CCS_TYPE_AUTO_EXECUTE_HANDLER &&
-		    new_entry->type != CCS_TYPE_DENIED_EXECUTE_HANDLER
-#endif
-		    )
-			return -EINVAL;
 	}
 	if (mutex_lock_interruptible(&ccs_policy_lock))
 		return -ENOMEM;
+	if (!list) {
+		error = ccs_update_inverse_list(new_entry, size, param);
+		goto unlock;
+	}
 	list_for_each_entry_srcu(entry, list, list, &ccs_ss) {
 		if (entry->is_deleted == CCS_GC_IN_PROGRESS)
 			continue;
@@ -3116,6 +3125,7 @@
 			error = 0;
 		}
 	}
+unlock:
 	mutex_unlock(&ccs_policy_lock);
 	return error;
 }
@@ -3222,15 +3232,8 @@
 			e->head.perm |= 1 << type;
 	if (!e->head.perm)
 		return -EINVAL;
-	if (param->data[0] == '@') {
-		param->data++;
-		e->address.group = ccs_get_group(param, CCS_ADDRESS_GROUP);
-		if (!e->address.group)
-			return -ENOMEM;
-	} else {
-		if (!ccs_parse_ipaddr_union(param, &e->address))
-			return -EINVAL;
-	}
+	if (!ccs_parse_ipaddr_union(param, &e->address))
+		return -EINVAL;
 	if (!ccs_parse_number_union(param, &e->port) ||
 	    e->port.values[1] > 65535)
 		return -EINVAL;
@@ -3271,6 +3274,28 @@
 #endif
 
 /**
+ * ccs_update_execute_acl - Update execute entry.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_update_execute_acl(struct ccs_acl_param *param)
+{
+	struct ccs_execute_acl *e = &param->e.execute_acl;
+	e->head.type = CCS_TYPE_EXECUTE_ACL;
+	e->head.perm = 1;
+	if (!ccs_parse_name_union(param, &e->program))
+		return -EINVAL;
+	param->data = ccs_get_transit_preference(param, e);
+	if (!param->data)
+		return -EINVAL;
+	return ccs_update_acl(sizeof(*e), param);
+}
+
+/**
  * ccs_write_file - Update file related list.
  *
  * @param: Pointer to "struct ccs_acl_param".
@@ -3284,8 +3309,10 @@
 	u16 perm = 0;
 	u8 type;
 	const char *operation = ccs_read_token(param);
+	if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_EXECUTE]))
+		return ccs_update_execute_acl(param);
 	for (type = 0; type < CCS_MAX_PATH_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_path_keyword[type]))
+		if (ccs_permstr(operation, ccs_mac_keywords[ccs_p2mac[type]]))
 			perm |= 1 << type;
 	if (perm) {
 		struct ccs_path_acl *e = &param->e.path_acl;
@@ -3360,13 +3387,9 @@
 {
 	if (ccs_str_starts(&param->data, "env ")) {
 		struct ccs_env_acl *e = &param->e.env_acl;
-		const char *data = ccs_read_token(param);
 		e->head.type = CCS_TYPE_ENV_ACL;
-		if (!ccs_correct_word(data) || strchr(data, '='))
+		if (!ccs_parse_name_union(param, &e->env))
 			return -EINVAL;
-		e->env = ccs_get_name(data);
-		if (!e->env)
-			return -ENOMEM;
 		return ccs_update_acl(sizeof(*e), param);
 	}
 	return -EINVAL;
@@ -3377,7 +3400,7 @@
 #ifdef CONFIG_CCSECURITY_IPC
 
 /**
- * ccs_write_ipc - Update "struct ccs_signal_acl" list.
+ * ccs_write_ipc - Update "struct ccs_ptrace_acl" list.
  *
  * @param: Pointer to "struct ccs_acl_param".
  *
@@ -3385,9 +3408,9 @@
  */
 static int ccs_write_ipc(struct ccs_acl_param *param)
 {
-	struct ccs_signal_acl *e = &param->e.signal_acl;
-	e->head.type = CCS_TYPE_SIGNAL_ACL;
-	if (!ccs_parse_number_union(param, &e->sig))
+	struct ccs_ptrace_acl *e = &param->e.ptrace_acl;
+	e->head.type = CCS_TYPE_PTRACE_ACL;
+	if (!ccs_parse_number_union(param, &e->request))
 		return -EINVAL;
 	e->domainname = ccs_get_domainname(param);
 	if (!e->domainname)
@@ -3426,6 +3449,31 @@
 #endif
 
 /**
+ * ccs_write_use_group_acl - Write "struct ccs_use_group_acl" list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_write_use_group_acl(struct ccs_acl_param *param)
+{
+	struct ccs_use_group_acl *e = &param->e.use_group_acl;
+	e->head.type = CCS_TYPE_USE_GROUP_ACL;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		e->is_not = true;
+		/* fall through */
+	case 1:
+		e->group = ccs_get_group(param, CCS_ACL_GROUP);
+		if (e->group)
+			return ccs_update_acl(sizeof(*e), param);
+	}
+	return -EINVAL;
+}
+
+/**
  * ccs_write_acl - Write "struct ccs_acl_info" list.
  *
  * @ns:        Pointer to "struct ccs_policy_namespace".
@@ -3463,9 +3511,10 @@
 		{ "capability ", ccs_write_capability },
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-		{ "ipc signal ", ccs_write_ipc },
+		{ "ipc ptrace ", ccs_write_ipc },
 #endif
 		{ "task ", ccs_write_task },
+		{ "use_group ", ccs_write_use_group_acl },
 	};
 	u8 i;
 	/* Forced zero clear for using memcmp() at ccs_update_acl(). */
@@ -3550,17 +3599,27 @@
 				domain->profile = (u8) profile;
 		return 0;
 	}
-	if (sscanf(data, "use_group %u\n", &profile) == 1
-	    && profile < CCS_MAX_ACL_GROUPS) {
-		if (!is_delete)
-			domain->group = (u8) profile;
+	if (ccs_str_starts(&data, "default_transition ")) {
+		static DEFINE_SPINLOCK(lock);
+		const struct ccs_path_info *new_transition = NULL;
+		const struct ccs_path_info *old_transition;
+		if (is_delete)
+			return 0;
+		if (ccs_correct_domain(data) || ccs_correct_path(data) ||
+		    !strcmp(data, "keep") || !strcmp(data, "child"))
+			new_transition = ccs_get_name(data);
+		if (!new_transition)
+			return -EINVAL;
+		spin_lock(&lock);
+		old_transition = domain->default_transition;
+		domain->default_transition = new_transition;
+		spin_unlock(&lock);
+		ccs_put_name(old_transition);
 		return 0;
 	}
-	for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
-		const char *cp = ccs_dif[profile];
-		if (strncmp(data, cp, strlen(cp) - 1))
-			continue;
-		domain->flags[profile] = !is_delete;
+	if (!strncmp(data, CCS_QUOTA_EXCEEDED,
+		     sizeof(CCS_QUOTA_EXCEEDED) - 2)) {
+		domain->quota_exceeded = !is_delete;
 		return 0;
 	}
 	return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete);
@@ -3578,7 +3637,7 @@
 				 const struct ccs_name_union *ptr)
 {
 	ccs_set_space(head);
-	if (!ccs_print_group(head, ptr->group))
+	if (!ccs_print_group(head, ptr->is_not, ptr->group))
 		ccs_set_string(head, ptr->filename->name);
 }
 
@@ -3593,7 +3652,7 @@
 static void ccs_print_name_union_quoted(struct ccs_io_buffer *head,
 					const struct ccs_name_union *ptr)
 {
-	if (!ccs_print_group(head, ptr->group)) {
+	if (!ccs_print_group(head, ptr->is_not, ptr->group)) {
 		ccs_set_string(head, "\"");
 		ccs_set_string(head, ptr->filename->name);
 		ccs_set_string(head, "\"");
@@ -3611,7 +3670,7 @@
 static void ccs_print_number_union_nospace(struct ccs_io_buffer *head,
 					   const struct ccs_number_union *ptr)
 {
-	if (!ccs_print_group(head, ptr->group)) {
+	if (!ccs_print_group(head, ptr->is_not, ptr->group)) {
 		int i;
 		unsigned long min = ptr->values[0];
 		const unsigned long max = ptr->values[1];
@@ -3674,10 +3733,6 @@
 	case 0:
 		head->r.cond_index = 0;
 		head->r.cond_step++;
-		if (cond->transit && cond->exec_transit) {
-			ccs_set_space(head);
-			ccs_set_string(head, cond->transit->name);
-		}
 		/* fall through */
 	case 1:
 		{
@@ -3791,12 +3846,6 @@
 			ccs_io_printf(head, " grant_log=%s",
 				      ccs_yesno(cond->grant_log ==
 						CCS_GRANTLOG_YES));
-		if (cond->transit && !cond->exec_transit) {
-			const char *name = cond->transit->name;
-			ccs_set_string(head, " auto_domain_transition=\"");
-			ccs_set_string(head, name);
-			ccs_set_string(head, "\"");
-		}
 		ccs_set_lf(head);
 		return true;
 	}
@@ -3815,7 +3864,11 @@
 {
 	if (head->type == CCS_EXCEPTION_POLICY) {
 		ccs_print_namespace(head);
-		ccs_io_printf(head, "acl_group %u ", head->r.acl_group_index);
+		ccs_set_string(head, "acl_group ");
+		ccs_set_string(head, head->r.acl_group_name->name);
+		ccs_set_space(head);
+	} else if (head->type == CCS_ACL_POLICY) {
+		ccs_set_string(head, "allow ");
 	}
 	ccs_set_string(head, category);
 }
@@ -3832,7 +3885,6 @@
 			    const struct ccs_acl_info *acl)
 {
 	const u8 acl_type = acl->type;
-	const bool may_trigger_transition = acl->cond && acl->cond->transit;
 	bool first = true;
 	u8 bit;
 	if (head->r.print_cond_part)
@@ -3841,26 +3893,25 @@
 		return true;
 	if (!ccs_flush(head))
 		return false;
-	else if (acl_type == CCS_TYPE_PATH_ACL) {
-		struct ccs_path_acl *ptr
+	/*
+	if (head->type == CCS_EXCEPTION_POLICY && head->r.acl_group_name)
+		printk(KERN_INFO "%s ptr=%p\n", __func__, acl);
+	*/
+	else if (acl_type == CCS_TYPE_EXECUTE_ACL) {
+		struct ccs_execute_acl *ptr
 			= container_of(acl, typeof(*ptr), head);
-		for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
-			if (!(acl->perm & (1 << bit)))
-				continue;
-			if (head->r.print_transition_related_only &&
-			    bit != CCS_TYPE_EXECUTE && !may_trigger_transition)
-				continue;
-			if (first) {
-				ccs_set_group(head, "file ");
-				first = false;
-			} else {
-				ccs_set_slash(head);
-			}
-			ccs_set_string(head, ccs_path_keyword[bit]);
+		if (head->r.print_default_transition) {
+			ccs_print_namespace(head);
+			ccs_set_string(head, "default_transition");
+		} else {
+			ccs_set_group(head, "file ");
+			ccs_set_string(head, "execute");
 		}
-		if (first)
-			return true;
-		ccs_print_name_union(head, &ptr->name);
+		ccs_print_name_union(head, &ptr->program);
+		if (ptr->transit) {
+			ccs_set_space(head);
+			ccs_set_string(head, ptr->transit->name);
+		}
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	} else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
 		   acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
@@ -3871,6 +3922,10 @@
 			       ? "auto_execute_handler " :
 			       "denied_execute_handler ");
 		ccs_set_string(head, ptr->handler->name);
+		if (ptr->transit) {
+			ccs_set_space(head);
+			ccs_set_string(head, ptr->transit->name);
+		}
 #endif
 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
 	} else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
@@ -3883,9 +3938,30 @@
 			       "manual_domain_transition ");
 		ccs_set_string(head, ptr->domainname->name);
 #endif
-	} else if (head->r.print_transition_related_only &&
-		   !may_trigger_transition) {
+	} else if (acl_type == CCS_TYPE_USE_GROUP_ACL) {
+		struct ccs_use_group_acl *ptr =
+			container_of(acl, typeof(*ptr), head);
+		ccs_set_group(head, "use_group ");
+		ccs_print_group(head, ptr->is_not, ptr->group);
+	} else if (head->r.print_transition_related_only) {
 		return true;
+	} else if (acl_type == CCS_TYPE_PATH_ACL) {
+		struct ccs_path_acl *ptr
+			= container_of(acl, typeof(*ptr), head);
+		for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
+			if (!(acl->perm & (1 << bit)))
+				continue;
+			if (first) {
+				ccs_set_group(head, "file ");
+				first = false;
+			} else {
+				ccs_set_slash(head);
+			}
+			ccs_set_string(head, ccs_mac_keywords[ccs_p2mac[bit]]);
+		}
+		if (first)
+			return true;
+		ccs_print_name_union(head, &ptr->name);
 	} else if (acl_type == CCS_TYPE_MKDEV_ACL) {
 		struct ccs_mkdev_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
@@ -3949,8 +4025,8 @@
 	} else if (acl_type == CCS_TYPE_ENV_ACL) {
 		struct ccs_env_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "misc env ");
-		ccs_set_string(head, ptr->env->name);
+		ccs_set_group(head, "misc env");
+		ccs_print_name_union(head, &ptr->env);
 #endif
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	} else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
@@ -3981,7 +4057,8 @@
 		if (first)
 			return true;
 		ccs_set_space(head);
-		if (!ccs_print_group(head, ptr->address.group)) {
+		if (!ccs_print_group(head, ptr->address.is_not,
+				     ptr->address.group)) {
 			char buf[128];
 			ccs_print_ip(buf, sizeof(buf), &ptr->address);
 			ccs_io_printf(head, "%s", buf);
@@ -4009,11 +4086,11 @@
 		ccs_print_name_union(head, &ptr->name);
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	} else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
-		struct ccs_signal_acl *ptr =
+	} else if (acl_type == CCS_TYPE_PTRACE_ACL) {
+		struct ccs_ptrace_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		ccs_set_group(head, "ipc signal ");
-		ccs_print_number_union_nospace(head, &ptr->sig);
+		ccs_set_group(head, "ipc ptrace ");
+		ccs_print_number_union_nospace(head, &ptr->request);
 		ccs_set_space(head);
 		ccs_set_string(head, ptr->domainname->name);
 #endif
@@ -4080,7 +4157,6 @@
 		struct ccs_domain_info *domain =
 			list_entry(head->r.domain, typeof(*domain), list);
 		switch (head->r.step) {
-			u8 i;
 		case 0:
 			if (domain->is_deleted &&
 			    !head->r.print_this_domain_only)
@@ -4090,12 +4166,13 @@
 			ccs_set_lf(head);
 			ccs_io_printf(head, "use_profile %u\n",
 				      domain->profile);
-			ccs_io_printf(head, "use_group %u\n", domain->group);
-			for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
-				if (domain->flags[i])
-					ccs_set_string(head, ccs_dif[i]);
+			ccs_set_string(head, "default_transition ");
+			ccs_set_string(head, domain->default_transition->name);
+			ccs_set_lf(head);
+			if (domain->quota_exceeded)
+				ccs_set_string(head, CCS_QUOTA_EXCEEDED);
+			ccs_set_lf(head);
 			head->r.step++;
-			ccs_set_lf(head);
 			/* fall through */
 		case 1:
 			if (!ccs_read_acl(head, &domain->acl_info_list))
@@ -4198,10 +4275,12 @@
  */
 static int ccs_write_group(struct ccs_acl_param *param, const u8 type)
 {
+	int error = -EINVAL;
 	struct ccs_group *group = ccs_get_group(param, type);
-	int error = -EINVAL;
-	if (!group)
+	if (!group || group == &ccs_group_any)
 		return -ENOMEM;
+	if (type != CCS_ACL_GROUP && ccs_group_type(&param->data))
+		goto out;
 	param->list = &group->member_list;
 	if (type == CCS_PATH_GROUP) {
 		struct ccs_path_group *e = &param->e.path_group;
@@ -4214,17 +4293,20 @@
 		ccs_put_name(e->member_name);
 	} else if (type == CCS_NUMBER_GROUP) {
 		struct ccs_number_group *e = &param->e.number_group;
-		if (param->data[0] == '@' ||
-		    !ccs_parse_number_union(param, &e->number))
-			goto out;
-		error = ccs_update_policy(sizeof(*e), param);
+		if (ccs_parse_number_union(param, &e->number))
+			error = ccs_update_policy(sizeof(*e), param);
+	} else if (type == CCS_ACL_GROUP) {
+		error = ccs_write_acl(param->ns, param->list, param->data,
+				      param->is_delete);
+		/*
+		printk(KERN_INFO "%s: ptr=%p ret=%d\n", __func__, group,
+		       error);
+		*/
 #ifdef CONFIG_CCSECURITY_NETWORK
 	} else {
 		struct ccs_address_group *e = &param->e.address_group;
-		if (param->data[0] == '@' ||
-		    !ccs_parse_ipaddr_union(param, &e->address))
-			goto out;
-		error = ccs_update_policy(sizeof(*e), param);
+		if (ccs_parse_ipaddr_union(param, &e->address))
+			error = ccs_update_policy(sizeof(*e), param);
 #endif
 	}
 out:
@@ -4232,146 +4314,130 @@
 	return error;
 }
 
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
 /**
- * ccs_lport_reserved - Check whether local port is reserved or not.
+ * ccs_write_transition_control - Write default domain transition rules.
  *
- * @port: Port number.
+ * @param: Pointer to "struct ccs_acl_param".
  *
- * Returns true if local port is reserved, false otherwise.
+ * Returns 0 on success, negative value otherwise.
  */
-static bool __ccs_lport_reserved(const u16 port)
+static int ccs_write_transition_control(struct ccs_acl_param *param)
 {
-	return ccs_reserved_port_map[port >> 3] & (1 << (port & 7))
-		? true : false;
+	param->list = &param->ns->default_transition_list;
+	return ccs_update_execute_acl(param);
 }
 
 /**
- * ccs_write_reserved_port - Update "struct ccs_reserved" list.
+ * ccs_update_domain_in_acl - Update "struct ccs_domain_info" in "struct ccs_acl_info".
  *
+ * @acl:   Pointer to "struct ccs_acl_info".
  * @param: Pointer to "struct ccs_acl_param".
  *
  * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
  */
-static int ccs_write_reserved_port(struct ccs_acl_param *param)
+static int ccs_update_domain_in_acl(struct ccs_acl_info *acl,
+				    struct ccs_acl_param *param)
 {
-	struct ccs_reserved *e = &param->e.reserved;
-	struct ccs_policy_namespace *ns = param->ns;
-	int error;
-	u8 *tmp;
-	if (param->data[0] == '@' ||
-	    !ccs_parse_number_union(param, &e->port) ||
-	    e->port.values[1] > 65535 || param->data[0])
-		return -EINVAL;
-	param->list = &ns->policy_list[CCS_ID_RESERVEDPORT];
-	error = ccs_update_policy(sizeof(*e), param);
-	if (error)
+	struct ccs_domain_info *ptr;
+	struct ccs_domain_info domain = { };
+	int error = param->is_delete ? -ENOENT : -ENOMEM;
+	domain.domainname = ccs_get_domainname(param);
+	if (!domain.domainname)
 		return error;
-	tmp = kzalloc(sizeof(ccs_reserved_port_map), CCS_GFP_FLAGS);
-	if (!tmp)
-		return -ENOMEM;
-	list_for_each_entry_srcu(ns, &ccs_namespace_list, namespace_list,
-				 &ccs_ss) {
-		struct ccs_reserved *ptr;
-		struct list_head *list = &ns->policy_list[CCS_ID_RESERVEDPORT];
-		list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
-			unsigned int port;
-			if (ptr->head.is_deleted)
-				continue;
-			for (port = ptr->port.values[0];
-			     port <= ptr->port.values[1]; port++)
-				tmp[port >> 3] |= 1 << (port & 7);
+	if (param->data[0]) {
+		domain.cond = ccs_get_condition(param);
+		if (!domain.cond)
+			goto out;
+	}
+	mutex_lock(&ccs_policy_lock);
+	list_for_each_entry_srcu(ptr, &acl->domain_list, list, &ccs_ss) {
+		if (ptr->cond != domain.cond ||
+		    ptr->domainname != domain.domainname)
+			continue;
+		ptr->is_deleted = param->is_delete;
+		error = 0;
+		break;
+	}
+	if (!param->is_delete && error) {
+		struct ccs_domain_info *entry =
+			ccs_commit_ok(&domain, sizeof(domain));
+		if (entry) {
+			INIT_LIST_HEAD(&entry->acl_info_list);
+			list_add_tail_rcu(&entry->list, &acl->domain_list);
+			error = 0;
 		}
 	}
-	memmove(ccs_reserved_port_map, tmp, sizeof(ccs_reserved_port_map));
-	kfree(tmp);
-	/*
-	 * Since this feature is no-op by default, we don't need to register
-	 * this callback hook unless the first entry is added.
-	 */
-	ccsecurity_ops.lport_reserved = __ccs_lport_reserved;
-	return 0;
-}
-#endif
-
-/**
- * ccs_write_aggregator - Write "struct ccs_aggregator" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_aggregator(struct ccs_acl_param *param)
-{
-	struct ccs_aggregator *e = &param->e.aggregator;
-	int error = param->is_delete ? -ENOENT : -ENOMEM;
-	const char *original_name = ccs_read_token(param);
-	const char *aggregated_name = ccs_read_token(param);
-	if (!ccs_correct_word(original_name) ||
-	    !ccs_correct_path(aggregated_name))
-		return -EINVAL;
-	e->original_name = ccs_get_name(original_name);
-	e->aggregated_name = ccs_get_name(aggregated_name);
-	if (!e->original_name || !e->aggregated_name ||
-	    e->aggregated_name->is_patterned) /* No patterns allowed. */
-		goto out;
-	param->list = &param->ns->policy_list[CCS_ID_AGGREGATOR];
-	error = ccs_update_policy(sizeof(*e), param);
+	mutex_unlock(&ccs_policy_lock);
 out:
-	ccs_put_name(e->original_name);
-	ccs_put_name(e->aggregated_name);
+	ccs_put_name(domain.domainname);
+	ccs_put_condition(domain.cond);
 	return error;
 }
 
 /**
- * ccs_write_transition_control - Write "struct ccs_transition_control" list.
+ * ccs_write_acl_policy - Write inverse mode policy.
  *
- * @param: Pointer to "struct ccs_acl_param".
- * @type:  Type of this entry.
+ * @head: Pointer to "struct ccs_io_buffer".
  *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_write_transition_control(struct ccs_acl_param *param,
-					const u8 type)
+static int ccs_write_acl_policy(struct ccs_io_buffer *head)
 {
-	struct ccs_transition_control *e = &param->e.transition_control;
-	int error = param->is_delete ? -ENOENT : -ENOMEM;
-	char *program = param->data;
-	char *domainname = strstr(program, " from ");
-	e->type = type;
-	if (domainname) {
-		*domainname = '\0';
-		domainname += 6;
-	} else if (type == CCS_TRANSITION_CONTROL_NO_KEEP ||
-		   type == CCS_TRANSITION_CONTROL_KEEP) {
-		domainname = program;
-		program = NULL;
+	static const struct {
+		const char *keyword;
+		int (*write) (struct ccs_acl_param *);
+	} ccs_callback[] = {
+		{ "file ", ccs_write_file },
+#ifdef CONFIG_CCSECURITY_NETWORK
+		{ "network inet ", ccs_write_inet_network },
+		{ "network unix ", ccs_write_unix_network },
+#endif
+#ifdef CONFIG_CCSECURITY_MISC
+		{ "misc ", ccs_write_misc },
+#endif
+#ifdef CONFIG_CCSECURITY_CAPABILITY
+		{ "capability ", ccs_write_capability },
+#endif
+#ifdef CONFIG_CCSECURITY_IPC
+		{ "ipc ptrace ", ccs_write_ipc },
+#endif
+	};
+	struct ccs_acl_param param = {
+		.data = head->write_buf,
+		.is_delete = head->w.is_delete,
+		.e.acl_info.perm = 1,
+	};
+	u8 i;
+	if (ccs_str_starts(&param.data, "by ")) {
+		if (!head->w.acl)
+			return -EINVAL;
+		return ccs_update_domain_in_acl(head->w.acl, &param);
 	}
-	if (program && strcmp(program, "any")) {
-		if (!ccs_correct_path(program))
+	if (ccs_str_starts(&param.data, "mode ")) {
+		u8 mode;
+		if (!head->w.acl)
 			return -EINVAL;
-		e->program = ccs_get_name(program);
-		if (!e->program)
-			goto out;
+		for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++)
+			if (!strcmp(param.data, ccs_mode[mode])) {
+				head->w.acl->mode = mode;
+				return 0;
+			}
+		return -EINVAL;
 	}
-	if (domainname && strcmp(domainname, "any")) {
-		if (!ccs_correct_domain(domainname)) {
-			if (!ccs_correct_path(domainname))
-				goto out;
-			e->is_last_name = true;
-		}
-		e->domainname = ccs_get_name(domainname);
-		if (!e->domainname)
-			goto out;
+	head->w.acl = NULL;
+	if (!ccs_str_starts(&param.data, "allow "))
+		return -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
+		int error;
+		if (!ccs_str_starts(&param.data, ccs_callback[i].keyword))
+			continue;
+		error = ccs_callback[i].write(&param);
+		if (!error && !head->w.is_delete)
+			head->w.acl = param.matched_entry;
+		ccs_del_acl(&param.e.acl_info.list);
+		return error;
 	}
-	param->list = &param->ns->policy_list[CCS_ID_TRANSITION_CONTROL];
-	error = ccs_update_policy(sizeof(*e), param);
-out:
-	ccs_put_name(e->domainname);
-	ccs_put_name(e->program);
-	return error;
+	return -EINVAL;
 }
 
 /**
@@ -4392,27 +4458,12 @@
 	u8 i;
 	/* Forced zero clear for using memcmp() at ccs_update_policy(). */
 	memset(&param.e, 0, sizeof(param.e));
-	if (ccs_str_starts(&param.data, "aggregator "))
-		return ccs_write_aggregator(&param);
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-	if (ccs_str_starts(&param.data, "deny_autobind "))
-		return ccs_write_reserved_port(&param);
-#endif
-	for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
-		if (ccs_str_starts(&param.data, ccs_transition_type[i]))
-			return ccs_write_transition_control(&param, i);
+	param.e.acl_info.perm = 1;
+	if (ccs_str_starts(&param.data, "default_transition "))
+		return ccs_write_transition_control(&param);
 	for (i = 0; i < CCS_MAX_GROUP; i++)
 		if (ccs_str_starts(&param.data, ccs_group_name[i]))
 			return ccs_write_group(&param, i);
-	if (ccs_str_starts(&param.data, "acl_group ")) {
-		unsigned int group;
-		char *data;
-		group = simple_strtoul(param.data, &data, 10);
-		if (group < CCS_MAX_ACL_GROUPS && *data++ == ' ')
-			return ccs_write_acl(head->w.ns,
-					     &head->w.ns->acl_group[group],
-					     data, is_delete);
-	}
 	return -EINVAL;
 }
 
@@ -4431,6 +4482,24 @@
 	struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
 						       namespace_list);
 	struct list_head *list = &ns->group_list[idx];
+	if (idx == CCS_ACL_GROUP) {
+		list_for_each_cookie(head->r.group, list) {
+			struct ccs_group *group =
+				list_entry(head->r.group, typeof(*group),
+					   head.list);
+			/*
+			printk(KERN_INFO "%s ptr=%p\n", __func__, group);
+			*/
+			head->r.acl_group_name = group->group_name;
+			head->r.domain = &group->member_list;
+			if (!ccs_read_acl(head, head->r.domain))
+				return false;
+			head->r.acl_group_name = NULL;
+			head->r.domain = NULL;
+		}
+		head->r.group = NULL;
+		return true;
+	}
 	list_for_each_cookie(head->r.group, list) {
 		struct ccs_group *group =
 			list_entry(head->r.group, typeof(*group), head.list);
@@ -4473,79 +4542,6 @@
 }
 
 /**
- * ccs_read_policy - Read "struct ccs_..._entry" list.
- *
- * @head: Pointer to "struct ccs_io_buffer".
- * @idx:  Index number.
- *
- * Returns true on success, false otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static bool ccs_read_policy(struct ccs_io_buffer *head, const int idx)
-{
-	struct ccs_policy_namespace *ns = container_of(head->r.ns, typeof(*ns),
-						       namespace_list);
-	struct list_head *list = &ns->policy_list[idx];
-	list_for_each_cookie(head->r.acl, list) {
-		struct ccs_acl_head *acl =
-			container_of(head->r.acl, typeof(*acl), list);
-		if (acl->is_deleted)
-			continue;
-		if (head->r.print_transition_related_only &&
-		    idx != CCS_ID_TRANSITION_CONTROL)
-			continue;
-		if (!ccs_flush(head))
-			return false;
-		switch (idx) {
-		case CCS_ID_TRANSITION_CONTROL:
-			{
-				struct ccs_transition_control *ptr =
-					container_of(acl, typeof(*ptr), head);
-				ccs_print_namespace(head);
-				ccs_set_string(head,
-					       ccs_transition_type[ptr->type]);
-				ccs_set_string(head, ptr->program ?
-					       ptr->program->name : "any");
-				ccs_set_string(head, " from ");
-				ccs_set_string(head, ptr->domainname ?
-					       ptr->domainname->name : "any");
-			}
-			break;
-		case CCS_ID_AGGREGATOR:
-			{
-				struct ccs_aggregator *ptr =
-					container_of(acl, typeof(*ptr), head);
-				ccs_print_namespace(head);
-				ccs_set_string(head, "aggregator ");
-				ccs_set_string(head, ptr->original_name->name);
-				ccs_set_space(head);
-				ccs_set_string(head,
-					       ptr->aggregated_name->name);
-			}
-			break;
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-		case CCS_ID_RESERVEDPORT:
-			{
-				struct ccs_reserved *ptr =
-					container_of(acl, typeof(*ptr), head);
-				ccs_print_namespace(head);
-				ccs_set_string(head, "deny_autobind ");
-				ccs_print_number_union_nospace(head,
-							       &ptr->port);
-			}
-			break;
-#endif
-		default:
-			continue;
-		}
-		ccs_set_lf(head);
-	}
-	head->r.acl = NULL;
-	return true;
-}
-
-/**
  * ccs_read_exception - Read exception policy.
  *
  * @head: Pointer to "struct ccs_io_buffer".
@@ -4560,26 +4556,14 @@
 						       namespace_list);
 	if (head->r.eof)
 		return;
-	while (head->r.step < CCS_MAX_POLICY &&
-	       ccs_read_policy(head, head->r.step))
-		head->r.step++;
-	if (head->r.step < CCS_MAX_POLICY)
-		return;
-	while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP &&
-	       ccs_read_group(head, head->r.step - CCS_MAX_POLICY))
-		head->r.step++;
-	if (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP)
-		return;
-	while (head->r.step < CCS_MAX_POLICY + CCS_MAX_GROUP
-	       + CCS_MAX_ACL_GROUPS) {
-		head->r.acl_group_index =
-			head->r.step - CCS_MAX_POLICY - CCS_MAX_GROUP;
-		if (!ccs_read_acl(head, &ns->acl_group
-				  [head->r.acl_group_index]))
+	while (head->r.step < CCS_MAX_GROUP)
+		if (!ccs_read_group(head, head->r.step))
 			return;
-		head->r.step++;
-	}
-	head->r.eof = true;
+		else
+			head->r.step++;
+	head->r.print_default_transition = true;
+	head->r.eof = ccs_read_acl(head, &ns->default_transition_list);
+	head->r.print_default_transition = false;
 }
 
 /**
@@ -4610,7 +4594,6 @@
 	char *buffer;
 	char *realpath = NULL;
 	char *argv0 = NULL;
-	char *symlink = NULL;
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	char *handler;
 #endif
@@ -4635,9 +4618,6 @@
 			realpath += 8;
 			len += ccs_truncate(realpath) + 6;
 		}
-		symlink = strstr(header, " symlink.target=\"");
-		if (symlink)
-			len += ccs_truncate(symlink + 1) + 1;
 	}
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	handler = strstr(header, "type=execute_handler");
@@ -4656,8 +4636,6 @@
 		ccs_addprintf(buffer, len, " exec.%s", realpath);
 	if (argv0)
 		ccs_addprintf(buffer, len, " exec.argv[0]=%s", argv0);
-	if (symlink)
-		ccs_addprintf(buffer, len, "%s", symlink);
 	ccs_normalize_line(buffer);
 	{
 		struct ccs_domain_info *domain = ccs_current_domain();
@@ -4721,10 +4699,10 @@
 	}
 	if (count < ccs_profile(r->profile)->pref[CCS_PREF_MAX_LEARNING_ENTRY])
 		return true;
-	if (!domain->flags[CCS_DIF_QUOTA_WARNED]) {
-		domain->flags[CCS_DIF_QUOTA_WARNED] = true;
+	if (!domain->quota_exceeded) {
+		domain->quota_exceeded = true;
 		/* r->granted = false; */
-		ccs_write_log(r, "%s", ccs_dif[CCS_DIF_QUOTA_WARNED]);
+		ccs_write_log(r, "%s", CCS_QUOTA_EXCEEDED);
 		printk(KERN_WARNING "WARNING: "
 		       "Domain '%s' has too many ACLs to hold. "
 		       "Stopped learning mode.\n", domain->domainname->name);
@@ -4751,6 +4729,11 @@
 	static unsigned int ccs_serial;
 	struct ccs_query entry = { };
 	bool quota_exceeded = false;
+	if (!r->inversed) {
+		r->profile = ccs_current_domain()->profile;
+		r->mode = ccs_get_config(r->profile, r->type) &
+			(CCS_CONFIG_MAX_MODE - 1);
+	}
 	va_start(args, fmt);
 	len = vsnprintf((char *) &len, 1, fmt, args) + 1;
 	va_end(args);
@@ -4862,9 +4845,12 @@
 #ifdef CONFIG_CCSECURITY_NETWORK
 		const u32 *address;
 #endif
+	case CCS_TYPE_EXECUTE_ACL:
+		return ccs_supervisor(r, "file execute %s\n",
+				      r->param.path.filename->name);
 	case CCS_TYPE_PATH_ACL:
-		return ccs_supervisor(r, "file %s %s\n", ccs_path_keyword
-				      [r->param.path.operation],
+		return ccs_supervisor(r, "file %s %s\n", ccs_mac_keywords
+				      [ccs_p2mac[r->param.path.operation]],
 				      r->param.path.filename->name);
 	case CCS_TYPE_PATH2_ACL:
 		return ccs_supervisor(r, "file %s %s %s\n", ccs_mac_keywords
@@ -4943,10 +4929,10 @@
 				      r->param.unix_network.address->name);
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	case CCS_TYPE_SIGNAL_ACL:
-		return ccs_supervisor(r, "ipc signal %d %s\n",
-				      r->param.signal.sig,
-				      r->param.signal.dest_pattern);
+	case CCS_TYPE_PTRACE_ACL:
+		return ccs_supervisor(r, "ipc ptrace %lu %s\n",
+				      r->param.ptrace.request,
+				      r->param.ptrace.domainname);
 #endif
 	}
 	return 0;
@@ -5359,18 +5345,24 @@
 		do_gettimeofday(&tv);
 		ccs_convert_time(tv.tv_sec, &stamp);
 	}
-	pos = snprintf(buffer, ccs_buffer_len - 1,
-		       "#%04u/%02u/%02u %02u:%02u:%02u# profile=%u mode=%s "
-		       "granted=%s (global-pid=%u) task={ pid=%u ppid=%u "
-		       "uid=%u gid=%u euid=%u egid=%u suid=%u sgid=%u "
-		       "fsuid=%u fsgid=%u type%s=execute_handler }",
-		       stamp.year, stamp.month, stamp.day, stamp.hour,
-		       stamp.min, stamp.sec, r->profile, ccs_mode[r->mode],
-		       ccs_yesno(r->granted), gpid, ccs_sys_getpid(),
-		       ccs_sys_getppid(), current_uid(), current_gid(),
-		       current_euid(), current_egid(), current_suid(),
-		       current_sgid(), current_fsuid(), current_fsgid(),
-		       ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ? "" : "!");
+	pos = snprintf(buffer, ccs_buffer_len - 1, "#%04u/%02u/%02u "
+		       "%02u:%02u:%02u# profile=", stamp.year, stamp.month,
+		       stamp.day, stamp.hour, stamp.min, stamp.sec);
+	if (r->inversed)
+		pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, "acl");
+	else
+		pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos, "%u",
+				r->profile);
+	pos += snprintf(buffer + pos, ccs_buffer_len - 1 - pos,
+			" mode=%s granted=%s (global-pid=%u) task={ "
+			"pid=%u ppid=%u uid=%u gid=%u euid=%u egid=%u suid=%u "
+			"sgid=%u fsuid=%u fsgid=%u type%s=execute_handler }",
+			ccs_mode[r->mode], ccs_yesno(r->granted), gpid,
+			ccs_sys_getpid(), ccs_sys_getppid(), current_uid(),
+			current_gid(), current_euid(), current_egid(),
+			current_suid(), current_sgid(), current_fsuid(),
+			current_fsgid(),
+			ccs_flags & CCS_TASK_IS_EXECUTE_HANDLER ? "" : "!");
 	if (!obj)
 		goto no_obj_info;
 	if (!obj->validate_done) {
@@ -5434,7 +5426,6 @@
 	char *buf = NULL;
 	char *bprm_info = NULL;
 	char *realpath = NULL;
-	const char *symlink = NULL;
 	const char *header = NULL;
 	int pos;
 	const char *domainname = ccs_current_domain()->domainname->name;
@@ -5456,10 +5447,6 @@
 			goto out;
 		/* +80 is for " exec={ realpath=\"%s\" argc=%d envc=%d %s }" */
 		len += strlen(realpath) + 80 + strlen(bprm_info);
-	} else if (r->obj && r->obj->symlink_target) {
-		symlink = r->obj->symlink_target->name;
-		/* +18 is for " symlink.target=\"%s\"" */
-		len += 18 + strlen(symlink);
 	}
 	len = ccs_round2(len);
 	buf = kzalloc(len, CCS_GFP_FLAGS);
@@ -5472,9 +5459,7 @@
 		pos += snprintf(buf + pos, len - pos,
 				" exec={ realpath=\"%s\" argc=%d envc=%d %s }",
 				realpath, bprm->argc, bprm->envc, bprm_info);
-	} else if (symlink)
-		pos += snprintf(buf + pos, len - pos, " symlink.target=\"%s\"",
-				symlink);
+	}
 	pos += snprintf(buf + pos, len - pos, "\n%s\n", domainname);
 	vsnprintf(buf + pos, len - pos, fmt, args);
 out:
@@ -5485,60 +5470,6 @@
 }
 
 /**
- * ccs_transition_failed - Print waning message and send signal when domain transition failed.
- *
- * @domainname: Name of domain to transit.
- *
- * Returns nothing.
- *
- * Note that if current->pid == 1, sending SIGKILL won't work.
- */
-void ccs_transition_failed(const char *domainname)
-{
-	printk(KERN_WARNING
-	       "ERROR: Unable to transit to '%s' domain.\n", domainname);
-	force_sig(SIGKILL, current);
-}
-
-/**
- * ccs_update_task_domain - Update task's domain.
- *
- * @r: Pointer to "struct ccs_request_info".
- *
- * Returns nothing.
- *
- * The task will retry as hard as possible. But if domain transition failed,
- * the task will be killed by SIGKILL.
- */
-static void ccs_update_task_domain(struct ccs_request_info *r)
-{
-	char *buf;
-	const char *cp;
-	const struct ccs_acl_info *acl = r->matched_acl;
-	r->matched_acl = NULL;
-	if (!acl || !acl->cond || !acl->cond->transit ||
-	    acl->cond->exec_transit)
-		return;
-	while (1) {
-		buf = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
-		if (buf)
-			break;
-		ssleep(1);
-		if (fatal_signal_pending(current))
-			return;
-	}
-	cp = acl->cond->transit->name;
-	if (*cp == '/')
-		snprintf(buf, CCS_EXEC_TMPSIZE - 1, "%s %s",
-			 ccs_current_domain()->domainname->name, cp);
-	else
-		strncpy(buf, cp, CCS_EXEC_TMPSIZE - 1);
-	if (!ccs_assign_domain(buf, true))
-		ccs_transition_failed(buf);
-	kfree(buf);
-}
-
-/**
  * ccs_get_audit - Get audit mode.
  *
  * @r: Pointer to "struct ccs_request_info".
@@ -5547,7 +5478,6 @@
  */
 static bool ccs_get_audit(const struct ccs_request_info *r)
 {
-	const struct ccs_acl_info *matched_acl = r->matched_acl;
 	const u8 profile = r->profile;
 	const u8 index = r->type;
 	const bool is_granted = r->granted;
@@ -5558,9 +5488,13 @@
 	p = ccs_profile(profile);
 	if (ccs_log_count >= p->pref[CCS_PREF_MAX_AUDIT_LOG])
 		return false;
-	if (is_granted && matched_acl && matched_acl->cond &&
-	    matched_acl->cond->grant_log != CCS_GRANTLOG_AUTO)
-		return matched_acl->cond->grant_log == CCS_GRANTLOG_YES;
+	if (is_granted) {
+		const struct ccs_acl_info *matched_acl = r->matched_acl;
+		if (matched_acl && matched_acl->cond &&
+		    matched_acl->cond->grant_log != CCS_GRANTLOG_AUTO)
+			return matched_acl->cond->grant_log ==
+				CCS_GRANTLOG_YES;
+	}
 	mode = p->config[index];
 	if (mode == CCS_CONFIG_USE_DEFAULT)
 		mode = p->config
@@ -5589,14 +5523,14 @@
 	struct ccs_log *entry;
 	bool quota_exceeded = false;
 	if (!ccs_get_audit(r))
-		goto out;
+		return;
 	buf = ccs_init_log(r, len, fmt, args);
 	if (!buf)
-		goto out;
+		return;
 	entry = kzalloc(sizeof(*entry), CCS_GFP_FLAGS);
 	if (!entry) {
 		kfree(buf);
-		goto out;
+		return;
 	}
 	entry->log = buf;
 	len = ccs_round2(strlen(buf) + 1);
@@ -5619,11 +5553,9 @@
 	if (quota_exceeded) {
 		kfree(buf);
 		kfree(entry);
-		goto out;
+		return;
 	}
 	wake_up(&ccs_log_wait);
-out:
-	ccs_update_task_domain(r);
 }
 
 /**
@@ -5861,6 +5793,21 @@
 	e.ns = ccs_assign_namespace(domainname);
 	if (!e.ns)
 		return NULL;
+	e.domainname = ccs_get_name(domainname);
+	if (!e.domainname)
+		return NULL;
+	e.default_transition = ccs_get_name("child");
+	if (!e.default_transition)
+		goto out;
+	if (mutex_lock_interruptible(&ccs_policy_lock))
+		goto out;
+	entry = ccs_find_domain(domainname);
+	if (entry)
+		goto done;
+	entry = ccs_commit_ok(&e, sizeof(e));
+	if (!entry)
+		goto done;
+	INIT_LIST_HEAD(&entry->acl_info_list);
 	/*
 	 * "use_profile" and "use_group" settings for automatically created
 	 * domains are inherited from current domain. These are 0 for manually
@@ -5869,34 +5816,51 @@
 	if (transit) {
 		const struct ccs_domain_info *domain =
 			security->ccs_domain_info;
-		e.profile = domain->profile;
-		e.group = domain->group;
-	}
-	e.domainname = ccs_get_name(domainname);
-	if (!e.domainname)
-		return NULL;
-	if (mutex_lock_interruptible(&ccs_policy_lock))
-		goto out;
-	entry = ccs_find_domain(domainname);
-	if (!entry) {
-		entry = ccs_commit_ok(&e, sizeof(e));
-		if (entry) {
-			INIT_LIST_HEAD(&entry->acl_info_list);
-			list_add_tail_rcu(&entry->list, &ccs_domain_list);
-			created = true;
+		struct ccs_acl_info *ptr;
+		entry->profile = domain->profile;
+		list_for_each_entry_srcu(ptr, &domain->acl_info_list, list,
+					 &ccs_ss) {
+			struct ccs_use_group_acl tmp;
+			struct ccs_use_group_acl *acl;
+			/*
+			printk(KERN_INFO "ptr->is_deleted=%u ptr->type=%u\n",
+			       ptr->is_deleted, ptr->type);
+			*/
+			if (ptr->is_deleted ||
+			    ptr->type != CCS_TYPE_USE_GROUP_ACL)
+				continue;
+			tmp = *container_of(ptr, typeof(tmp), head);
+			atomic_inc(&tmp.group->head.users);
+			if (tmp.head.cond)
+				atomic_inc(&tmp.head.cond->head.users);
+			/*
+			printk(KERN_INFO "Inherit %s\n",
+			       tmp.group->group_name->name);
+			*/
+			acl = ccs_commit_ok(&tmp, sizeof(tmp));
+			if (!acl) {
+				entry->is_deleted = true;
+				break;
+			}
+			list_add_tail(&acl->head.list, &entry->acl_info_list);
 		}
 	}
+	list_add_tail_rcu(&entry->list, &ccs_domain_list);
+	if (!entry->is_deleted)
+		created = true;
+	else
+		entry = NULL;
+done:
 	mutex_unlock(&ccs_policy_lock);
 out:
 	ccs_put_name(e.domainname);
+	ccs_put_name(e.default_transition);
 	if (entry && transit) {
 		security->ccs_domain_info = entry;
 		if (created) {
-			struct ccs_request_info r;
-			ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE);
-			r.granted = false;
+			struct ccs_request_info r = { };
+			r.type = CCS_MAC_FILE_EXECUTE;
 			ccs_write_log(&r, "use_profile %u\n", entry->profile);
-			ccs_write_log(&r, "use_group %u\n", entry->group);
 			ccs_update_stat(CCS_STAT_POLICY_UPDATES);
 		}
 	}
@@ -5954,6 +5918,8 @@
 		return ccs_write_answer(head);
 	case CCS_MANAGER:
 		return ccs_write_manager(head);
+	case CCS_ACL_POLICY:
+		return ccs_write_acl_policy(head);
 	default:
 		return -ENOSYS;
 	}
@@ -6055,6 +6021,99 @@
 }
 
 /**
+ * ccs_read_domain_in_acl - Read domainname and condition.
+ *
+ * @head: Pointer to "struct ccs_io_buffer".
+ * @list: Pointer to "struct list_head".
+ *
+ * Returns true on success, false otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static bool ccs_read_domain_in_acl(struct ccs_io_buffer *head,
+				   struct list_head *list)
+{
+	list_for_each_cookie(head->r.domain, list) {
+		struct ccs_domain_info *domain =
+			list_entry(head->r.domain, typeof(*domain), list);
+		switch (head->r.step) {
+		case 3:
+			if (domain->is_deleted)
+				continue;
+			if (!ccs_flush(head))
+				return false;
+			ccs_set_string(head, "    by ");
+			ccs_set_string(head, domain->domainname->name);
+			head->r.cond_step = 0;
+			head->r.step++;
+			/* fall through */
+		case 4:
+			if (!ccs_flush(head))
+				return false;
+			if (domain->cond) {
+				if (!ccs_print_condition(head, domain->cond))
+					return false;
+			} else {
+				ccs_set_lf(head);
+			}
+			head->r.step--;
+		}
+	}
+	return true;
+}
+
+/**
+ * ccs_read_inverse_policy - Read inversed mode policy.
+ *
+ * @head: Pointer to "struct ccs_io_buffer".
+ *
+ * Caller holds ccs_read_lock().
+ */
+static void ccs_read_inverse_policy(struct ccs_io_buffer *head)
+{
+	if (head->r.eof)
+		return;
+	list_for_each_cookie(head->r.acl, &ccs_inversed_acl_list) {
+		struct ccs_acl_info *ptr =
+			list_entry(head->r.acl, typeof(*ptr), list);
+		switch (head->r.step) {
+		case 0:
+			if (ptr->is_deleted)
+				continue;
+			head->r.step++;
+			/* fall through */
+		case 1:
+			if (!ccs_print_entry(head, ptr))
+				return;
+			head->r.step++;
+			/* fall through */
+		case 2:
+			if (!ccs_flush(head))
+				return;
+			ccs_set_string(head, "    mode ");
+			ccs_set_string(head, ccs_mode[ptr->mode]);
+			ccs_set_lf(head);
+			head->r.domain = NULL;
+			head->r.step++;
+			/* fall through */
+		case 3:
+		case 4:
+			if (!ccs_read_domain_in_acl(head, &ptr->domain_list))
+				return;
+			head->r.domain = NULL;
+			head->r.step = 5;
+			/* fall through */
+		case 5:
+			if (!ccs_flush(head))
+				return;
+			ccs_set_lf(head);
+			head->r.step = 0;
+		}
+	}
+	head->r.eof = true;
+}
+
+/**
  * ccs_open - open() for /proc/ccs/ interface.
  *
  * @inode: Pointer to "struct inode".
@@ -6208,6 +6267,9 @@
 			case CCS_MANAGER:
 				ccs_read_manager(head);
 				break;
+			case CCS_ACL_POLICY:
+				ccs_read_inverse_policy(head);
+				break;
 			}
 		} while (ccs_flush(head) && ccs_has_more_namespace(head));
 	ccs_read_unlock(idx);
@@ -6249,11 +6311,11 @@
 	if (ccs_correct_domain(data)) {
 		const int idx = ccs_read_lock();
 		struct ccs_path_info name;
-		struct ccs_request_info r;
+		struct ccs_request_info r = { };
 		name.name = data;
 		ccs_fill_path_info(&name);
 		/* Check "task manual_domain_transition" permission. */
-		ccs_init_request_info(&r, CCS_MAC_FILE_EXECUTE);
+		r.type = CCS_MAC_FILE_EXECUTE;
 		r.param_type = CCS_TYPE_MANUAL_TASK_ACL;
 		r.param.task.domainname = &name;
 		ccs_check_acl(&r);
@@ -6359,6 +6421,7 @@
 			case CCS_STAT:
 			case CCS_PROFILE:
 			case CCS_MANAGER:
+			case CCS_ACL_POLICY:
 				ccs_update_stat(CCS_STAT_POLICY_UPDATES);
 				break;
 			default:
@@ -6431,6 +6494,7 @@
 	ccs_create_entry(".execute_handler", 0666, ccs_dir,
 			 CCS_EXECUTE_HANDLER);
 #endif
+	ccs_create_entry("acl_policy",       0600, ccs_dir, CCS_ACL_POLICY);
 	{
 		struct proc_dir_entry *e = create_proc_entry("self_domain",
 							     0666, ccs_dir);
@@ -6455,8 +6519,19 @@
 	if (init_srcu_struct(&ccs_ss))
 		panic("Out of memory.");
 #endif
+	{
+		static struct ccs_path_info any;
+		any.name = "any";
+		ccs_fill_path_info(&any);
+		ccs_group_any.group_name = &any;
+		INIT_LIST_HEAD(&ccs_group_any.head.list);
+		INIT_LIST_HEAD(&ccs_group_any.member_list);
+	}
 	ccs_kernel_namespace.name = "<kernel>";
 	ccs_init_policy_namespace(&ccs_kernel_namespace);
+	ccs_kernel_transition.name = "child";
+	ccs_fill_path_info(&ccs_kernel_transition);
+	ccs_kernel_domain.default_transition = &ccs_kernel_transition;
 	ccs_kernel_domain.ns = &ccs_kernel_namespace;
 	INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
 	ccs_mm_init();
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/permission.c
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/permission.c	(revision 5698)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/permission.c	(working copy)
@@ -43,18 +43,16 @@
 };
 
 /* Mapping table from "enum ccs_path_acl_index" to "enum ccs_mac_index". */
-static const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION] = {
-	[CCS_TYPE_EXECUTE]    = CCS_MAC_FILE_EXECUTE,
-	[CCS_TYPE_READ]       = CCS_MAC_FILE_OPEN,
-	[CCS_TYPE_WRITE]      = CCS_MAC_FILE_OPEN,
-	[CCS_TYPE_APPEND]     = CCS_MAC_FILE_OPEN,
+const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION] = {
+	[CCS_TYPE_READ]       = CCS_MAC_FILE_READ,
+	[CCS_TYPE_WRITE]      = CCS_MAC_FILE_WRITE,
+	[CCS_TYPE_APPEND]     = CCS_MAC_FILE_APPEND,
 	[CCS_TYPE_UNLINK]     = CCS_MAC_FILE_UNLINK,
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
 	[CCS_TYPE_GETATTR]    = CCS_MAC_FILE_GETATTR,
 #endif
 	[CCS_TYPE_RMDIR]      = CCS_MAC_FILE_RMDIR,
 	[CCS_TYPE_TRUNCATE]   = CCS_MAC_FILE_TRUNCATE,
-	[CCS_TYPE_SYMLINK]    = CCS_MAC_FILE_SYMLINK,
 	[CCS_TYPE_CHROOT]     = CCS_MAC_FILE_CHROOT,
 	[CCS_TYPE_UMOUNT]     = CCS_MAC_FILE_UMOUNT,
 };
@@ -70,6 +68,7 @@
 	[CCS_TYPE_LINK]       = CCS_MAC_FILE_LINK,
 	[CCS_TYPE_RENAME]     = CCS_MAC_FILE_RENAME,
 	[CCS_TYPE_PIVOT_ROOT] = CCS_MAC_FILE_PIVOT_ROOT,
+	[CCS_TYPE_SYMLINK]    = CCS_MAC_FILE_SYMLINK,
 };
 
 /*
@@ -158,7 +157,6 @@
 	[CCS_SYS_SETHOSTNAME]   = CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
 	[CCS_USE_KERNEL_MODULE] = CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
 	[CCS_SYS_KEXEC_LOAD]    = CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
-	[CCS_SYS_PTRACE]        = CCS_MAC_CAPABILITY_SYS_PTRACE,
 };
 
 #endif
@@ -198,6 +196,8 @@
 static bool ccs_byte_range(const char *str);
 static bool ccs_check_entry(struct ccs_request_info *r,
 			    struct ccs_acl_info *ptr);
+static bool ccs_check_execute_acl(struct ccs_request_info *r,
+				  const struct ccs_acl_info *ptr);
 static bool ccs_check_mkdev_acl(struct ccs_request_info *r,
 				const struct ccs_acl_info *ptr);
 static bool ccs_check_mount_acl(struct ccs_request_info *r,
@@ -208,6 +208,8 @@
 			       const struct ccs_acl_info *ptr);
 static bool ccs_check_path_number_acl(struct ccs_request_info *r,
 				      const struct ccs_acl_info *ptr);
+static bool ccs_check_use_group_acl(struct ccs_request_info *r,
+				    struct ccs_acl_info *ptr);
 static bool ccs_compare_number_union(const unsigned long value,
 				     const struct ccs_number_union *ptr);
 static bool ccs_condition(struct ccs_request_info *r,
@@ -237,19 +239,12 @@
 static bool ccs_scan_exec_realpath(struct file *file,
 				   const struct ccs_name_union *ptr,
 				   const bool match);
-static bool ccs_scan_transition(const struct list_head *list,
-				const struct ccs_path_info *domainname,
-				const struct ccs_path_info *program,
-				const char *last_name,
-				const enum ccs_transition_type type);
-static const char *ccs_last_word(const char *name);
-static const struct ccs_path_info *ccs_compare_name_union
-(const struct ccs_path_info *name, const struct ccs_name_union *ptr);
-static const struct ccs_path_info *ccs_path_matches_group
-(const struct ccs_path_info *pathname, const struct ccs_group *group);
-static enum ccs_transition_type ccs_transition_type
-(const struct ccs_policy_namespace *ns, const struct ccs_path_info *domainname,
- const struct ccs_path_info *program);
+static bool ccs_compare_name_union(const struct ccs_path_info *name,
+				   const struct ccs_name_union *ptr);
+static bool ccs_path_matches_group(const struct ccs_path_info *pathname,
+				   const struct ccs_group *group);
+static const struct ccs_path_info *ccs_transition_type
+(struct ccs_request_info *r);
 static int __ccs_chmod_permission(struct dentry *dentry,
 				  struct vfsmount *vfsmnt, mode_t mode);
 static int __ccs_chown_permission(struct dentry *dentry,
@@ -299,6 +294,8 @@
 static int __ccs_uselib_permission(struct dentry *dentry,
 				   struct vfsmount *mnt);
 #endif
+static int ccs_execute_path(struct linux_binprm *bprm,
+			    struct ccs_path_info *name);
 static int ccs_execute_permission(struct ccs_request_info *r,
 				  const struct ccs_path_info *filename);
 static int ccs_find_next_domain(struct ccs_execve *ee);
@@ -307,8 +304,7 @@
 static int ccs_mkdev_perm(const u8 operation, struct dentry *dentry,
 			  struct vfsmount *mnt, const unsigned int mode,
 			  unsigned int dev);
-static int ccs_mount_acl(struct ccs_request_info *r, char *dev_name,
-			 struct path *dir, const char *type,
+static int ccs_mount_acl(char *dev_name, struct path *dir, const char *type,
 			 unsigned long flags);
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)
 static int ccs_new_open_permission(struct file *filp);
@@ -327,17 +323,18 @@
 static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
 				struct vfsmount *vfsmnt, unsigned long number);
 static int ccs_path_perm(const u8 operation, struct dentry *dentry,
-			 struct vfsmount *mnt, const char *target);
-static int ccs_path_permission(struct ccs_request_info *r, u8 operation,
-			       const struct ccs_path_info *filename);
+			 struct vfsmount *mnt);
+static int ccs_path_permission(u8 operation,
+			       const struct ccs_path_info *filename,
+			       struct ccs_obj_info *obj);
 static int ccs_start_execve(struct linux_binprm *bprm,
 			    struct ccs_execve **eep);
-static int ccs_symlink_path(const char *pathname, struct ccs_path_info *name);
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
 static void __ccs_clear_open_mode(void);
 static void __ccs_save_open_mode(int mode);
 #endif
 static void ccs_add_slash(struct ccs_path_info *buf);
+static void ccs_check_auto_domain_transition(void);
 static void ccs_finish_execve(int retval, struct ccs_execve *ee);
 
 #ifdef CONFIG_CCSECURITY_MISC
@@ -392,11 +389,9 @@
 #endif
 
 #ifdef CONFIG_CCSECURITY_IPC
-static bool ccs_check_signal_acl(struct ccs_request_info *r,
+static bool ccs_check_ptrace_acl(struct ccs_request_info *r,
 				 const struct ccs_acl_info *ptr);
-static int ccs_signal_acl(const int pid, const int sig);
-static int ccs_signal_acl0(pid_t tgid, pid_t pid, int sig);
-static int ccs_signal_acl2(const int sig, const int pid);
+static int __ccs_ptrace_permission(long request, long pid);
 #endif
 
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
@@ -666,6 +661,9 @@
 /* The list for "struct ccs_domain_info". */
 LIST_HEAD(ccs_domain_list);
 
+/* The list for inverse mode. */
+LIST_HEAD(ccs_inversed_acl_list);
+
 /***** SECTION6: Dependent functions section *****/
 
 /**
@@ -674,24 +672,25 @@
  * @pathname: The name of pathname.
  * @group:    Pointer to "struct ccs_path_group".
  *
- * Returns matched member's pathname if @pathname matches pathnames in @group,
- * NULL otherwise.
+ * Returns true if @pathname matches pathnames in @group, false otherwise.
  *
  * Caller holds ccs_read_lock().
  */
-static const struct ccs_path_info *ccs_path_matches_group
-(const struct ccs_path_info *pathname, const struct ccs_group *group)
+static bool ccs_path_matches_group(const struct ccs_path_info *pathname,
+				   const struct ccs_group *group)
 {
 	struct ccs_path_group *member;
+	if (group == &ccs_group_any)
+		return true;
 	list_for_each_entry_srcu(member, &group->member_list, head.list,
 				 &ccs_ss) {
 		if (member->head.is_deleted)
 			continue;
 		if (!ccs_path_matches_pattern(pathname, member->member_name))
 			continue;
-		return member->member_name;
+		return true;
 	}
-	return NULL;
+	return false;
 }
 
 /**
@@ -711,6 +710,8 @@
 {
 	struct ccs_number_group *member;
 	bool matched = false;
+	if (group == &ccs_group_any)
+		return true;
 	list_for_each_entry_srcu(member, &group->member_list, head.list,
 				 &ccs_ss) {
 		if (member->head.is_deleted)
@@ -725,6 +726,32 @@
 }
 
 /**
+ * ccs_check_use_group_acl - Do recursive permission check.
+ *
+ * @r:   Pointer to "struct ccs_request_info".
+ * @ptr: Pointer to "struct ccs_acl_info".
+ *
+ * Returns true on match, false otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static bool ccs_check_use_group_acl(struct ccs_request_info *r,
+				    struct ccs_acl_info *ptr)
+{
+	const struct ccs_use_group_acl *acl = container_of(ptr, typeof(*acl),
+							   head);
+	const struct list_head *list = &acl->group->member_list;
+	list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
+		if (!ptr->type == CCS_TYPE_USE_GROUP_ACL)
+			continue;
+		if (!ccs_check_entry(r, ptr) || !ccs_condition(r, ptr->cond))
+			continue;
+		return !acl->is_not;
+	}
+	return acl->is_not;
+}
+
+/**
  * ccs_check_entry - Do permission check.
  *
  * @r:   Pointer to "struct ccs_request_info".
@@ -740,6 +767,8 @@
 	if (ptr->is_deleted || ptr->type != r->param_type)
 		return false;
 	switch (r->param_type) {
+	case CCS_TYPE_EXECUTE_ACL:
+		return ccs_check_execute_acl(r, ptr);
 	case CCS_TYPE_PATH_ACL:
 		return ccs_check_path_acl(r, ptr);
 	case CCS_TYPE_PATH2_ACL:
@@ -765,19 +794,21 @@
 		return ccs_check_unix_acl(r, ptr);
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	case CCS_TYPE_SIGNAL_ACL:
-		return ccs_check_signal_acl(r, ptr);
+	case CCS_TYPE_PTRACE_ACL:
+		return ccs_check_ptrace_acl(r, ptr);
 #endif
 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
 	case CCS_TYPE_MANUAL_TASK_ACL:
 		return ccs_check_task_acl(r, ptr);
 #endif
+	case CCS_TYPE_USE_GROUP_ACL:
+		return ccs_check_use_group_acl(r, ptr);
 	}
 	return true;
 }
 
 /**
- * ccs_check_acl - Do permission check.
+ * ccs_check_inverselist - Do permission check.
  *
  * @r: Pointer to "struct ccs_request_info".
  *
@@ -785,15 +816,61 @@
  *
  * Caller holds ccs_read_lock().
  */
+static int ccs_check_inverselist(struct ccs_request_info *r)
+{
+	struct ccs_acl_info *ptr;
+	const struct ccs_path_info *self = ccs_current_domain()->domainname;
+retry_all:
+	list_for_each_entry_srcu(ptr, &ccs_inversed_acl_list, list, &ccs_ss) {
+		struct ccs_domain_info *domain;
+		int error;
+		if (ptr->mode == CCS_CONFIG_DISABLED)
+			continue;
+		if (!ccs_check_entry(r, ptr))
+			continue;
+		if (!ccs_condition(r, ptr->cond))
+			continue;
+		r->mode = ptr->mode;
+		list_for_each_entry_srcu(domain, &ptr->domain_list, list,
+					 &ccs_ss) {
+			if (!ccs_pathcmp(self, domain->domainname) &&
+			    ccs_condition(r, domain->cond))
+				goto next;
+		}
+		/* Did not match. */
+		r->granted = false;
+		error = ccs_audit_log(r);
+		if (error == CCS_RETRY_REQUEST)
+			goto retry_all;
+		if (error)
+			return error;
+next:
+		r->granted = true;
+		ccs_audit_log(r);
+	}
+	return 0;
+}
+
+/**
+ * ccs_check_acl - Do permission check.
+ *
+ * @r: Pointer to "struct ccs_request_info".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
 int ccs_check_acl(struct ccs_request_info *r)
 {
 	const struct ccs_domain_info *domain = ccs_current_domain();
+	struct ccs_acl_info *ptr;
 	int error;
-	bool retried = false;
+	const int idx = ccs_read_lock();
+	r->inversed = true;
+	error = ccs_check_inverselist(r);
+	if (error)
+		goto done;
+	r->inversed = false;
 	do {
-		struct ccs_acl_info *ptr;
 		const struct list_head *list = &domain->acl_info_list;
-retry:
 		list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
 			if (!ccs_check_entry(r, ptr))
 				continue;
@@ -802,123 +879,43 @@
 			r->matched_acl = ptr;
 			r->granted = true;
 			ccs_audit_log(r);
-			return 0;
+			error = 0;
+			goto done;
 		}
-		if (!retried) {
-			retried = true;
-			list = &domain->ns->acl_group[domain->group];
-			goto retry;
-		}
 		r->granted = false;
-		if (r->mode != CCS_CONFIG_DISABLED ||
-		    r->type != CCS_MAC_FILE_EXECUTE)
-			error = ccs_audit_log(r);
-		else
-			error = 0;
-	} while (error == CCS_RETRY_REQUEST &&
-		 r->type != CCS_MAC_FILE_EXECUTE);
+		error = ccs_audit_log(r);
+	} while (error == CCS_RETRY_REQUEST);
+done:
+	ccs_read_unlock(idx);
 	return error;
 }
 
 /**
- * ccs_last_word - Get last component of a domainname.
+ * ccs_transition_type - Get domain transition type.
  *
- * @name: Domainname to check.
+ * @r: Pointer to "struct ccs_request_info".
  *
- * Returns the last word of @name.
- */
-static const char *ccs_last_word(const char *name)
-{
-	const char *cp = strrchr(name, ' ');
-	if (cp)
-		return cp + 1;
-	return name;
-}
-
-/**
- * ccs_scan_transition - Try to find specific domain transition type.
+ * Returns pointer to "struct ccs_path_info" if found one, NULL otheriwse.
  *
- * @list:       Pointer to "struct list_head".
- * @domainname: The name of current domain.
- * @program:    The name of requested program.
- * @last_name:  The last component of @domainname.
- * @type:       One of values in "enum ccs_transition_type".
- *
- * Returns true if found one, false otherwise.
- *
  * Caller holds ccs_read_lock().
  */
-static bool ccs_scan_transition(const struct list_head *list,
-				const struct ccs_path_info *domainname,
-				const struct ccs_path_info *program,
-				const char *last_name,
-				const enum ccs_transition_type type)
+static const struct ccs_path_info *ccs_transition_type
+(struct ccs_request_info *r)
 {
-	const struct ccs_transition_control *ptr;
-	list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
-		if (ptr->head.is_deleted || ptr->type != type)
+	const struct list_head * const list = &ccs_current_namespace()->
+		default_transition_list;
+	struct ccs_acl_info *ptr;
+	list_for_each_entry_srcu(ptr, list, list, &ccs_ss) {
+		if (ptr->is_deleted)
 			continue;
-		if (ptr->domainname) {
-			if (!ptr->is_last_name) {
-				if (ptr->domainname != domainname)
-					continue;
-			} else {
-				/*
-				 * Use direct strcmp() since this is
-				 * unlikely used.
-				 */
-				if (strcmp(ptr->domainname->name, last_name))
-					continue;
-			}
-		}
-		if (ptr->program && ccs_pathcmp(ptr->program, program))
+		if (!ccs_check_execute_acl(r, ptr))
 			continue;
-		return true;
-	}
-	return false;
-}
-
-/**
- * ccs_transition_type - Get domain transition type.
- *
- * @ns:         Pointer to "struct ccs_policy_namespace".
- * @domainname: The name of current domain.
- * @program:    The name of requested program.
- *
- * Returns CCS_TRANSITION_CONTROL_TRANSIT if executing @program causes domain
- * transition across namespaces, CCS_TRANSITION_CONTROL_INITIALIZE if executing
- * @program reinitializes domain transition within that namespace,
- * CCS_TRANSITION_CONTROL_KEEP if executing @program stays at @domainname ,
- * others otherwise.
- *
- * Caller holds ccs_read_lock().
- */
-static enum ccs_transition_type ccs_transition_type
-(const struct ccs_policy_namespace *ns, const struct ccs_path_info *domainname,
- const struct ccs_path_info *program)
-{
-	const char *last_name = ccs_last_word(domainname->name);
-	enum ccs_transition_type type = CCS_TRANSITION_CONTROL_NO_RESET;
-	while (type < CCS_MAX_TRANSITION_TYPE) {
-		const struct list_head * const list =
-			&ns->policy_list[CCS_ID_TRANSITION_CONTROL];
-		if (!ccs_scan_transition(list, domainname, program, last_name,
-					 type)) {
-			type++;
+		if (!ccs_condition(r, ptr->cond))
 			continue;
-		}
-		if (type != CCS_TRANSITION_CONTROL_NO_RESET &&
-		    type != CCS_TRANSITION_CONTROL_NO_INITIALIZE)
-			break;
-		/*
-		 * Do not check for reset_domain if no_reset_domain matched.
-		 * Do not check for initialize_domain if no_initialize_domain
-		 * matched.
-		 */
-		type++;
-		type++;
+		return container_of(ptr, struct ccs_execute_acl, head)->
+			transit;
 	}
-	return type;
+	return NULL;
 }
 
 /**
@@ -938,23 +935,20 @@
 #endif
 	struct ccs_domain_info *domain = NULL;
 	struct ccs_domain_info * const old_domain = ccs_current_domain();
-	struct linux_binprm *bprm = ee->bprm;
 	struct ccs_security *task = ccs_current_security();
-	const struct ccs_path_info *candidate;
 	struct ccs_path_info exename;
 	int retval;
-	bool reject_on_transition_failure = false;
+	const char *domainname;
 
 	/* Get symlink's pathname of program. */
-	retval = ccs_symlink_path(bprm->filename, &exename);
+	retval = ccs_execute_path(ee->bprm, &exename);
 	if (retval < 0)
 		return retval;
 
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 	if (handler) {
 		/* No permission check for execute handler. */
-		candidate = &exename;
-		if (ccs_pathcmp(candidate, handler)) {
+		if (ccs_pathcmp(&exename, handler)) {
 			/* Failed to verify execute handler. */
 			static u8 counter = 20;
 			if (counter) {
@@ -967,113 +961,34 @@
 	} else
 #endif
 	{
-		struct ccs_aggregator *ptr;
-		struct list_head *list;
-retry:
-		/* Check 'aggregator' directive. */
-		candidate = &exename;
-		list = &old_domain->ns->policy_list[CCS_ID_AGGREGATOR];
-		list_for_each_entry_srcu(ptr, list, head.list, &ccs_ss) {
-			if (ptr->head.is_deleted ||
-			    !ccs_path_matches_pattern(candidate,
-						      ptr->original_name))
-				continue;
-			candidate = ptr->aggregated_name;
-			break;
-		}
-
 		/* Check execute permission. */
-		retval = ccs_execute_permission(r, candidate);
-		if (retval == CCS_RETRY_REQUEST)
-			goto retry;
+		retval = ccs_execute_permission(r, &exename);
 		if (retval < 0)
 			goto out;
-		/*
-		 * To be able to specify domainnames with wildcards, use the
-		 * pathname specified in the policy (which may contain
-		 * wildcard) rather than the pathname passed to execve()
-		 * (which never contains wildcard).
-		 */
-		if (r->param.path.matched_path)
-			candidate = r->param.path.matched_path;
 	}
-	/*
-	 * Check for domain transition preference if "file execute" matched.
-	 * If preference is given, make do_execve() fail if domain transition
-	 * has failed, for domain transition preference should be used with
-	 * destination domain defined.
-	 */
-	if (r->ee->transition) {
-		const char *domainname = r->ee->transition->name;
-		reject_on_transition_failure = true;
-		if (!strcmp(domainname, "keep"))
-			goto force_keep_domain;
-		if (!strcmp(domainname, "child"))
-			goto force_child_domain;
-		if (!strcmp(domainname, "reset"))
-			goto force_reset_domain;
-		if (!strcmp(domainname, "initialize"))
-			goto force_initialize_domain;
-		if (!strcmp(domainname, "parent")) {
-			char *cp;
-			strncpy(ee->tmp, old_domain->domainname->name,
-				CCS_EXEC_TMPSIZE - 1);
-			cp = strrchr(ee->tmp, ' ');
-			if (cp)
-				*cp = '\0';
-		} else if (*domainname == '<')
-			strncpy(ee->tmp, domainname, CCS_EXEC_TMPSIZE - 1);
-		else
-			snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
-				 old_domain->domainname->name, domainname);
-		goto force_jump_domain;
-	}
-	/*
-	 * No domain transition preference specified.
-	 * Calculate domain to transit to.
-	 */
-	switch (ccs_transition_type(old_domain->ns, old_domain->domainname,
-				    candidate)) {
-	case CCS_TRANSITION_CONTROL_RESET:
-force_reset_domain:
-		/* Transit to the root of specified namespace. */
-		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "<%s>",
-			 candidate->name);
-		/*
-		 * Make do_execve() fail if domain transition across namespaces
-		 * has failed.
-		 */
-		reject_on_transition_failure = true;
-		break;
-	case CCS_TRANSITION_CONTROL_INITIALIZE:
-force_initialize_domain:
-		/* Transit to the child of current namespace's root. */
-		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
-			 old_domain->ns->name, candidate->name);
-		break;
-	case CCS_TRANSITION_CONTROL_KEEP:
-force_keep_domain:
+	if (!ee->transition)
+		ee->transition = ccs_transition_type(r);
+	if (!ee->transition)
+		ee->transition = old_domain->default_transition;
+	BUG_ON(!ee->transition);
+	domainname = ee->transition->name;
+	if (!strcmp(domainname, "keep"))
 		/* Keep current domain. */
 		domain = old_domain;
-		break;
-	default:
-		if (old_domain == &ccs_kernel_domain && !ccs_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;
-			break;
-		}
-force_child_domain:
+	else if (!strcmp(domainname, "child"))
 		/* Normal domain transition. */
 		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
-			 old_domain->domainname->name, candidate->name);
-		break;
-	}
-force_jump_domain:
+			 old_domain->domainname->name, exename.name);
+	else if (*domainname == '<')
+		/* Transit to the specified domain. */
+		strncpy(ee->tmp, domainname, CCS_EXEC_TMPSIZE - 1);
+	else if (old_domain == &ccs_kernel_domain && !ccs_policy_loaded)
+		/* Do not transit before starting /sbin/init. */
+		domain = old_domain;
+	else
+		/* Transit to the child domain. */
+		snprintf(ee->tmp, CCS_EXEC_TMPSIZE - 1, "%s %s",
+			 old_domain->domainname->name, exename.name);
 	/*
 	 * Tell GC that I started execve().
 	 * Also, tell open_exec() to check read permission.
@@ -1092,25 +1007,12 @@
 	 */
 	if (!domain)
 		domain = ccs_assign_domain(ee->tmp, true);
-	if (domain)
+	if (domain) {
 		retval = 0;
-	else if (reject_on_transition_failure) {
-		printk(KERN_WARNING
-		       "ERROR: Domain '%s' not ready.\n", ee->tmp);
-		retval = -ENOMEM;
-	} else if (r->mode == CCS_CONFIG_ENFORCING)
-		retval = -ENOMEM;
-	else {
-		retval = 0;
-		if (!old_domain->flags[CCS_DIF_TRANSITION_FAILED]) {
-			old_domain->flags[CCS_DIF_TRANSITION_FAILED] = true;
-			r->granted = false;
-			ccs_write_log(r, "%s",
-				      ccs_dif[CCS_DIF_TRANSITION_FAILED]);
-			printk(KERN_WARNING
-			       "ERROR: Domain '%s' not defined.\n", ee->tmp);
-		}
+		goto out;
 	}
+	printk(KERN_WARNING "ERROR: Domain '%s' not ready.\n", ee->tmp);
+	retval = -ENOMEM;
 out:
 	kfree(exename.name);
 	return retval;
@@ -1387,9 +1289,8 @@
 		return false;
 	ee->handler = container_of(r->matched_acl, struct ccs_handler_acl,
 				   head)->handler;
-	ee->transition = r->matched_acl && r->matched_acl->cond &&
-		r->matched_acl->cond->exec_transit ?
-		r->matched_acl->cond->transit : NULL;
+	ee->transition = container_of(r->matched_acl, struct ccs_handler_acl,
+				      head)->transit;
 	return true;
 }
 
@@ -1467,6 +1368,7 @@
 	struct ccs_execve *ee;
 	int idx;
 	*eep = NULL;
+	ccs_check_auto_domain_transition();
 	ee = kzalloc(sizeof(*ee), CCS_GFP_FLAGS);
 	if (!ee)
 		return -ENOMEM;
@@ -1481,7 +1383,6 @@
 	/* Clear manager flag. */
 	task->ccs_flags &= ~CCS_TASK_IS_MANAGER;
 	*eep = ee;
-	ccs_init_request_info(&ee->r, CCS_MAC_FILE_EXECUTE);
 	ee->r.ee = ee;
 	ee->bprm = bprm;
 	ee->r.obj = &ee->obj;
@@ -1506,7 +1407,7 @@
 	}
 #endif
 #ifdef CONFIG_CCSECURITY_MISC
-	if (!retval)
+	if (!retval && bprm->envc)
 		retval = ccs_environ(ee);
 #endif
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
@@ -1563,8 +1464,7 @@
  * Returns 0 on success, negative value otherwise.
  *
  * Performs permission checks for do_execve() and domain transition.
- * Domain transition by "struct ccs_domain_transition_control" and
- * "auto_domain_transition=" parameter of "struct ccs_condition" are reverted
+ * Domain transition by "struct ccs_acl_info" will be reverted
  * if do_execve() failed.
  * Garbage collector does not remove "struct ccs_domain_info" from
  * ccs_domain_list nor kfree("struct ccs_domain_info") if the current thread is
@@ -1655,15 +1555,10 @@
 		__ccs_socket_post_recvmsg_permission;
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	ccsecurity_ops.kill_permission = ccs_signal_acl;
-	ccsecurity_ops.tgkill_permission = ccs_signal_acl0;
-	ccsecurity_ops.tkill_permission = ccs_signal_acl;
-	ccsecurity_ops.sigqueue_permission = ccs_signal_acl;
-	ccsecurity_ops.tgsigqueue_permission = ccs_signal_acl0;
+	ccsecurity_ops.ptrace_permission = __ccs_ptrace_permission;
 #endif
 #ifdef CONFIG_CCSECURITY_CAPABILITY
 	ccsecurity_ops.capable = __ccs_capable;
-	ccsecurity_ops.ptrace_permission = __ccs_ptrace_permission;
 #endif
 	ccsecurity_ops.search_binary_handler = __ccs_search_binary_handler;
 }
@@ -1714,35 +1609,53 @@
 }
 
 /**
- * ccs_symlink_path - Get symlink's pathname.
+ * ccs_execute_path - Get program's pathname.
  *
- * @pathname: The pathname to solve. Maybe NULL.
- * @name:     Pointer to "struct ccs_path_info".
+ * @bprm: Pointer to "struct linux_binprm".
+ * @name: Pointer to "struct ccs_path_info".
  *
  * Returns 0 on success, negative value otherwise.
  *
  * This function uses kzalloc(), so caller must kfree() if this function
  * didn't return NULL.
  */
-static int ccs_symlink_path(const char *pathname, struct ccs_path_info *name)
+static int ccs_execute_path(struct linux_binprm *bprm,
+			    struct ccs_path_info *name)
 {
 	char *buf;
-	struct path path;
+	/*
+	 * Follow symlinks if the requested pathname is on procfs, for
+	 * /proc/\$/exe is meaningless.
+	 */
+	/*
+	 * Force use of normal pathnames in order to use this pathname for
+	 * making domainnames.
+	 */
+	if (bprm->file->f_dentry->d_sb->s_magic == PROC_SUPER_MAGIC) {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+		struct path path = { bprm->file->f_vfsmnt,
+				     bprm->file->f_dentry };
+		buf = ccs_realpath2(&path, true);
+#else
+		buf = ccs_realpath2(&bprm->file->f_path, true);
+#endif
+	} else {
+		struct path path;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
-	if (ccs_kern_path(pathname, 0, &path))
-		return -ENOENT;
+		if (ccs_kern_path(bprm->filename, 0, &path))
+			return -ENOENT;
 #else
-	if (ccs_kern_path(pathname, LOOKUP_POSITIVE, &path))
-		return -ENOENT;
+		if (ccs_kern_path(bprm->filename, LOOKUP_POSITIVE, &path))
+			return -ENOENT;
 #endif
-	buf = ccs_realpath(&path);
-	path_put(&path);
-	if (buf) {
-		name->name = buf;
-		ccs_fill_path_info(name);
-		return 0;
+		buf = ccs_realpath2(&path, true);
+		path_put(&path);
 	}
-	return -ENOMEM;
+	if (!buf)
+		return -ENOMEM;
+	name->name = buf;
+	ccs_fill_path_info(name);
+	return 0;
 }
 
 /**
@@ -1768,20 +1681,17 @@
 /**
  * ccs_mount_acl - Check permission for mount() operation.
  *
- * @r:        Pointer to "struct ccs_request_info".
  * @dev_name: Name of device file. Maybe NULL.
  * @dir:      Pointer to "struct path".
  * @type:     Name of filesystem type.
  * @flags:    Mount options.
  *
  * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
  */
-static int ccs_mount_acl(struct ccs_request_info *r, char *dev_name,
-			 struct path *dir, const char *type,
+static int ccs_mount_acl(char *dev_name, struct path *dir, const char *type,
 			 unsigned long flags)
 {
+	struct ccs_request_info r = { };
 	struct ccs_obj_info obj = { };
 	struct file_system_type *fstype = NULL;
 	const char *requested_type = NULL;
@@ -1792,7 +1702,7 @@
 	struct ccs_path_info rdir;
 	int need_dev = 0;
 	int error = -ENOMEM;
-	r->obj = &obj;
+	r.obj = &obj;
 
 	/* Get fstype. */
 	requested_type = ccs_encode(type);
@@ -1855,13 +1765,14 @@
 	}
 	rdev.name = requested_dev_name;
 	ccs_fill_path_info(&rdev);
-	r->param_type = CCS_TYPE_MOUNT_ACL;
-	r->param.mount.need_dev = need_dev;
-	r->param.mount.dev = &rdev;
-	r->param.mount.dir = &rdir;
-	r->param.mount.type = &rtype;
-	r->param.mount.flags = flags;
-	error = ccs_check_acl(r);
+	r.type = CCS_MAC_FILE_MOUNT;
+	r.param_type = CCS_TYPE_MOUNT_ACL;
+	r.param.mount.need_dev = need_dev;
+	r.param.mount.dev = &rdev;
+	r.param.mount.dir = &rdir;
+	r.param.mount.type = &rtype;
+	r.param.mount.flags = flags;
+	error = ccs_check_acl(&r);
 out:
 	kfree(requested_dev_name);
 	kfree(requested_dir_name);
@@ -1889,9 +1800,6 @@
 				  const char *type, unsigned long flags,
 				  void *data_page)
 {
-	struct ccs_request_info r;
-	int error = 0;
-	int idx;
 	if ((flags & MS_MGC_MSK) == MS_MGC_VAL)
 		flags &= ~MS_MGC_MSK;
 	if (flags & MS_REMOUNT) {
@@ -1924,12 +1832,7 @@
 	}
 	if (!type)
 		type = "<NULL>";
-	idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, CCS_MAC_FILE_MOUNT)
-	    != CCS_CONFIG_DISABLED)
-		error = ccs_mount_acl(&r, dev_name, path, type, flags);
-	ccs_read_unlock(idx);
-	return error;
+	return ccs_mount_acl(dev_name, path, type, flags);
 }
 
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24)
@@ -1967,7 +1870,8 @@
 				     const struct ccs_number_union *ptr)
 {
 	if (ptr->group)
-		return ccs_number_matches_group(value, value, ptr->group);
+		return ccs_number_matches_group(value, value, ptr->group) !=
+			ptr->is_not;
 	return value >= ptr->values[0] && value <= ptr->values[1];
 }
 
@@ -1977,16 +1881,15 @@
  * @name: Pointer to "struct ccs_path_info".
  * @ptr:  Pointer to "struct ccs_name_union".
  *
- * Returns "struct ccs_path_info" if @name matches @ptr, NULL otherwise.
+ * Returns true if @name matches @ptr, false otherwise.
  */
-static const struct ccs_path_info *ccs_compare_name_union
-(const struct ccs_path_info *name, const struct ccs_name_union *ptr)
+static bool ccs_compare_name_union(const struct ccs_path_info *name,
+				   const struct ccs_name_union *ptr)
 {
 	if (ptr->group)
-		return ccs_path_matches_group(name, ptr->group);
-	if (ccs_path_matches_pattern(name, ptr->filename))
-		return ptr->filename;
-	return NULL;
+		return ccs_path_matches_group(name, ptr->group) !=
+			ptr->is_not;
+	return ccs_path_matches_pattern(name, ptr->filename);
 }
 
 /**
@@ -2027,28 +1930,35 @@
 }
 
 /**
- * ccs_check_path_acl - Check permission for path operation.
+ * ccs_check_execute_acl - Check permission for execute operation.
  *
  * @r:   Pointer to "struct ccs_request_info".
  * @ptr: Pointer to "struct ccs_acl_info".
  *
  * Returns true if granted, false otherwise.
+ */
+static bool ccs_check_execute_acl(struct ccs_request_info *r,
+				  const struct ccs_acl_info *ptr)
+{
+	const struct ccs_execute_acl *acl = container_of(ptr, typeof(*acl),
+							 head);
+	return ccs_compare_name_union(r->param.execute.program, &acl->program);
+}
+
+/**
+ * ccs_check_path_acl - Check permission for path operation.
  *
- * To be able to use wildcard for domain transition, this function sets
- * matching entry on success. Since the caller holds ccs_read_lock(),
- * it is safe to set matching entry.
+ * @r:   Pointer to "struct ccs_request_info".
+ * @ptr: Pointer to "struct ccs_acl_info".
+ *
+ * Returns true if granted, false otherwise.
  */
 static bool ccs_check_path_acl(struct ccs_request_info *r,
 			       const struct ccs_acl_info *ptr)
 {
 	const struct ccs_path_acl *acl = container_of(ptr, typeof(*acl), head);
-	if (ptr->perm & (1 << r->param.path.operation)) {
-		r->param.path.matched_path =
-			ccs_compare_name_union(r->param.path.filename,
-					       &acl->name);
-		return r->param.path.matched_path != NULL;
-	}
-	return false;
+	return (ptr->perm & (1 << r->param.path.operation)) &&
+		ccs_compare_name_union(r->param.path.filename, &acl->name);
 }
 
 /**
@@ -2113,56 +2023,40 @@
 /**
  * ccs_path_permission - Check permission for path operation.
  *
- * @r:         Pointer to "struct ccs_request_info".
  * @operation: Type of operation.
  * @filename:  Filename to check.
+ * @obj:       Pointer to "struct ccs_obj_info". Maybe NULL.
  *
  * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
  */
-static int ccs_path_permission(struct ccs_request_info *r, u8 operation,
-			       const struct ccs_path_info *filename)
+static int ccs_path_permission(u8 operation,
+			       const struct ccs_path_info *filename,
+			       struct ccs_obj_info *obj)
 {
-	r->type = ccs_p2mac[operation];
-	r->mode = ccs_get_mode(r->profile, r->type);
-	if (r->mode == CCS_CONFIG_DISABLED)
-		return 0;
-	r->param_type = CCS_TYPE_PATH_ACL;
-	r->param.path.filename = filename;
-	r->param.path.operation = operation;
-	return ccs_check_acl(r);
+	struct ccs_request_info r = { };
+	r.type = ccs_p2mac[operation];
+	r.obj = obj;
+	r.param_type = CCS_TYPE_PATH_ACL;
+	r.param.path.filename = filename;
+	r.param.path.operation = operation;
+	return ccs_check_acl(&r);
 }
 
 /**
  * ccs_execute_permission - Check permission for execute operation.
  *
- * @r:         Pointer to "struct ccs_request_info".
- * @filename:  Filename to check.
+ * @r:        Pointer to "struct ccs_request_info".
+ * @filename: Filename to check.
  *
- * Returns 0 on success, CCS_RETRY_REQUEST on retry, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
+ * Returns 0 on success, negative value otherwise.
  */
 static int ccs_execute_permission(struct ccs_request_info *r,
 				  const struct ccs_path_info *filename)
 {
-	int error;
-	/*
-	 * Unlike other permission checks, this check is done regardless of
-	 * profile mode settings in order to check for domain transition
-	 * preference.
-	 */
 	r->type = CCS_MAC_FILE_EXECUTE;
-	r->mode = ccs_get_mode(r->profile, r->type);
-	r->param_type = CCS_TYPE_PATH_ACL;
-	r->param.path.filename = filename;
-	r->param.path.operation = CCS_TYPE_EXECUTE;
-	error = ccs_check_acl(r);
-	r->ee->transition = r->matched_acl && r->matched_acl->cond &&
-		r->matched_acl->cond->exec_transit ?
-		r->matched_acl->cond->transit : NULL;
-	return error;
+	r->param_type = CCS_TYPE_EXECUTE_ACL;
+	r->param.execute.program = filename;
+	return ccs_check_acl(r);
 }
 
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
@@ -2219,7 +2113,6 @@
 static int __ccs_open_permission(struct dentry *dentry, struct vfsmount *mnt,
 				 const int flag)
 {
-	struct ccs_request_info r;
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry,
 		.path1.mnt = mnt,
@@ -2236,7 +2129,6 @@
 #endif
 	int error = 0;
 	struct ccs_path_info buf;
-	int idx;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30)
 	if (current->in_execve && !(ccs_flags & CCS_TASK_IS_IN_EXECVE))
 		return 0;
@@ -2246,39 +2138,37 @@
 		return 0;
 #endif
 	buf.name = NULL;
-	r.mode = CCS_CONFIG_DISABLED;
-	idx = ccs_read_lock();
-	if (acc_mode && ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
-	    != CCS_CONFIG_DISABLED) {
+	if (!(ccs_flags & CCS_TASK_IS_IN_EXECVE))
+		ccs_check_auto_domain_transition();
+	if (acc_mode & MAY_READ) {
 		if (!ccs_get_realpath(&buf, &obj.path1)) {
 			error = -ENOMEM;
 			goto out;
 		}
-		r.obj = &obj;
-		if (acc_mode & MAY_READ)
-			error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
-		if (!error && (acc_mode & MAY_WRITE))
-			error = ccs_path_permission(&r, (flag & O_APPEND) ?
-						    CCS_TYPE_APPEND :
-						    CCS_TYPE_WRITE, &buf);
+		error = ccs_path_permission(CCS_TYPE_READ, &buf, &obj);
+		if (error)
+			goto out;
 	}
+	if (acc_mode & MAY_WRITE) {
+		if (!buf.name && !ccs_get_realpath(&buf, &obj.path1)) {
+			error = -ENOMEM;
+			goto out;
+		}
+		error = ccs_path_permission((flag & O_APPEND) ?
+					    CCS_TYPE_APPEND :
+					    CCS_TYPE_WRITE, &buf, &obj);
+	}
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 32)
-	if (!error && (flag & O_TRUNC) &&
-	    ccs_init_request_info(&r, CCS_MAC_FILE_TRUNCATE)
-	    != CCS_CONFIG_DISABLED) {
+	if (!error && (flag & O_TRUNC)) {
 		if (!buf.name && !ccs_get_realpath(&buf, &obj.path1)) {
 			error = -ENOMEM;
 			goto out;
 		}
-		r.obj = &obj;
-		error = ccs_path_permission(&r, CCS_TYPE_TRUNCATE, &buf);
+		error = ccs_path_permission(CCS_TYPE_TRUNCATE, &buf, &obj);
 	}
 #endif
 out:
 	kfree(buf.name);
-	ccs_read_unlock(idx);
-	if (r.mode != CCS_CONFIG_ENFORCING)
-		error = 0;
 	return error;
 }
 
@@ -2300,61 +2190,33 @@
 #endif
 
 /**
- * ccs_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "getattr", "chroot" and "unmount".
+ * ccs_path_perm - Check permission for "unlink", "rmdir", "truncate", "append", "getattr", "chroot" and "unmount".
  *
  * @operation: Type of operation.
  * @dentry:    Pointer to "struct dentry".
  * @mnt:       Pointer to "struct vfsmount". Maybe NULL.
- * @target:    Symlink's target if @operation is CCS_TYPE_SYMLINK,
- *             NULL otherwise.
  *
  * Returns 0 on success, negative value otherwise.
  */
 static int ccs_path_perm(const u8 operation, struct dentry *dentry,
-			 struct vfsmount *mnt, const char *target)
+			 struct vfsmount *mnt)
 {
-	struct ccs_request_info r;
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry,
 		.path1.mnt = mnt,
 	};
-	int error = 0;
+	int error;
 	struct ccs_path_info buf;
-	bool is_enforce = false;
-	struct ccs_path_info symlink_target;
-	int idx;
-	buf.name = NULL;
-	symlink_target.name = NULL;
-	idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, ccs_p2mac[operation])
-	    == CCS_CONFIG_DISABLED)
-		goto out;
-	is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
-	error = -ENOMEM;
 	if (!ccs_get_realpath(&buf, &obj.path1))
-		goto out;
-	r.obj = &obj;
+		return -ENOMEM;
 	switch (operation) {
 	case CCS_TYPE_RMDIR:
 	case CCS_TYPE_CHROOT:
 		ccs_add_slash(&buf);
 		break;
-	case CCS_TYPE_SYMLINK:
-		symlink_target.name = ccs_encode(target);
-		if (!symlink_target.name)
-			goto out;
-		ccs_fill_path_info(&symlink_target);
-		obj.symlink_target = &symlink_target;
-		break;
 	}
-	error = ccs_path_permission(&r, operation, &buf);
-	if (operation == CCS_TYPE_SYMLINK)
-		kfree(symlink_target.name);
-out:
+	error = ccs_path_permission(operation, &buf, &obj);
 	kfree(buf.name);
-	ccs_read_unlock(idx);
-	if (!is_enforce)
-		error = 0;
 	return error;
 }
 
@@ -2373,42 +2235,31 @@
 			  struct vfsmount *mnt, const unsigned int mode,
 			  unsigned int dev)
 {
-	struct ccs_request_info r;
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry,
 		.path1.mnt = mnt,
 	};
-	int error = 0;
+	int error;
 	struct ccs_path_info buf;
-	bool is_enforce = false;
-	int idx;
-	idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, ccs_pnnn2mac[operation])
-	    == CCS_CONFIG_DISABLED)
-		goto out;
-	is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
-	error = -EPERM;
-	if (!capable(CAP_MKNOD))
-		goto out;
-	error = -ENOMEM;
+	ccs_check_auto_domain_transition();
 	if (!ccs_get_realpath(&buf, &obj.path1))
-		goto out;
-	r.obj = &obj;
+		return -ENOMEM;
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0)
 	dev = new_decode_dev(dev);
 #endif
-	r.param_type = CCS_TYPE_MKDEV_ACL;
-	r.param.mkdev.filename = &buf;
-	r.param.mkdev.operation = operation;
-	r.param.mkdev.mode = mode;
-	r.param.mkdev.major = MAJOR(dev);
-	r.param.mkdev.minor = MINOR(dev);
-	error = ccs_check_acl(&r);
+	{
+		struct ccs_request_info r = { };
+		r.type = ccs_pnnn2mac[operation];
+		r.obj = &obj;
+		r.param_type = CCS_TYPE_MKDEV_ACL;
+		r.param.mkdev.filename = &buf;
+		r.param.mkdev.operation = operation;
+		r.param.mkdev.mode = mode;
+		r.param.mkdev.major = MAJOR(dev);
+		r.param.mkdev.minor = MINOR(dev);
+		error = ccs_check_acl(&r);
+	}
 	kfree(buf.name);
-out:
-	ccs_read_unlock(idx);
-	if (!is_enforce)
-		error = 0;
 	return error;
 }
 
@@ -2427,29 +2278,22 @@
 			  struct vfsmount *mnt1, struct dentry *dentry2,
 			  struct vfsmount *mnt2)
 {
-	struct ccs_request_info r;
-	int error = 0;
-	struct ccs_path_info buf1;
-	struct ccs_path_info buf2;
-	bool is_enforce = false;
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry1,
 		.path1.mnt = mnt1,
 		.path2.dentry = dentry2,
 		.path2.mnt = mnt2,
 	};
-	int idx;
-	buf1.name = NULL;
-	buf2.name = NULL;
-	idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, ccs_pp2mac[operation])
-	    == CCS_CONFIG_DISABLED)
-		goto out;
-	is_enforce = (r.mode == CCS_CONFIG_ENFORCING);
-	error = -ENOMEM;
-	if (!ccs_get_realpath(&buf1, &obj.path1) ||
-	    !ccs_get_realpath(&buf2, &obj.path2))
-		goto out;
+	int error;
+	struct ccs_path_info buf1;
+	struct ccs_path_info buf2;
+	ccs_check_auto_domain_transition();
+	if (!ccs_get_realpath(&buf1, &obj.path1))
+		return -ENOMEM;
+	if (!ccs_get_realpath(&buf2, &obj.path2)) {
+		kfree(buf1.name);
+		return -ENOMEM;
+	}
 	switch (operation) {
 	case CCS_TYPE_RENAME:
 	case CCS_TYPE_LINK:
@@ -2461,22 +2305,65 @@
 		ccs_add_slash(&buf2);
 		break;
 	}
-	r.obj = &obj;
-	r.param_type = CCS_TYPE_PATH2_ACL;
-	r.param.path2.operation = operation;
-	r.param.path2.filename1 = &buf1;
-	r.param.path2.filename2 = &buf2;
-	error = ccs_check_acl(&r);
-out:
+	{
+		struct ccs_request_info r = { };
+		r.type = ccs_pp2mac[operation];
+		r.obj = &obj;
+		r.param_type = CCS_TYPE_PATH2_ACL;
+		r.param.path2.operation = operation;
+		r.param.path2.filename1 = &buf1;
+		r.param.path2.filename2 = &buf2;
+		error = ccs_check_acl(&r);
+	}
 	kfree(buf1.name);
 	kfree(buf2.name);
-	ccs_read_unlock(idx);
-	if (!is_enforce)
-		error = 0;
 	return error;
 }
 
 /**
+ * __ccs_symlink_permission - Check permission for "symlink".
+ *
+ * @dentry: Pointer to "struct dentry".
+ * @mnt:    Pointer to "struct vfsmount". Maybe NULL.
+ * @target: Content of symlink.
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int __ccs_symlink_permission(struct dentry *dentry,
+				    struct vfsmount *mnt, const char *target)
+{
+	struct ccs_obj_info obj = {
+		.path1.dentry = dentry,
+		.path1.mnt = mnt,
+	};
+	int error;
+	struct ccs_path_info buf1;
+	struct ccs_path_info buf2;
+	ccs_check_auto_domain_transition();
+	if (!ccs_get_realpath(&buf1, &obj.path1))
+		return -ENOMEM;
+	buf2.name = ccs_encode(target);
+	if (!buf2.name) {
+		kfree(buf1.name);
+		return -ENOMEM;
+	}
+	ccs_fill_path_info(&buf2);
+	{
+		struct ccs_request_info r = { };
+		r.type = CCS_MAC_FILE_SYMLINK;
+		r.obj = &obj;
+		r.param_type = CCS_TYPE_PATH2_ACL;
+		r.param.path2.operation = CCS_TYPE_SYMLINK;
+		r.param.path2.filename1 = &buf1;
+		r.param.path2.filename2 = &buf2;
+		error = ccs_check_acl(&r);
+	}
+	kfree(buf1.name);
+	kfree(buf2.name);
+	return error;
+}
+
+/**
  * ccs_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
  *
  * @type:   Type of operation.
@@ -2489,35 +2376,30 @@
 static int ccs_path_number_perm(const u8 type, struct dentry *dentry,
 				struct vfsmount *vfsmnt, unsigned long number)
 {
-	struct ccs_request_info r;
 	struct ccs_obj_info obj = {
 		.path1.dentry = dentry,
 		.path1.mnt = vfsmnt,
 	};
-	int error = 0;
+	int error;
 	struct ccs_path_info buf;
-	int idx;
 	if (!dentry)
 		return 0;
-	idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, ccs_pn2mac[type]) == CCS_CONFIG_DISABLED)
-		goto out;
-	error = -ENOMEM;
+	ccs_check_auto_domain_transition();
 	if (!ccs_get_realpath(&buf, &obj.path1))
-		goto out;
-	r.obj = &obj;
+		return -ENOMEM;
 	if (type == CCS_TYPE_MKDIR)
 		ccs_add_slash(&buf);
-	r.param_type = CCS_TYPE_PATH_NUMBER_ACL;
-	r.param.path_number.operation = type;
-	r.param.path_number.filename = &buf;
-	r.param.path_number.number = number;
-	error = ccs_check_acl(&r);
+	{
+		struct ccs_request_info r = { };
+		r.type = ccs_pn2mac[type];
+		r.obj = &obj;
+		r.param_type = CCS_TYPE_PATH_NUMBER_ACL;
+		r.param.path_number.operation = type;
+		r.param.path_number.filename = &buf;
+		r.param.path_number.number = number;
+		error = ccs_check_acl(&r);
+	}
 	kfree(buf.name);
-out:
-	ccs_read_unlock(idx);
-	if (r.mode != CCS_CONFIG_ENFORCING)
-		error = 0;
 	return error;
 }
 
@@ -2631,7 +2513,7 @@
  */
 static int __ccs_chroot_permission(struct path *path)
 {
-	return ccs_path_perm(CCS_TYPE_CHROOT, path->dentry, path->mnt, NULL);
+	return ccs_path_perm(CCS_TYPE_CHROOT, path->dentry, path->mnt);
 }
 
 /**
@@ -2644,7 +2526,7 @@
  */
 static int __ccs_umount_permission(struct vfsmount *mnt, int flags)
 {
-	return ccs_path_perm(CCS_TYPE_UMOUNT, mnt->mnt_root, mnt, NULL);
+	return ccs_path_perm(CCS_TYPE_UMOUNT, mnt->mnt_root, mnt);
 }
 
 /**
@@ -2713,7 +2595,7 @@
  */
 static int __ccs_rmdir_permission(struct dentry *dentry, struct vfsmount *mnt)
 {
-	return ccs_path_perm(CCS_TYPE_RMDIR, dentry, mnt, NULL);
+	return ccs_path_perm(CCS_TYPE_RMDIR, dentry, mnt);
 }
 
 /**
@@ -2726,7 +2608,7 @@
  */
 static int __ccs_unlink_permission(struct dentry *dentry, struct vfsmount *mnt)
 {
-	return ccs_path_perm(CCS_TYPE_UNLINK, dentry, mnt, NULL);
+	return ccs_path_perm(CCS_TYPE_UNLINK, dentry, mnt);
 }
 
 #ifdef CONFIG_CCSECURITY_FILE_GETATTR
@@ -2742,27 +2624,12 @@
 static int __ccs_getattr_permission(struct vfsmount *mnt,
 				    struct dentry *dentry)
 {
-	return ccs_path_perm(CCS_TYPE_GETATTR, dentry, mnt, NULL);
+	return ccs_path_perm(CCS_TYPE_GETATTR, dentry, mnt);
 }
 
 #endif
 
 /**
- * __ccs_symlink_permission - Check permission for vfs_symlink().
- *
- * @dentry: Pointer to "struct dentry".
- * @mnt:    Pointer to "struct vfsmount". Maybe NULL.
- * @from:   Content of symlink.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int __ccs_symlink_permission(struct dentry *dentry,
-				    struct vfsmount *mnt, const char *from)
-{
-	return ccs_path_perm(CCS_TYPE_SYMLINK, dentry, mnt, from);
-}
-
-/**
  * __ccs_truncate_permission - Check permission for notify_change().
  *
  * @dentry: Pointer to "struct dentry".
@@ -2773,7 +2640,7 @@
 static int __ccs_truncate_permission(struct dentry *dentry,
 				     struct vfsmount *mnt)
 {
-	return ccs_path_perm(CCS_TYPE_TRUNCATE, dentry, mnt, NULL);
+	return ccs_path_perm(CCS_TYPE_TRUNCATE, dentry, mnt);
 }
 
 /**
@@ -2865,20 +2732,12 @@
 	int op = 0;
 	struct ccs_path_info buf;
 	char *buffer = NULL;
-	struct ccs_request_info r;
-	int idx;
 	if (oldval)
 		op |= 004;
 	if (newval)
 		op |= 002;
 	if (!op) /* Neither read nor write */
 		return 0;
-	idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, CCS_MAC_FILE_OPEN)
-	    == CCS_CONFIG_DISABLED) {
-		error = 0;
-		goto out;
-	}
 	buffer = kmalloc(PAGE_SIZE, CCS_GFP_FLAGS);
 	if (!buffer)
 		goto out;
@@ -2933,11 +2792,12 @@
 			goto out;
 		ccs_fill_path_info(&buf);
 		if (op & MAY_READ)
-			error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
+			error = ccs_path_permission(CCS_TYPE_READ, &buf, NULL);
 		else
 			error = 0;
 		if (!error && (op & MAY_WRITE))
-			error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
+			error = ccs_path_permission(CCS_TYPE_WRITE, &buf,
+						    NULL);
 		kfree(buf.name);
 		if (error)
 			goto out;
@@ -2954,17 +2814,17 @@
 			goto out;
 		ccs_fill_path_info(&buf);
 		if (op & MAY_READ)
-			error = ccs_path_permission(&r, CCS_TYPE_READ, &buf);
+			error = ccs_path_permission(CCS_TYPE_READ, &buf, NULL);
 		else
 			error = 0;
 		if (!error && (op & MAY_WRITE))
-			error = ccs_path_permission(&r, CCS_TYPE_WRITE, &buf);
+			error = ccs_path_permission(CCS_TYPE_WRITE, &buf,
+						    NULL);
 		kfree(buf.name);
 		goto out;
 	}
 	error = -ENOTDIR;
 out:
-	ccs_read_unlock(idx);
 	kfree(buffer);
 	return error;
 }
@@ -3023,6 +2883,8 @@
 	struct ccs_address_group *member;
 	bool matched = false;
 	const u8 size = is_ipv6 ? 16 : 4;
+	if (group == &ccs_group_any)
+		return true;
 	list_for_each_entry_srcu(member, &group->member_list, head.list,
 				 &ccs_ss) {
 		if (member->head.is_deleted)
@@ -3057,7 +2919,8 @@
 	if (acl->address.group)
 		return ccs_address_matches_group(r->param.inet_network.is_ipv6,
 						 r->param.inet_network.address,
-						 acl->address.group);
+						 acl->address.group)
+			!= acl->address.is_not;
 	return acl->address.is_ipv6 == r->param.inet_network.is_ipv6 &&
 		memcmp(&acl->address.ip[0],
 		       r->param.inet_network.address, size) <= 0 &&
@@ -3091,11 +2954,11 @@
  */
 static int ccs_inet_entry(const struct ccs_addr_info *address)
 {
-	const int idx = ccs_read_lock();
-	struct ccs_request_info r;
-	int error = 0;
 	const u8 type = ccs_inet2mac[address->protocol][address->operation];
-	if (type && ccs_init_request_info(&r, type) != CCS_CONFIG_DISABLED) {
+	ccs_check_auto_domain_transition();
+	if (type) {
+		struct ccs_request_info r = { };
+		r.type = type;
 		r.param_type = CCS_TYPE_INET_ACL;
 		r.param.inet_network.protocol = address->protocol;
 		r.param.inet_network.operation = address->operation;
@@ -3108,10 +2971,9 @@
 			|| address->operation == CCS_NETWORK_RECV
 #endif
 			;
-		error = ccs_check_acl(&r);
+		return ccs_check_acl(&r);
 	}
-	ccs_read_unlock(idx);
-	return error;
+	return 0;
 }
 
 /**
@@ -3164,11 +3026,9 @@
  */
 static int ccs_unix_entry(const struct ccs_addr_info *address)
 {
-	const int idx = ccs_read_lock();
-	struct ccs_request_info r;
 	int error = 0;
 	const u8 type = ccs_unix2mac[address->protocol][address->operation];
-	if (type && ccs_init_request_info(&r, type) != CCS_CONFIG_DISABLED) {
+	if (type) {
 		char *buf = address->unix0.addr;
 		int len = address->unix0.addr_len - sizeof(sa_family_t);
 		if (len <= 0) {
@@ -3180,8 +3040,10 @@
 		buf = ccs_encode2(buf, len);
 		if (buf) {
 			struct ccs_path_info addr;
+			struct ccs_request_info r = { };
 			addr.name = buf;
 			ccs_fill_path_info(&addr);
+			r.type = type;
 			r.param_type = CCS_TYPE_UNIX_ACL;
 			r.param.unix_network.protocol = address->protocol;
 			r.param.unix_network.operation = address->operation;
@@ -3197,7 +3059,6 @@
 		} else
 			error = -ENOMEM;
 	}
-	ccs_read_unlock(idx);
 	return error;
 }
 
@@ -3562,17 +3423,11 @@
  */
 static bool __ccs_capable(const u8 operation)
 {
-	struct ccs_request_info r;
-	int error = 0;
-	const int idx = ccs_read_lock();
-	if (ccs_init_request_info(&r, ccs_c2mac[operation])
-	    != CCS_CONFIG_DISABLED) {
-		r.param_type = CCS_TYPE_CAPABILITY_ACL;
-		r.param.capability.operation = operation;
-		error = ccs_check_acl(&r);
-	}
-	ccs_read_unlock(idx);
-	return !error;
+	struct ccs_request_info r = { };
+	r.type = ccs_c2mac[operation];
+	r.param_type = CCS_TYPE_CAPABILITY_ACL;
+	r.param.capability.operation = operation;
+	return !ccs_check_acl(&r);
 }
 
 /**
@@ -3595,152 +3450,67 @@
 	return 0;
 }
 
-/**
- * __ccs_ptrace_permission - Check permission for ptrace().
- *
- * @request: Unused.
- * @pid:     Unused.
- *
- * Returns 0 on success, negative value otherwise.
- *
- * Since this function is called from location where it is permitted to sleep,
- * it is racy to check target process's domainname anyway. Therefore, we don't
- * use target process's domainname.
- */
-static int __ccs_ptrace_permission(long request, long pid)
-{
-	return __ccs_capable(CCS_SYS_PTRACE) ? 0 : -EPERM;
-}
-
 #endif
 
 #ifdef CONFIG_CCSECURITY_IPC
 
 /**
- * ccs_check_signal_acl - Check permission for signal operation.
+ * ccs_check_ptrace_acl - Check permission for ptrace operation.
  *
  * @r:   Pointer to "struct ccs_request_info".
  * @ptr: Pointer to "struct ccs_acl_info".
  *
  * Returns true if granted, false otherwise.
  */
-static bool ccs_check_signal_acl(struct ccs_request_info *r,
+static bool ccs_check_ptrace_acl(struct ccs_request_info *r,
 				 const struct ccs_acl_info *ptr)
 {
-	const struct ccs_signal_acl *acl =
+	const struct ccs_ptrace_acl *acl =
 		container_of(ptr, typeof(*acl), head);
-	if (ccs_compare_number_union(r->param.signal.sig, &acl->sig)) {
-		const int len = acl->domainname->total_len;
-		if (!strncmp(acl->domainname->name,
-			     r->param.signal.dest_pattern, len)) {
-			switch (r->param.signal.dest_pattern[len]) {
-			case ' ':
-			case '\0':
-				return true;
-			}
-		}
-	}
-	return false;
+	return ccs_compare_number_union(r->param.ptrace.request,
+					&acl->request) &&
+		!strcmp(acl->domainname->name, r->param.ptrace.domainname);
 }
 
 /**
- * ccs_signal_acl2 - Check permission for signal.
+ * __ccs_ptrace_permission - Check permission for ptrace().
  *
- * @sig: Signal number.
- * @pid: Target's PID.
+ * @request: Command number.
+ * @pid:     Target's PID.
  *
  * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
  */
-static int ccs_signal_acl2(const int sig, const int pid)
+static int __ccs_ptrace_permission(long request, long pid)
 {
-	struct ccs_request_info r;
 	struct ccs_domain_info *dest = NULL;
-	const struct ccs_domain_info * const domain = ccs_current_domain();
-	if (ccs_init_request_info(&r, CCS_MAC_SIGNAL) == CCS_CONFIG_DISABLED)
-		return 0;
-	if (!sig)
-		return 0;                /* No check for NULL signal. */
-	r.param_type = CCS_TYPE_SIGNAL_ACL;
-	r.param.signal.sig = sig;
-	r.param.signal.dest_pattern = domain->domainname->name;
-	r.granted = true;
-	if (ccs_sys_getpid() == pid) {
-		ccs_audit_log(&r);
-		return 0;                /* No check for self process. */
-	}
-	{ /* Simplified checking. */
+	struct ccs_request_info r = { };
+	int error = -ESRCH;
+	const int idx = ccs_read_lock();
+	ccs_check_auto_domain_transition();
+	{
 		struct task_struct *p = NULL;
 		ccs_tasklist_lock();
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
-		if (pid > 0)
-			p = ccsecurity_exports.find_task_by_vpid((pid_t) pid);
-		else if (pid == 0)
-			p = current;
-		else if (pid == -1)
-			dest = &ccs_kernel_domain;
-		else
-			p = ccsecurity_exports.find_task_by_vpid((pid_t) -pid);
+		p = ccsecurity_exports.find_task_by_vpid((pid_t) pid);
 #else
-		if (pid > 0)
-			p = find_task_by_pid((pid_t) pid);
-		else if (pid == 0)
-			p = current;
-		else if (pid == -1)
-			dest = &ccs_kernel_domain;
-		else
-			p = find_task_by_pid((pid_t) -pid);
+		p = find_task_by_pid((pid_t) -pid);
 #endif
 		if (p)
 			dest = ccs_task_domain(p);
 		ccs_tasklist_unlock();
+		if (!dest)
+			goto out;
 	}
-	if (!dest)
-		return 0; /* I can't find destinatioin. */
-	if (domain == dest) {
-		ccs_audit_log(&r);
-		return 0;                /* No check for self domain. */
-	}
-	r.param.signal.dest_pattern = dest->domainname->name;
-	return ccs_check_acl(&r);
-}
-
-/**
- * ccs_signal_acl - Check permission for signal.
- *
- * @pid: Target's PID.
- * @sig: Signal number.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_signal_acl(const int pid, const int sig)
-{
-	int error;
-	if (!sig)
-		error = 0;
-	else {
-		const int idx = ccs_read_lock();
-		error = ccs_signal_acl2(sig, pid);
-		ccs_read_unlock(idx);
-	}
+	r.type = CCS_MAC_PTRACE;
+	r.param_type = CCS_TYPE_PTRACE_ACL;
+	r.param.ptrace.request = request;
+	r.param.ptrace.domainname = dest->domainname->name;
+	error = ccs_check_acl(&r);
+out:
+	ccs_read_unlock(idx);
 	return error;
 }
 
-/**
- * ccs_signal_acl0 - Permission check for signal().
- *
- * @tgid: Unused.
- * @pid:  Target's PID.
- * @sig:  Signal number.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_signal_acl0(pid_t tgid, pid_t pid, int sig)
-{
-	return ccs_signal_acl(pid, sig);
-}
-
 #endif
 
 #ifdef CONFIG_CCSECURITY_MISC
@@ -3757,7 +3527,7 @@
 			      const struct ccs_acl_info *ptr)
 {
 	const struct ccs_env_acl *acl = container_of(ptr, typeof(*acl), head);
-	return ccs_path_matches_pattern(r->param.environ.name, acl->env);
+	return ccs_compare_name_union(r->param.environ.name, &acl->env);
 }
 
 /**
@@ -3767,8 +3537,6 @@
  * @env: The name of environment variable.
  *
  * Returns 0 on success, negative value otherwise.
- *
- * Caller holds ccs_read_lock().
  */
 static int ccs_env_perm(struct ccs_request_info *r, const char *env)
 {
@@ -3777,6 +3545,7 @@
 		return 0;
 	environ.name = env;
 	ccs_fill_path_info(&environ);
+	r->type = CCS_MAC_ENVIRON;
 	r->param_type = CCS_TYPE_ENV_ACL;
 	r->param.environ.name = &environ;
 	return ccs_check_acl(r);
@@ -3801,13 +3570,7 @@
 	int offset = pos % PAGE_SIZE;
 	int argv_count = bprm->argc;
 	int envp_count = bprm->envc;
-	/* printk(KERN_DEBUG "start %d %d\n", argv_count, envp_count); */
 	int error = -ENOMEM;
-	ee->r.type = CCS_MAC_ENVIRON;
-	ee->r.profile = ccs_current_domain()->profile;
-	ee->r.mode = ccs_get_mode(ee->r.profile, CCS_MAC_ENVIRON);
-	if (!r->mode || !envp_count)
-		return 0;
 	arg_ptr = kzalloc(CCS_EXEC_TMPSIZE, CCS_GFP_FLAGS);
 	if (!arg_ptr)
 		goto out;
@@ -3859,8 +3622,6 @@
 		offset = 0;
 	}
 out:
-	if (r->mode != CCS_CONFIG_ENFORCING)
-		error = 0;
 	kfree(env_page.data);
 	kfree(arg_ptr);
 	return error;
@@ -4218,23 +3979,11 @@
 		/* Check string expressions. */
 		if (right == CCS_NAME_UNION) {
 			const struct ccs_name_union *ptr = names_p++;
-			switch (left) {
-				struct ccs_path_info *symlink;
-				struct ccs_execve *ee;
-				struct file *file;
-			case CCS_SYMLINK_TARGET:
-				symlink = obj ? obj->symlink_target : NULL;
-				if (!symlink ||
-				    !ccs_compare_name_union(symlink, ptr)
-				    == match)
-					goto out;
-				break;
-			case CCS_EXEC_REALPATH:
-				ee = r->ee;
-				file = ee ? ee->bprm->file : NULL;
+			if (left == CCS_EXEC_REALPATH) {
+				struct ccs_execve *ee = r->ee;
+				struct file *file = ee ? ee->bprm->file : NULL;
 				if (!ccs_scan_exec_realpath(file, ptr, match))
 					goto out;
-				break;
 			}
 			continue;
 		}
@@ -4478,10 +4227,10 @@
 			/* Fetch values now. */
 			const struct ccs_number_union *ptr = numbers_p++;
 			if (ptr->group) {
-				if (ccs_number_matches_group(min_v[0],
-							     max_v[0],
-							     ptr->group)
-				    == match)
+				if ((ccs_number_matches_group(min_v[0],
+							      max_v[0],
+							      ptr->group)
+				     != ptr->is_not) == match)
 					continue;
 			} else {
 				if ((min_v[0] <= ptr->values[1] &&
@@ -4549,47 +4298,35 @@
 #endif
 
 /**
- * ccs_init_request_info - Initialize "struct ccs_request_info" members.
+ * ccs_check_auto_domain_transition - Check "task auto_domain_transition" entry.
  *
- * @r:     Pointer to "struct ccs_request_info" to initialize.
- * @index: Index number of functionality.
+ * Returns nothing.
  *
- * Returns mode.
- *
- * "task auto_domain_transition" keyword is evaluated before returning mode for
- * @index. If "task auto_domain_transition" keyword was specified and
- * transition to that domain failed, the current thread will be killed by
- * SIGKILL. Note that if current->pid == 1, sending SIGKILL won't work.
+ * If "task auto_domain_transition" keyword was specified and transition to
+ * that domain failed, the current thread will be killed by SIGKILL. Note that
+ * if current->pid == 1, sending SIGKILL won't work.
  */
-int ccs_init_request_info(struct ccs_request_info *r, const u8 index)
+static void ccs_check_auto_domain_transition(void)
 {
 #ifdef CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
 	u8 i;
 	const char *buf;
+	const int idx = ccs_read_lock();
 	for (i = 0; i < 255; i++) {
-		const u8 profile = ccs_current_domain()->profile;
-		memset(r, 0, sizeof(*r));
-		r->profile = profile;
-		r->type = index;
-		r->mode = ccs_get_mode(profile, index);
-		r->param_type = CCS_TYPE_AUTO_TASK_ACL;
-		ccs_check_acl(r);
-		if (!r->granted)
-			return r->mode;
-		buf = container_of(r->matched_acl, typeof(struct ccs_task_acl),
+		struct ccs_request_info r = { };
+		r.param_type = CCS_TYPE_AUTO_TASK_ACL;
+		ccs_check_acl(&r);
+		if (!r.granted)
+			goto done;
+		buf = container_of(r.matched_acl, typeof(struct ccs_task_acl),
 				   head)->domainname->name;
 		if (!ccs_assign_domain(buf, true))
 			break;
 	}
-	ccs_transition_failed(buf);
-	return CCS_CONFIG_DISABLED;
-#else
-	const u8 profile = ccs_current_domain()->profile;
-	memset(r, 0, sizeof(*r));
-	r->profile = profile;
-	r->type = index;
-	r->mode = ccs_get_mode(profile, index);
-	return r->mode;
+	printk(KERN_WARNING "ERROR: Unable to transit to '%s' domain.\n", buf);
+	force_sig(SIGKILL, current);
+done:
+	ccs_read_unlock(idx);
 #endif
 }
 
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/gc.c
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/gc.c	(revision 5696)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/gc.c	(working copy)
@@ -54,6 +54,7 @@
 static bool ccs_struct_used_by_io_buffer(const struct list_head *element);
 static int ccs_gc_thread(void *unused);
 static void ccs_collect_acl(struct list_head *list);
+static void ccs_collect_domain(struct list_head *list);
 static void ccs_collect_entry(void);
 static void ccs_collect_member(const enum ccs_policy_id id,
 			       struct list_head *member_list);
@@ -103,18 +104,12 @@
 {
 	/* Size of an element. */
 	static const u8 e[CCS_MAX_POLICY] = {
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-		[CCS_ID_RESERVEDPORT] = sizeof(struct ccs_reserved),
-#endif
 		[CCS_ID_GROUP] = sizeof(struct ccs_group),
 #ifdef CONFIG_CCSECURITY_NETWORK
 		[CCS_ID_ADDRESS_GROUP] = sizeof(struct ccs_address_group),
 #endif
 		[CCS_ID_PATH_GROUP] = sizeof(struct ccs_path_group),
 		[CCS_ID_NUMBER_GROUP] = sizeof(struct ccs_number_group),
-		[CCS_ID_AGGREGATOR] = sizeof(struct ccs_aggregator),
-		[CCS_ID_TRANSITION_CONTROL]
-		= sizeof(struct ccs_transition_control),
 		[CCS_ID_MANAGER] = sizeof(struct ccs_manager),
 		/* [CCS_ID_CONDITION] = "struct ccs_condition"->size, */
 		/* [CCS_ID_NAME] = "struct ccs_name"->size, */
@@ -140,7 +135,7 @@
 		[CCS_TYPE_CAPABILITY_ACL] = sizeof(struct ccs_capability_acl),
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-		[CCS_TYPE_SIGNAL_ACL] = sizeof(struct ccs_signal_acl),
+		[CCS_TYPE_PTRACE_ACL] = sizeof(struct ccs_ptrace_acl),
 #endif
 #ifdef CONFIG_CCSECURITY_TASK_EXECUTE_HANDLER
 		[CCS_TYPE_AUTO_EXECUTE_HANDLER]
@@ -152,6 +147,7 @@
 		[CCS_TYPE_AUTO_TASK_ACL] = sizeof(struct ccs_task_acl),
 		[CCS_TYPE_MANUAL_TASK_ACL] = sizeof(struct ccs_task_acl),
 #endif
+		[CCS_TYPE_USE_GROUP_ACL] = sizeof(struct ccs_use_group_acl),
 	};
 	size_t size;
 	if (type == CCS_ID_ACL)
@@ -211,7 +207,8 @@
 		spin_unlock(&ccs_io_buffer_list_lock);
 		mutex_lock(&head->io_sem);
 		if (head->r.domain == element || head->r.group == element ||
-		    head->r.acl == element || &head->w.domain->list == element)
+		    head->r.acl == element || &head->w.domain->list == element
+		    || &head->w.acl->list == element)
 			in_use = true;
 		mutex_unlock(&head->io_sem);
 		spin_lock(&ccs_io_buffer_list_lock);
@@ -259,36 +256,6 @@
 }
 
 /**
- * ccs_del_transition_control - Delete members in "struct ccs_transition_control".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void ccs_del_transition_control(struct list_head *element)
-{
-	struct ccs_transition_control *ptr =
-		container_of(element, typeof(*ptr), head.list);
-	ccs_put_name(ptr->domainname);
-	ccs_put_name(ptr->program);
-}
-
-/**
- * ccs_del_aggregator - Delete members in "struct ccs_aggregator".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void ccs_del_aggregator(struct list_head *element)
-{
-	struct ccs_aggregator *ptr =
-		container_of(element, typeof(*ptr), head.list);
-	ccs_put_name(ptr->original_name);
-	ccs_put_name(ptr->aggregated_name);
-}
-
-/**
  * ccs_del_manager - Delete members in "struct ccs_manager".
  *
  * @element: Pointer to "struct list_head".
@@ -446,7 +413,7 @@
 		{
 			struct ccs_env_acl *entry =
 				container_of(acl, typeof(*entry), head);
-			ccs_put_name(entry->env);
+			ccs_put_name_union(&entry->env);
 		}
 		break;
 #endif
@@ -458,11 +425,11 @@
 		break;
 #endif
 #ifdef CONFIG_CCSECURITY_IPC
-	case CCS_TYPE_SIGNAL_ACL:
+	case CCS_TYPE_PTRACE_ACL:
 		{
-			struct ccs_signal_acl *entry =
+			struct ccs_ptrace_acl *entry =
 				container_of(acl, typeof(*entry), head);
-			ccs_put_number_union(&entry->sig);
+			ccs_put_number_union(&entry->request);
 			ccs_put_name(entry->domainname);
 		}
 		break;
@@ -487,6 +454,12 @@
 		}
 		break;
 #endif
+	case CCS_TYPE_USE_GROUP_ACL:
+		{
+			struct ccs_use_group_acl *entry =
+				container_of(acl, typeof(*entry), head);
+			ccs_put_group(entry->group);
+		}
 	}
 }
 
@@ -514,7 +487,9 @@
 		ccs_del_acl(&acl->list);
 		ccs_memory_free(acl, CCS_ID_ACL);
 	}
+	ccs_put_name(domain->default_transition);
 	ccs_put_name(domain->domainname);
+	ccs_put_condition(domain->cond);
 }
 
 /**
@@ -570,18 +545,6 @@
 }
 
 /**
- * ccs_del_reservedport - Delete members in "struct ccs_reserved".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static inline void ccs_del_reservedport(struct list_head *element)
-{
-	/* Nothing to do. */
-}
-
-/**
  * ccs_del_condition - Delete members in "struct ccs_condition".
  *
  * @element: Pointer to "struct list_head".
@@ -618,7 +581,6 @@
 		ccs_put_name(envp->name);
 		ccs_put_name(envp->value);
 	}
-	ccs_put_name(cond->transit);
 }
 
 /**
@@ -732,15 +694,9 @@
 	if (ccs_struct_used_by_io_buffer(element))
 		goto reinject;
 	switch (type) {
-	case CCS_ID_TRANSITION_CONTROL:
-		ccs_del_transition_control(element);
-		break;
 	case CCS_ID_MANAGER:
 		ccs_del_manager(element);
 		break;
-	case CCS_ID_AGGREGATOR:
-		ccs_del_aggregator(element);
-		break;
 	case CCS_ID_GROUP:
 		ccs_del_group(element);
 		break;
@@ -755,11 +711,6 @@
 	case CCS_ID_NUMBER_GROUP:
 		ccs_del_number_group(element);
 		break;
-#ifdef CONFIG_CCSECURITY_PORTRESERVE
-	case CCS_ID_RESERVEDPORT:
-		ccs_del_reservedport(element);
-		break;
-#endif
 	case CCS_ID_CONDITION:
 		ccs_del_condition(element);
 		break;
@@ -855,6 +806,27 @@
 }
 
 /**
+ * ccs_collect_domain - Delete domains in "struct ccs_acl_info".
+ *
+ * @list: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ *
+ * Caller holds ccs_policy_lock mutex.
+ */
+static void ccs_collect_domain(struct list_head *list)
+{
+	struct ccs_domain_info *domain;
+	struct ccs_domain_info *tmp;
+	list_for_each_entry_safe(domain, tmp, list, list) {
+		if (!domain->is_deleted)
+			continue;
+		domain->is_deleted = CCS_GC_IN_PROGRESS;
+		ccs_try_to_gc(CCS_ID_DOMAIN, &domain->list);
+	}
+}
+
+/**
  * ccs_collect_entry - Try to kfree() deleted elements.
  *
  * Returns nothing.
@@ -862,7 +834,6 @@
 static void ccs_collect_entry(void)
 {
 	int i;
-	enum ccs_policy_id id;
 	struct ccs_policy_namespace *ns;
 	mutex_lock(&ccs_policy_lock);
 	{
@@ -876,13 +847,23 @@
 			ccs_try_to_gc(CCS_ID_DOMAIN, &domain->list);
 		}
 	}
+	ccs_collect_member(CCS_ID_MANAGER, &ccs_manager_list);
 	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
-		for (id = 0; id < CCS_MAX_POLICY; id++)
-			ccs_collect_member(id, &ns->policy_list[id]);
-		for (i = 0; i < CCS_MAX_ACL_GROUPS; i++)
-			ccs_collect_acl(&ns->acl_group[i]);
+		ccs_collect_acl(&ns->default_transition_list);
 	}
 	{
+		struct ccs_acl_info *ptr;
+		struct ccs_acl_info *tmp;
+		list_for_each_entry_safe(ptr, tmp, &ccs_inversed_acl_list,
+					  list) {
+			ccs_collect_domain(&ptr->domain_list);
+			if (!ptr->is_deleted || !list_empty(&ptr->domain_list))
+				continue;
+			ptr->is_deleted = CCS_GC_IN_PROGRESS;
+			ccs_try_to_gc(CCS_ID_ACL, &ptr->list);
+		}
+	}
+	{
 		struct ccs_shared_acl_head *ptr;
 		struct ccs_shared_acl_head *tmp;
 		list_for_each_entry_safe(ptr, tmp, &ccs_condition_list, list) {
@@ -897,28 +878,40 @@
 			struct list_head *list = &ns->group_list[i];
 			struct ccs_group *group;
 			struct ccs_group *tmp;
-			switch (i) {
-			case 0:
+			enum ccs_policy_id id;
+			if (i == CCS_PATH_GROUP)
 				id = CCS_ID_PATH_GROUP;
-				break;
-			case 1:
+			else if (i == CCS_NUMBER_GROUP)
 				id = CCS_ID_NUMBER_GROUP;
-				break;
-			default:
+			else if (i == CCS_ACL_GROUP)
+				id = CCS_ID_ACL;
 #ifdef CONFIG_CCSECURITY_NETWORK
+			else
 				id = CCS_ID_ADDRESS_GROUP;
-#else
-				continue;
 #endif
-				break;
-			}
 			list_for_each_entry_safe(group, tmp, list, head.list) {
-				ccs_collect_member(id, &group->member_list);
+				if (id == CCS_ID_ACL)
+					ccs_collect_acl(&group->member_list);
+				else
+					ccs_collect_member(id, &group->
+							   member_list);
 				if (!list_empty(&group->member_list) ||
-				    atomic_read(&group->head.users) > 0)
+				    atomic_read(&group->head.users) > 0) {
+					/*
+					if (id == CCS_ID_ACL)
+						printk("%s users=%d\n",
+			       __func__, atomic_read(&group->head.users));
+					*/
 					continue;
+				}
 				atomic_set(&group->head.users,
 					   CCS_GC_IN_PROGRESS);
+				/*
+				if (id == CCS_ID_ACL)
+					printk("%s trying to gc %s\n",
+					       __func__,
+					       group->group_name->name);
+				*/
 				ccs_try_to_gc(CCS_ID_GROUP, &group->head.list);
 			}
 		}
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/Config.in
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/Config.in	(revision 5696)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/Config.in	(working copy)
@@ -71,13 +71,6 @@
   [ -z "$CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION" ] && define_bool CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION y
   bool "Enable domain transition without program execution request." CONFIG_CCSECURITY_TASK_DOMAIN_TRANSITION
 
-  if [ "$CONFIG_NET" = "y" ]; then
-
-     [ -z "$CONFIG_CCSECURITY_PORTRESERVE" ] && define_bool CONFIG_CCSECURITY_PORTRESERVE y
-     bool "Enable local port reserver." CONFIG_CCSECURITY_PORTRESERVE
-
-  fi
-
 fi
 
 endmenu
Index: trunk/1.8.x/ccs-patch/security/ccsecurity/Makefile
===================================================================
--- trunk/1.8.x/ccs-patch/security/ccsecurity/Makefile	(revision 5696)
+++ trunk/1.8.x/ccs-patch/security/ccsecurity/Makefile	(working copy)
@@ -24,8 +24,8 @@
 policy/exception_policy.conf:
 	@mkdir -p policy/
 	@echo Creating a default policy/exception_policy.conf
-	@echo initialize_domain /sbin/modprobe from any >> $@
-	@echo initialize_domain /sbin/hotplug from any >> $@
+	@echo default_transition /sbin/modprobe <kernel> /sbin/modprobe >> $@
+	@echo default_transition /sbin/hotplug <kernel> /sbin/hotplug >> $@
 
 policy/domain_policy.conf:
 	@mkdir -p policy/
@@ -80,8 +80,8 @@
 $(obj)/policy/exception_policy.conf:
 	@mkdir -p $(obj)/policy/
 	@echo Creating a default policy/exception_policy.conf
-	@echo initialize_domain /sbin/modprobe from any >> $@
-	@echo initialize_domain /sbin/hotplug from any >> $@
+	@echo default_transition /sbin/modprobe <kernel> /sbin/modprobe >> $@
+	@echo default_transition /sbin/hotplug <kernel> /sbin/hotplug >> $@
 
 $(obj)/policy/domain_policy.conf:
 	@mkdir -p $(obj)/policy/
Index: trunk/1.8.x/ccs-tools/ccstools/Include.make
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/Include.make	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/Include.make	(working copy)
@@ -4,4 +4,5 @@
 USRSBINDIR      := /usr/sbin
 USRLIBDIR       := /usr/lib
 MAN8            := /usr/share/man/man8
-CFLAGS          := -Wall -O2
+CFLAGS          := -Wall -O0 -g
+#CFLAGS          := -Wall -O2
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccstools.h
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccstools.h	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccstools.h	(working copy)
@@ -53,6 +53,7 @@
 
 #define CCS_PROC_POLICY_DIR              "/proc/ccs/"
 #define CCS_PROC_POLICY_DOMAIN_POLICY    "/proc/ccs/domain_policy"
+#define CCS_PROC_POLICY_ACL_POLICY       "/proc/ccs/acl_policy"
 #define CCS_PROC_POLICY_EXCEPTION_POLICY "/proc/ccs/exception_policy"
 #define CCS_PROC_POLICY_AUDIT            "/proc/ccs/audit"
 #define CCS_PROC_POLICY_MANAGER          "/proc/ccs/manager"
@@ -91,7 +92,6 @@
 	int string_count;
 	u8 profile;
 	_Bool profile_assigned;
-	u8 group;
 };
 
 struct ccs_domain_policy {
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-checkpolicy.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-checkpolicy.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-checkpolicy.c	(working copy)
@@ -103,7 +103,6 @@
 					     CCS_TASK_IS_EXECUTE_HANDLER */
 		CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
 		CCS_EXEC_REALPATH,
-		CCS_SYMLINK_TARGET,
 		CCS_PATH1_UID,
 		CCS_PATH1_GID,
 		CCS_PATH1_INO,
@@ -171,7 +170,6 @@
 		[CCS_TASK_TYPE]            = "task.type",
 		[CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
 		[CCS_EXEC_REALPATH]        = "exec.realpath",
-		[CCS_SYMLINK_TARGET]       = "symlink.target",
 		[CCS_PATH1_UID]            = "path1.uid",
 		[CCS_PATH1_GID]            = "path1.gid",
 		[CCS_PATH1_INO]            = "path1.ino",
@@ -268,10 +266,10 @@
 				goto out;
 		}
 		pos = eq + 1;
-		if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) {
+		if (left == CCS_EXEC_REALPATH) {
 			if (r_len < 2)
 				goto out;
-			if (pos[0] == '@')
+			if (pos[0] == '\\' && (pos[1] == '=' || pos[1] == '!'))
 				goto next;
 			if (pos[0] == '"' && pos[r_len - 1] == '"')
 				goto next;
@@ -283,7 +281,8 @@
 				continue;
 			goto next;
 		}
-		if (pos[0] == '@' && pos[1])
+		if (pos[0] == '\\' && (pos[1] == '=' || pos[1] == '!') &&
+		    pos[2])
 			goto next;
 		if (!ccs_check_number_range(pos))
 			goto out;
@@ -323,7 +322,7 @@
 	unsigned long max_value;
 	if (cp)
 		*cp++ = '\0';
-	if (*arg == '@')
+	if (*arg == '\\' && (*(arg + 1) == '=' || *(arg + 1) == '!'))
 		goto ok;
 	if (!ccs_parse_ulong(&min_value, &arg))
 		return false;
@@ -354,16 +353,14 @@
 static _Bool ccs_check_transition(char *arg)
 {
 	char *cp;
-	_Bool conflict = strstr(arg, " auto_domain_transition=") != NULL;
 	if (*arg == '<')
-		return !conflict && ccs_check_domain(arg);
+		return ccs_check_domain(arg);
 	cp = strchr(arg, ' ');
 	if (cp)
 		*cp++ = '\0';
 	if (ccs_correct_path(arg) || !strcmp(arg, "keep") ||
-	    !strcmp(arg, "initialize") || !strcmp(arg, "reset") ||
-	    !strcmp(arg, "child") || !strcmp(arg, "parent"))
-		return !conflict && ccs_prune_word(arg, cp);
+	    !strcmp(arg, "child"))
+		return ccs_prune_word(arg, cp);
 	if (cp)
 		*--cp = ' ';
 	return true;
@@ -381,7 +378,7 @@
 	static const char * const list[] = {
 		"use_route", "use_packet", "SYS_REBOOT", "SYS_VHANGUP",
 		"SYS_TIME", "SYS_NICE", "SYS_SETHOSTNAME", "use_kernel_module",
-		"SYS_KEXEC_LOAD", "SYS_PTRACE", NULL
+		"SYS_KEXEC_LOAD", NULL
 	};
 	int i;
 	char *cp = strchr(arg, ' ');
@@ -404,24 +401,14 @@
 	return ccs_prune_word(arg, cp);
 }
 
-static _Bool ccs_check_u16(char *arg)
-{
-	char *cp = strchr(arg, ' ');
-	unsigned int value;
-	if (cp)
-		*cp++ = '\0';
-	if (sscanf(arg, "%u", &value) != 1 || value >= 65536)
-		return false;
-	return ccs_prune_word(arg, cp);
-}
-
 static _Bool ccs_check_ip_address(char *arg)
 {
 	char *cp = strchr(arg, ' ');
 	struct ccs_ip_address_entry entry = { };
 	if (cp)
 		*cp++ = '\0';
-	if (*arg == '@') /* Don't reject address_group. */
+	if (*arg == '\\' && (*(arg + 1) == '=' || *(arg + 1) == '!'))
+		/* Don't reject address_group. */
 		goto found;
 	if (ccs_parse_ip(arg, &entry) ||
 	    memcmp(entry.min, entry.max, 16) > 0)
@@ -513,19 +500,9 @@
 
 static _Bool ccs_check_path_domain(char *arg)
 {
-	if (!strncmp(arg, "any ", 4))
-		ccs_prune_word(arg, arg + 4);
-	else if (*arg != '/' || !ccs_check_path(arg))
+	if (*arg != '/' || !ccs_check_path(arg))
 		return false;
-	if (!strncmp(arg, "from ", 5))
-		ccs_prune_word(arg, arg + 5);
-	else if (!*arg)
-		return true;
-	else
-		return false;
-	if (!strncmp(arg, "any", 3)) {
-		ccs_prune_word(arg, arg + 3);
-	} else if (*arg == '/') {
+	if (*arg == '/') {
 		if (!ccs_check_path(arg))
 			return false;
 	} else {
@@ -583,7 +560,7 @@
 		{ "read", ccs_check_path },
 		{ "rename", ccs_check_path2 },
 		{ "rmdir", ccs_check_path },
-		{ "symlink", ccs_check_path },
+		{ "symlink", ccs_check_path2 },
 		{ "truncate", ccs_check_path },
 		{ "unlink", ccs_check_path },
 		{ "unmount", ccs_check_path },
@@ -629,7 +606,7 @@
 	} list[] = {
 		{ "capability ", ccs_check_capability },
 		{ "file ", ccs_check_file },
-		{ "ipc signal ", ccs_check_u16, ccs_check_domain },
+		{ "ipc ptrace ", ccs_check_number, ccs_check_domain },
 		{ "misc env ", ccs_check_path },
 		{ "network ", ccs_check_network },
 		{ "task auto_domain_transition ", ccs_check_domain },
@@ -662,11 +639,10 @@
 			ccs_errors++;
 		}
 		return;
-	} else if (!strcmp(policy, "quota_exceeded") ||
-		   !strcmp(policy, "transition_failed")) {
-		return;
-	} else if (ccs_str_starts(policy, "use_group ") ||
-		   ccs_str_starts(policy, "use_profile ")) {
+	} else if (ccs_str_starts(policy, "default_transition ")) {
+		if (ccs_check_domain(policy) && !*policy)
+			return;
+	} else if (ccs_str_starts(policy, "use_profile ")) {
 		if (ccs_check_u8(policy))
 			return;
 	} else if (ccs_check_domain_policy2(policy))
@@ -688,18 +664,11 @@
 		_Bool (*arg1) (char *arg);
 		_Bool (*arg2) (char *arg);
 	} list[] = {
-		{ "acl_group ", ccs_check_u8, ccs_check_domain_policy2 },
+		{ "acl_group ", ccs_check_path, ccs_check_domain_policy2 },
 		{ "address_group ", ccs_check_path, ccs_check_ip_address },
-		{ "aggregator ", ccs_check_path, ccs_check_path },
-		{ "deny_autobind ", ccs_check_port },
-		{ "initialize_domain ", ccs_check_path_domain },
-		{ "keep_domain ", ccs_check_path_domain },
-		{ "no_initialize_domain ", ccs_check_path_domain },
-		{ "no_keep_domain ", ccs_check_path_domain },
-		{ "no_reset_domain ", ccs_check_path_domain },
+		{ "default_transition ", ccs_check_path_domain },
 		{ "number_group ", ccs_check_path, ccs_check_number },
 		{ "path_group ", ccs_check_path, ccs_check_path },
-		{ "reset_domain ", ccs_check_path_domain },
 		{ }
 	};
 	u8 type;
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-loadpolicy.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-loadpolicy.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-loadpolicy.c	(working copy)
@@ -192,8 +192,8 @@
 			if (*ptr++ != '-')
 				goto usage;
 			target = *ptr++;
-			if (target != 'e' && target != 'd' && target != 'p' &&
-			    target != 'm' && target != 's')
+			if (target != 'e' && target != 'a' && target != 'd' &&
+			    target != 'p' && target != 'm' && target != 's')
 				goto usage;
 			if (*ptr) {
 				if ((target != 'e' && target != 'd') ||
@@ -233,6 +233,12 @@
 		result = ccs_move_file_to_proc
 			(CCS_PROC_POLICY_EXCEPTION_POLICY);
 		break;
+	case 'a':
+		if (refresh_policy)
+			result = ccs_delete_proc_policy
+				(CCS_PROC_POLICY_ACL_POLICY);
+		result = ccs_move_file_to_proc(CCS_PROC_POLICY_ACL_POLICY);
+		break;
 	case 'd':
 		if (!refresh_policy) {
 			result = ccs_move_file_to_proc
@@ -248,11 +254,13 @@
 	}
 	return !result;
 usage:
-	printf("%s {-e|-ef|-d|-df|-m|-p|-s} [remote_ip:remote_port]\n\n"
+	printf("%s {-e|-ef|-a|-af|-d|-df|-m|-p|-s} [remote_ip:remote_port]\n\n"
 	       "-e  : Read from stdin and append to "
 	       "/proc/ccs/exception_policy .\n"
 	       "-ef : Read from stdin and overwrite "
 	       "/proc/ccs/exception_policy .\n"
+	       "-a  : Read from stdin and append to /proc/ccs/acl_policy .\n"
+	       "-af : Read from stdin and overwrite /proc/ccs/acl_policy .\n"
 	       "-d  : Read from stdin and append to /proc/ccs/domain_policy "
 	       ".\n"
 	       "-df : Read from stdin and overwrite /proc/ccs/domain_policy "
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy.c	(working copy)
@@ -30,6 +30,22 @@
 /* Readline history. */
 static struct ccs_readline_data ccs_rl = { };
 
+/* Structure for holding explicit domain transition. */
+static struct ccs_explicit_transition {
+	int index;
+	char *program;
+	char *transit;
+} *ccs_explicit_transition_list = NULL;
+static int ccs_explicit_transition_list_len = 0;
+
+/* Structure for holding implicit domain transition. */
+struct ccs_implicit_transition {
+	const struct ccs_path_info *ns;
+	char *program;
+	char *transit;
+} *ccs_implicit_transition_list = NULL;
+static int ccs_implicit_transition_list_len = 0;
+
 /* Array of "path_group" entries. */
 struct ccs_path_group_entry *ccs_path_group_list = NULL;
 /* Length of ccs_path_group_list array. */
@@ -61,13 +77,6 @@
 enum ccs_screen_type ccs_current_screen = CCS_SCREEN_DOMAIN_LIST;
 /* Previously active screen's index. */
 static enum ccs_screen_type ccs_previous_screen = CCS_SCREEN_DOMAIN_LIST;
-/*
- * Array of "initialize_domain"/"no_initialize_domain"/"keep_domain"/
- * "no_keep_domain" entries.
- */
-static struct ccs_transition_control_entry *ccs_transition_control_list = NULL;
-/* Length of ccs_transition_control_list array. */
-static int ccs_transition_control_list_len = 0;
 /* Sort profiles by value? */
 static _Bool ccs_profile_sort_type = false;
 /* Number of domain jump source domains. */
@@ -99,16 +108,6 @@
 /* Namespace to use. */
 const struct ccs_path_info *ccs_current_ns = NULL;
 
-/* Domain transition coltrol keywords. */
-static const char *ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
-	[CCS_TRANSITION_CONTROL_RESET]         = "reset_domain ",
-	[CCS_TRANSITION_CONTROL_NO_RESET]      = "no_reset_domain ",
-	[CCS_TRANSITION_CONTROL_INITIALIZE]    = "initialize_domain ",
-	[CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
-	[CCS_TRANSITION_CONTROL_KEEP]          = "keep_domain ",
-	[CCS_TRANSITION_CONTROL_NO_KEEP]       = "no_keep_domain ",
-};
-
 static FILE *ccs_editpolicy_open_write(const char *filename);
 static _Bool ccs_deleted_domain(const int index);
 static _Bool ccs_domain_unreachable(const int index);
@@ -120,8 +119,9 @@
 				  const _Bool readonly);
 static const char *ccs_eat(const char *str);
 static const char *ccs_get_last_name(const int index);
-static const struct ccs_transition_control_entry *ccs_transition_control
-(const struct ccs_path_info *ns, const char *domainname, const char *program);
+//static const struct ccs_implicit_transition *ccs_transition_control
+//(const struct ccs_path_info *ns, const char *domainname,
+//const char *program);
 static enum ccs_screen_type ccs_generic_list_loop(void);
 static enum ccs_screen_type ccs_select_window(const int current);
 static int ccs_add_path_group_entry(const struct ccs_path_info *ns,
@@ -130,13 +130,11 @@
 				    const _Bool is_delete);
 static int ccs_add_path_group_policy(const struct ccs_path_info *ns,
 				     char *data, const _Bool is_delete);
-static int ccs_add_transition_control_entry(const struct ccs_path_info *ns,
-					    const char *domainname,
-					    const char *program, const enum
-					    ccs_transition_type type);
-static int ccs_add_transition_control_policy(const struct ccs_path_info *ns,
-					     char *data, const enum
-					     ccs_transition_type type);
+//static int ccs_add_transition_control_entry(const struct ccs_path_info *ns,
+//const char *domainname,
+//					    const char *program);
+//static int ccs_add_transition_control_policy(const struct ccs_path_info *ns,
+//char *data);
 static int ccs_count(const unsigned char *array, const int len);
 static int ccs_count2(const struct ccs_generic_acl *array, int len);
 static int ccs_domainname_attribute_compare(const void *a, const void *b);
@@ -244,6 +242,7 @@
 	return index;
 }
 
+#if 0
 /**
  * ccs_add_string_entry - Add string entry to a domain.
  *
@@ -282,6 +281,7 @@
 	ccs_dp.list[index].string_count = acl_count;
 	return 0;
 }
+#endif
 
 /**
  * ccs_clear_domain_policy3 - Clean up domain policy.
@@ -290,12 +290,14 @@
  */
 static void ccs_clear_domain_policy3(void)
 {
+#if 0
 	int index;
 	for (index = 0; index < ccs_dp.list_len; index++) {
 		free(ccs_dp.list[index].string_ptr);
 		ccs_dp.list[index].string_ptr = NULL;
 		ccs_dp.list[index].string_count = 0;
 	}
+#endif
 	free(ccs_dp.list);
 	ccs_dp.list = NULL;
 	ccs_dp.list_len = 0;
@@ -554,30 +556,21 @@
 	return strcmp(a1, b1);
 }
 
+#if 0
 /**
- * ccs_add_transition_control_policy - Add "reset_domain"/"no_reset_domain"/"initialize_domain"/"no_initialize_domain"/"keep_domain"/"no_keep_domain" entries.
+ * ccs_add_transition_control_policy - Add "default_transition" entries.
  *
  * @ns:   Pointer to "const struct ccs_path_info".
  * @data: Line to parse.
- * @type: One of values in "enum ccs_transition_type".
  *
  * Returns 0 on success, negative value otherwise.
  */
 static int ccs_add_transition_control_policy
-(const struct ccs_path_info *ns, char *data,
- const enum ccs_transition_type type)
+(const struct ccs_path_info *ns, char *data)
 {
-	char *domainname = strstr(data, " from ");
-	if (domainname) {
-		*domainname = '\0';
-		domainname += 6;
-	} else if (type == CCS_TRANSITION_CONTROL_NO_KEEP ||
-		   type == CCS_TRANSITION_CONTROL_KEEP) {
-		domainname = data;
-		data = NULL;
-	}
-	return ccs_add_transition_control_entry(ns, domainname, data, type);
+	return ENOSYS;
 }
+#endif
 
 /**
  * ccs_add_path_group_policy - Add "path_group" entry.
@@ -608,7 +601,8 @@
 static void ccs_assign_djs(const struct ccs_path_info *ns,
 			   const char *domainname, const char *program)
 {
-	const struct ccs_transition_control_entry *d_t =
+#if 0
+	const struct ccs_implicit_transition *d_t =
 		ccs_transition_control(ns, domainname, program);
 	if (!d_t)
 		return;
@@ -631,6 +625,7 @@
 		free(cp);
 		ccs_put();
 	}
+#endif
 }
 
 /**
@@ -717,7 +712,7 @@
 static int ccs_show_domain_line(const int index)
 {
 	int tmp_col = 0;
-	const struct ccs_transition_control_entry *transition_control;
+	//const struct ccs_implicit_transition *transition_control;
 	char *line;
 	const char *sp;
 	const int number = ccs_dp.list[index].number;
@@ -761,21 +756,20 @@
 		printw("%s", ccs_eat(" )"));
 		tmp_col += 2;
 	}
+#if 0
 	transition_control = ccs_dp.list[index].d_t;
 	if (!transition_control || is_djs)
 		goto no_transition_control;
 	ccs_get();
-	line = ccs_shprintf(" ( %s%s from %s )",
-			    ccs_transition_type[transition_control->type],
-			    transition_control->program ?
-			    transition_control->program->name : "any",
-			    transition_control->domainname ?
-			    transition_control->domainname->name : "any");
+	line = ccs_shprintf(" ( default_transition %s %s )",
+			    transition_control->program->name,
+			    transition_control->transition->name);
 	printw("%s", ccs_eat(line));
 	tmp_col += strlen(line);
 	ccs_put();
 	goto done;
 no_transition_control:
+#endif
 	if (!is_djs)
 		goto done;
 	ccs_get();
@@ -1100,6 +1094,7 @@
 	return str;
 }
 
+#if 0
 /**
  * ccs_transition_control - Find domain transition control.
  *
@@ -1107,62 +1102,26 @@
  * @domainname: Domainname.
  * @program:    Program name.
  *
- * Returns pointer to "const struct ccs_transition_control_entry" if found one,
+ * Returns pointer to "const struct ccs_implicit_transition" if found one,
  * NULL otherwise.
  */
-static const struct ccs_transition_control_entry *ccs_transition_control
+static const struct ccs_implicit_transition *ccs_transition_control
 (const struct ccs_path_info *ns, const char *domainname, const char *program)
 {
 	int i;
-	u8 type;
 	struct ccs_path_info domain;
-	struct ccs_path_info last_name;
 	domain.name = domainname;
-	last_name.name = ccs_get_last_word(domainname);
 	ccs_fill_path_info(&domain);
-	ccs_fill_path_info(&last_name);
-	for (type = 0; type < CCS_MAX_TRANSITION_TYPE; type++) {
-next:
-		for (i = 0; i < ccs_transition_control_list_len; i++) {
-			struct ccs_transition_control_entry *ptr
-				= &ccs_transition_control_list[i];
-			if (ptr->type != type)
-				continue;
-			if (ccs_pathcmp(ptr->ns, ns))
-				continue;
-			if (ptr->domainname &&
-			    ccs_pathcmp(ptr->domainname, &domain) &&
-			    ccs_pathcmp(ptr->domainname, &last_name))
-				continue;
-			if (ptr->program &&
-			    strcmp(ptr->program->name, program))
-				continue;
-			if (type == CCS_TRANSITION_CONTROL_NO_RESET) {
-				/*
-				 * Do not check for reset_domain if
-				 * no_reset_domain matched.
-				 */
-				type = CCS_TRANSITION_CONTROL_NO_INITIALIZE;
-				goto next;
-			}
-			if (type == CCS_TRANSITION_CONTROL_NO_INITIALIZE) {
-				/*
-				 * Do not check for initialize_domain if
-				 * no_initialize_domain matched.
-				 */
-				type = CCS_TRANSITION_CONTROL_NO_KEEP;
-				goto next;
-			}
-			if (type == CCS_TRANSITION_CONTROL_RESET ||
-			    type == CCS_TRANSITION_CONTROL_INITIALIZE ||
-			    type == CCS_TRANSITION_CONTROL_KEEP)
-				return ptr;
-			else
-				return NULL;
-		}
+	for (i = 0; i < ccs_transition_control_list_len; i++) {
+		struct ccs_implicit_transition *ptr
+			= &ccs_implicit_transition_list[i];
+		if (ccs_pathcmp(ptr->ns, ns))
+			continue;
+		return NULL;
 	}
 	return NULL;
 }
+#endif
 
 /**
  * ccs_profile_entry_compare -  strcmp() for qsort() callback.
@@ -1374,43 +1333,6 @@
 }
 
 /**
- * ccs_add_transition_control_entry - Add "reset_domain"/"no_reset_domain"/"initialize_domain"/"no_initialize_domain"/"keep_domain"/ "no_keep_domain" entries.
- *
- * @ns:         Pointer to "const struct ccs_path_info".
- * @domainname: Domainname.
- * @program:    Program name.
- * @type:       One of values in "enum ccs_transition_type".
- *
- * Returns 0 on success, -EINVAL otherwise.
- */
-static int ccs_add_transition_control_entry
-(const struct ccs_path_info *ns, const char *domainname, const char *program,
- const enum ccs_transition_type type)
-{
-	struct ccs_transition_control_entry *ptr;
-	if (program && strcmp(program, "any"))
-		if (!ccs_correct_path(program))
-			return -EINVAL;
-	if (domainname && strcmp(domainname, "any"))
-		if (!ccs_correct_domain(domainname))
-			if (!ccs_correct_path(domainname))
-				return -EINVAL;
-	ccs_transition_control_list =
-		ccs_realloc(ccs_transition_control_list,
-			    (ccs_transition_control_list_len + 1) *
-			    sizeof(struct ccs_transition_control_entry));
-	ptr = &ccs_transition_control_list[ccs_transition_control_list_len++];
-	memset(ptr, 0, sizeof(*ptr));
-	ptr->ns = ns;
-	if (program && strcmp(program, "any"))
-		ptr->program = ccs_savename(program);
-	if (domainname && strcmp(domainname, "any"))
-		ptr->domainname = ccs_savename(domainname);
-	ptr->type = type;
-	return 0;
-}
-
-/**
  * ccs_add_path_group_entry - Add "path_group" entry.
  *
  * @ns:          Pointer to "const struct ccs_path_info".
@@ -1472,47 +1394,33 @@
 	return 0;
 }
 
-/*
- * List of "task auto_domain_transition" "task manual_domain_transition"
- * "auto_domain_transition=" part.
- */
+static char *ccs_pickup_transition_part(char *line)
+{
+	if (*line != '<') {
+		char *cp = strchr(line, ' ');
+		if (cp)
+			*cp = '\0';
+		if (ccs_correct_path(line) || !strcmp(line, "keep") ||
+		    !strcmp(line, "child"))
+			return line;
+	} else {
+		int pos;
+		for (pos = 0; line[pos]; pos++)
+			if (line[pos] == ' ' && line[pos + 1] != '/') {
+				line[pos] = '\0';
+				break;
+			}
+		if (ccs_correct_domain(line))
+			return line;
+	}
+	return NULL;
+}
+
+/* List of "task auto_domain_transition" "task manual_domain_transition". */
 static char **ccs_jump_list = NULL;
 static int ccs_jump_list_len = 0;
 
 /**
- * ccs_add_condition_domain_transition - Add auto_domain_transition= part.
- *
- * @line:  Line to parse.
- * @index: Current domain's index.
- *
- * Returns nothing.
- */
-static void ccs_add_condition_domain_transition(char *line, const int index)
-{
-	static char domainname[4096];
-	int source;
-	char *cp = strrchr(line, ' ');
-	if (!cp)
-		return;
-	if (strncmp(cp, " auto_domain_transition=\"", 25))
-		return;
-	*cp = '\0';
-	cp += 25;
-	source = strlen(cp);
-	if (!source)
-		return;
-	cp[source - 1] = '\0';
-	snprintf(domainname, sizeof(domainname) - 1, "%s  %s",
-		 ccs_dp.list[index].domainname->name, cp);
-	domainname[sizeof(domainname) - 1] = '\0';
-	ccs_normalize_line(domainname);
-	ccs_jump_list = ccs_realloc(ccs_jump_list,
-				    (ccs_jump_list_len + 1) * sizeof(char *));
-	ccs_jump_list[ccs_jump_list_len++] = ccs_strdup(domainname);
-	ccs_assign_domain3(domainname, *cp == '<' ? cp : domainname, false);
-}
-
-/**
  * ccs_add_acl_domain_transition - Add task acl.
  *
  * @line:  Line to parse.
@@ -1523,14 +1431,8 @@
 static void ccs_add_acl_domain_transition(char *line, const int index)
 {
 	static char domainname[4096];
-	int pos;
-	/* Chop off condition part which follows domainname. */
-	for (pos = 0; line[pos]; pos++)
-		if (line[pos] == ' ' && line[pos + 1] != '/') {
-			line[pos] = '\0';
-			break;
-		}
-	if (!ccs_correct_domain(line))
+	line = ccs_pickup_transition_part(line);
+	if (!line || !ccs_correct_domain(line))
 		return;
 	ccs_jump_list = ccs_realloc(ccs_jump_list,
 				    (ccs_jump_list_len + 1) * sizeof(char *));
@@ -1542,105 +1444,94 @@
 	ccs_assign_domain3(domainname, line, false);
 }
 
-/* Structure for holding domain transition preference. */
-static struct ccs_transition_preference {
-	int index;
-	char *program;
-	char *domainname;
-} *ccs_transition_preference_list = NULL;
-static int ccs_transition_preference_list_len = 0;
-
 /**
- * ccs_parse_transition_preference - Parse transition preference.
+ * ccs_add_explicit_transition - Parse explicit transition entries.
  *
- * @program:    Pathname or path_group.
- * @domainname: Domainname or transition preference.
- * @index:      Current domain's index.
+ * @index:   Current domain's index.
+ * @program: Pathname or path_group.
+ * @transit: Transition control.
  *
  * Returns true if transition preference was found, false otherwise.
  */
-static _Bool ccs_parse_transition_preference(char *program, char *domainname,
-					     const int index)
+static _Bool ccs_add_explicit_transition(const int index, char *program,
+					 char *transit)
 {
-	struct ccs_transition_preference *ptr;
-	char *cp = strchr(domainname, ' ');
-	if (*domainname == '<')
-		goto add;
-	if (cp)
-		*cp = '\0';
-	if (ccs_correct_path(domainname) || !strcmp(domainname, "keep") ||
-	    !strcmp(domainname, "reset") || !strcmp(domainname, "initialize")
-	    || !strcmp(domainname, "child") || !strcmp(domainname, "parent"))
-		goto add;
-	return false;
-add:
-	ccs_transition_preference_list =
-		ccs_realloc(ccs_transition_preference_list, sizeof(*ptr) *
-			    (ccs_transition_preference_list_len + 1));
-	ptr = &ccs_transition_preference_list
-		[ccs_transition_preference_list_len++];
+	struct ccs_explicit_transition *ptr;
+	if (*transit) {
+		transit = ccs_pickup_transition_part(transit);
+		if (!transit)
+			return false;
+	}
+	ccs_explicit_transition_list =
+		ccs_realloc(ccs_explicit_transition_list, sizeof(*ptr) *
+			    (ccs_explicit_transition_list_len + 1));
+	ptr = &ccs_explicit_transition_list
+		[ccs_explicit_transition_list_len++];
 	ptr->index = index;
-	ptr->domainname = ccs_strdup(domainname);
 	ptr->program = ccs_strdup(program);
+	ptr->transit = ccs_strdup(transit);
 	return true;
 
 }
 
 /**
- * ccs_make_transition_preference - Create transition preference.
+ * ccs_add_implicit_transition - Add "default_transition" entries.
  *
+ * @ns:      Pointer to "const struct ccs_path_info".
+ * @program: Program name.
+ * @transit: Transition control.
+ *
+ * Returns 0 on success, -EINVAL otherwise.
+ */
+static int ccs_add_implicit_transition(const struct ccs_path_info *ns,
+				       const char *program, char *transit)
+{
+	struct ccs_implicit_transition *ptr;
+	if (!ccs_correct_path(program))
+		return -EINVAL;
+	transit = ccs_pickup_transition_part(transit);
+	if (!transit)
+		return -EINVAL;
+	ccs_implicit_transition_list =
+		ccs_realloc(ccs_implicit_transition_list,
+			    (ccs_implicit_transition_list_len + 1) *
+			    sizeof(struct ccs_implicit_transition));
+	ptr = &ccs_implicit_transition_list
+		[ccs_implicit_transition_list_len++];
+	memset(ptr, 0, sizeof(*ptr));
+	ptr->ns = ns;
+	ptr->program = ccs_strdup(program);
+	ptr->transit = ccs_strdup(transit);
+	return 0;
+}
+
+/**
+ * ccs_make_explicit_transition - Create transition preference.
+ *
+ * @index:      Current domain's index.
  * @program:    Pathname or path_group.
  * @domainname: Domainname or transition preference.
- * @index:      Current domain's index.
  *
  * Returns true if transition preference was found, false otherwise.
  */
-static void ccs_make_transition_preference(char *program, char *domainname,
-					   const int index)
+static void ccs_make_explicit_transition(const int index, char *program,
+					 char *domainname)
 {
 	static char buffer[4096];
 	const char *self = ccs_dp.list[index].domainname->name;
-	int i;
-	struct ccs_path_group_entry *group = *program == '@' ?
-		ccs_find_path_group_ns(ccs_get_ns(self), program + 1) : NULL;
-	const int j = group ? group->member_name_len : 0;
 	buffer[sizeof(buffer) - 1] = '\0';
 	if (*domainname == '<')
 		snprintf(buffer, sizeof(buffer) - 1, "%s", domainname);
 	else if (!strcmp(domainname, "keep"))
 		snprintf(buffer, sizeof(buffer) - 1, "%s", self);
-	else if (!strcmp(domainname, "reset")) {
-		if (*program == '@') {
+	else if (!strcmp(domainname, "child")) {
+		if (!strncmp(program, "\\=", 2)) {
+			struct ccs_path_group_entry *group =
+				ccs_find_path_group_ns(ccs_get_ns(self),
+						       program + 2);
+			const int j = group ? group->member_name_len : 0;
+			int i;
 			for (i = 0; i < j; i++) {
-				snprintf(buffer, sizeof(buffer) - 1, "<%s>",
-					 group->member_name[i]->name);
-				ccs_add_acl_domain_transition(buffer, index);
-			}
-			return;
-		}
-		snprintf(buffer, sizeof(buffer) - 1, "<%s>", program);
-	} else if (!strcmp(domainname, "initialize")) {
-		char *tmp = ccs_strdup(self);
-		char *cp = strchr(tmp, ' ');
-		if (cp)
-			*cp = '\0';
-		if (*program == '@') {
-			for (i = 0; i < j; i++) {
-				const char *cp2 = group->member_name[i]->name;
-				if (*cp2 != '/')
-					continue;
-				snprintf(buffer, sizeof(buffer) - 1, "%s %s",
-					 tmp, cp2);
-				ccs_add_acl_domain_transition(buffer, index);
-			}
-			free(tmp);
-			return;
-		}
-		snprintf(buffer, sizeof(buffer) - 1, "%s %s", tmp, program);
-		free(tmp);
-	} else if (!strcmp(domainname, "child")) {
-		if (*program == '@') {
-			for (i = 0; i < j; i++) {
 				const char *cp = group->member_name[i]->name;
 				if (*cp != '/')
 					continue;
@@ -1649,20 +1540,34 @@
 				ccs_add_acl_domain_transition(buffer, index);
 			}
 			return;
-		}
+		} else if (!strncmp(program, "\\!", 2))
+			return;
 		snprintf(buffer, sizeof(buffer) - 1, "%s %s", self, program);
-	} else if (!strcmp(domainname, "parent")) {
-		char *cp;
-		snprintf(buffer, sizeof(buffer) - 1, "%s", self);
-		cp = strrchr(buffer, ' ');
-		if (cp)
-			*cp = '\0';
 	} else
 		snprintf(buffer, sizeof(buffer) - 1, "%s %s", self,
 			 domainname);
 	ccs_add_acl_domain_transition(buffer, index);
 }
 
+static void ccs_make_implicit_transition(struct ccs_explicit_transition *ptr) {
+	int i;
+	_Bool matched = false;
+	for (i = 0; i < ccs_implicit_transition_list_len; i++) {
+		struct ccs_implicit_transition *ptr2 =
+			&ccs_implicit_transition_list[i];
+		if (strcmp(ptr->program, ptr2->program) ||
+		    !ccs_is_same_namespace(ccs_dp.list[ptr->index].
+					   domainname->name, ptr2->ns))
+			continue;
+		ccs_make_explicit_transition(ptr->index, ptr->program,
+					     ptr2->transit);
+		matched = true;
+	}
+	if (matched)
+		return;
+	// TODO: make domain's default_transition entry.
+}
+
 /**
  * ccs_parse_domain_line - Parse an ACL entry in domain policy.
  *
@@ -1678,22 +1583,15 @@
 				  const int index, const bool parse_flags)
 {
 	_Bool exec = false;
-	ccs_add_condition_domain_transition(line, index);
 	if (ccs_str_starts(line, "task auto_execute_handler ") ||
 	    ccs_str_starts(line, "task denied_execute_handler ") ||
 	    (exec = true, ccs_str_starts(line, "file execute "))) {
-		/*
-		 * Chop off condition part which follows pathname.
-		 * But check for domain transition preference.
-		 */
 		char *cp = strchr(line, ' ');
-		if (cp) {
+		if (cp)
 			*cp++ = '\0';
-			if (ccs_parse_transition_preference(line, cp, index))
-				return;
-		}
-		if ((exec && *line == '@') || ccs_correct_path(line))
-			ccs_add_string_entry3(line, index);
+		else
+			cp = "";
+		ccs_add_explicit_transition(index, line, cp);
 	} else if (ccs_str_starts(line, "task auto_domain_transition ") ||
 		   ccs_str_starts(line, "task manual_domain_transition ")) {
 		ccs_add_acl_domain_transition(line, index);
@@ -1701,8 +1599,9 @@
 		unsigned int profile;
 		if (sscanf(line, "use_profile %u", &profile) == 1)
 			ccs_dp.list[index].profile = (u8) profile;
-		else if (sscanf(line, "use_group %u", &profile) == 1)
-			ccs_dp.list[index].group = (u8) profile;
+		else if (ccs_str_starts(line, "use_group ")) {
+			//ccs_dp.list[index].group = (u8) profile;
+		}
 	}
 }
 
@@ -1717,28 +1616,29 @@
 static void ccs_parse_exception_line(const struct ccs_path_info *ns,
 				     char *line)
 {
-	unsigned int group;
-	for (group = 0; group < CCS_MAX_TRANSITION_TYPE; group++) {
-		if (!ccs_str_starts(line, ccs_transition_type[group]))
-			continue;
-		ccs_add_transition_control_policy(ns, line, group);
-		return;
-	}
 	if (ccs_str_starts(line, "path_group "))
 		ccs_add_path_group_policy(ns, line, false);
 	else if (ccs_str_starts(line, "address_group "))
 		ccs_add_address_group_policy(line, false);
 	else if (ccs_str_starts(line, "number_group "))
 		ccs_add_number_group_policy(line, false);
-	else if (sscanf(line, "acl_group %u", &group) == 1 && group < 256) {
-		int index;
-		line = strchr(line + 10, ' ');
+	else if (ccs_str_starts(line, "default_transition ")) {
+		char *cp = strchr(line, ' ');
+		if (!cp)
+			return;
+		*cp++ = '\0';
+		ccs_add_implicit_transition(ns, line, cp);
+	} else if (ccs_str_starts(line, "acl_group ")) {
+		unsigned int index;
+		char *cp = strchr(line, ' ');
+		if (!cp)
+			return;
 		if (!line++)
 			return;
 		for (index = 0; index < ccs_dp.list_len; index++) {
 			char *cp;
 			const struct ccs_domain *ptr = &ccs_dp.list[index];
-			if (ptr->group != group || ptr->target || ptr->is_dd)
+			if (ptr->target || ptr->is_dd)
 				continue;
 			cp = ccs_strdup(line);
 			ccs_parse_domain_line(ns, cp, index, false);
@@ -1760,7 +1660,7 @@
 {
 	FILE *fp;
 	int i;
-	int j;
+	//int j;
 	int index;
 	int max_index;
 	static const struct ccs_path_info *ccs_kernel_ns = NULL;
@@ -1769,7 +1669,6 @@
 	while (ccs_jump_list_len)
 		free(ccs_jump_list[--ccs_jump_list_len]);
 	ccs_clear_domain_policy3();
-	ccs_transition_control_list_len = 0;
 	ccs_editpolicy_clear_groups();
 	if (!ccs_kernel_ns)
 		ccs_kernel_ns = ccs_savename("<kernel>");
@@ -1850,30 +1749,43 @@
 		fclose(fp);
 	}
 
-	/* Create domain transition preference. */
-	for (i = 0; i < ccs_transition_preference_list_len; i++) {
-		struct ccs_transition_preference *ptr =
-			&ccs_transition_preference_list[i];
-		ccs_make_transition_preference(ptr->program, ptr->domainname,
-					       ptr->index);
-		free(ptr->domainname);
+	/* Create domain jump sources. */
+	for (i = 0; i < ccs_explicit_transition_list_len; i++) {
+		struct ccs_explicit_transition *ptr =
+			&ccs_explicit_transition_list[i];
+		if (*ptr->transit)
+			ccs_make_explicit_transition(ptr->index, ptr->program,
+						     ptr->transit);
+		else
+			ccs_make_implicit_transition(ptr);
+		free(ptr->transit);
 		free(ptr->program);
 	}
-	free(ccs_transition_preference_list);
-	ccs_transition_preference_list= NULL;
-	ccs_transition_preference_list_len = 0;
+	free(ccs_explicit_transition_list);
+	ccs_explicit_transition_list= NULL;
+	ccs_explicit_transition_list_len = 0;
+	
+	for (i = 0; i < ccs_implicit_transition_list_len; i++) {
+		struct ccs_implicit_transition *ptr =
+			&ccs_implicit_transition_list[i];
+		free(ptr->transit);
+		free(ptr->program);
+	}
+	free(ccs_implicit_transition_list);
+	ccs_implicit_transition_list= NULL;
+	ccs_implicit_transition_list_len = 0;
 
+#if 0
 	/*
 	 * Domain jump sources by "task manual_domain_transition" keyword or
-	 * "task auto_domain_transition" keyword or "auto_domain_transition="
-	 * part of conditional ACL have been created by now because these
-	 * keywords do not depend on domain transition control directives
-	 * defined in the exception policy.
+	 * "task auto_domain_transition" keyword have been created by now
+	 * because these keywords do not depend on domain transition control
+	 * directives defined in the exception policy.
 	 *
 	 * Create domain jump sources for "task auto_execute_handler" keyword
 	 * or "task denied_execute_handler" keyword or "file execute" keyword
-	 * now because these keywords depend on domain transition control
-	 * directives defined in the exception policy. Note that "file execute"
+	 * now because these keywords may depend on "default_transition"
+	 * keyword defined in the exception policy. Note that "file execute"
 	 * allows referring "path_group" directives.
 	 */
 	max_index = ccs_dp.list_len;
@@ -1889,11 +1801,12 @@
 		for (i = 0; i < max_count; i++) {
 			const char *name = string_ptr[i]->name;
 			struct ccs_path_group_entry *group;
-			if (name[0] != '@') {
+			if (strncmp(name, "\\=", 2)) {
 				ccs_assign_djs(ns, domainname, name);
 				continue;
-			}
-			group = ccs_find_path_group_ns(ns, name + 1);
+			} else if (!strncmp(name, "\\!", 2))
+				continue;
+			group = ccs_find_path_group_ns(ns, name + 2);
 			if (!group)
 				continue;
 			for (j = 0; j < group->member_name_len; j++) {
@@ -1902,6 +1815,7 @@
 			}
 		}
 	}
+#endif
 
 	/* Create missing parent domains. */
 	max_index = ccs_dp.list_len;
@@ -1929,8 +1843,7 @@
 	/*
 	 * Find domains that might be reachable via
 	 * "task manual_domain_transition" keyword or
-	 * "task auto_domain_transition" keyword or
-	 * "auto_domain_transition=" part of conditional ACL.
+	 * "task auto_domain_transition" keyword.
 	 * Such domains are marked with '*'.
 	 */
 	for (i = 0; i < ccs_jump_list_len; i++) {
@@ -1940,9 +1853,11 @@
 			ptr->is_djt = true;
 	}
 
+#if 0
 	/*
-	 * Find domains that might be reachable via "initialize_domain"
-	 * keyword. Such domains are marked with '*'.
+	 * Find domains that might be reachable via
+	 * "default_transition ... initialize" keyword.
+	 * Such domains are marked with '*'.
 	 */
 	for (index = 0; index < max_index; index++) {
 		const struct ccs_domain *domain = &ccs_dp.list[index];
@@ -1958,30 +1873,12 @@
 		cp = strchr(domainname, ' ');
 		if (!cp++ || strchr(cp, ' '))
 			continue;
-		/* Check "no_initialize_domain $program from any" entry. */
-		for (i = 0; i < ccs_transition_control_list_len; i++) {
-			struct ccs_transition_control_entry *ptr
-				= &ccs_transition_control_list[i];
-			if (ptr->type != CCS_TRANSITION_CONTROL_NO_INITIALIZE)
-				continue;
-			if (!ccs_is_same_namespace(domainname, ptr->ns))
-				continue;
-			if (ptr->domainname)
-				continue;
-			if (ptr->program && strcmp(ptr->program->name, cp))
-				continue;
-			break;
-		}
-		if (i < ccs_transition_control_list_len)
-			continue;
 		/*
 		 * Check "initialize_domain $program from $domainname" entry.
 		 */
 		for (i = 0; i < ccs_transition_control_list_len; i++) {
 			struct ccs_transition_control_entry *ptr
 				= &ccs_transition_control_list[i];
-			if (ptr->type != CCS_TRANSITION_CONTROL_INITIALIZE)
-				continue;
 			if (!ccs_is_same_namespace(domainname, ptr->ns))
 				continue;
 			if (ptr->program && strcmp(ptr->program->name, cp))
@@ -1993,8 +1890,9 @@
 	}
 
 	/*
-	 * Find domains that might suppress domain transition via "keep_domain"
-	 * keyword. Such domains are marked with '#'.
+	 * Find domains that might suppress domain transition via
+	 * "default_transition ... keep" keyword.
+	 * Such domains are marked with '#'.
 	 */
 	for (index = 0; index < max_index; index++) {
 		const struct ccs_domain *domain = &ccs_dp.list[index];
@@ -2003,23 +1901,6 @@
 		/* Ignore domain jump sources. */
 		if (domain->target)
 			continue;
-		/* Check "no_keep_domain any from $domainname" entry. */
-		for (i = 0; i < ccs_transition_control_list_len; i++) {
-			struct ccs_transition_control_entry *ptr
-				= &ccs_transition_control_list[i];
-			if (ptr->type != CCS_TRANSITION_CONTROL_NO_KEEP)
-				continue;
-			if (!ccs_is_same_namespace(name->name, ptr->ns))
-				continue;
-			if (ptr->program)
-				continue;
-			if (!ptr->domainname ||
-			    !ccs_pathcmp(ptr->domainname, name) ||
-			    !strcmp(ptr->domainname->name, last_name))
-				break;
-		}
-		if (i < ccs_transition_control_list_len)
-			continue;
 		/* Check "keep_domain $program from $domainname" entry. */
 		for (i = 0; i < ccs_transition_control_list_len; i++) {
 			struct ccs_transition_control_entry *ptr
@@ -2039,8 +1920,10 @@
 
 	/*
 	 * Find unreachable domains. Such domains are marked with '!'.
-	 * Unreachable domains are caused by one of "initialize_domain" keyword
-	 * or "keep_domain" keyword or "reset_domain" keyword.
+	 * Unreachable domains are caused by one of
+	 * "default_transition ... initialize" keyword or
+	 * "default_transition ... keep" keyword or
+	 * "default_transition ... reset" keyword.
 	 */
 	for (index = 0; index < max_index; index++) {
 		char *line;
@@ -2068,7 +1951,7 @@
 		while (true) {
 			const struct ccs_domain *ptr =
 				ccs_find_domain3_by_name(line);
-			const struct ccs_transition_control_entry *d_t;
+			const struct ccs_implicit_transition *d_t;
 			char *cp;
 			/* Stop traversal if current is domain jump target. */
 			if (ptr && ptr->is_djt)
@@ -2086,6 +1969,7 @@
 		if (domain->d_t)
 			domain->is_du = true;
 	}
+#endif
 
 	/* Sort by domain name. */
 	qsort(ccs_dp.list, ccs_dp.list_len, sizeof(struct ccs_domain),
@@ -2100,7 +1984,7 @@
 		if (ccs_is_current_namespace(ccs_dp.list[index].
 					     domainname->name))
 			continue;
-		free(ccs_dp.list[index].string_ptr);
+		//free(ccs_dp.list[index].string_ptr);
 		ccs_dp.list_len--;
 		for (i = index; i < ccs_dp.list_len; i++)
 			ccs_dp.list[i] = ccs_dp.list[i + 1];
@@ -2567,18 +2451,10 @@
 		if (ret)
 			return ret;
 		return strcmp(a2, b2);
-	} else if (a0->directive == CCS_DIRECTIVE_USE_GROUP) {
+	} else if (a0->directive == CCS_DIRECTIVE_DEFAULT_TRANSITION) {
 		return 1;
-	} else if (b0->directive == CCS_DIRECTIVE_USE_GROUP) {
+	} else if (b0->directive == CCS_DIRECTIVE_DEFAULT_TRANSITION) {
 		return -1;
-	} else if (a0->directive == CCS_DIRECTIVE_TRANSITION_FAILED) {
-		return 2;
-	} else if (b0->directive == CCS_DIRECTIVE_TRANSITION_FAILED) {
-		return -2;
-	} else if (a0->directive == CCS_DIRECTIVE_QUOTA_EXCEEDED) {
-		return 3;
-	} else if (b0->directive == CCS_DIRECTIVE_QUOTA_EXCEEDED) {
-		return -3;
 	} else {
 		const int ret = strcmp(a2, b2);
 		if (ret)
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_offline.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_offline.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_offline.c	(working copy)
@@ -24,6 +24,8 @@
 #include "editpolicy.h"
 #include <poll.h>
 
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
 struct list_head {
 	struct list_head *next;
 	struct list_head *prev;
@@ -81,24 +83,6 @@
 
 /* Enumeration definition for internal use. */
 
-/* Index numbers for Access Controls. */
-enum ccs_acl_entry_type_index {
-	CCS_TYPE_PATH_ACL,
-	CCS_TYPE_PATH2_ACL,
-	CCS_TYPE_PATH_NUMBER_ACL,
-	CCS_TYPE_MKDEV_ACL,
-	CCS_TYPE_MOUNT_ACL,
-	CCS_TYPE_ENV_ACL,
-	CCS_TYPE_CAPABILITY_ACL,
-	CCS_TYPE_INET_ACL,
-	CCS_TYPE_UNIX_ACL,
-	CCS_TYPE_SIGNAL_ACL,
-	CCS_TYPE_AUTO_EXECUTE_HANDLER,
-	CCS_TYPE_DENIED_EXECUTE_HANDLER,
-	CCS_TYPE_AUTO_TASK_ACL,
-	CCS_TYPE_MANUAL_TASK_ACL,
-};
-
 /* Index numbers for Capability Controls. */
 enum ccs_capability_acl_index {
 	/* socket(PF_ROUTE, *, *)                                      */
@@ -119,11 +103,29 @@
 	CCS_USE_KERNEL_MODULE,
 	/* sys_kexec_load()                                            */
 	CCS_SYS_KEXEC_LOAD,
-	/* sys_ptrace()                                                */
-	CCS_SYS_PTRACE,
 	CCS_MAX_CAPABILITY_INDEX
 };
 
+/* Index numbers for Access Controls. */
+enum ccs_acl_entry_type_index {
+	CCS_TYPE_EXECUTE_ACL,
+	CCS_TYPE_PATH_ACL,
+	CCS_TYPE_PATH2_ACL,
+	CCS_TYPE_PATH_NUMBER_ACL,
+	CCS_TYPE_MKDEV_ACL,
+	CCS_TYPE_MOUNT_ACL,
+	CCS_TYPE_ENV_ACL,
+	CCS_TYPE_CAPABILITY_ACL,
+	CCS_TYPE_INET_ACL,
+	CCS_TYPE_UNIX_ACL,
+	CCS_TYPE_PTRACE_ACL,
+	CCS_TYPE_AUTO_EXECUTE_HANDLER,
+	CCS_TYPE_DENIED_EXECUTE_HANDLER,
+	CCS_TYPE_AUTO_TASK_ACL,
+	CCS_TYPE_MANUAL_TASK_ACL,
+	CCS_TYPE_USE_GROUP_ACL,
+};
+
 /* Index numbers for "struct ccs_condition". */
 enum ccs_conditions_index {
 	CCS_TASK_UID,             /* current_uid()   */
@@ -161,7 +163,6 @@
 				     CCS_TASK_IS_EXECUTE_HANDLER */
 	CCS_TASK_EXECUTE_HANDLER, /* CCS_TASK_IS_EXECUTE_HANDLER */
 	CCS_EXEC_REALPATH,
-	CCS_SYMLINK_TARGET,
 	CCS_PATH1_UID,
 	CCS_PATH1_GID,
 	CCS_PATH1_INO,
@@ -195,20 +196,6 @@
 	CCS_ENVP_ENTRY,
 };
 
-/* Index numbers for domain's attributes. */
-enum ccs_domain_info_flags_index {
-	/* Quota warnning flag.   */
-	CCS_DIF_QUOTA_WARNED,
-	/*
-	 * This domain was unable to create a new domain at
-	 * ccs_find_next_domain() because the name of the domain to be created
-	 * was too long or it could not allocate memory.
-	 * More than one process continued execve() without domain transition.
-	 */
-	CCS_DIF_TRANSITION_FAILED,
-	CCS_MAX_DOMAIN_INFO_FLAGS
-};
-
 /* Index numbers for audit type. */
 enum ccs_grant_log {
 	/* Follow profile's configuration. */
@@ -223,6 +210,7 @@
 enum ccs_group_id {
 	CCS_PATH_GROUP,
 	CCS_NUMBER_GROUP,
+	CCS_ACL_GROUP,
 	CCS_ADDRESS_GROUP,
 	CCS_MAX_GROUP
 };
@@ -240,7 +228,9 @@
 /* Index numbers for functionality. */
 enum ccs_mac_index {
 	CCS_MAC_FILE_EXECUTE,
-	CCS_MAC_FILE_OPEN,
+	CCS_MAC_FILE_READ,
+	CCS_MAC_FILE_WRITE,
+	CCS_MAC_FILE_APPEND,
 	CCS_MAC_FILE_CREATE,
 	CCS_MAC_FILE_UNLINK,
 	CCS_MAC_FILE_GETATTR,
@@ -284,7 +274,7 @@
 	CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
 	CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
 	CCS_MAC_ENVIRON,
-	CCS_MAC_SIGNAL,
+	CCS_MAC_PTRACE,
 	CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
 	CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
 	CCS_MAC_CAPABILITY_SYS_REBOOT,
@@ -294,7 +284,6 @@
 	CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
 	CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
 	CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
-	CCS_MAC_CAPABILITY_SYS_PTRACE,
 	CCS_MAX_MAC_INDEX
 };
 
@@ -341,12 +330,12 @@
 	CCS_TYPE_LINK,
 	CCS_TYPE_RENAME,
 	CCS_TYPE_PIVOT_ROOT,
+	CCS_TYPE_SYMLINK,
 	CCS_MAX_PATH2_OPERATION
 };
 
 /* Index numbers for access controls with one pathname. */
 enum ccs_path_acl_index {
-	CCS_TYPE_EXECUTE,
 	CCS_TYPE_READ,
 	CCS_TYPE_WRITE,
 	CCS_TYPE_APPEND,
@@ -354,7 +343,6 @@
 	CCS_TYPE_GETATTR,
 	CCS_TYPE_RMDIR,
 	CCS_TYPE_TRUNCATE,
-	CCS_TYPE_SYMLINK,
 	CCS_TYPE_CHROOT,
 	CCS_TYPE_UMOUNT,
 	CCS_MAX_PATH_OPERATION
@@ -383,13 +371,26 @@
 	CCS_MAX_PATH_STAT
 };
 
+/* Index numbers for entry type. */
+enum ccs_policy_id {
+	CCS_ID_GROUP,
+	CCS_ID_ADDRESS_GROUP,
+	CCS_ID_PATH_GROUP,
+	CCS_ID_NUMBER_GROUP,
+	CCS_ID_MANAGER,
+	CCS_ID_CONDITION,
+	CCS_ID_NAME,
+	CCS_ID_ACL,
+	CCS_ID_DOMAIN,
+	CCS_MAX_POLICY
+};
+
 /* Index numbers for /proc/ccs/stat interface. */
 enum ccs_policy_stat_type {
-	/* Do not change this order. */
 	CCS_STAT_POLICY_UPDATES,
-	CCS_STAT_POLICY_LEARNING,   /* == CCS_CONFIG_LEARNING */
-	CCS_STAT_POLICY_PERMISSIVE, /* == CCS_CONFIG_PERMISSIVE */
-	CCS_STAT_POLICY_ENFORCING,  /* == CCS_CONFIG_ENFORCING */
+	CCS_STAT_POLICY_LEARNING,
+	CCS_STAT_POLICY_PERMISSIVE,
+	CCS_STAT_POLICY_ENFORCING,
 	CCS_MAX_POLICY_STAT
 };
 
@@ -403,8 +404,8 @@
 
 /* Index numbers for /proc/ccs/ interfaces. */
 enum ccs_proc_interface_index {
-	CCS_DOMAINPOLICY,
-	CCS_EXCEPTIONPOLICY,
+	CCS_DOMAIN_POLICY,
+	CCS_EXCEPTION_POLICY,
 	CCS_PROCESS_STATUS,
 	CCS_STAT,
 	CCS_AUDIT,
@@ -413,6 +414,7 @@
 	CCS_QUERY,
 	CCS_MANAGER,
 	CCS_EXECUTE_HANDLER,
+	CCS_ACL_POLICY,
 };
 
 /* Index numbers for special mount operations. */
@@ -457,38 +459,36 @@
 /* Profile number is an integer between 0 and 255. */
 #define CCS_MAX_PROFILES 256
 
-/* Group number is an integer between 0 and 255. */
-#define CCS_MAX_ACL_GROUPS 256
-
 /* Structure definition for internal use. */
 
-struct ccs_policy_namespace;
-
 /* Common header for holding ACL entries. */
 struct ccs_acl_head {
 	struct list_head list;
-	bool is_deleted;
-} __attribute__((__packed__));
+	s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
+};
 
 /* Common header for shared entries. */
 struct ccs_shared_acl_head {
 	struct list_head list;
-	unsigned int users;
-} __attribute__((__packed__));
+};
 
 /* Common header for individual entries. */
 struct ccs_acl_info {
 	struct list_head list;
+	struct list_head domain_list; /* Used by inverse mode. */
 	struct ccs_condition *cond; /* Maybe NULL. */
-	bool is_deleted;
+	s8 is_deleted; /* true or false or CCS_GC_IN_PROGRESS */
 	u8 type; /* One of values in "enum ccs_acl_entry_type_index". */
-} __attribute__((__packed__));
+	u8 mode; /* Used by inverse mode. */
+	u16 perm;
+};
 
 /* Structure for holding a word. */
 struct ccs_name_union {
 	/* Either @filename or @group is NULL. */
 	const struct ccs_path_info *filename;
 	struct ccs_group *group;
+	bool is_not;
 };
 
 /* Structure for holding a number. */
@@ -497,6 +497,7 @@
 	struct ccs_group *group; /* Maybe NULL. */
 	/* One of values in "enum ccs_value_type". */
 	u8 value_type[2];
+	bool is_not;
 };
 
 /* Structure for holding an IP address. */
@@ -504,13 +505,13 @@
 	struct in6_addr ip[2]; /* Big endian. */
 	struct ccs_group *group; /* Pointer to address group. */
 	bool is_ipv6; /* Valid only if @group == NULL. */
+	bool is_not;
 };
 
 /* Structure for "path_group"/"number_group"/"address_group" directive. */
 struct ccs_group {
 	struct ccs_shared_acl_head head;
-	struct ccs_policy_namespace *ns;
-	/* Name of group (without leading '@'). */
+	/* Name of group (without leading "\\=" or "\\!"). */
 	const struct ccs_path_info *group_name;
 	/*
 	 * List of "struct ccs_path_group" or "struct ccs_number_group" or
@@ -536,6 +537,7 @@
 	struct ccs_acl_head head;
 	/* Structure for holding an IP address. */
 	struct ccs_ipaddr_union address;
+	bool is_not;
 };
 
 /* Structure for entries which follows "struct ccs_condition". */
@@ -566,8 +568,6 @@
 	u16 argc; /* Number of "struct ccs_argv". */
 	u16 envc; /* Number of "struct ccs_envp". */
 	u8 grant_log; /* One of values in "enum ccs_grant_log". */
-	bool exec_transit; /* True if transit is for "file execute". */
-	const struct ccs_path_info *transit; /* Maybe NULL. */
 	/*
 	 * struct ccs_condition_element condition[condc];
 	 * struct ccs_number_union values[numbers_count];
@@ -577,34 +577,24 @@
 	 */
 };
 
-/*
- * Structure for "reset_domain"/"no_reset_domain"/"initialize_domain"/
- * "no_initialize_domain"/"keep_domain"/"no_keep_domain" keyword.
- */
-struct ccs_transition_control {
-	struct ccs_acl_head head;
-	u8 type; /* One of values in "enum ccs_transition_type" */
-	bool is_last_name; /* True if the domainname is ccs_last_word(). */
-	const struct ccs_path_info *domainname; /* Maybe NULL */
-	const struct ccs_path_info *program;    /* Maybe NULL */
-	struct ccs_policy_namespace *ns;
-};
+struct ccs_policy_namespace;
 
-/* Structure for "aggregator" keyword. */
-struct ccs_aggregator {
-	struct ccs_acl_head head;
-	const struct ccs_path_info *original_name;
-	const struct ccs_path_info *aggregated_name;
+/* Structure for domain information. */
+struct ccs_domain_info4 {
+	struct list_head list;
+	struct list_head acl_info_list;
+	/* Name of this domain. Never NULL.          */
+	const struct ccs_path_info *domainname;
+	/* Namespace for this domain. Never NULL. */
 	struct ccs_policy_namespace *ns;
+	/* Default domain transition. Never NULL. */
+	const struct ccs_path_info *default_transition;
+	u8 profile;        /* Profile number to use. */
+	bool quota_exceeded;
+	s8 is_deleted;     /* Delete flag.           */
+	struct ccs_condition *cond; /* Used by inverse mode. */
 };
 
-/* Structure for "deny_autobind" keyword. */
-struct ccs_reserved {
-	struct ccs_acl_head head;
-	struct ccs_number_union port;
-	struct ccs_policy_namespace *ns;
-};
-
 /* Structure for policy manager. */
 struct ccs_manager {
 	struct ccs_acl_head head;
@@ -648,6 +638,7 @@
 struct ccs_handler_acl {
 	struct ccs_acl_info head;       /* type = CCS_TYPE_*_EXECUTE_HANDLER */
 	const struct ccs_path_info *handler; /* Pointer to single pathname.  */
+	const struct ccs_path_info *transit; /* Maybe NULL. */
 };
 
 /*
@@ -660,23 +651,29 @@
 	const struct ccs_path_info *domainname;
 };
 
+/* Structure for "file execute" directive. */
+struct ccs_execute_acl {
+	struct ccs_acl_info head; /* type = CCS_TYPE_EXECUTE_ACL */
+	struct ccs_name_union program;
+	const struct ccs_path_info *transit; /* Maybe NULL. */
+};
+
 /*
- * Structure for "file execute", "file read", "file write", "file append",
- * "file unlink", "file getattr", "file rmdir", "file truncate",
- * "file symlink", "file chroot" and "file unmount" directive.
+ * Structure for "file read", "file write", "file append", "file unlink",
+ * "file getattr", "file rmdir", "file truncate", "file chroot" and
+ * "file unmount" directive.
  */
 struct ccs_path_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_PATH_ACL */
-	u16 perm; /* Bitmask of values in "enum ccs_path_acl_index". */
 	struct ccs_name_union name;
 };
 
 /*
- * Structure for "file rename", "file link" and "file pivot_root" directive.
+ * Structure for "file rename", "file link", "file pivot_root" and
+ * "file symlink" directive.
  */
 struct ccs_path2_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_PATH2_ACL */
-	u8 perm; /* Bitmask of values in "enum ccs_path2_acl_index". */
 	struct ccs_name_union name1;
 	struct ccs_name_union name2;
 };
@@ -687,7 +684,6 @@
  */
 struct ccs_path_number_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_PATH_NUMBER_ACL */
-	u8 perm; /* Bitmask of values in "enum ccs_path_number_acl_index". */
 	struct ccs_name_union name;
 	struct ccs_number_union number;
 };
@@ -695,7 +691,6 @@
 /* Structure for "file mkblock" and "file mkchar" directive. */
 struct ccs_mkdev_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_MKDEV_ACL */
-	u8 perm; /* Bitmask of values in "enum ccs_mkdev_acl_index". */
 	struct ccs_name_union name;
 	struct ccs_number_union mode;
 	struct ccs_number_union major;
@@ -713,8 +708,8 @@
 
 /* Structure for "misc env" directive in domain policy. */
 struct ccs_env_acl {
-	struct ccs_acl_info head;        /* type = CCS_TYPE_ENV_ACL  */
-	const struct ccs_path_info *env; /* environment variable */
+	struct ccs_acl_info head;  /* type = CCS_TYPE_ENV_ACL  */
+	struct ccs_name_union env; /* environment variable */
 };
 
 /* Structure for "capability" directive. */
@@ -723,11 +718,10 @@
 	u8 operation; /* One of values in "enum ccs_capability_acl_index". */
 };
 
-/* Structure for "ipc signal" directive. */
-struct ccs_signal_acl {
-	struct ccs_acl_info head; /* type = CCS_TYPE_SIGNAL_ACL */
-	struct ccs_number_union sig;
-	/* Pointer to destination pattern. */
+/* Structure for "ipc ptrace" directive. */
+struct ccs_ptrace_acl {
+	struct ccs_acl_info head; /* type = CCS_TYPE_PTRACE_ACL */
+	struct ccs_number_union request;
 	const struct ccs_path_info *domainname;
 };
 
@@ -735,7 +729,6 @@
 struct ccs_inet_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_INET_ACL */
 	u8 protocol;
-	u8 perm; /* Bitmask of values in "enum ccs_network_acl_index" */
 	struct ccs_ipaddr_union address;
 	struct ccs_number_union port;
 };
@@ -744,10 +737,16 @@
 struct ccs_unix_acl {
 	struct ccs_acl_info head; /* type = CCS_TYPE_UNIX_ACL */
 	u8 protocol;
-	u8 perm; /* Bitmask of values in "enum ccs_network_acl_index" */
 	struct ccs_name_union name;
 };
 
+/* Structure for "use_group" directive. */
+struct ccs_use_group_acl {
+	struct ccs_acl_info head; /* type = CCS_TYPE_USE_GROUP_ACL */
+	struct ccs_group *group;
+	bool is_not;
+};
+
 /* Structure for holding string data. */
 struct ccs_name {
 	struct ccs_shared_acl_head head;
@@ -757,13 +756,51 @@
 
 /* Structure for holding a line from /proc/ccs/ interface. */
 struct ccs_acl_param {
-	char *namespace;
 	char *data; /* Unprocessed data. */
 	struct list_head *list; /* List to add or remove. */
 	struct ccs_policy_namespace *ns; /* Namespace to use. */
 	bool is_delete; /* True if it is a delete request. */
+	union ccs_acl_union {
+		struct ccs_acl_info acl_info;
+		struct ccs_handler_acl handler_acl;
+		struct ccs_task_acl task_acl;
+		struct ccs_execute_acl execute_acl;
+		struct ccs_path_acl path_acl;
+		struct ccs_path2_acl path2_acl;
+		struct ccs_path_number_acl path_number_acl;
+		struct ccs_mkdev_acl mkdev_acl;
+		struct ccs_mount_acl mount_acl;
+		struct ccs_env_acl env_acl;
+		struct ccs_capability_acl capability_acl;
+		struct ccs_ptrace_acl ptrace_acl;
+		struct ccs_inet_acl inet_acl;
+		struct ccs_unix_acl unix_acl;
+		struct ccs_use_group_acl use_group_acl;
+		/**/
+		struct ccs_acl_head acl_head;
+		struct ccs_manager manager;
+		struct ccs_path_group path_group;
+		struct ccs_number_group number_group;
+		struct ccs_address_group address_group;
+	} e;
+	struct ccs_acl_info *matched_entry; /* Used by inverse mode. */
 };
 
+/* Structure for reading/writing policy via /proc/ccs/ interfaces. */
+struct ccs_io_buffer {
+	const struct ccs_path_info *acl_group_name;
+	struct ccs_policy_namespace *ns;
+	struct ccs_domain_info4 *domain;
+	struct ccs_acl_info *acl; /* Used by inverse mode. */
+	char *write_buf;
+	u8 type;
+	bool reset;
+	bool print_this_domain_only;
+	bool print_transition_related_only;
+	bool print_default_transition;
+	bool is_delete;
+} head;
+
 /* Structure for /proc/ccs/profile interface. */
 struct ccs_profile {
 	const struct ccs_path_info *comment;
@@ -772,22 +809,14 @@
 	unsigned int pref[CCS_MAX_PREF];
 };
 
-/* Structure for representing YYYY/MM/DD hh/mm/ss. */
-struct ccs_time {
-	u16 year;
-	u8 month;
-	u8 day;
-	u8 hour;
-	u8 min;
-	u8 sec;
-};
-
 /* Structure for policy namespace. */
 struct ccs_policy_namespace {
 	/* Profile table. Memory is allocated as needed. */
 	struct ccs_profile *profile_ptr[CCS_MAX_PROFILES];
-	/* The global ACL referred by "use_group" keyword. */
-	struct list_head acl_group[CCS_MAX_ACL_GROUPS];
+	/* List of "struct ccs_group". */
+	struct list_head group_list[CCS_MAX_GROUP];
+	/* List of default transition pattern. */
+	struct list_head default_transition_list;
 	/* List for connecting to ccs_namespace_list list. */
 	struct list_head namespace_list;
 	/* Profile version. Currently only 20100903 is defined. */
@@ -796,30 +825,180 @@
 	const char *name;
 };
 
-struct ccs_domain2_info {
-	struct list_head list;
-	struct list_head acl_info_list;
-	/* Name of this domain. Never NULL.          */
-	const struct ccs_path_info *domainname;
-	u8 profile;        /* Profile number to use. */
-	u8 group;          /* Group number to use.   */
-	bool is_deleted;   /* Delete flag.           */
-	bool flags[CCS_MAX_DOMAIN_INFO_FLAGS];
+/* Prototype definition for internal use. */
+
+static bool ccs_memory_ok(const void *ptr, const unsigned int size);
+static struct ccs_domain_info4 *ccs_assign_domain4(const char *domainname);
+static void *ccs_commit_ok(void *data, const unsigned int size);
+
+/* Variable definition for internal use. */
+
+/* Mapping table from "enum ccs_path_acl_index" to "enum ccs_mac_index". */
+static const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION] = {
+	[CCS_TYPE_READ]       = CCS_MAC_FILE_READ,
+	[CCS_TYPE_WRITE]      = CCS_MAC_FILE_WRITE,
+	[CCS_TYPE_APPEND]     = CCS_MAC_FILE_APPEND,
+	[CCS_TYPE_UNLINK]     = CCS_MAC_FILE_UNLINK,
+	[CCS_TYPE_GETATTR]    = CCS_MAC_FILE_GETATTR,
+	[CCS_TYPE_RMDIR]      = CCS_MAC_FILE_RMDIR,
+	[CCS_TYPE_TRUNCATE]   = CCS_MAC_FILE_TRUNCATE,
+	[CCS_TYPE_CHROOT]     = CCS_MAC_FILE_CHROOT,
+	[CCS_TYPE_UMOUNT]     = CCS_MAC_FILE_UMOUNT,
 };
 
-struct ccs_io_buffer {
-	char *data;
-	struct ccs_policy_namespace *ns;
-	struct ccs_domain2_info *domain;
-	struct ccs_domain2_info *print_this_domain_only;
-	bool is_delete;
-	bool print_transition_related_only;
-	bool eof;
-	bool reset;
-	u8 type;
-	u8 acl_group_index;
+/* Mapping table from "enum ccs_mkdev_acl_index" to "enum ccs_mac_index". */
+static const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION] = {
+	[CCS_TYPE_MKBLOCK] = CCS_MAC_FILE_MKBLOCK,
+	[CCS_TYPE_MKCHAR]  = CCS_MAC_FILE_MKCHAR,
 };
 
+/* Mapping table from "enum ccs_path2_acl_index" to "enum ccs_mac_index". */
+static const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION] = {
+	[CCS_TYPE_LINK]       = CCS_MAC_FILE_LINK,
+	[CCS_TYPE_RENAME]     = CCS_MAC_FILE_RENAME,
+	[CCS_TYPE_PIVOT_ROOT] = CCS_MAC_FILE_PIVOT_ROOT,
+	[CCS_TYPE_SYMLINK]    = CCS_MAC_FILE_SYMLINK,
+};
+
+/*
+ * Mapping table from "enum ccs_path_number_acl_index" to "enum ccs_mac_index".
+ */
+static const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION] = {
+	[CCS_TYPE_CREATE] = CCS_MAC_FILE_CREATE,
+	[CCS_TYPE_MKDIR]  = CCS_MAC_FILE_MKDIR,
+	[CCS_TYPE_MKFIFO] = CCS_MAC_FILE_MKFIFO,
+	[CCS_TYPE_MKSOCK] = CCS_MAC_FILE_MKSOCK,
+	[CCS_TYPE_IOCTL]  = CCS_MAC_FILE_IOCTL,
+	[CCS_TYPE_CHMOD]  = CCS_MAC_FILE_CHMOD,
+	[CCS_TYPE_CHOWN]  = CCS_MAC_FILE_CHOWN,
+	[CCS_TYPE_CHGRP]  = CCS_MAC_FILE_CHGRP,
+};
+
+/*
+ * Mapping table from "enum ccs_capability_acl_index" to "enum ccs_mac_index".
+ */
+static const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX] = {
+	[CCS_USE_ROUTE_SOCKET]  = CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
+	[CCS_USE_PACKET_SOCKET] = CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
+	[CCS_SYS_REBOOT]        = CCS_MAC_CAPABILITY_SYS_REBOOT,
+	[CCS_SYS_VHANGUP]       = CCS_MAC_CAPABILITY_SYS_VHANGUP,
+	[CCS_SYS_SETTIME]       = CCS_MAC_CAPABILITY_SYS_SETTIME,
+	[CCS_SYS_NICE]          = CCS_MAC_CAPABILITY_SYS_NICE,
+	[CCS_SYS_SETHOSTNAME]   = CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
+	[CCS_USE_KERNEL_MODULE] = CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
+	[CCS_SYS_KEXEC_LOAD]    = CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
+};
+
+static struct ccs_domain_info4 ccs_kernel_domain;
+static struct ccs_group ccs_group_any;
+static LIST_HEAD(ccs_domain_list);
+static LIST_HEAD(ccs_inversed_acl_list);
+static unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT];
+static unsigned int ccs_memory_used[CCS_MAX_MEMORY_STAT];
+
+/* Inlined functions for internal use. */
+
+/**
+ * ccs_put_condition - Drop reference on "struct ccs_condition".
+ *
+ * @cond: Pointer to "struct ccs_condition". Maybe NULL.
+ *
+ * Returns nothing.
+ */
+static inline void ccs_put_condition(struct ccs_condition *cond)
+{
+}
+
+/**
+ * ccs_put_group - Drop reference on "struct ccs_group".
+ *
+ * @group: Pointer to "struct ccs_group". Maybe NULL.
+ *
+ * Returns nothing.
+ */
+static inline void ccs_put_group(struct ccs_group *group)
+{
+}
+
+/**
+ * ccs_put_name - Drop reference on "struct ccs_name".
+ *
+ * @name: Pointer to "struct ccs_path_info". Maybe NULL.
+ *
+ * Returns nothing.
+ */
+static inline void ccs_put_name(const struct ccs_path_info *name)
+{
+}
+
+/***** SECTION1: Constants definition *****/
+
+/* Mapping table from "enum ccs_mac_index" to "enum ccs_mac_category_index". */
+static const u8 ccs_index2category[CCS_MAX_MAC_INDEX] = {
+	/* CONFIG::file group */
+	[CCS_MAC_FILE_EXECUTE]    = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_READ]       = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_WRITE]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_APPEND]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_CREATE]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_UNLINK]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_GETATTR]    = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_MKDIR]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_RMDIR]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_MKFIFO]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_MKSOCK]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_TRUNCATE]   = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_SYMLINK]    = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_MKBLOCK]    = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_MKCHAR]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_LINK]       = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_RENAME]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_CHMOD]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_CHOWN]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_CHGRP]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_IOCTL]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_CHROOT]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_MOUNT]      = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_UMOUNT]     = CCS_MAC_CATEGORY_FILE,
+	[CCS_MAC_FILE_PIVOT_ROOT] = CCS_MAC_CATEGORY_FILE,
+	/* CONFIG::misc group */
+	[CCS_MAC_ENVIRON]         = CCS_MAC_CATEGORY_MISC,
+	/* CONFIG::network group */
+	[CCS_MAC_NETWORK_INET_STREAM_BIND]       = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_STREAM_LISTEN]     = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_STREAM_CONNECT]    = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_STREAM_ACCEPT]     = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_DGRAM_BIND]        = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_DGRAM_SEND]        = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_DGRAM_RECV]        = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_RAW_BIND]          = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_RAW_SEND]          = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_INET_RAW_RECV]          = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_STREAM_BIND]       = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]     = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]    = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]     = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_DGRAM_BIND]        = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_DGRAM_SEND]        = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_DGRAM_RECV]        = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]    = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = CCS_MAC_CATEGORY_NETWORK,
+	[CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]  = CCS_MAC_CATEGORY_NETWORK,
+	/* CONFIG::ipc group */
+	[CCS_MAC_PTRACE]          = CCS_MAC_CATEGORY_IPC,
+	/* CONFIG::capability group */
+	[CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET]  = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_SYS_REBOOT]        = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_SYS_VHANGUP]       = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_SYS_SETTIME]       = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_SYS_NICE]          = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = CCS_MAC_CATEGORY_CAPABILITY,
+	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = CCS_MAC_CATEGORY_CAPABILITY,
+};
+
 /* String table for operation mode. */
 static const char * const ccs_mode[CCS_CONFIG_MAX_MODE] = {
 	[CCS_CONFIG_DISABLED]   = "disabled",
@@ -833,7 +1012,9 @@
 					   + CCS_MAX_MAC_CATEGORY_INDEX] = {
 	/* CONFIG::file group */
 	[CCS_MAC_FILE_EXECUTE]    = "execute",
-	[CCS_MAC_FILE_OPEN]       = "open",
+	[CCS_MAC_FILE_READ]       = "read",
+	[CCS_MAC_FILE_WRITE]      = "write",
+	[CCS_MAC_FILE_APPEND]     = "append",
 	[CCS_MAC_FILE_CREATE]     = "create",
 	[CCS_MAC_FILE_UNLINK]     = "unlink",
 	[CCS_MAC_FILE_GETATTR]    = "getattr",
@@ -880,7 +1061,7 @@
 	[CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = "unix_seqpacket_connect",
 	[CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]  = "unix_seqpacket_accept",
 	/* CONFIG::ipc group */
-	[CCS_MAC_SIGNAL] = "signal",
+	[CCS_MAC_PTRACE] = "ptrace",
 	/* CONFIG::capability group */
 	[CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET]  = "use_route",
 	[CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = "use_packet",
@@ -891,7 +1072,6 @@
 	[CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = "SYS_SETHOSTNAME",
 	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = "use_kernel_module",
 	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = "SYS_KEXEC_LOAD",
-	[CCS_MAC_CAPABILITY_SYS_PTRACE]        = "SYS_PTRACE",
 	/* CONFIG group */
 	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_FILE]       = "file",
 	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_NETWORK]    = "network",
@@ -900,21 +1080,6 @@
 	[CCS_MAX_MAC_INDEX + CCS_MAC_CATEGORY_CAPABILITY] = "capability",
 };
 
-/* String table for path operation. */
-static const char * const ccs_path_keyword[CCS_MAX_PATH_OPERATION] = {
-	[CCS_TYPE_EXECUTE]    = "execute",
-	[CCS_TYPE_READ]       = "read",
-	[CCS_TYPE_WRITE]      = "write",
-	[CCS_TYPE_APPEND]     = "append",
-	[CCS_TYPE_UNLINK]     = "unlink",
-	[CCS_TYPE_GETATTR]    = "getattr",
-	[CCS_TYPE_RMDIR]      = "rmdir",
-	[CCS_TYPE_TRUNCATE]   = "truncate",
-	[CCS_TYPE_SYMLINK]    = "symlink",
-	[CCS_TYPE_CHROOT]     = "chroot",
-	[CCS_TYPE_UMOUNT]     = "unmount",
-};
-
 /* String table for socket's operation. */
 static const char * const ccs_socket_keyword[CCS_MAX_NETWORK_OPERATION] = {
 	[CCS_NETWORK_BIND]    = "bind",
@@ -925,6 +1090,16 @@
 	[CCS_NETWORK_RECV]    = "recv",
 };
 
+/* String table for socket's protocols. */
+static const char * const ccs_proto_keyword[CCS_SOCK_MAX] = {
+	[SOCK_STREAM]    = "stream",
+	[SOCK_DGRAM]     = "dgram",
+	[SOCK_RAW]       = "raw",
+	[SOCK_SEQPACKET] = "seqpacket",
+	[0] = " ", /* Dummy for avoiding NULL pointer dereference. */
+	[4] = " ", /* Dummy for avoiding NULL pointer dereference. */
+};
+
 /* String table for categories. */
 static const char * const ccs_category_keywords[CCS_MAX_MAC_CATEGORY_INDEX] = {
 	[CCS_MAC_CATEGORY_FILE]       = "file",
@@ -970,7 +1145,6 @@
 	[CCS_TASK_TYPE]            = "task.type",
 	[CCS_TASK_EXECUTE_HANDLER] = "execute_handler",
 	[CCS_EXEC_REALPATH]        = "exec.realpath",
-	[CCS_SYMLINK_TARGET]       = "symlink.target",
 	[CCS_PATH1_UID]            = "path1.uid",
 	[CCS_PATH1_GID]            = "path1.gid",
 	[CCS_PATH1_INO]            = "path1.ino",
@@ -1006,121 +1180,25 @@
 	[CCS_PREF_ENFORCING_PENALTY]  = "enforcing_penalty",
 };
 
-/* Mapping table from "enum ccs_path_acl_index" to "enum ccs_mac_index". */
-static const u8 ccs_p2mac[CCS_MAX_PATH_OPERATION] = {
-	[CCS_TYPE_EXECUTE]    = CCS_MAC_FILE_EXECUTE,
-	[CCS_TYPE_READ]       = CCS_MAC_FILE_OPEN,
-	[CCS_TYPE_WRITE]      = CCS_MAC_FILE_OPEN,
-	[CCS_TYPE_APPEND]     = CCS_MAC_FILE_OPEN,
-	[CCS_TYPE_UNLINK]     = CCS_MAC_FILE_UNLINK,
-	[CCS_TYPE_GETATTR]    = CCS_MAC_FILE_GETATTR,
-	[CCS_TYPE_RMDIR]      = CCS_MAC_FILE_RMDIR,
-	[CCS_TYPE_TRUNCATE]   = CCS_MAC_FILE_TRUNCATE,
-	[CCS_TYPE_SYMLINK]    = CCS_MAC_FILE_SYMLINK,
-	[CCS_TYPE_CHROOT]     = CCS_MAC_FILE_CHROOT,
-	[CCS_TYPE_UMOUNT]     = CCS_MAC_FILE_UMOUNT,
-};
+/* String table for domain flags. */
+#define CCS_QUOTA_EXCEEDED "quota_exceeded\n"
 
-/* Mapping table from "enum ccs_mkdev_acl_index" to "enum ccs_mac_index". */
-static const u8 ccs_pnnn2mac[CCS_MAX_MKDEV_OPERATION] = {
-	[CCS_TYPE_MKBLOCK] = CCS_MAC_FILE_MKBLOCK,
-	[CCS_TYPE_MKCHAR]  = CCS_MAC_FILE_MKCHAR,
+/* String table for grouping keywords. */
+static const char * const ccs_group_name[CCS_MAX_GROUP] = {
+	[CCS_PATH_GROUP]    = "path_group ",
+	[CCS_NUMBER_GROUP]  = "number_group ",
+	[CCS_ACL_GROUP]     = "acl_group ",
+	[CCS_ADDRESS_GROUP] = "address_group ",
 };
 
-/* Mapping table from "enum ccs_path2_acl_index" to "enum ccs_mac_index". */
-static const u8 ccs_pp2mac[CCS_MAX_PATH2_OPERATION] = {
-	[CCS_TYPE_LINK]       = CCS_MAC_FILE_LINK,
-	[CCS_TYPE_RENAME]     = CCS_MAC_FILE_RENAME,
-	[CCS_TYPE_PIVOT_ROOT] = CCS_MAC_FILE_PIVOT_ROOT,
+/* String table for /proc/ccs/stat interface. */
+static const char * const ccs_policy_headers[CCS_MAX_POLICY_STAT] = {
+	[CCS_STAT_POLICY_UPDATES]    = "update:",
+	[CCS_STAT_POLICY_LEARNING]   = "violation in learning mode:",
+	[CCS_STAT_POLICY_PERMISSIVE] = "violation in permissive mode:",
+	[CCS_STAT_POLICY_ENFORCING]  = "violation in enforcing mode:",
 };
 
-/*
- * Mapping table from "enum ccs_path_number_acl_index" to "enum ccs_mac_index".
- */
-static const u8 ccs_pn2mac[CCS_MAX_PATH_NUMBER_OPERATION] = {
-	[CCS_TYPE_CREATE] = CCS_MAC_FILE_CREATE,
-	[CCS_TYPE_MKDIR]  = CCS_MAC_FILE_MKDIR,
-	[CCS_TYPE_MKFIFO] = CCS_MAC_FILE_MKFIFO,
-	[CCS_TYPE_MKSOCK] = CCS_MAC_FILE_MKSOCK,
-	[CCS_TYPE_IOCTL]  = CCS_MAC_FILE_IOCTL,
-	[CCS_TYPE_CHMOD]  = CCS_MAC_FILE_CHMOD,
-	[CCS_TYPE_CHOWN]  = CCS_MAC_FILE_CHOWN,
-	[CCS_TYPE_CHGRP]  = CCS_MAC_FILE_CHGRP,
-};
-
-/*
- * Mapping table from "enum ccs_network_acl_index" to "enum ccs_mac_index" for
- * inet domain socket.
- */
-static const u8 ccs_inet2mac[CCS_SOCK_MAX][CCS_MAX_NETWORK_OPERATION] = {
-	[SOCK_STREAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_INET_STREAM_BIND,
-		[CCS_NETWORK_LISTEN]  = CCS_MAC_NETWORK_INET_STREAM_LISTEN,
-		[CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_INET_STREAM_CONNECT,
-		[CCS_NETWORK_ACCEPT]  = CCS_MAC_NETWORK_INET_STREAM_ACCEPT,
-	},
-	[SOCK_DGRAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_INET_DGRAM_BIND,
-		[CCS_NETWORK_SEND]    = CCS_MAC_NETWORK_INET_DGRAM_SEND,
-		[CCS_NETWORK_RECV]    = CCS_MAC_NETWORK_INET_DGRAM_RECV,
-	},
-	[SOCK_RAW]    = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_INET_RAW_BIND,
-		[CCS_NETWORK_SEND]    = CCS_MAC_NETWORK_INET_RAW_SEND,
-		[CCS_NETWORK_RECV]    = CCS_MAC_NETWORK_INET_RAW_RECV,
-	},
-};
-
-/*
- * Mapping table from "enum ccs_network_acl_index" to "enum ccs_mac_index" for
- * unix domain socket.
- */
-static const u8 ccs_unix2mac[CCS_SOCK_MAX][CCS_MAX_NETWORK_OPERATION] = {
-	[SOCK_STREAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_UNIX_STREAM_BIND,
-		[CCS_NETWORK_LISTEN]  = CCS_MAC_NETWORK_UNIX_STREAM_LISTEN,
-		[CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_UNIX_STREAM_CONNECT,
-		[CCS_NETWORK_ACCEPT]  = CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT,
-	},
-	[SOCK_DGRAM] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_UNIX_DGRAM_BIND,
-		[CCS_NETWORK_SEND]    = CCS_MAC_NETWORK_UNIX_DGRAM_SEND,
-		[CCS_NETWORK_RECV]    = CCS_MAC_NETWORK_UNIX_DGRAM_RECV,
-	},
-	[SOCK_SEQPACKET] = {
-		[CCS_NETWORK_BIND]    = CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND,
-		[CCS_NETWORK_LISTEN]  = CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
-		[CCS_NETWORK_CONNECT] = CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
-		[CCS_NETWORK_ACCEPT]  = CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT,
-	},
-};
-
-/* String table for socket's protocols. */
-static const char * const ccs_proto_keyword[CCS_SOCK_MAX] = {
-	[SOCK_STREAM]    = "stream",
-	[SOCK_DGRAM]     = "dgram",
-	[SOCK_RAW]       = "raw",
-	[SOCK_SEQPACKET] = "seqpacket",
-	[0] = " ", /* Dummy for avoiding NULL pointer dereference. */
-	[4] = " ", /* Dummy for avoiding NULL pointer dereference. */
-};
-
-/*
- * Mapping table from "enum ccs_capability_acl_index" to "enum ccs_mac_index".
- */
-static const u8 ccs_c2mac[CCS_MAX_CAPABILITY_INDEX] = {
-	[CCS_USE_ROUTE_SOCKET]  = CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET,
-	[CCS_USE_PACKET_SOCKET] = CCS_MAC_CAPABILITY_USE_PACKET_SOCKET,
-	[CCS_SYS_REBOOT]        = CCS_MAC_CAPABILITY_SYS_REBOOT,
-	[CCS_SYS_VHANGUP]       = CCS_MAC_CAPABILITY_SYS_VHANGUP,
-	[CCS_SYS_SETTIME]       = CCS_MAC_CAPABILITY_SYS_SETTIME,
-	[CCS_SYS_NICE]          = CCS_MAC_CAPABILITY_SYS_NICE,
-	[CCS_SYS_SETHOSTNAME]   = CCS_MAC_CAPABILITY_SYS_SETHOSTNAME,
-	[CCS_USE_KERNEL_MODULE] = CCS_MAC_CAPABILITY_USE_KERNEL_MODULE,
-	[CCS_SYS_KEXEC_LOAD]    = CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD,
-	[CCS_SYS_PTRACE]        = CCS_MAC_CAPABILITY_SYS_PTRACE,
-};
-
 /* String table for /proc/ccs/stat interface. */
 static const char * const ccs_memory_headers[CCS_MAX_MEMORY_STAT] = {
 	[CCS_MEMORY_POLICY]     = "policy:",
@@ -1128,353 +1206,512 @@
 	[CCS_MEMORY_QUERY]      = "query message:",
 };
 
-/* String table for domain transition control keywords. */
-static const char * const ccs_transition_type[CCS_MAX_TRANSITION_TYPE] = {
-	[CCS_TRANSITION_CONTROL_NO_RESET]      = "no_reset_domain ",
-	[CCS_TRANSITION_CONTROL_RESET]         = "reset_domain ",
-	[CCS_TRANSITION_CONTROL_NO_INITIALIZE] = "no_initialize_domain ",
-	[CCS_TRANSITION_CONTROL_INITIALIZE]    = "initialize_domain ",
-	[CCS_TRANSITION_CONTROL_NO_KEEP]       = "no_keep_domain ",
-	[CCS_TRANSITION_CONTROL_KEEP]          = "keep_domain ",
-};
+/***** SECTION2: Structure definition *****/
 
-/* String table for grouping keywords. */
-static const char * const ccs_group_name[CCS_MAX_GROUP] = {
-	[CCS_PATH_GROUP]    = "path_group ",
-	[CCS_NUMBER_GROUP]  = "number_group ",
-	[CCS_ADDRESS_GROUP] = "address_group ",
-};
+/***** SECTION3: Prototype definition section *****/
 
-/* String table for domain flags. */
-static const char * const ccs_dif[CCS_MAX_DOMAIN_INFO_FLAGS] = {
-	[CCS_DIF_QUOTA_WARNED]      = "quota_exceeded\n",
-	[CCS_DIF_TRANSITION_FAILED] = "transition_failed\n",
-};
+static _Bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv);
+static _Bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp);
+static _Bool ccs_parse_name_union(struct ccs_acl_param *param,
+				 struct ccs_name_union *ptr);
+static _Bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
+					struct ccs_name_union *ptr);
+static _Bool ccs_parse_number_union(struct ccs_acl_param *param,
+				   struct ccs_number_union *ptr);
+static _Bool ccs_permstr(const char *string, const char *keyword);
+static void ccs_print_condition(const struct ccs_condition *cond);
+static void ccs_print_entry(const struct ccs_acl_info *acl);
+static _Bool ccs_print_group(const _Bool is_not, const struct ccs_group *group);
+static void ccs_read_acl(struct list_head *list);
+static void ccs_read_group(const int idx);
+static _Bool ccs_same_condition(const struct ccs_condition *a,
+			       const struct ccs_condition *b);
+static _Bool ccs_select_domain(const char *data);
+static _Bool ccs_set_lf(void);
+static _Bool ccs_str_starts2(char **src, const char *find);
+static char *ccs_get_transit_preference(struct ccs_acl_param *param,
+					struct ccs_execute_acl *e);
+static char *ccs_read_token(struct ccs_acl_param *param);
+static const char *ccs_yesno(const unsigned int value);
+static const struct ccs_path_info *ccs_get_domainname
+(struct ccs_acl_param *param);
+static const struct ccs_path_info *ccs_get_dqword(char *start);
+static void ccs_delete_domain4(char *domainname);
+static int ccs_parse_policy(char *line);
+static int ccs_set_mode(char *name, const char *value,
+			struct ccs_profile *profile);
+static int ccs_update_acl(const int size, struct ccs_acl_param *param);
+static int ccs_update_inverse_list(struct ccs_acl_info *new_entry,
+				   const int size,
+				   struct ccs_acl_param *param);
+static int ccs_update_manager_entry(const char *manager, const _Bool is_delete);
+static int ccs_update_policy(const int size, struct ccs_acl_param *param);
+static int ccs_write_acl(struct ccs_policy_namespace *ns,
+			 struct list_head *list, char *data,
+			 const _Bool is_delete);
+static int ccs_write_acl_policy(void);
+static int ccs_write_domain(void);
+static int ccs_write_exception(void);
+static int ccs_write_file(struct ccs_acl_param *param);
+static int ccs_write_group(struct ccs_acl_param *param, const u8 type);
+static int ccs_write_manager(void);
+static int ccs_write_profile(void);
+static int ccs_write_stat(void);
+static int ccs_write_task(struct ccs_acl_param *param);
+static int ccs_write_transition_control(struct ccs_acl_param *param);
+static int ccs_write_use_group_acl(struct ccs_acl_param *param);
+static s8 ccs_find_yesno(const char *string, const char *find);
+static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry);
+static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param);
+static struct ccs_domain_info4 *ccs_assign_domain4(const char *domainname);
+static struct ccs_domain_info4 *ccs_find_domain4(const char *domainname);
+static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
+				       const u8 idx);
+static struct ccs_policy_namespace *ccs_assign_namespace
+(const char *domainname);
+static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
+						       const unsigned int len);
+static struct ccs_profile *ccs_assign_profile(struct ccs_policy_namespace *ns,
+					      const unsigned int profile);
+static u8 ccs_condition_type(const char *word);
+static u8 ccs_group_type(char **src);
+static u8 ccs_parse_ulong(unsigned long *result, char **str);
+static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns);
+static void cprint(const char *string);
+static void cprintf(const char *fmt, ...) __attribute__((format(printf,1,2)));
+static void ccs_print_config(const u8 config);
+static void ccs_print_name_union(const struct ccs_name_union *ptr);
+static void ccs_print_name_union_quoted(const struct ccs_name_union *ptr);
+static void ccs_print_namespace(void);
+static void ccs_print_number_union(const struct ccs_number_union *ptr);
+static void ccs_print_number_union_nospace(const struct ccs_number_union *ptr);
+static void ccs_read_domain(void);
+static void ccs_read_exception(void);
+static void ccs_read_inverse_policy(void);
+static void ccs_read_manager(void);
+static void ccs_read_profile(void);
+static void ccs_read_stat(void);
+static void ccs_set_group(const char *category);
+static void ccs_set_slash(void);
+static void ccs_set_space(void);
+static void ccs_set_uint(unsigned int *i, const char *string,
+			 const char *find);
+static _Bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
+				   struct ccs_ipaddr_union *ptr);
+static void ccs_print_ipv4(const u32 *ip);
+static void ccs_print_ipv6(const struct in6_addr *ip);
+static int ccs_write_inet_network(struct ccs_acl_param *param);
+static int ccs_write_unix_network(struct ccs_acl_param *param);
+static void ccs_print_ip(const struct ccs_ipaddr_union *ptr);
+static int ccs_write_capability(struct ccs_acl_param *param);
+static int ccs_write_misc(struct ccs_acl_param *param);
+static int ccs_write_ipc(struct ccs_acl_param *param);
 
-/* Mapping table from "enum ccs_mac_index" to "enum ccs_mac_category_index". */
-static const u8 ccs_index2category[CCS_MAX_MAC_INDEX] = {
-	/* CONFIG::file group */
-	[CCS_MAC_FILE_EXECUTE]    = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_OPEN]       = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_CREATE]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_UNLINK]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_GETATTR]    = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_MKDIR]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_RMDIR]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_MKFIFO]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_MKSOCK]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_TRUNCATE]   = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_SYMLINK]    = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_MKBLOCK]    = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_MKCHAR]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_LINK]       = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_RENAME]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_CHMOD]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_CHOWN]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_CHGRP]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_IOCTL]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_CHROOT]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_MOUNT]      = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_UMOUNT]     = CCS_MAC_CATEGORY_FILE,
-	[CCS_MAC_FILE_PIVOT_ROOT] = CCS_MAC_CATEGORY_FILE,
-	/* CONFIG::misc group */
-	[CCS_MAC_ENVIRON]         = CCS_MAC_CATEGORY_MISC,
-	/* CONFIG::network group */
-	[CCS_MAC_NETWORK_INET_STREAM_BIND]       = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_STREAM_LISTEN]     = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_STREAM_CONNECT]    = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_STREAM_ACCEPT]     = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_DGRAM_BIND]        = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_DGRAM_SEND]        = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_DGRAM_RECV]        = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_RAW_BIND]          = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_RAW_SEND]          = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_INET_RAW_RECV]          = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_STREAM_BIND]       = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_STREAM_LISTEN]     = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_STREAM_CONNECT]    = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_STREAM_ACCEPT]     = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_DGRAM_BIND]        = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_DGRAM_SEND]        = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_DGRAM_RECV]        = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_SEQPACKET_BIND]    = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_SEQPACKET_LISTEN]  = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_SEQPACKET_CONNECT] = CCS_MAC_CATEGORY_NETWORK,
-	[CCS_MAC_NETWORK_UNIX_SEQPACKET_ACCEPT]  = CCS_MAC_CATEGORY_NETWORK,
-	/* CONFIG::ipc group */
-	[CCS_MAC_SIGNAL]          = CCS_MAC_CATEGORY_IPC,
-	/* CONFIG::capability group */
-	[CCS_MAC_CAPABILITY_USE_ROUTE_SOCKET]  = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_USE_PACKET_SOCKET] = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_REBOOT]        = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_VHANGUP]       = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_SETTIME]       = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_NICE]          = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_SETHOSTNAME]   = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_USE_KERNEL_MODULE] = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_KEXEC_LOAD]    = CCS_MAC_CATEGORY_CAPABILITY,
-	[CCS_MAC_CAPABILITY_SYS_PTRACE]        = CCS_MAC_CATEGORY_CAPABILITY,
-};
+/***** SECTION4: Standalone functions section *****/
 
-static struct ccs_io_buffer head;
-static struct ccs_domain2_info ccs_kernel_domain;
-static struct ccs_policy_namespace ccs_kernel_namespace;
-static LIST_HEAD(ccs_domain_list);
-static LIST_HEAD(ccs_manager_list);
-static LIST_HEAD(ccs_path_group);
-static LIST_HEAD(ccs_number_group);
-static LIST_HEAD(ccs_address_group);
-static LIST_HEAD(ccs_transition_list);
-static LIST_HEAD(ccs_aggregator_list);
-static LIST_HEAD(ccs_reserved_list);
-static LIST_HEAD(ccs_namespace_list);
-static bool ccs_namespace_enabled;
-static struct list_head ccs_name_list[CCS_MAX_HASH];
-static unsigned int ccs_memory_quota[CCS_MAX_MEMORY_STAT];
-
-/**
- * ccs_put_condition - Drop reference on "struct ccs_condition".
- *
- * @cond: Pointer to "struct ccs_condition". Maybe NULL.
- *
- * Returns nothing.
+/*
+ * Routines for parsing IPv4 or IPv6 address.
+ * These are copied from lib/hexdump.c net/core/utils.c .
  */
-static inline void ccs_put_condition(struct ccs_condition *cond)
+#include <ctype.h>
+
+static int hex_to_bin(char ch)
 {
-	if (cond)
-		cond->head.users--;
+	if ((ch >= '0') && (ch <= '9'))
+		return ch - '0';
+	ch = tolower(ch);
+	if ((ch >= 'a') && (ch <= 'f'))
+		return ch - 'a' + 10;
+	return -1;
 }
 
-/**
- * ccs_put_group - Drop reference on "struct ccs_group".
- *
- * @group: Pointer to "struct ccs_group". Maybe NULL.
- *
- * Returns nothing.
- */
-static inline void ccs_put_group(struct ccs_group *group)
+#define IN6PTON_XDIGIT		0x00010000
+#define IN6PTON_DIGIT		0x00020000
+#define IN6PTON_COLON_MASK	0x00700000
+#define IN6PTON_COLON_1		0x00100000	/* single : requested */
+#define IN6PTON_COLON_2		0x00200000	/* second : requested */
+#define IN6PTON_COLON_1_2	0x00400000	/* :: requested */
+#define IN6PTON_DOT		0x00800000	/* . */
+#define IN6PTON_DELIM		0x10000000
+#define IN6PTON_NULL		0x20000000	/* first/tail */
+#define IN6PTON_UNKNOWN		0x40000000
+
+static inline int xdigit2bin(char c, int delim)
 {
-	if (group)
-		group->head.users--;
+	int val;
+
+	if (c == delim || c == '\0')
+		return IN6PTON_DELIM;
+	if (c == ':')
+		return IN6PTON_COLON_MASK;
+	if (c == '.')
+		return IN6PTON_DOT;
+
+	val = hex_to_bin(c);
+	if (val >= 0)
+		return val | IN6PTON_XDIGIT | (val < 10 ? IN6PTON_DIGIT : 0);
+
+	if (delim == -1)
+		return IN6PTON_DELIM;
+	return IN6PTON_UNKNOWN;
 }
 
-/**
- * ccs_put_name - Drop reference on "struct ccs_name".
- *
- * @name: Pointer to "struct ccs_path_info". Maybe NULL.
- *
- * Returns nothing.
- */
-static inline void ccs_put_name(const struct ccs_path_info *name)
+static int ccs_in4_pton(const char *src, int srclen, u8 *dst, int delim,
+			const char **end)
 {
-	if (name)
-		container_of(name, struct ccs_name, entry)->head.users--;
+	const char *s;
+	u8 *d;
+	u8 dbuf[4];
+	int ret = 0;
+	int i;
+	int w = 0;
+
+	if (srclen < 0)
+		srclen = strlen(src);
+	s = src;
+	d = dbuf;
+	i = 0;
+	while (1) {
+		int c;
+		c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
+		if (!(c & (IN6PTON_DIGIT | IN6PTON_DOT | IN6PTON_DELIM |
+			   IN6PTON_COLON_MASK)))
+			goto out;
+		if (c & (IN6PTON_DOT | IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+			if (w == 0)
+				goto out;
+			*d++ = w & 0xff;
+			w = 0;
+			i++;
+			if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+				if (i != 4)
+					goto out;
+				break;
+			}
+			goto cont;
+		}
+		w = (w * 10) + c;
+		if ((w & 0xffff) > 255)
+			goto out;
+cont:
+		if (i >= 4)
+			goto out;
+		s++;
+		srclen--;
+	}
+	ret = 1;
+	memcpy(dst, dbuf, sizeof(dbuf));
+out:
+	if (end)
+		*end = s;
+	return ret;
 }
 
-/**
- * ccs_put_name_union - Drop reference on "struct ccs_name_union".
- *
- * @ptr: Pointer to "struct ccs_name_union".
- *
- * Returns nothing.
- */
-static void ccs_put_name_union(struct ccs_name_union *ptr)
+static int ccs_in6_pton(const char *src, int srclen, u8 *dst, int delim,
+			const char **end)
 {
-	ccs_put_group(ptr->group);
-	ccs_put_name(ptr->filename);
+	const char *s, *tok = NULL;
+	u8 *d, *dc = NULL;
+	u8 dbuf[16];
+	int ret = 0;
+	int i;
+	int state = IN6PTON_COLON_1_2 | IN6PTON_XDIGIT | IN6PTON_NULL;
+	int w = 0;
+
+	memset(dbuf, 0, sizeof(dbuf));
+
+	s = src;
+	d = dbuf;
+	if (srclen < 0)
+		srclen = strlen(src);
+
+	while (1) {
+		int c;
+
+		c = xdigit2bin(srclen > 0 ? *s : '\0', delim);
+		if (!(c & state))
+			goto out;
+		if (c & (IN6PTON_DELIM | IN6PTON_COLON_MASK)) {
+			/* process one 16-bit word */
+			if (!(state & IN6PTON_NULL)) {
+				*d++ = (w >> 8) & 0xff;
+				*d++ = w & 0xff;
+			}
+			w = 0;
+			if (c & IN6PTON_DELIM) {
+				/* We've processed last word */
+				break;
+			}
+			/*
+			 * COLON_1 => XDIGIT
+			 * COLON_2 => XDIGIT|DELIM
+			 * COLON_1_2 => COLON_2
+			 */
+			switch (state & IN6PTON_COLON_MASK) {
+			case IN6PTON_COLON_2:
+				dc = d;
+				state = IN6PTON_XDIGIT | IN6PTON_DELIM;
+				if (dc - dbuf >= sizeof(dbuf))
+					state |= IN6PTON_NULL;
+				break;
+			case IN6PTON_COLON_1|IN6PTON_COLON_1_2:
+				state = IN6PTON_XDIGIT | IN6PTON_COLON_2;
+				break;
+			case IN6PTON_COLON_1:
+				state = IN6PTON_XDIGIT;
+				break;
+			case IN6PTON_COLON_1_2:
+				state = IN6PTON_COLON_2;
+				break;
+			default:
+				state = 0;
+			}
+			tok = s + 1;
+			goto cont;
+		}
+
+		if (c & IN6PTON_DOT) {
+			ret = ccs_in4_pton(tok ? tok : s, srclen +
+					   (int)(s - tok), d, delim, &s);
+			if (ret > 0) {
+				d += 4;
+				break;
+			}
+			goto out;
+		}
+
+		w = (w << 4) | (0xff & c);
+		state = IN6PTON_COLON_1 | IN6PTON_DELIM;
+		if (!(w & 0xf000))
+			state |= IN6PTON_XDIGIT;
+		if (!dc && d + 2 < dbuf + sizeof(dbuf)) {
+			state |= IN6PTON_COLON_1_2;
+			state &= ~IN6PTON_DELIM;
+		}
+		if (d + 2 >= dbuf + sizeof(dbuf))
+			state &= ~(IN6PTON_COLON_1|IN6PTON_COLON_1_2);
+cont:
+		if ((dc && d + 4 < dbuf + sizeof(dbuf)) ||
+		    d + 4 == dbuf + sizeof(dbuf))
+			state |= IN6PTON_DOT;
+		if (d >= dbuf + sizeof(dbuf))
+			state &= ~(IN6PTON_XDIGIT|IN6PTON_COLON_MASK);
+		s++;
+		srclen--;
+	}
+
+	i = 15; d--;
+
+	if (dc) {
+		while (d >= dc)
+			dst[i--] = *d--;
+		while (i >= dc - dbuf)
+			dst[i--] = 0;
+		while (i >= 0)
+			dst[i--] = *d--;
+	} else
+		memcpy(dst, dbuf, sizeof(dbuf));
+
+	ret = 1;
+out:
+	if (end)
+		*end = s;
+	return ret;
 }
 
-/**
- * ccs_put_number_union - Drop reference on "struct ccs_number_union".
- *
- * @ptr: Pointer to "struct ccs_number_union".
- *
- * Returns nothing.
+/*
+ * Routines for printing IPv4 or IPv6 address.
+ * These are copied from include/linux/kernel.h include/net/ipv6.h
+ * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified.
  */
-static void ccs_put_number_union(struct ccs_number_union *ptr)
+static const char hex_asc[] = "0123456789abcdef";
+#define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
+#define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]
+
+static inline char *pack_hex_byte(char *buf, u8 byte)
 {
-	ccs_put_group(ptr->group);
+	*buf++ = hex_asc_hi(byte);
+	*buf++ = hex_asc_lo(byte);
+	return buf;
 }
 
-/**
- * ccs_del_condition - Delete members in "struct ccs_condition".
- *
- * @element: Pointer to "struct list_head".
- *
- * Returns nothing.
- */
-static void ccs_del_condition(struct list_head *element)
+static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
 {
-	struct ccs_condition *cond = container_of(element, typeof(*cond),
-						  head.list);
-	const u16 condc = cond->condc;
-	const u16 numbers_count = cond->numbers_count;
-	const u16 names_count = cond->names_count;
-	const u16 argc = cond->argc;
-	const u16 envc = cond->envc;
-	unsigned int i;
-	const struct ccs_condition_element *condp
-		= (const struct ccs_condition_element *) (cond + 1);
-	struct ccs_number_union *numbers_p
-		= (struct ccs_number_union *) (condp + condc);
-	struct ccs_name_union *names_p
-		= (struct ccs_name_union *) (numbers_p + numbers_count);
-	const struct ccs_argv *argv
-		= (const struct ccs_argv *) (names_p + names_count);
-	const struct ccs_envp *envp
-		= (const struct ccs_envp *) (argv + argc);
-	for (i = 0; i < numbers_count; i++)
-		ccs_put_number_union(numbers_p++);
-	for (i = 0; i < names_count; i++)
-		ccs_put_name_union(names_p++);
-	for (i = 0; i < argc; argv++, i++)
-		ccs_put_name(argv->value);
-	for (i = 0; i < envc; envp++, i++) {
-		ccs_put_name(envp->name);
-		ccs_put_name(envp->value);
-	}
-	ccs_put_name(cond->transit);
+	return (a->s6_addr32[0] | a->s6_addr32[1] |
+		(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
 }
 
-/**
- * ccs_yesno - Return "yes" or "no".
- *
- * @value: Bool value.
- *
- * Returns "yes" if @value is not 0, "no" otherwise.
- */
-static const char *ccs_yesno(const unsigned int value)
+static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
 {
-	return value ? "yes" : "no";
+	return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
 }
 
-/**
- * ccs_same_name_union - Check for duplicated "struct ccs_name_union" entry.
- *
- * @a: Pointer to "struct ccs_name_union".
- * @b: Pointer to "struct ccs_name_union".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool ccs_same_name_union(const struct ccs_name_union *a,
-				       const struct ccs_name_union *b)
+static char *ip4_string(char *p, const u8 *addr)
 {
-	return a->filename == b->filename && a->group == b->group;
+	/*
+	 * Since this function is called outside vsnprintf(), I can use
+	 * sprintf() here.
+	 */
+	return p +
+		sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
 }
 
-/**
- * ccs_same_number_union - Check for duplicated "struct ccs_number_union" entry.
- *
- * @a: Pointer to "struct ccs_number_union".
- * @b: Pointer to "struct ccs_number_union".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static inline bool ccs_same_number_union(const struct ccs_number_union *a,
-					 const struct ccs_number_union *b)
+static char *ip6_compressed_string(char *p, const char *addr)
 {
-	return a->values[0] == b->values[0] && a->values[1] == b->values[1] &&
-		a->group == b->group && a->value_type[0] == b->value_type[0] &&
-		a->value_type[1] == b->value_type[1];
+	int i, j, range;
+	unsigned char zerolength[8];
+	int longest = 1;
+	int colonpos = -1;
+	u16 word;
+	u8 hi, lo;
+	_Bool needcolon = false;
+	_Bool useIPv4;
+	struct in6_addr in6;
+
+	memcpy(&in6, addr, sizeof(struct in6_addr));
+
+	useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
+
+	memset(zerolength, 0, sizeof(zerolength));
+
+	if (useIPv4)
+		range = 6;
+	else
+		range = 8;
+
+	/* find position of longest 0 run */
+	for (i = 0; i < range; i++) {
+		for (j = i; j < range; j++) {
+			if (in6.s6_addr16[j] != 0)
+				break;
+			zerolength[i]++;
+		}
+	}
+	for (i = 0; i < range; i++) {
+		if (zerolength[i] > longest) {
+			longest = zerolength[i];
+			colonpos = i;
+		}
+	}
+	if (longest == 1)		/* don't compress a single 0 */
+		colonpos = -1;
+
+	/* emit address */
+	for (i = 0; i < range; i++) {
+		if (i == colonpos) {
+			if (needcolon || i == 0)
+				*p++ = ':';
+			*p++ = ':';
+			needcolon = false;
+			i += longest - 1;
+			continue;
+		}
+		if (needcolon) {
+			*p++ = ':';
+			needcolon = false;
+		}
+		/* hex u16 without leading 0s */
+		word = ntohs(in6.s6_addr16[i]);
+		hi = word >> 8;
+		lo = word & 0xff;
+		if (hi) {
+			if (hi > 0x0f)
+				p = pack_hex_byte(p, hi);
+			else
+				*p++ = hex_asc_lo(hi);
+			p = pack_hex_byte(p, lo);
+		} else if (lo > 0x0f)
+			p = pack_hex_byte(p, lo);
+		else
+			*p++ = hex_asc_lo(lo);
+		needcolon = true;
+	}
+
+	if (useIPv4) {
+		if (needcolon)
+			*p++ = ':';
+		p = ip4_string(p, &in6.s6_addr[12]);
+	}
+	*p = '\0';
+
+	return p;
 }
 
 /**
- * ccs_same_ipaddr_union - Check for duplicated "struct ccs_ipaddr_union" entry.
+ * ccs_print_ipv4 - Print an IPv4 address.
  *
- * @a: Pointer to "struct ccs_ipaddr_union".
- * @b: Pointer to "struct ccs_ipaddr_union".
+ * @ip: Pointer to "u32 in network byte order".
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns nothing.
  */
-static inline bool ccs_same_ipaddr_union(const struct ccs_ipaddr_union *a,
-					 const struct ccs_ipaddr_union *b)
+static void ccs_print_ipv4(const u32 *ip)
 {
-	return !memcmp(a->ip, b->ip, sizeof(a->ip)) && a->group == b->group &&
-		a->is_ipv6 == b->is_ipv6;
+	char addr[sizeof("255.255.255.255")];
+	ip4_string(addr, (const u8 *) ip);
+	cprint(addr);
 }
 
 /**
- * ccs_partial_name_hash - Hash name.
+ * ccs_print_ipv6 - Print an IPv6 address.
  *
- * @c:        A unsigned long value.
- * @prevhash: A previous hash value.
+ * @ip: Pointer to "struct in6_addr".
  *
- * Returns new hash value.
- *
- * This function is copied from partial_name_hash() in the kernel source.
+ * Returns nothing.
  */
-static inline unsigned long ccs_partial_name_hash(unsigned long c,
-						  unsigned long prevhash)
+static void ccs_print_ipv6(const struct in6_addr *ip)
 {
-	return (prevhash + (c << 4) + (c >> 4)) * 11;
+	char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
+	ip6_compressed_string(addr, (const u8 *) ip);
+	cprintf(addr);
 }
 
+/***** SECTION5: Variables definition section *****/
+
+static int client_fd;
+
+/* List of namespaces. */
+static LIST_HEAD(ccs_namespace_list);
+/* True if namespace other than ccs_kernel_namespace is defined. */
+static _Bool ccs_namespace_enabled;
+
+/* Initial namespace.*/
+static struct ccs_policy_namespace ccs_kernel_namespace;
+
+static struct ccs_group ccs_group_any;
+
+/* List of "struct ccs_condition". */
+static LIST_HEAD(ccs_condition_list);
+
+/* List of "struct ccs_manager". */
+static LIST_HEAD(ccs_manager_list);
+
+/***** SECTION6: Dependent functions section *****/
+
 /**
- * ccs_full_name_hash - Hash full name.
+ * ccs_memory_ok - Check memory quota.
  *
- * @name: Pointer to "const unsigned char".
- * @len:  Length of @name in byte.
+ * @ptr:  Pointer to allocated memory. Maybe NULL.
+ * @size: Size in byte. Not used if @ptr is NULL.
  *
- * Returns hash value.
+ * Returns true if @ptr is not NULL and quota not exceeded, false otherwise.
  *
- * This function is copied from full_name_hash() in the kernel source.
+ * Caller holds ccs_policy_lock mutex.
  */
-static inline unsigned int ccs_full_name_hash(const unsigned char *name,
-					      unsigned int len)
+static bool ccs_memory_ok(const void *ptr, const unsigned int size)
 {
-	unsigned long hash = 0;
-	while (len--)
-		hash = ccs_partial_name_hash(*name++, hash);
-	return (unsigned int) hash;
+	return ptr != NULL;
 }
 
 /**
- * ccs_get_name - Allocate memory for string data.
- *
- * @name: The string to store into the permernent memory.
- *
- * Returns pointer to "struct ccs_path_info" on success, abort otherwise.
- */
-static const struct ccs_path_info *ccs_get_name(const char *name)
-{
-	struct ccs_name *ptr;
-	unsigned int hash;
-	int len;
-	int allocated_len;
-	struct list_head *head;
-
-	if (!name)
-		name = "";
-	len = strlen(name) + 1;
-	hash = ccs_full_name_hash((const unsigned char *) name, len - 1);
-	head = &ccs_name_list[hash % CCS_MAX_HASH];
-	list_for_each_entry(ptr, head, head.list) {
-		if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name))
-			continue;
-		ptr->head.users++;
-		goto out;
-	}
-	allocated_len = sizeof(*ptr) + len;
-	ptr = ccs_malloc(allocated_len);
-	ptr->entry.name = ((char *) ptr) + sizeof(*ptr);
-	memmove((char *) ptr->entry.name, name, len);
-	ptr->head.users = 1;
-	ccs_fill_path_info(&ptr->entry);
-	ptr->size = allocated_len;
-	list_add_tail(&ptr->head.list, head);
-out:
-	return &ptr->entry;
-}
-
-
-/**
  * ccs_commit_ok - Allocate memory and check memory quota.
  *
  * @data: Data to copy from.
  * @size: Size in byte.
  *
- * Returns pointer to allocated memory on success, abort otherwise.
+ * Returns pointer to allocated memory on success, NULL otherwise.
  * @data is zero-cleared on success.
+ *
+ * Caller holds ccs_policy_lock mutex.
  */
 static void *ccs_commit_ok(void *data, const unsigned int size)
 {
@@ -1485,21 +1722,25 @@
 }
 
 /**
- * ccs_permstr - Find permission keywords.
+ * ccs_print_ip - Print an IP address.
  *
- * @string: String representation for permissions in foo/bar/buz format.
- * @keyword: Keyword to find from @string/
+ * @ptr: Pointer to "struct ipaddr_union".
  *
- * Returns ture if @keyword was found in @string, false otherwise.
- *
- * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
+ * Returns nothing.
  */
-static bool ccs_permstr(const char *string, const char *keyword)
+static void ccs_print_ip(const struct ccs_ipaddr_union *ptr)
 {
-	const char *cp = strstr(string, keyword);
-	if (cp)
-		return cp == string || *(cp - 1) == '/';
-	return false;
+	if (ptr->is_ipv6)
+		ccs_print_ipv6(&ptr->ip[0]);
+	else
+		ccs_print_ipv4(&ptr->ip[0].s6_addr32[0]);
+	if (!memcmp(&ptr->ip[0], &ptr->ip[1], 16))
+		return;
+	cprint("-");
+	if (ptr->is_ipv6)
+		ccs_print_ipv6(&ptr->ip[1]);
+	else
+		ccs_print_ipv4(&ptr->ip[1].s6_addr32[0]);
 }
 
 /**
@@ -1525,69 +1766,74 @@
 }
 
 /**
- * ccs_get_domainname - Read a domainname from a line.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns a domainname on success, NULL otherwise.
- */
-static const struct ccs_path_info *ccs_get_domainname
-(struct ccs_acl_param *param)
-{
-	char *start = param->data;
-	char *pos = start;
-	while (*pos) {
-		if (*pos++ != ' ' || *pos++ == '/')
-			continue;
-		pos -= 2;
-		*pos++ = '\0';
-		break;
-	}
-	param->data = pos;
-	if (ccs_correct_domain(start))
-		return ccs_get_name(start);
-	return NULL;
-}
-
-/**
  * ccs_get_group - Allocate memory for "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group".
  *
  * @param: Pointer to "struct ccs_acl_param".
- * @list:  List to use.
+ * @idx:   Index number.
  *
  * Returns pointer to "struct ccs_group" on success, NULL otherwise.
  */
 static struct ccs_group *ccs_get_group(struct ccs_acl_param *param,
-				       struct list_head *list)
+				       const u8 idx)
 {
 	struct ccs_group e = { };
 	struct ccs_group *group = NULL;
+	struct list_head *list;
 	const char *group_name = ccs_read_token(param);
-	bool found = false;
-	if (!ccs_correct_word(group_name))
+	_Bool found = false;
+	if (!strcmp(group_name, "any"))
+		return &ccs_group_any;
+	if (!ccs_correct_word(group_name) || idx >= CCS_MAX_GROUP)
 		return NULL;
-	e.ns = param->ns;
-	e.group_name = ccs_get_name(group_name);
+	e.group_name = ccs_savename(group_name);
+	list = &param->ns->group_list[idx];
 	list_for_each_entry(group, list, head.list) {
-		if (e.ns != group->ns || e.group_name != group->group_name)
+		if (e.group_name != group->group_name)
 			continue;
-		group->head.users++;
 		found = true;
 		break;
 	}
 	if (!found) {
 		struct ccs_group *entry = ccs_commit_ok(&e, sizeof(e));
-		INIT_LIST_HEAD(&entry->member_list);
-		entry->head.users = 1;
-		list_add_tail(&entry->head.list, list);
-		group = entry;
-		found = true;
+		if (entry) {
+			INIT_LIST_HEAD(&entry->member_list);
+			list_add_tail(&entry->head.list, list);
+			group = entry;
+			found = true;
+		}
 	}
 	ccs_put_name(e.group_name);
 	return found ? group : NULL;
 }
 
 /**
+ * ccs_parse_name_union - Parse a ccs_name_union.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ * @ptr:   Pointer to "struct ccs_name_union".
+ *
+ * Returns true on success, false otherwise.
+ */
+static _Bool ccs_parse_name_union(struct ccs_acl_param *param,
+				 struct ccs_name_union *ptr)
+{
+	char *filename;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		ptr->is_not = true;
+		/* fall through */
+	case 1:
+		ptr->group = ccs_get_group(param, CCS_PATH_GROUP);
+		return ptr->group != NULL;
+	}
+	filename = ccs_read_token(param);
+	if (!ccs_correct_word(filename))
+		return false;
+	ptr->filename = ccs_savename(filename);
+	return true;
+}
+
+/**
  * ccs_parse_ulong - Parse an "unsigned long" value.
  *
  * @result: Pointer to "unsigned long".
@@ -1628,30 +1874,6 @@
 }
 
 /**
- * ccs_parse_name_union - Parse a ccs_name_union.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @ptr:   Pointer to "struct ccs_name_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_name_union(struct ccs_acl_param *param,
-				 struct ccs_name_union *ptr)
-{
-	char *filename;
-	if (param->data[0] == '@') {
-		param->data++;
-		ptr->group = ccs_get_group(param, &ccs_path_group);
-		return ptr->group != NULL;
-	}
-	filename = ccs_read_token(param);
-	if (!ccs_correct_word(filename))
-		return false;
-	ptr->filename = ccs_get_name(filename);
-	return true;
-}
-
-/**
  * ccs_parse_number_union - Parse a ccs_number_union.
  *
  * @param: Pointer to "struct ccs_acl_param".
@@ -1659,16 +1881,19 @@
  *
  * Returns true on success, false otherwise.
  */
-static bool ccs_parse_number_union(struct ccs_acl_param *param,
+static _Bool ccs_parse_number_union(struct ccs_acl_param *param,
 				   struct ccs_number_union *ptr)
 {
 	char *data;
 	u8 type;
 	unsigned long v;
 	memset(ptr, 0, sizeof(*ptr));
-	if (param->data[0] == '@') {
-		param->data++;
-		ptr->group = ccs_get_group(param, &ccs_number_group);
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		ptr->is_not = true;
+		/* fall through */
+	case 1:
+		ptr->group = ccs_get_group(param, CCS_NUMBER_GROUP);
 		return ptr->group != NULL;
 	}
 	data = ccs_read_token(param);
@@ -1693,117 +1918,54 @@
 }
 
 /**
- * ccs_find_domain2 - Find a domain by the given name.
+ * ccs_parse_ipaddr_union - Parse an IP address.
  *
- * @domainname: The domainname to find.
+ * @param: Pointer to "struct ccs_acl_param".
+ * @ptr:   Pointer to "struct ccs_ipaddr_union".
  *
- * Returns pointer to "struct ccs_domain2_info" if found, NULL otherwise.
+ * Returns true on success, false otherwise.
  */
-static struct ccs_domain2_info *ccs_find_domain2(const char *domainname)
+static _Bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
+				   struct ccs_ipaddr_union *ptr)
 {
-	struct ccs_domain2_info *domain;
-	struct ccs_path_info name;
-	name.name = domainname;
-	ccs_fill_path_info(&name);
-	list_for_each_entry(domain, &ccs_domain_list, list) {
-		if (!domain->is_deleted &&
-		    !ccs_pathcmp(&name, domain->domainname))
-			return domain;
+	u8 * const min = ptr->ip[0].in6_u.u6_addr8;
+	u8 * const max = ptr->ip[1].in6_u.u6_addr8;
+	char *address;
+	const char *end;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		ptr->is_not = true;
+		/* fall through */
+	case 1:
+		ptr->group = ccs_get_group(param, CCS_ADDRESS_GROUP);
+		return ptr->group != NULL;
 	}
-	return NULL;
-}
-
-static int client_fd = EOF;
-
-static void cprintf(const char *fmt, ...)
-	__attribute__ ((format(printf, 1, 2)));
-
-/**
- * cprintf - printf() over socket.
- *
- * @fmt: The printf()'s format string, followed by parameters.
- *
- * Returns nothing.
- */
-static void cprintf(const char *fmt, ...)
-{
-	va_list args;
-	static char *buffer = NULL;
-	static unsigned int buffer_len = 0;
-	static unsigned int buffer_pos = 0;
-	int len;
-	if (head.reset) {
-		head.reset = false;
-		buffer_pos = 0;
+	address = ccs_read_token(param);
+	if (!strchr(address, ':') &&
+	    ccs_in4_pton(address, -1, min, '-', &end) > 0) {
+		ptr->is_ipv6 = false;
+		if (!*end)
+			ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
+		else if (*end++ != '-' ||
+			 ccs_in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
+			return false;
+		return true;
 	}
-	while (1) {
-		va_start(args, fmt);
-		len = vsnprintf(buffer + buffer_pos, buffer_len - buffer_pos,
-				fmt, args);
-		va_end(args);
-		if (len < 0)
-			_exit(1);
-		if (buffer_pos + len < buffer_len) {
-			buffer_pos += len;
-			break;
-		}
-		buffer_len = buffer_pos + len + 4096;
-		buffer = ccs_realloc(buffer, buffer_len);
+	if (ccs_in6_pton(address, -1, min, '-', &end) > 0) {
+		ptr->is_ipv6 = true;
+		if (!*end)
+			memmove(max, min, sizeof(u16) * 8);
+		else if (*end++ != '-' ||
+			 ccs_in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
+			return false;
+		return true;
 	}
-	if (len && buffer_pos < 1048576)
-		return;
-	/*
-	 * Reader might close connection without reading until EOF.
-	 * In that case, we should not call _exit() because offline daemon does
-	 * not call fork() for each accept()ed socket connection.
-	 */
-	if (write(client_fd, buffer, buffer_pos) != buffer_pos) {
-		close(client_fd);
-		client_fd = EOF;
-	}
-	buffer_pos = 0;
+	return false;
 }
 
 /**
- * ccs_update_policy - Update an entry for exception policy.
+ * ccs_get_dqword - ccs_savename() for a quoted string.
  *
- * @new_entry:       Pointer to "struct ccs_acl_info".
- * @size:            Size of @new_entry in bytes.
- * @param:           Pointer to "struct ccs_acl_param".
- * @check_duplicate: Callback function to find duplicated entry.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_update_policy(struct ccs_acl_head *new_entry, const int size,
-			     struct ccs_acl_param *param,
-			     bool (*check_duplicate)
-			     (const struct ccs_acl_head *,
-			      const struct ccs_acl_head *))
-{
-	int error = param->is_delete ? -ENOENT : -ENOMEM;
-	struct ccs_acl_head *entry;
-	struct list_head *list = param->list;
-	list_for_each_entry(entry, list, list) {
-		if (!check_duplicate(entry, new_entry))
-			continue;
-		entry->is_deleted = param->is_delete;
-		error = 0;
-		break;
-	}
-	if (error && !param->is_delete) {
-		entry = ccs_commit_ok(new_entry, size);
-		list_add_tail(&entry->list, list);
-		error = 0;
-	}
-	return error;
-}
-
-/* List of "struct ccs_condition". */
-static LIST_HEAD(ccs_condition_list);
-
-/**
- * ccs_get_dqword - ccs_get_name() for a quoted string.
- *
  * @start: String to save.
  *
  * Returns pointer to "struct ccs_path_info" on success, NULL otherwise.
@@ -1816,7 +1978,7 @@
 	*cp = '\0';
 	if (*start && !ccs_correct_word(start))
 		return NULL;
-	return ccs_get_name(start);
+	return ccs_savename(start);
 }
 
 /**
@@ -1827,11 +1989,11 @@
  *
  * Returns true on success, false otherwise.
  */
-static bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
+static _Bool ccs_parse_name_union_quoted(struct ccs_acl_param *param,
 					struct ccs_name_union *ptr)
 {
 	char *filename = param->data;
-	if (*filename == '@')
+	if (ccs_group_type(&filename))
 		return ccs_parse_name_union(param, ptr);
 	ptr->filename = ccs_get_dqword(filename);
 	return ptr->filename != NULL;
@@ -1846,7 +2008,7 @@
  *
  * Returns true on success, false otherwise.
  */
-static bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv)
+static _Bool ccs_parse_argv(char *left, char *right, struct ccs_argv *argv)
 {
 	if (ccs_parse_ulong(&argv->index, &left) != CCS_VALUE_TYPE_DECIMAL ||
 	    *left++ != ']' || *left)
@@ -1864,7 +2026,7 @@
  *
  * Returns true on success, false otherwise.
  */
-static bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp)
+static _Bool ccs_parse_envp(char *left, char *right, struct ccs_envp *envp)
 {
 	const struct ccs_path_info *name;
 	const struct ccs_path_info *value;
@@ -1874,7 +2036,9 @@
 	*cp = '\0';
 	if (!ccs_correct_word(left))
 		goto out;
-	name = ccs_get_name(left);
+	name = ccs_savename(left);
+	if (!name)
+		goto out;
 	if (!strcmp(right, "NULL")) {
 		value = NULL;
 	} else {
@@ -1899,16 +2063,15 @@
  *
  * Returns true if @a == @b, false otherwise.
  */
-static inline bool ccs_same_condition(const struct ccs_condition *a,
-				      const struct ccs_condition *b)
+static _Bool ccs_same_condition(const struct ccs_condition *a,
+			       const struct ccs_condition *b)
 {
 	return a->size == b->size && a->condc == b->condc &&
 		a->numbers_count == b->numbers_count &&
 		a->names_count == b->names_count &&
 		a->argc == b->argc && a->envc == b->envc &&
 		a->grant_log == b->grant_log &&
-		a->exec_transit == b->exec_transit && a->transit == b->transit
-		&& !memcmp(a + 1, b + 1, a->size - sizeof(*a));
+		!memcmp(a + 1, b + 1, a->size - sizeof(*a));
 }
 
 /**
@@ -1929,15 +2092,6 @@
 	return i;
 }
 
-/* Define this to enable debug mode. */
-/* #define DEBUG_CONDITION */
-
-#ifdef DEBUG_CONDITION
-#define dprintk printk
-#else
-#define dprintk(...) do { } while (0)
-#endif
-
 /**
  * ccs_commit_condition - Commit "struct ccs_condition".
  *
@@ -1951,18 +2105,16 @@
 static struct ccs_condition *ccs_commit_condition(struct ccs_condition *entry)
 {
 	struct ccs_condition *ptr;
-	bool found = false;
+	_Bool found = false;
 	list_for_each_entry(ptr, &ccs_condition_list, head.list) {
 		if (!ccs_same_condition(ptr, entry))
 			continue;
 		/* Same entry found. Share this entry. */
-		ptr->head.users++;
 		found = true;
 		break;
 	}
 	if (!found) {
-		if (entry) {
-			entry->head.users = 1;
+		if (ccs_memory_ok(entry, entry->size)) {
 			list_add(&entry->head.list, &ccs_condition_list);
 		} else {
 			found = true;
@@ -1970,7 +2122,6 @@
 		}
 	}
 	if (found) {
-		ccs_del_condition(&entry->head.list);
 		free(entry);
 		entry = ptr;
 	}
@@ -1978,6 +2129,31 @@
 }
 
 /**
+ * ccs_get_domainname - Read a domainname from a line.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns a domainname on success, NULL otherwise.
+ */
+static const struct ccs_path_info *ccs_get_domainname
+(struct ccs_acl_param *param)
+{
+	char *start = param->data;
+	char *pos = start;
+	while (*pos) {
+		if (*pos++ != ' ' || *pos++ == '/')
+			continue;
+		pos -= 2;
+		*pos++ = '\0';
+		break;
+	}
+	param->data = pos;
+	if (ccs_correct_domain(start))
+		return ccs_savename(start);
+	return NULL;
+}
+
+/**
  * ccs_get_transit_preference - Parse domain transition preference for execve().
  *
  * @param: Pointer to "struct ccs_acl_param".
@@ -1986,10 +2162,10 @@
  * Returns the condition string part.
  */
 static char *ccs_get_transit_preference(struct ccs_acl_param *param,
-					struct ccs_condition *e)
+					struct ccs_execute_acl *e)
 {
 	char * const pos = param->data;
-	bool flag;
+	_Bool flag;
 	if (*pos == '<') {
 		e->transit = ccs_get_domainname(param);
 		goto done;
@@ -1999,24 +2175,17 @@
 		if (cp)
 			*cp = '\0';
 		flag = ccs_correct_path(pos) || !strcmp(pos, "keep") ||
-			!strcmp(pos, "initialize") || !strcmp(pos, "reset") ||
-			!strcmp(pos, "child") || !strcmp(pos, "parent");
+			!strcmp(pos, "child");
 		if (cp)
 			*cp = ' ';
 	}
 	if (!flag)
 		return pos;
-	e->transit = ccs_get_name(ccs_read_token(param));
+	e->transit = ccs_savename(ccs_read_token(param));
 done:
-	if (e->transit) {
-		e->exec_transit = true;
+	if (e->transit)
 		return param->data;
-	}
-	/*
-	 * Return a bad read-only condition string that will let
-	 * ccs_get_condition() return NULL.
-	 */
-	return "/";
+	return NULL;
 }
 
 /**
@@ -2026,7 +2195,7 @@
  *
  * Returns pointer to "struct ccs_condition" on success, NULL otherwise.
  */
-static struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param)
+struct ccs_condition *ccs_get_condition(struct ccs_acl_param *param)
 {
 	struct ccs_condition *entry = NULL;
 	struct ccs_condition_element *condp = NULL;
@@ -2035,7 +2204,7 @@
 	struct ccs_argv *argv = NULL;
 	struct ccs_envp *envp = NULL;
 	struct ccs_condition e = { };
-	char * const start_of_string = ccs_get_transit_preference(param, &e);
+	char * const start_of_string = param->data;
 	char * const end_of_string = start_of_string + strlen(start_of_string);
 	char *pos;
 rerun:
@@ -2046,7 +2215,7 @@
 		char *left_word = pos;
 		char *cp;
 		char *right_word;
-		bool is_not;
+		_Bool is_not;
 		if (!*left_word)
 			break;
 		/*
@@ -2076,8 +2245,6 @@
 			*right_word++ = '\0'; /* Will restore later. */
 		else
 			goto out;
-		dprintk(KERN_WARNING "%u: <%s>%s=<%s>\n", __LINE__, left_word,
-			is_not ? "!" : "", right_word);
 		if (!strcmp(left_word, "grant_log")) {
 			if (entry) {
 				if (is_not ||
@@ -2092,18 +2259,6 @@
 			}
 			continue;
 		}
-		if (!strcmp(left_word, "auto_domain_transition")) {
-			if (entry) {
-				if (is_not || entry->transit)
-					goto out;
-				entry->transit = ccs_get_dqword(right_word);
-				if (!entry->transit ||
-				    (entry->transit->name[0] != '/' &&
-				     !ccs_domain_def(entry->transit->name)))
-					goto out;
-			}
-			continue;
-		}
 		if (!strncmp(left_word, "exec.argv[", 10)) {
 			if (!argv) {
 				e.argc++;
@@ -2135,8 +2290,6 @@
 			goto store_value;
 		}
 		left = ccs_condition_type(left_word);
-		dprintk(KERN_WARNING "%u: <%s> left=%u\n", __LINE__, left_word,
-			left);
 		if (left == CCS_MAX_CONDITION_KEYWORD) {
 			if (!numbers_p) {
 				e.numbers_count++;
@@ -2144,7 +2297,7 @@
 				e.numbers_count--;
 				left = CCS_NUMBER_UNION;
 				param->data = left_word;
-				if (*left_word == '@' ||
+				if (ccs_group_type(&left_word) ||
 				    !ccs_parse_number_union(param,
 							    numbers_p++))
 					goto out;
@@ -2154,7 +2307,7 @@
 			e.condc++;
 		else
 			e.condc--;
-		if (left == CCS_EXEC_REALPATH || left == CCS_SYMLINK_TARGET) {
+		if (left == CCS_EXEC_REALPATH) {
 			if (!names_p) {
 				e.names_count++;
 			} else {
@@ -2181,22 +2334,13 @@
 			}
 		}
 store_value:
-		if (!condp) {
-			dprintk(KERN_WARNING "%u: dry_run left=%u right=%u "
-				"match=%u\n", __LINE__, left, right, !is_not);
+		if (!condp)
 			continue;
-		}
 		condp->left = left;
 		condp->right = right;
 		condp->equals = !is_not;
-		dprintk(KERN_WARNING "%u: left=%u right=%u match=%u\n",
-			__LINE__, condp->left, condp->right,
-			condp->equals);
 		condp++;
 	}
-	dprintk(KERN_INFO "%u: cond=%u numbers=%u names=%u ac=%u ec=%u\n",
-		__LINE__, e.condc, e.numbers_count, e.names_count, e.argc,
-		e.envc);
 	if (entry)
 		return ccs_commit_condition(entry);
 	e.size = sizeof(*entry)
@@ -2207,14 +2351,13 @@
 		+ e.envc * sizeof(struct ccs_envp);
 	entry = ccs_malloc(e.size);
 	*entry = e;
-	e.transit = NULL;
 	condp = (struct ccs_condition_element *) (entry + 1);
 	numbers_p = (struct ccs_number_union *) (condp + e.condc);
 	names_p = (struct ccs_name_union *) (numbers_p + e.numbers_count);
 	argv = (struct ccs_argv *) (names_p + e.names_count);
 	envp = (struct ccs_envp *) (argv + e.argc);
 	{
-		bool flag = false;
+		_Bool flag = false;
 		for (pos = start_of_string; pos < end_of_string; pos++) {
 			if (*pos)
 				continue;
@@ -2229,1180 +2372,140 @@
 	}
 	goto rerun;
 out:
-	dprintk(KERN_WARNING "%u: %s failed\n", __LINE__, __func__);
-	if (entry) {
-		ccs_del_condition(&entry->head.list);
-		free(entry);
-	}
-	ccs_put_name(e.transit);
- 	return NULL;
+	free(entry);
+	return NULL;
 }
 
 /**
- * ccs_same_acl_head - Check for duplicated "struct ccs_acl_info" entry.
+ * ccs_yesno - Return "yes" or "no".
  *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
+ * @value: _Bool value.
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns "yes" if @value is not 0, "no" otherwise.
  */
-static inline bool ccs_same_acl_head(const struct ccs_acl_info *a,
-				     const struct ccs_acl_info *b)
+static const char *ccs_yesno(const unsigned int value)
 {
-	return a->type == b->type && a->cond == b->cond;
+	return value ? "yes" : "no";
 }
 
 /**
- * ccs_update_domain - Update an entry for domain policy.
+ * cprint - Print a string.
  *
- * @new_entry:       Pointer to "struct ccs_acl_info".
- * @size:            Size of @new_entry in bytes.
- * @param:           Pointer to "struct ccs_acl_param".
- * @check_duplicate: Callback function to find duplicated entry.
- * @merge_duplicate: Callback function to merge duplicated entry. Maybe NULL.
+ * @string: String to print.
  *
- * Returns 0 on success, negative value otherwise.
+ * Returns nothing.
  */
-static int ccs_update_domain(struct ccs_acl_info *new_entry, const int size,
-			     struct ccs_acl_param *param,
-			     bool (*check_duplicate)
-			     (const struct ccs_acl_info *,
-			      const struct ccs_acl_info *),
-			     bool (*merge_duplicate)
-			     (struct ccs_acl_info *, struct ccs_acl_info *,
-			      const bool))
+static void cprint(const char *string)
 {
-	const bool is_delete = param->is_delete;
-	int error = is_delete ? -ENOENT : -ENOMEM;
-	struct ccs_acl_info *entry;
-	struct list_head * const list = param->list;
-	if (param->data[0]) {
-		new_entry->cond = ccs_get_condition(param);
-		if (!new_entry->cond)
-			return -EINVAL;
-		/*
-		 * Domain transition preference is allowed for only 
-		 * "file execute"/"task auto_execute_handler"/
-		 * "task denied_auto_execute_handler" entries.
-		 */
-		if (new_entry->cond->exec_transit &&
-		    !(new_entry->type == CCS_TYPE_PATH_ACL &&
-		      container_of(new_entry, struct ccs_path_acl, head)->perm
-		      == 1 << CCS_TYPE_EXECUTE) &&
-		    new_entry->type != CCS_TYPE_AUTO_EXECUTE_HANDLER &&
-		    new_entry->type != CCS_TYPE_DENIED_EXECUTE_HANDLER)
-			goto out;
-	}
-	list_for_each_entry(entry, list, list) {
-		if (!ccs_same_acl_head(entry, new_entry) ||
-		    !check_duplicate(entry, new_entry))
-			continue;
-		if (merge_duplicate)
-			entry->is_deleted = merge_duplicate(entry, new_entry,
-							    is_delete);
-		else
-			entry->is_deleted = is_delete;
-		error = 0;
-		break;
-	}
-	if (error && !is_delete) {
-		entry = ccs_commit_ok(new_entry, size);
-		list_add_tail(&entry->list, list);
-		error = 0;
-	}
-out:
-	ccs_put_condition(new_entry->cond);
-	return error;
+	cprintf("%s", string);
 }
 
 /**
- * ccs_same_transition_control - Check for duplicated "struct ccs_transition_control" entry.
+ * cprintf - printf() to editor process.
  *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
+ * @fmt: The printf()'s format string, followed by parameters.
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns nothing.
  */
-static bool ccs_same_transition_control(const struct ccs_acl_head *a,
-					const struct ccs_acl_head *b)
+static void cprintf(const char *fmt, ...)
 {
-	const struct ccs_transition_control *p1 = container_of(a, typeof(*p1),
-							       head);
-	const struct ccs_transition_control *p2 = container_of(b, typeof(*p2),
-							       head);
-	return p1->type == p2->type && p1->is_last_name == p2->is_last_name
-		&& p1->domainname == p2->domainname
-		&& p1->program == p2->program && p1->ns == p2->ns;
-}
-
-/**
- * ccs_write_transition_control - Write "struct ccs_transition_control" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @type:  Type of this entry.
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_transition_control(struct ccs_acl_param *param,
-					const u8 type)
-{
-	struct ccs_transition_control e = { .type = type, .ns = param->ns };
-	int error = param->is_delete ? -ENOENT : -ENOMEM;
-	char *program = param->data;
-	char *domainname = strstr(program, " from ");
-	if (domainname) {
-		*domainname = '\0';
-		domainname += 6;
-	} else if (type == CCS_TRANSITION_CONTROL_NO_KEEP ||
-		   type == CCS_TRANSITION_CONTROL_KEEP) {
-		domainname = program;
-		program = NULL;
+	va_list args;
+	static char *buffer = NULL;
+	static unsigned int buffer_len = 0;
+	static unsigned int buffer_pos = 0;
+	int len;
+	if (head.reset) {
+		head.reset = false;
+		buffer_pos = 0;
 	}
-	if (program && strcmp(program, "any")) {
-		if (!ccs_correct_path(program))
-			return -EINVAL;
-		e.program = ccs_get_name(program);
-	}
-	if (domainname && strcmp(domainname, "any")) {
-		if (!ccs_correct_domain(domainname)) {
-			if (!ccs_correct_path(domainname))
-				goto out;
-			e.is_last_name = true;
+	while (1) {
+		va_start(args, fmt);
+		len = vsnprintf(buffer + buffer_pos, buffer_len - buffer_pos,
+				fmt, args);
+		va_end(args);
+		if (len < 0)
+			_exit(1);
+		if (buffer_pos + len < buffer_len) {
+			buffer_pos += len;
+			break;
 		}
-		e.domainname = ccs_get_name(domainname);
+		buffer_len = buffer_pos + len + 4096;
+		buffer = ccs_realloc(buffer, buffer_len);
 	}
-	param->list = &ccs_transition_list;
-	error = ccs_update_policy(&e.head, sizeof(e), param,
-				  ccs_same_transition_control);
-out:
-	ccs_put_name(e.domainname);
-	ccs_put_name(e.program);
-	return error;
-}
-
-/**
- * ccs_same_aggregator - Check for duplicated "struct ccs_aggregator" entry.
- *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool ccs_same_aggregator(const struct ccs_acl_head *a,
-				const struct ccs_acl_head *b)
-{
-	const struct ccs_aggregator *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_aggregator *p2 = container_of(b, typeof(*p2), head);
-	return p1->original_name == p2->original_name &&
-		p1->aggregated_name == p2->aggregated_name && p1->ns == p2->ns;
-}
-
-/**
- * ccs_write_aggregator - Write "struct ccs_aggregator" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_aggregator(struct ccs_acl_param *param)
-{
-	struct ccs_aggregator e = { .ns = param->ns };
-	int error = param->is_delete ? -ENOENT : -ENOMEM;
-	const char *original_name = ccs_read_token(param);
-	const char *aggregated_name = ccs_read_token(param);
-	if (!ccs_correct_word(original_name) ||
-	    !ccs_correct_path(aggregated_name))
-		return -EINVAL;
-	e.original_name = ccs_get_name(original_name);
-	e.aggregated_name = ccs_get_name(aggregated_name);
-	if (e.aggregated_name->is_patterned) /* No patterns allowed. */
-		goto out;
-	param->list = &ccs_aggregator_list;
-	error = ccs_update_policy(&e.head, sizeof(e), param,
-				  ccs_same_aggregator);
-out:
-	ccs_put_name(e.original_name);
-	ccs_put_name(e.aggregated_name);
-	return error;
-}
-
-/* Domain create handler. */
-
-/**
- * ccs_find_namespace - Find specified namespace.
- *
- * @name: Name of namespace to find.
- * @len:  Length of @name.
- *
- * Returns pointer to "struct ccs_policy_namespace" if found, NULL otherwise.
- */
-static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
-						       const unsigned int len)
-{
-	struct ccs_policy_namespace *ns;
-	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
-		if (strncmp(name, ns->name, len) ||
-		    (name[len] && name[len] != ' '))
-			continue;
-		return ns;
-	}
-	return NULL;
-}
-
-/**
- * ccs_assign_namespace - Create a new namespace.
- *
- * @domainname: Name of namespace to create.
- *
- * Returns pointer to "struct ccs_policy_namespace" on success, NULL otherwise.
- */
-static struct ccs_policy_namespace *ccs_assign_namespace(const char *domainname)
-{
-	struct ccs_policy_namespace *ptr;
-	struct ccs_policy_namespace *entry;
-	const char *cp = domainname;
-	unsigned int len = 0;
-	while (*cp && *cp++ != ' ')
-		len++;
-	ptr = ccs_find_namespace(domainname, len);
-	if (ptr)
-		return ptr;
-	if (len >= CCS_EXEC_TMPSIZE - 10 || !ccs_domain_def(domainname))
-		return NULL;
-	entry = ccs_malloc(sizeof(*entry) + len + 1);
-	{
-		char *name = (char *) (entry + 1);
-		memmove(name, domainname, len);
-		name[len] = '\0';
-		entry->name = name;
-	}
-	entry->profile_version = 20100903;
-	for (len = 0; len < CCS_MAX_ACL_GROUPS; len++)
-		INIT_LIST_HEAD(&entry->acl_group[len]);
-	ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
-	list_add_tail(&entry->namespace_list, &ccs_namespace_list);
-	return entry;
-}
-
-/**
- * ccs_assign_domain2 - Create a domain or a namespace.
- *
- * @domainname: The name of domain.
- *
- * Returns pointer to "struct ccs_domain2_info" on success, NULL otherwise.
- */
-static struct ccs_domain2_info *ccs_assign_domain2(const char *domainname)
-{
-	struct ccs_domain2_info e = { };
-	struct ccs_domain2_info *entry = ccs_find_domain2(domainname);
-	if (entry)
-		return entry;
-	/* Requested domain does not exist. */
-	/* Don't create requested domain if domainname is invalid. */
-	if (strlen(domainname) >= CCS_EXEC_TMPSIZE - 10 ||
-	    !ccs_correct_domain(domainname))
-		return NULL;
-	e.domainname = ccs_get_name(domainname);
-	entry = ccs_commit_ok(&e, sizeof(e));
-	INIT_LIST_HEAD(&entry->acl_info_list);
-	list_add_tail(&entry->list, &ccs_domain_list);
-	ccs_put_name(e.domainname);
-	return entry;
-}
-
-/**
- * ccs_same_path_acl - Check for duplicated "struct ccs_path_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool ccs_same_path_acl(const struct ccs_acl_info *a,
-			      const struct ccs_acl_info *b)
-{
-	const struct ccs_path_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_path_acl *p2 = container_of(b, typeof(*p2), head);
-	return ccs_same_name_union(&p1->name, &p2->name);
-}
-
-/**
- * ccs_merge_path_acl - Merge duplicated "struct ccs_path_acl" entry.
- *
- * @a:         Pointer to "struct ccs_acl_info".
- * @b:         Pointer to "struct ccs_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool ccs_merge_path_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
-			       const bool is_delete)
-{
-	u16 * const a_perm = &container_of(a, struct ccs_path_acl, head)->perm;
-	u16 perm = *a_perm;
-	const u16 b_perm = container_of(b, struct ccs_path_acl, head)->perm;
-	if (is_delete)
-		perm &= ~b_perm;
-	else
-		perm |= b_perm;
-	*a_perm = perm;
-	return !perm;
-}
-
-/**
- * ccs_update_path_acl - Update "struct ccs_path_acl" list.
- *
- * @perm:  Permission.
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_update_path_acl(const u16 perm, struct ccs_acl_param *param)
-{
-	struct ccs_path_acl e = {
-		.head.type = CCS_TYPE_PATH_ACL,
-		.perm = perm
-	};
-	int error;
-	if (!ccs_parse_name_union(param, &e.name))
-		error = -EINVAL;
-	else
-		error = ccs_update_domain(&e.head, sizeof(e), param,
-					  ccs_same_path_acl,
-					  ccs_merge_path_acl);
-	ccs_put_name_union(&e.name);
-	return error;
-}
-
-/**
- * ccs_same_mkdev_acl - Check for duplicated "struct ccs_mkdev_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool ccs_same_mkdev_acl(const struct ccs_acl_info *a,
-			       const struct ccs_acl_info *b)
-{
-	const struct ccs_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
-	return ccs_same_name_union(&p1->name, &p2->name) &&
-		ccs_same_number_union(&p1->mode, &p2->mode) &&
-		ccs_same_number_union(&p1->major, &p2->major) &&
-		ccs_same_number_union(&p1->minor, &p2->minor);
-}
-
-/**
- * ccs_merge_mkdev_acl - Merge duplicated "struct ccs_mkdev_acl" entry.
- *
- * @a:         Pointer to "struct ccs_acl_info".
- * @b:         Pointer to "struct ccs_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool ccs_merge_mkdev_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
-				const bool is_delete)
-{
-	u8 *const a_perm = &container_of(a, struct ccs_mkdev_acl, head)->perm;
-	u8 perm = *a_perm;
-	const u8 b_perm = container_of(b, struct ccs_mkdev_acl, head)->perm;
-	if (is_delete)
-		perm &= ~b_perm;
-	else
-		perm |= b_perm;
-	*a_perm = perm;
-	return !perm;
-}
-
-/**
- * ccs_update_mkdev_acl - Update "struct ccs_mkdev_acl" list.
- *
- * @perm:  Permission.
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_update_mkdev_acl(const u8 perm, struct ccs_acl_param *param)
-{
-	struct ccs_mkdev_acl e = {
-		.head.type = CCS_TYPE_MKDEV_ACL,
-		.perm = perm
-	};
-	int error;
-	if (!ccs_parse_name_union(param, &e.name) ||
-	    !ccs_parse_number_union(param, &e.mode) ||
-	    !ccs_parse_number_union(param, &e.major) ||
-	    !ccs_parse_number_union(param, &e.minor))
-		error = -EINVAL;
-	else
-		error = ccs_update_domain(&e.head, sizeof(e), param,
-					  ccs_same_mkdev_acl,
-					  ccs_merge_mkdev_acl);
-	ccs_put_name_union(&e.name);
-	ccs_put_number_union(&e.mode);
-	ccs_put_number_union(&e.major);
-	ccs_put_number_union(&e.minor);
-	return error;
-}
-
-/**
- * ccs_same_path2_acl - Check for duplicated "struct ccs_path2_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool ccs_same_path2_acl(const struct ccs_acl_info *a,
-			       const struct ccs_acl_info *b)
-{
-	const struct ccs_path2_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_path2_acl *p2 = container_of(b, typeof(*p2), head);
-	return ccs_same_name_union(&p1->name1, &p2->name1) &&
-		ccs_same_name_union(&p1->name2, &p2->name2);
-}
-
-/**
- * ccs_merge_path2_acl - Merge duplicated "struct ccs_path2_acl" entry.
- *
- * @a:         Pointer to "struct ccs_acl_info".
- * @b:         Pointer to "struct ccs_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool ccs_merge_path2_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
-				const bool is_delete)
-{
-	u8 * const a_perm = &container_of(a, struct ccs_path2_acl, head)->perm;
-	u8 perm = *a_perm;
-	const u8 b_perm = container_of(b, struct ccs_path2_acl, head)->perm;
-	if (is_delete)
-		perm &= ~b_perm;
-	else
-		perm |= b_perm;
-	*a_perm = perm;
-	return !perm;
-}
-
-/**
- * ccs_update_path2_acl - Update "struct ccs_path2_acl" list.
- *
- * @perm:  Permission.
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_update_path2_acl(const u8 perm, struct ccs_acl_param *param)
-{
-	struct ccs_path2_acl e = {
-		.head.type = CCS_TYPE_PATH2_ACL,
-		.perm = perm
-	};
-	int error;
-	if (!ccs_parse_name_union(param, &e.name1) ||
-	    !ccs_parse_name_union(param, &e.name2))
-		error = -EINVAL;
-	else
-		error = ccs_update_domain(&e.head, sizeof(e), param,
-					  ccs_same_path2_acl,
-					  ccs_merge_path2_acl);
-	ccs_put_name_union(&e.name1);
-	ccs_put_name_union(&e.name2);
-	return error;
-}
-
-/**
- * ccs_same_path_number_acl - Check for duplicated "struct ccs_path_number_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool ccs_same_path_number_acl(const struct ccs_acl_info *a,
-				     const struct ccs_acl_info *b)
-{
-	const struct ccs_path_number_acl *p1 = container_of(a, typeof(*p1),
-							    head);
-	const struct ccs_path_number_acl *p2 = container_of(b, typeof(*p2),
-							    head);
-	return ccs_same_name_union(&p1->name, &p2->name) &&
-		ccs_same_number_union(&p1->number, &p2->number);
-}
-
-/**
- * ccs_merge_path_number_acl - Merge duplicated "struct ccs_path_number_acl" entry.
- *
- * @a:         Pointer to "struct ccs_acl_info".
- * @b:         Pointer to "struct ccs_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool ccs_merge_path_number_acl(struct ccs_acl_info *a,
-				      struct ccs_acl_info *b,
-				      const bool is_delete)
-{
-	u8 * const a_perm = &container_of(a, struct ccs_path_number_acl, head)
-		->perm;
-	u8 perm = *a_perm;
-	const u8 b_perm = container_of(b, struct ccs_path_number_acl, head)
-		->perm;
-	if (is_delete)
-		perm &= ~b_perm;
-	else
-		perm |= b_perm;
-	*a_perm = perm;
-	return !perm;
-}
-
-/**
- * ccs_update_path_number_acl - Update create/mkdir/mkfifo/mksock/ioctl/chmod/chown/chgrp ACL.
- *
- * @perm:  Permission.
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_update_path_number_acl(const u8 perm,
-				      struct ccs_acl_param *param)
-{
-	struct ccs_path_number_acl e = {
-		.head.type = CCS_TYPE_PATH_NUMBER_ACL,
-		.perm = perm
-	};
-	int error;
-	if (!ccs_parse_name_union(param, &e.name) ||
-	    !ccs_parse_number_union(param, &e.number))
-		error = -EINVAL;
-	else
-		error = ccs_update_domain(&e.head, sizeof(e), param,
-					  ccs_same_path_number_acl,
-					  ccs_merge_path_number_acl);
-	ccs_put_name_union(&e.name);
-	ccs_put_number_union(&e.number);
-	return error;
-}
-
-/**
- * ccs_same_mount_acl - Check for duplicated "struct ccs_mount_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool ccs_same_mount_acl(const struct ccs_acl_info *a,
-			       const struct ccs_acl_info *b)
-{
-	const struct ccs_mount_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_mount_acl *p2 = container_of(b, typeof(*p2), head);
-	return ccs_same_name_union(&p1->dev_name, &p2->dev_name) &&
-		ccs_same_name_union(&p1->dir_name, &p2->dir_name) &&
-		ccs_same_name_union(&p1->fs_type, &p2->fs_type) &&
-		ccs_same_number_union(&p1->flags, &p2->flags);
-}
-
-/**
- * ccs_update_mount_acl - Write "struct ccs_mount_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_update_mount_acl(struct ccs_acl_param *param)
-{
-	struct ccs_mount_acl e = { .head.type = CCS_TYPE_MOUNT_ACL };
-	int error;
-	if (!ccs_parse_name_union(param, &e.dev_name) ||
-	    !ccs_parse_name_union(param, &e.dir_name) ||
-	    !ccs_parse_name_union(param, &e.fs_type) ||
-	    !ccs_parse_number_union(param, &e.flags))
-		error = -EINVAL;
-	else
-		error = ccs_update_domain(&e.head, sizeof(e), param,
-					  ccs_same_mount_acl, NULL);
-	ccs_put_name_union(&e.dev_name);
-	ccs_put_name_union(&e.dir_name);
-	ccs_put_name_union(&e.fs_type);
-	ccs_put_number_union(&e.flags);
-	return error;
-}
-
-/**
- * ccs_write_file - Update file related list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_file(struct ccs_acl_param *param)
-{
-	u16 perm = 0;
-	u8 type;
-	const char *operation = ccs_read_token(param);
-	for (type = 0; type < CCS_MAX_PATH_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_path_keyword[type]))
-			perm |= 1 << type;
-	if (perm)
-		return ccs_update_path_acl(perm, param);
-	for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]]))
-			perm |= 1 << type;
-	if (perm)
-		return ccs_update_path2_acl(perm, param);
-	for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]]))
-			perm |= 1 << type;
-	if (perm)
-		return ccs_update_path_number_acl(perm, param);
-	for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++)
-		if (ccs_permstr(operation,
-				ccs_mac_keywords[ccs_pnnn2mac[type]]))
-			perm |= 1 << type;
-	if (perm)
-		return ccs_update_mkdev_acl(perm, param);
-	if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT]))
-		return ccs_update_mount_acl(param);
-	return -EINVAL;
-}
-
-/**
- * ccs_parse_ipaddr_union - Parse an IP address.
- *
- * @param: Pointer to "struct ccs_acl_param".
- * @ptr:   Pointer to "struct ccs_ipaddr_union".
- *
- * Returns true on success, false otherwise.
- */
-static bool ccs_parse_ipaddr_union(struct ccs_acl_param *param,
-				   struct ccs_ipaddr_union *ptr)
-{
-	struct ccs_ip_address_entry e;
-	memset(ptr, 0, sizeof(ptr));
-	if (ccs_parse_ip(ccs_read_token(param), &e) == 0) {
-		memmove(&ptr->ip[0], e.min, sizeof(ptr->ip[0]));
-		memmove(&ptr->ip[1], e.max, sizeof(ptr->ip[1]));
-		ptr->is_ipv6 = e.is_ipv6;
-		return true;
-	}
-	return false;
-}
-
-/*
- * Routines for printing IPv4 or IPv6 address.
- * These are copied from include/linux/kernel.h include/net/ipv6.h
- * include/net/addrconf.h lib/hexdump.c lib/vsprintf.c and simplified.
- */
-static const char hex_asc[] = "0123456789abcdef";
-#define hex_asc_lo(x)   hex_asc[((x) & 0x0f)]
-#define hex_asc_hi(x)   hex_asc[((x) & 0xf0) >> 4]
-
-static inline char *pack_hex_byte(char *buf, u8 byte)
-{
-	*buf++ = hex_asc_hi(byte);
-	*buf++ = hex_asc_lo(byte);
-	return buf;
-}
-
-static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
-{
-	return (a->s6_addr32[0] | a->s6_addr32[1] |
-		(a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0;
-}
-
-static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
-{
-	return (addr->s6_addr32[2] | htonl(0x02000000)) == htonl(0x02005EFE);
-}
-
-static char *ip4_string(char *p, const u8 *addr)
-{
+	if (len && buffer_pos < 1048576)
+		return;
 	/*
-	 * Since this function is called outside vsnprintf(), I can use
-	 * sprintf() here.
+	 * Reader might close connection without reading until EOF.
+	 * In that case, we should not call _exit() because offline daemon does
+	 * not call fork() for each accept()ed socket connection.
 	 */
-	return p +
-		sprintf(p, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3]);
-}
-
-static char *ip6_compressed_string(char *p, const char *addr)
-{
-	int i, j, range;
-	unsigned char zerolength[8];
-	int longest = 1;
-	int colonpos = -1;
-	u16 word;
-	u8 hi, lo;
-	bool needcolon = false;
-	bool useIPv4;
-	struct in6_addr in6;
-
-	memcpy(&in6, addr, sizeof(struct in6_addr));
-
-	useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
-
-	memset(zerolength, 0, sizeof(zerolength));
-
-	if (useIPv4)
-		range = 6;
-	else
-		range = 8;
-
-	/* find position of longest 0 run */
-	for (i = 0; i < range; i++) {
-		for (j = i; j < range; j++) {
-			if (in6.s6_addr16[j] != 0)
-				break;
-			zerolength[i]++;
-		}
+	if (write(client_fd, buffer, buffer_pos) != buffer_pos) {
+		close(client_fd);
+		client_fd = EOF;
 	}
-	for (i = 0; i < range; i++) {
-		if (zerolength[i] > longest) {
-			longest = zerolength[i];
-			colonpos = i;
-		}
-	}
-	if (longest == 1)		/* don't compress a single 0 */
-		colonpos = -1;
-
-	/* emit address */
-	for (i = 0; i < range; i++) {
-		if (i == colonpos) {
-			if (needcolon || i == 0)
-				*p++ = ':';
-			*p++ = ':';
-			needcolon = false;
-			i += longest - 1;
-			continue;
-		}
-		if (needcolon) {
-			*p++ = ':';
-			needcolon = false;
-		}
-		/* hex u16 without leading 0s */
-		word = ntohs(in6.s6_addr16[i]);
-		hi = word >> 8;
-		lo = word & 0xff;
-		if (hi) {
-			if (hi > 0x0f)
-				p = pack_hex_byte(p, hi);
-			else
-				*p++ = hex_asc_lo(hi);
-			p = pack_hex_byte(p, lo);
-		}
-		else if (lo > 0x0f)
-			p = pack_hex_byte(p, lo);
-		else
-			*p++ = hex_asc_lo(lo);
-		needcolon = true;
-	}
-
-	if (useIPv4) {
-		if (needcolon)
-			*p++ = ':';
-		p = ip4_string(p, &in6.s6_addr[12]);
-	}
-	*p = '\0';
-
-	return p;
+	buffer_pos = 0;
 }
 
 /**
- * ccs_print_ipv4 - Print an IPv4 address.
+ * ccs_set_space - Put a space.
  *
- * @min_ip: Pointer to "u32 in network byte order".
- * @max_ip: Pointer to "u32 in network byte order".
- *
  * Returns nothing.
  */
-static void ccs_print_ipv4(const u32 *min_ip, const u32 *max_ip)
+static void ccs_set_space(void)
 {
-	char addr[sizeof("255.255.255.255")];
-	ip4_string(addr, (const u8 *) min_ip);
-	cprintf("%s", addr);
-	if (*min_ip == *max_ip)
-		return;
-	ip4_string(addr, (const u8 *) max_ip);
-	cprintf("-%s", addr);
+	cprint(" ");
 }
 
 /**
- * ccs_print_ipv6 - Print an IPv6 address.
+ * ccs_set_lf - Put a line feed.
  *
- * @min_ip: Pointer to "struct in6_addr".
- * @max_ip: Pointer to "struct in6_addr".
- *
  * Returns nothing.
  */
-static void ccs_print_ipv6(const struct in6_addr *min_ip,
-			   const struct in6_addr *max_ip)
+static _Bool ccs_set_lf(void)
 {
-	char addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
-	ip6_compressed_string(addr, (const char *) min_ip);
-	cprintf("%s", addr);
-	if (!memcmp(min_ip, max_ip, 16))
-		return;
-	ip6_compressed_string(addr, (const char *) max_ip);
-	cprintf("-%s", addr);
+	cprint("\n");
+	return true;
 }
 
 /**
- * ccs_print_ip - Print an IP address.
+ * ccs_set_slash - Put a shash.
  *
- * @ptr: Pointer to "struct ccs_ipaddr_union".
- *
  * Returns nothing.
  */
-static void ccs_print_ip(const struct ccs_ipaddr_union *ptr)
+static void ccs_set_slash(void)
 {
-	if (ptr->is_ipv6)
-		ccs_print_ipv6(&ptr->ip[0], &ptr->ip[1]);
-	else
-		ccs_print_ipv4(&ptr->ip[0].s6_addr32[0],
-			       &ptr->ip[1].s6_addr32[0]);
+	cprint("/");
 }
 
 /**
- * ccs_same_inet_acl - Check for duplicated "struct ccs_inet_acl" entry.
+ * ccs_init_policy_namespace - Initialize namespace.
  *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
+ * @ns: Pointer to "struct ccs_policy_namespace".
  *
- * Returns true if @a == @b except permission bits, false otherwise.
+ * Returns nothing.
  */
-static bool ccs_same_inet_acl(const struct ccs_acl_info *a,
-			      const struct ccs_acl_info *b)
+static void ccs_init_policy_namespace(struct ccs_policy_namespace *ns)
 {
-	const struct ccs_inet_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_inet_acl *p2 = container_of(b, typeof(*p2), head);
-	return p1->protocol == p2->protocol &&
-		ccs_same_ipaddr_union(&p1->address, &p2->address) &&
-		ccs_same_number_union(&p1->port, &p2->port);
+	unsigned int idx;
+	for (idx = 0; idx < CCS_MAX_GROUP; idx++)
+		INIT_LIST_HEAD(&ns->group_list[idx]);
+	INIT_LIST_HEAD(&ns->default_transition_list);
+	ns->profile_version = 20100903;
+	ccs_namespace_enabled = !list_empty(&ccs_namespace_list);
+	list_add_tail(&ns->namespace_list, &ccs_namespace_list);
 }
 
 /**
- * ccs_same_unix_acl - Check for duplicated "struct ccs_unix_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b except permission bits, false otherwise.
- */
-static bool ccs_same_unix_acl(const struct ccs_acl_info *a,
-			      const struct ccs_acl_info *b)
-{
-	const struct ccs_unix_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_unix_acl *p2 = container_of(b, typeof(*p2), head);
-	return p1->protocol == p2->protocol &&
-		ccs_same_name_union(&p1->name, &p2->name);
-}
-
-/**
- * ccs_merge_inet_acl - Merge duplicated "struct ccs_inet_acl" entry.
- *
- * @a:         Pointer to "struct ccs_acl_info".
- * @b:         Pointer to "struct ccs_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool ccs_merge_inet_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
-			       const bool is_delete)
-{
-	u8 * const a_perm = &container_of(a, struct ccs_inet_acl, head)->perm;
-	u8 perm = *a_perm;
-	const u8 b_perm = container_of(b, struct ccs_inet_acl, head)->perm;
-	if (is_delete)
-		perm &= ~b_perm;
-	else
-		perm |= b_perm;
-	*a_perm = perm;
-	return !perm;
-}
-
-/**
- * ccs_merge_unix_acl - Merge duplicated "struct ccs_unix_acl" entry.
- *
- * @a:         Pointer to "struct ccs_acl_info".
- * @b:         Pointer to "struct ccs_acl_info".
- * @is_delete: True for @a &= ~@b, false for @a |= @b.
- *
- * Returns true if @a is empty, false otherwise.
- */
-static bool ccs_merge_unix_acl(struct ccs_acl_info *a, struct ccs_acl_info *b,
-			       const bool is_delete)
-{
-	u8 * const a_perm = &container_of(a, struct ccs_unix_acl, head)->perm;
-	u8 perm = *a_perm;
-	const u8 b_perm = container_of(b, struct ccs_unix_acl, head)->perm;
-	if (is_delete)
-		perm &= ~b_perm;
-	else
-		perm |= b_perm;
-	*a_perm = perm;
-	return !perm;
-}
-
-/**
- * ccs_write_inet_network - Write "struct ccs_inet_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_inet_network(struct ccs_acl_param *param)
-{
-	struct ccs_inet_acl e = { .head.type = CCS_TYPE_INET_ACL };
-	int error = -EINVAL;
-	u8 type;
-	const char *protocol = ccs_read_token(param);
-	const char *operation = ccs_read_token(param);
-	for (e.protocol = 0; e.protocol < CCS_SOCK_MAX; e.protocol++)
-		if (!strcmp(protocol, ccs_proto_keyword[e.protocol]))
-			break;
-	for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_socket_keyword[type]))
-			e.perm |= 1 << type;
-	if (e.protocol == CCS_SOCK_MAX || !e.perm)
-		return -EINVAL;
-	if (param->data[0] == '@') {
-		param->data++;
-		e.address.group = ccs_get_group(param, &ccs_address_group);
-		if (!e.address.group)
-			return -ENOMEM;
-	} else {
-		if (!ccs_parse_ipaddr_union(param, &e.address))
-			goto out;
-	}
-	if (!ccs_parse_number_union(param, &e.port) ||
-	    e.port.values[1] > 65535)
-		goto out;
-	error = ccs_update_domain(&e.head, sizeof(e), param, ccs_same_inet_acl,
-				  ccs_merge_inet_acl);
-out:
-	ccs_put_group(e.address.group);
-	ccs_put_number_union(&e.port);
-	return error;
-}
-
-/**
- * ccs_write_unix_network - Write "struct ccs_unix_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_unix_network(struct ccs_acl_param *param)
-{
-	struct ccs_unix_acl e = { .head.type = CCS_TYPE_UNIX_ACL };
-	int error;
-	u8 type;
-	const char *protocol = ccs_read_token(param);
-	const char *operation = ccs_read_token(param);
-	for (e.protocol = 0; e.protocol < CCS_SOCK_MAX; e.protocol++)
-		if (!strcmp(protocol, ccs_proto_keyword[e.protocol]))
-			break;
-	for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
-		if (ccs_permstr(operation, ccs_socket_keyword[type]))
-			e.perm |= 1 << type;
-	if (e.protocol == CCS_SOCK_MAX || !e.perm)
-		return -EINVAL;
-	if (!ccs_parse_name_union(param, &e.name))
-		return -EINVAL;
-	error = ccs_update_domain(&e.head, sizeof(e), param, ccs_same_unix_acl,
-				  ccs_merge_unix_acl);
-	ccs_put_name_union(&e.name);
-	return error;
-}
-
-/**
- * ccs_same_capability_acl - Check for duplicated "struct ccs_capability_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool ccs_same_capability_acl(const struct ccs_acl_info *a,
-				    const struct ccs_acl_info *b)
-{
-	const struct ccs_capability_acl *p1 = container_of(a, typeof(*p1),
-							   head);
-	const struct ccs_capability_acl *p2 = container_of(b, typeof(*p2),
-							   head);
-	return p1->operation == p2->operation;
-}
-
-/**
- * ccs_write_capability - Write "struct ccs_capability_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_capability(struct ccs_acl_param *param)
-{
-	struct ccs_capability_acl e = { .head.type = CCS_TYPE_CAPABILITY_ACL };
-	const char *operation = ccs_read_token(param);
-	for (e.operation = 0; e.operation < CCS_MAX_CAPABILITY_INDEX;
-	     e.operation++) {
-		if (strcmp(operation,
-			   ccs_mac_keywords[ccs_c2mac[e.operation]]))
-			continue;
-		return ccs_update_domain(&e.head, sizeof(e), param,
-					 ccs_same_capability_acl, NULL);
-	}
-	return -EINVAL;
-}
-
-/**
- * ccs_same_env_acl - Check for duplicated "struct ccs_env_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool ccs_same_env_acl(const struct ccs_acl_info *a,
-			     const struct ccs_acl_info *b)
-{
-	const struct ccs_env_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_env_acl *p2 = container_of(b, typeof(*p2), head);
-	return p1->env == p2->env;
-}
-
-/**
- * ccs_write_env - Write "struct ccs_env_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_env(struct ccs_acl_param *param)
-{
-	struct ccs_env_acl e = { .head.type = CCS_TYPE_ENV_ACL };
-	int error = -ENOMEM;
-	const char *data = ccs_read_token(param);
-	if (!ccs_correct_word(data) || strchr(data, '='))
-		return -EINVAL;
-	e.env = ccs_get_name(data);
-	error = ccs_update_domain(&e.head, sizeof(e), param,
-				  ccs_same_env_acl, NULL);
-	ccs_put_name(e.env);
-	return error;
-}
-
-/**
- * ccs_write_misc - Update environment variable list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_misc(struct ccs_acl_param *param)
-{
-	if (ccs_str_starts(param->data, "env "))
-		return ccs_write_env(param);
-	return -EINVAL;
-}
-
-/**
- * ccs_same_signal_acl - Check for duplicated "struct ccs_signal_acl" entry.
- *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool ccs_same_signal_acl(const struct ccs_acl_info *a,
-				const struct ccs_acl_info *b)
-{
-	const struct ccs_signal_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_signal_acl *p2 = container_of(b, typeof(*p2), head);
-	return ccs_same_number_union(&p1->sig, &p2->sig) &&
-		p1->domainname == p2->domainname;
-}
-
-/**
- * ccs_write_ipc - Update "struct ccs_signal_acl" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_ipc(struct ccs_acl_param *param)
-{
-	struct ccs_signal_acl e = { .head.type = CCS_TYPE_SIGNAL_ACL };
-	int error;
-	if (!ccs_parse_number_union(param, &e.sig))
-		return -EINVAL;
-	e.domainname = ccs_get_domainname(param);
-	if (!e.domainname)
-		error = -EINVAL;
-	else
-		error = ccs_update_domain(&e.head, sizeof(e), param,
-					  ccs_same_signal_acl, NULL);
-	ccs_put_name(e.domainname);
-	ccs_put_number_union(&e.sig);
-	return error;
-}
-
-
-/**
- * ccs_same_reserved - Check for duplicated "struct ccs_reserved" entry.
- *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
- *
- * Returns true if @a == @b, false otherwise.
- */
-static bool ccs_same_reserved(const struct ccs_acl_head *a,
-			      const struct ccs_acl_head *b)
-{
-	const struct ccs_reserved *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_reserved *p2 = container_of(b, typeof(*p2), head);
-	return p1->ns == p2->ns && ccs_same_number_union(&p1->port, &p2->port);
-}
-
-/**
- * ccs_write_reserved_port - Update "struct ccs_reserved" list.
- *
- * @param: Pointer to "struct ccs_acl_param".
- *
- * Returns 0 on success, negative value otherwise.
- */
-static int ccs_write_reserved_port(struct ccs_acl_param *param)
-{
-	struct ccs_reserved e = { .ns = param->ns };
-	int error;
-	if (param->data[0] == '@' || !ccs_parse_number_union(param, &e.port) ||
-	    e.port.values[1] > 65535 || param->data[0])
-		return -EINVAL;
-	param->list = &ccs_reserved_list;
-	error = ccs_update_policy(&e.head, sizeof(e), param,
-				  ccs_same_reserved);
-	/*
-	 * ccs_put_number_union() is not needed because param->data[0] != '@'.
-	 */
-	return error;
-}
-
-/**
  * ccs_print_namespace - Print namespace header.
  *
- * @ns: Pointer to "struct ccs_policy_namespace".
- *
  * Returns nothing.
  */
-static void ccs_print_namespace(const struct ccs_policy_namespace *ns)
+static void ccs_print_namespace(void)
 {
 	if (!ccs_namespace_enabled)
 		return;
-	cprintf("%s ", ns->name);
+	cprint(head.ns->name);
+	ccs_set_space();
 }
 
 /**
@@ -3423,12 +2526,10 @@
 	if (ptr)
 		return ptr;
 	ptr = ccs_malloc(sizeof(*ptr));
-	ptr->default_config = CCS_CONFIG_DISABLED |
+	ptr->default_config =
 		CCS_CONFIG_WANT_GRANT_LOG | CCS_CONFIG_WANT_REJECT_LOG;
-	memset(ptr->config, CCS_CONFIG_USE_DEFAULT,
-	       sizeof(ptr->config));
-	ptr->pref[CCS_PREF_MAX_AUDIT_LOG] = 1024;
-	ptr->pref[CCS_PREF_MAX_LEARNING_ENTRY] = 2048;
+	memset(ptr->config, CCS_CONFIG_USE_DEFAULT, sizeof(ptr->config));
+	ptr->pref[CCS_PREF_MAX_AUDIT_LOG] = 2048;
 	ns->profile_ptr[profile] = ptr;
 	return ptr;
 }
@@ -3471,6 +2572,66 @@
 }
 
 /**
+ * ccs_str_starts2 - Check whether the given string starts with the given keyword.
+ *
+ * @src:  Pointer to pointer to the string.
+ * @find: Pointer to the keyword.
+ *
+ * Returns true if @src starts with @find, false otherwise.
+ *
+ * The @src is updated to point the first character after the @find
+ * if @src starts with @find.
+ */
+static _Bool ccs_str_starts2(char **src, const char *find)
+{
+	const int len = strlen(find);
+	char *tmp = *src;
+	if (strncmp(tmp, find, len))
+		return false;
+	tmp += len;
+	*src = tmp;
+	return true;
+}
+
+/**
+ * ccs_group_type - Check whether the given string refers group or not.
+ *
+ * @src:  Pointer to pointer to the string.
+ *
+ * Returns 1 if @src refers a group in positive match, 2 if psrc refers a group
+ * in negative match, 0 otherwise.
+ *
+ * The @src is updated to point the first character of a group name if @src
+ * refers a group.
+ */
+static u8 ccs_group_type(char **src)
+{
+	if (ccs_str_starts2(src, "\\="))
+		return 1;
+	if (ccs_str_starts2(src, "\\!"))
+		return 2;
+	return 0;
+}
+
+/**
+ * ccs_print_group - Print group's name.
+ *
+ * @is_not: True if @group is negative match, false otherwise.
+ * @group:  Pointer to "struct ccsgroup". Maybe NULL.
+ *
+ * Returns true if @group is not NULL. false otherwise.
+ */
+static _Bool ccs_print_group(const _Bool is_not, const struct ccs_group *group)
+{
+	if (group) {
+		cprint(is_not ? "\\!" : "\\=");
+		cprint(group->group_name->name);
+		return true;
+	}
+	return false;
+}
+
+/**
  * ccs_set_mode - Set mode for specified profile.
  *
  * @name:    Name of functionality.
@@ -3487,7 +2648,7 @@
 	if (!strcmp(name, "CONFIG")) {
 		i = CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
 		config = profile->default_config;
-	} else if (ccs_str_starts(name, "CONFIG::")) {
+	} else if (ccs_str_starts2(&name, "CONFIG::")) {
 		config = 0;
 		for (i = 0; i < CCS_MAX_MAC_INDEX + CCS_MAX_MAC_CATEGORY_INDEX;
 		     i++) {
@@ -3555,7 +2716,7 @@
  */
 static int ccs_write_profile(void)
 {
-	char *data = head.data;
+	char *data = head.write_buf;
 	unsigned int i;
 	char *cp;
 	struct ccs_profile *profile;
@@ -3574,8 +2735,11 @@
 		return -EINVAL;
 	*cp++ = '\0';
 	if (!strcmp(data, "COMMENT")) {
-		const struct ccs_path_info *new_comment = ccs_get_name(cp);
-		const struct ccs_path_info *old_comment = profile->comment;
+		const struct ccs_path_info *new_comment = ccs_savename(cp);
+		const struct ccs_path_info *old_comment;
+		if (!new_comment)
+			return -ENOMEM;
+		old_comment = profile->comment;
 		profile->comment = new_comment;
 		ccs_put_name(old_comment);
 		return 0;
@@ -3613,37 +2777,39 @@
  */
 static void ccs_read_profile(void)
 {
-	struct ccs_policy_namespace *ns;
-	if (head.eof)
-		return;
-	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
+	list_for_each_entry(head.ns, &ccs_namespace_list, namespace_list) {
 		u16 index;
-		ccs_print_namespace(ns);
+		struct ccs_policy_namespace *ns = head.ns;
+		ccs_print_namespace();
 		cprintf("PROFILE_VERSION=%u\n", ns->profile_version);
 		for (index = 0; index < CCS_MAX_PROFILES; index++) {
 			u8 i;
+			const struct ccs_path_info *comment;
 			const struct ccs_profile *profile =
 				ns->profile_ptr[index];
 			if (!profile)
 				continue;
-			ccs_print_namespace(ns);
-			cprintf("%u-COMMENT=%s\n", index, profile->comment ?
-				profile->comment->name : "");
-			ccs_print_namespace(ns);
+			comment = profile->comment;
+			ccs_print_namespace();
+			cprintf("%u-COMMENT=", index);
+			if (comment)
+				cprint(comment->name);
+			ccs_set_lf();
+			ccs_print_namespace();
 			cprintf("%u-PREFERENCE={ ", index);
 			for (i = 0; i < CCS_MAX_PREF; i++)
 				cprintf("%s=%u ", ccs_pref_keywords[i],
 					profile->pref[i]);
-			cprintf("}\n");
-			ccs_print_namespace(ns);
-			cprintf("%u-CONFIG", index);
+			cprint("}\n");
+			ccs_print_namespace();
+			cprintf("%u-%s", index, "CONFIG");
 			ccs_print_config(profile->default_config);
-			for (i = 0; i < CCS_MAX_MAC_INDEX
-				     + CCS_MAX_MAC_CATEGORY_INDEX; i++) {
+			for (i = 0; i < CCS_MAX_MAC_INDEX +
+				     CCS_MAX_MAC_CATEGORY_INDEX; i++) {
 				const u8 config = profile->config[i];
 				if (config == CCS_CONFIG_USE_DEFAULT)
 					continue;
-				ccs_print_namespace(ns);
+				ccs_print_namespace();
 				if (i < CCS_MAX_MAC_INDEX)
 					cprintf("%u-CONFIG::%s::%s", index,
 						ccs_category_keywords
@@ -3656,22 +2822,39 @@
 			}
 		}
 	}
-	head.eof = true;
 }
 
 /**
- * ccs_same_manager - Check for duplicated "struct ccs_manager" entry.
+ * ccs_update_policy - Update an entry for exception policy.
  *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
+ * @size:  Size of new entry in bytes.
+ * @param: Pointer to "struct ccs_acl_param".
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
-static bool ccs_same_manager(const struct ccs_acl_head *a,
-			     const struct ccs_acl_head *b)
+static int ccs_update_policy(const int size, struct ccs_acl_param *param)
 {
-	return container_of(a, struct ccs_manager, head)->manager
-		== container_of(b, struct ccs_manager, head)->manager;
+	struct ccs_acl_head *new_entry = &param->e.acl_head;
+	int error = param->is_delete ? -ENOENT : -ENOMEM;
+	struct ccs_acl_head *entry;
+	struct list_head *list = param->list;
+	list_for_each_entry(entry, list, list) {
+		if (memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
+			continue;
+		entry->is_deleted = param->is_delete;
+		error = 0;
+		break;
+	}
+	if (error && !param->is_delete) {
+		entry = ccs_commit_ok(new_entry, size);
+		if (entry) {
+			list_add_tail(&entry->list, list);
+			error = 0;
+		}
+	}
+	return error;
 }
 
 /**
@@ -3682,27 +2865,31 @@
  *
  * Returns 0 on success, negative value otherwise.
  */
-static inline int ccs_update_manager_entry(const char *manager,
-					   const bool is_delete)
+static int ccs_update_manager_entry(const char *manager,
+				    const _Bool is_delete)
 {
-	struct ccs_manager e = { };
 	struct ccs_acl_param param = {
+		/* .ns = &ccs_kernel_namespace, */
 		.is_delete = is_delete,
 		.list = &ccs_manager_list,
 	};
+	struct ccs_manager *e = &param.e.manager;
 	int error = is_delete ? -ENOENT : -ENOMEM;
+	/* Forced zero clear for using memcmp() at ccs_update_policy(). */
+	memset(&param.e, 0, sizeof(param.e));
 	if (ccs_domain_def(manager)) {
 		if (!ccs_correct_domain(manager))
 			return -EINVAL;
-		e.is_domain = true;
+		e->is_domain = true;
 	} else {
 		if (!ccs_correct_path(manager))
 			return -EINVAL;
 	}
-	e.manager = ccs_get_name(manager);
-	error = ccs_update_policy(&e.head, sizeof(e), &param,
-				  ccs_same_manager);
-	ccs_put_name(e.manager);
+	e->manager = ccs_savename(manager);
+	if (e->manager) {
+		error = ccs_update_policy(sizeof(*e), &param);
+		ccs_put_name(e->manager);
+	}
 	return error;
 }
 
@@ -3713,146 +2900,494 @@
  */
 static int ccs_write_manager(void)
 {
-	return ccs_update_manager_entry(head.data, head.is_delete);
+	const char *data = head.write_buf;
+	return ccs_update_manager_entry(data, head.is_delete);
 }
 
 /**
  * ccs_read_manager - Read manager policy.
  *
  * Returns nothing.
+ *
+ * Caller holds ccs_read_lock().
  */
 static void ccs_read_manager(void)
 {
 	struct ccs_manager *ptr;
-	if (head.eof)
-		return;
-	list_for_each_entry(ptr, &ccs_manager_list, head.list)
-		if (!ptr->head.is_deleted)
-			cprintf("%s\n", ptr->manager->name);
-	head.eof = true;
+	list_for_each_entry(ptr, &ccs_manager_list, head.list) {
+		if (ptr->head.is_deleted)
+			continue;
+		cprint(ptr->manager->name);
+		ccs_set_lf();
+	}
 }
 
 /**
+ * ccs_find_domain4 - Find a domain by the given name.
+ *
+ * @domainname: The domainname to find.
+ *
+ * Returns pointer to "struct ccs_domain_info4" if found, NULL otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static struct ccs_domain_info4 *ccs_find_domain4(const char *domainname)
+{
+	struct ccs_domain_info4 *domain;
+	struct ccs_path_info name;
+	name.name = domainname;
+	ccs_fill_path_info(&name);
+	list_for_each_entry(domain, &ccs_domain_list, list) {
+		if (!domain->is_deleted &&
+		    !ccs_pathcmp(&name, domain->domainname))
+			return domain;
+	}
+	return NULL;
+}
+
+/**
  * ccs_select_domain - Parse select command.
  *
  * @data: String to parse.
  *
  * Returns true on success, false otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
-static bool ccs_select_domain(const char *data)
+static _Bool ccs_select_domain(const char *data)
 {
-	struct ccs_domain2_info *domain = NULL;
+	struct ccs_domain_info4 *domain = NULL;
 	if (strncmp(data, "select ", 7))
 		return false;
 	data += 7;
 	if (!strncmp(data, "domain=", 7)) {
 		if (*(data + 7) == '<')
-			domain = ccs_find_domain2(data + 7);
+			domain = ccs_find_domain4(data + 7);
 	} else
 		return false;
-	if (domain) {
-		head.domain = domain;
-		head.print_this_domain_only = domain;
-	} else
-		head.eof = true;
-	cprintf("# select %s\n", data);
+	head.domain = domain;
+	head.print_this_domain_only = true;
 	return true;
 }
 
 /**
- * ccs_same_handler_acl - Check for duplicated "struct ccs_handler_acl" entry.
+ * ccs_update_inverse_list - Update an entry for domain policy.
  *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
+ * @new_entry: Pointer to "struct ccs_acl_info".
+ * @size:      Size of @new_entry in bytes.
+ * @param:     Pointer to "struct ccs_acl_param".
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
-static bool ccs_same_handler_acl(const struct ccs_acl_info *a,
-				 const struct ccs_acl_info *b)
+static int ccs_update_inverse_list(struct ccs_acl_info *new_entry,
+				   const int size, struct ccs_acl_param *param)
 {
-	const struct ccs_handler_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_handler_acl *p2 = container_of(b, typeof(*p2), head);
-	return p1->handler == p2->handler;
+	const _Bool is_delete = param->is_delete;
+	struct ccs_acl_info *entry;
+	list_for_each_entry(entry, &ccs_inversed_acl_list, list) {
+		if (entry->perm != new_entry->perm ||
+		    entry->type != new_entry->type ||
+		    entry->cond != new_entry->cond ||
+		    memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
+			continue;
+		entry->is_deleted = is_delete;
+		param->matched_entry = entry;
+		return 0;
+	}
+	if (is_delete)
+		return -ENOENT;
+	entry = ccs_commit_ok(new_entry, size);
+	if (!entry)
+		return -ENOMEM;
+	INIT_LIST_HEAD(&entry->domain_list);
+	list_add_tail(&entry->list, &ccs_inversed_acl_list);
+	param->matched_entry = entry;
+	return 0;
 }
 
 /**
- * ccs_same_task_acl - Check for duplicated "struct ccs_task_acl" entry.
+ * ccs_update_acl - Update "struct ccs_acl_info" entry.
  *
- * @a: Pointer to "struct ccs_acl_info".
- * @b: Pointer to "struct ccs_acl_info".
+ * @size:  Size of new entry in bytes.
+ * @param: Pointer to "struct ccs_acl_param".
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
-static bool ccs_same_task_acl(const struct ccs_acl_info *a,
-			      const struct ccs_acl_info *b)
+static int ccs_update_acl(const int size, struct ccs_acl_param *param)
 {
-	const struct ccs_task_acl *p1 = container_of(a, typeof(*p1), head);
-	const struct ccs_task_acl *p2 = container_of(b, typeof(*p2), head);
-	return p1->domainname == p2->domainname;
+	struct ccs_acl_info *new_entry = &param->e.acl_info;
+	const _Bool is_delete = param->is_delete;
+	int error = is_delete ? -ENOENT : -ENOMEM;
+	struct ccs_acl_info *entry;
+	struct list_head * const list = param->list;
+	if (param->data[0]) {
+		new_entry->cond = ccs_get_condition(param);
+		if (!new_entry->cond)
+			return -EINVAL;
+	}
+	if (!list)
+		return ccs_update_inverse_list(new_entry, size, param);
+	list_for_each_entry(entry, list, list) {
+		if (entry->type != new_entry->type ||
+		    entry->cond != new_entry->cond ||
+		    memcmp(entry + 1, new_entry + 1, size - sizeof(*entry)))
+			continue;
+		if (is_delete)
+			entry->perm &= ~new_entry->perm;
+		else
+			entry->perm |= new_entry->perm;
+		entry->is_deleted = !entry->perm;
+		error = 0;
+		break;
+	}
+	if (error && !is_delete) {
+		entry = ccs_commit_ok(new_entry, size);
+		if (entry) {
+			list_add_tail(&entry->list, list);
+			error = 0;
+		}
+	}
+	return error;
 }
 
 /**
+ * ccs_permstr - Find permission keywords.
+ *
+ * @string: String representation for permissions in foo/bar/buz format.
+ * @keyword: Keyword to find from @string/
+ *
+ * Returns ture if @keyword was found in @string, false otherwise.
+ *
+ * This function assumes that strncmp(w1, w2, strlen(w1)) != 0 if w1 != w2.
+ */
+static _Bool ccs_permstr(const char *string, const char *keyword)
+{
+	const char *cp = strstr(string, keyword);
+	if (cp)
+		return cp == string || *(cp - 1) == '/';
+	return false;
+}
+
+/**
  * ccs_write_task - Update task related list.
  *
  * @param: Pointer to "struct ccs_acl_param".
  *
  * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
 static int ccs_write_task(struct ccs_acl_param *param)
 {
 	int error;
-	const bool is_auto = ccs_str_starts(param->data,
+	const _Bool is_auto = ccs_str_starts2(&param->data,
 					    "auto_domain_transition ");
-	if (!is_auto && !ccs_str_starts(param->data,
+	if (!is_auto && !ccs_str_starts2(&param->data,
 					"manual_domain_transition ")) {
-		struct ccs_handler_acl e = { };
+		struct ccs_handler_acl *e = &param->e.handler_acl;
 		char *handler;
-		if (ccs_str_starts(param->data, "auto_execute_handler "))
-			e.head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
-		else if (ccs_str_starts(param->data,
+		if (ccs_str_starts2(&param->data, "auto_execute_handler "))
+			e->head.type = CCS_TYPE_AUTO_EXECUTE_HANDLER;
+		else if (ccs_str_starts2(&param->data,
 					"denied_execute_handler "))
-			e.head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
+			e->head.type = CCS_TYPE_DENIED_EXECUTE_HANDLER;
 		else
 			return -EINVAL;
 		handler = ccs_read_token(param);
 		if (!ccs_correct_path(handler))
 			return -EINVAL;
-		e.handler = ccs_get_name(handler);
-		if (e.handler->is_patterned)
-			error = -EINVAL; /* No patterns allowed. */
-		else
-			error = ccs_update_domain(&e.head, sizeof(e), param,
-						  ccs_same_handler_acl, NULL);
-		ccs_put_name(e.handler);
+		e->handler = ccs_savename(handler);
+		if (!e->handler)
+			return -ENOMEM;
+		if (e->handler->is_patterned)
+			return -EINVAL; /* No patterns allowed. */
+		return ccs_update_acl(sizeof(*e), param);
 	} else {
-		struct ccs_task_acl e = {
-			.head.type = is_auto ?
-			CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL,
-			.domainname = ccs_get_domainname(param),
-		};
-		if (!e.domainname)
-			error = -EINVAL;
-		else
-			error = ccs_update_domain(&e.head, sizeof(e), param,
-						  ccs_same_task_acl, NULL);
-		ccs_put_name(e.domainname);
+		struct ccs_task_acl *e = &param->e.task_acl;
+		e->head.type = is_auto ?
+			CCS_TYPE_AUTO_TASK_ACL : CCS_TYPE_MANUAL_TASK_ACL;
+		e->domainname = ccs_get_domainname(param);
+		if (!e->domainname)
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
 	}
 	return error;
 }
 
 /**
- * ccs_write_domain2 - Write domain policy.
+ * ccs_write_inet_network - Write "struct ccs_inet_acl" list.
  *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_write_inet_network(struct ccs_acl_param *param)
+{
+	struct ccs_inet_acl *e = &param->e.inet_acl;
+	u8 type;
+	const char *protocol = ccs_read_token(param);
+	const char *operation = ccs_read_token(param);
+	e->head.type = CCS_TYPE_INET_ACL;
+	for (type = 0; type < CCS_SOCK_MAX; type++)
+		if (!strcmp(protocol, ccs_proto_keyword[type]))
+			break;
+	if (type == CCS_SOCK_MAX)
+		return -EINVAL;
+	e->protocol = type;
+	e->head.perm = 0;
+	for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
+		if (ccs_permstr(operation, ccs_socket_keyword[type]))
+			e->head.perm |= 1 << type;
+	if (!e->head.perm)
+		return -EINVAL;
+	if (!ccs_parse_ipaddr_union(param, &e->address))
+		return -EINVAL;
+	if (!ccs_parse_number_union(param, &e->port) ||
+	    e->port.values[1] > 65535)
+		return -EINVAL;
+	return ccs_update_acl(sizeof(*e), param);
+}
+
+/**
+ * ccs_write_unix_network - Write "struct ccs_unix_acl" list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int ccs_write_unix_network(struct ccs_acl_param *param)
+{
+	struct ccs_unix_acl *e = &param->e.unix_acl;
+	u8 type;
+	const char *protocol = ccs_read_token(param);
+	const char *operation = ccs_read_token(param);
+	e->head.type = CCS_TYPE_UNIX_ACL;
+	for (type = 0; type < CCS_SOCK_MAX; type++)
+		if (!strcmp(protocol, ccs_proto_keyword[type]))
+			break;
+	if (type == CCS_SOCK_MAX)
+		return -EINVAL;
+	e->protocol = type;
+	e->head.perm = 0;
+	for (type = 0; type < CCS_MAX_NETWORK_OPERATION; type++)
+		if (ccs_permstr(operation, ccs_socket_keyword[type]))
+			e->head.perm |= 1 << type;
+	if (!e->head.perm)
+		return -EINVAL;
+	if (!ccs_parse_name_union(param, &e->name))
+		return -EINVAL;
+	return ccs_update_acl(sizeof(*e), param);
+}
+
+/**
+ * ccs_update_execute_acl - Update execute entry.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_update_execute_acl(struct ccs_acl_param *param)
+{
+	struct ccs_execute_acl *e = &param->e.execute_acl;
+	e->head.type = CCS_TYPE_EXECUTE_ACL;
+	e->head.perm = 1;
+	if (!ccs_parse_name_union(param, &e->program))
+		return -EINVAL;
+	param->data = ccs_get_transit_preference(param, e);
+	if (!param->data)
+		return -EINVAL;
+	return ccs_update_acl(sizeof(*e), param);
+}
+
+/**
+ * ccs_write_file - Update file related list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_write_file(struct ccs_acl_param *param)
+{
+	u16 perm = 0;
+	u8 type;
+	const char *operation = ccs_read_token(param);
+	if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_EXECUTE]))
+		return ccs_update_execute_acl(param);
+	for (type = 0; type < CCS_MAX_PATH_OPERATION; type++)
+		if (ccs_permstr(operation, ccs_mac_keywords[ccs_p2mac[type]]))
+			perm |= 1 << type;
+	if (perm) {
+		struct ccs_path_acl *e = &param->e.path_acl;
+		e->head.type = CCS_TYPE_PATH_ACL;
+		e->head.perm = perm;
+		if (!ccs_parse_name_union(param, &e->name))
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	for (type = 0; type < CCS_MAX_PATH2_OPERATION; type++)
+		if (ccs_permstr(operation, ccs_mac_keywords[ccs_pp2mac[type]]))
+			perm |= 1 << type;
+	if (perm) {
+		struct ccs_path2_acl *e = &param->e.path2_acl;
+		e->head.type = CCS_TYPE_PATH2_ACL;
+		e->head.perm = perm;
+		if (!ccs_parse_name_union(param, &e->name1) ||
+		    !ccs_parse_name_union(param, &e->name2))
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	for (type = 0; type < CCS_MAX_PATH_NUMBER_OPERATION; type++)
+		if (ccs_permstr(operation, ccs_mac_keywords[ccs_pn2mac[type]]))
+			perm |= 1 << type;
+	if (perm) {
+		struct ccs_path_number_acl *e = &param->e.path_number_acl;
+		e->head.type = CCS_TYPE_PATH_NUMBER_ACL;
+		e->head.perm = perm;
+		if (!ccs_parse_name_union(param, &e->name) ||
+		    !ccs_parse_number_union(param, &e->number))
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	for (type = 0; type < CCS_MAX_MKDEV_OPERATION; type++)
+		if (ccs_permstr(operation,
+				ccs_mac_keywords[ccs_pnnn2mac[type]]))
+			perm |= 1 << type;
+	if (perm) {
+		struct ccs_mkdev_acl *e = &param->e.mkdev_acl;
+		e->head.type = CCS_TYPE_MKDEV_ACL;
+		e->head.perm = perm;
+		if (!ccs_parse_name_union(param, &e->name) ||
+		    !ccs_parse_number_union(param, &e->mode) ||
+		    !ccs_parse_number_union(param, &e->major) ||
+		    !ccs_parse_number_union(param, &e->minor))
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	if (ccs_permstr(operation, ccs_mac_keywords[CCS_MAC_FILE_MOUNT])) {
+		struct ccs_mount_acl *e = &param->e.mount_acl;
+		e->head.type = CCS_TYPE_MOUNT_ACL;
+		if (!ccs_parse_name_union(param, &e->dev_name) ||
+		    !ccs_parse_name_union(param, &e->dir_name) ||
+		    !ccs_parse_name_union(param, &e->fs_type) ||
+		    !ccs_parse_number_union(param, &e->flags))
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	return -EINVAL;
+}
+
+/**
+ * ccs_write_misc - Update environment variable list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int ccs_write_misc(struct ccs_acl_param *param)
+{
+	if (ccs_str_starts2(&param->data, "env ")) {
+		struct ccs_env_acl *e = &param->e.env_acl;
+		e->head.type = CCS_TYPE_ENV_ACL;
+		if (!ccs_parse_name_union(param, &e->env))
+			return -EINVAL;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	return -EINVAL;
+}
+
+/**
+ * ccs_write_ipc - Update "struct ccs_ptrace_acl" list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ */
+static int ccs_write_ipc(struct ccs_acl_param *param)
+{
+	struct ccs_ptrace_acl *e = &param->e.ptrace_acl;
+	e->head.type = CCS_TYPE_PTRACE_ACL;
+	if (!ccs_parse_number_union(param, &e->request))
+		return -EINVAL;
+	e->domainname = ccs_get_domainname(param);
+	if (!e->domainname)
+		return -EINVAL;
+	return ccs_update_acl(sizeof(*e), param);
+}
+
+/**
+ * ccs_write_capability - Write "struct ccs_capability_acl" list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_write_capability(struct ccs_acl_param *param)
+{
+	struct ccs_capability_acl *e = &param->e.capability_acl;
+	const char *operation = ccs_read_token(param);
+	u8 type;
+	e->head.type = CCS_TYPE_CAPABILITY_ACL;
+	for (type = 0; type < CCS_MAX_CAPABILITY_INDEX; type++) {
+		if (strcmp(operation, ccs_mac_keywords[ccs_c2mac[type]]))
+			continue;
+		e->operation = type;
+		return ccs_update_acl(sizeof(*e), param);
+	}
+	return -EINVAL;
+}
+
+/**
+ * ccs_write_use_group_acl - Write "struct ccs_use_group_acl" list.
+ *
+ * @param: Pointer to "struct ccs_acl_param".
+ *
+ * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static int ccs_write_use_group_acl(struct ccs_acl_param *param)
+{
+	struct ccs_use_group_acl *e = &param->e.use_group_acl;
+	e->head.type = CCS_TYPE_USE_GROUP_ACL;
+	switch (ccs_group_type(&param->data)) {
+	case 2:
+		e->is_not = true;
+		/* fall through */
+	case 1:
+		e->group = ccs_get_group(param, CCS_ACL_GROUP);
+		if (e->group)
+			return ccs_update_acl(sizeof(*e), param);
+	}
+	return -EINVAL;
+}
+
+/**
+ * ccs_write_acl - Write "struct ccs_acl_info" list.
+ *
  * @ns:        Pointer to "struct ccs_policy_namespace".
  * @list:      Pointer to "struct list_head".
  * @data:      Policy to be interpreted.
  * @is_delete: True if it is a delete request.
  *
  * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
-static int ccs_write_domain2(struct ccs_policy_namespace *ns,
-			     struct list_head *list, char *data,
-			     const bool is_delete)
+static int ccs_write_acl(struct ccs_policy_namespace *ns,
+			 struct list_head *list, char *data,
+			 const _Bool is_delete)
 {
 	struct ccs_acl_param param = {
 		.ns = ns,
@@ -3863,18 +3398,22 @@
 	static const struct {
 		const char *keyword;
 		int (*write) (struct ccs_acl_param *);
-	} ccs_callback[7] = {
+	} ccs_callback[] = {
 		{ "file ", ccs_write_file },
 		{ "network inet ", ccs_write_inet_network },
 		{ "network unix ", ccs_write_unix_network },
 		{ "misc ", ccs_write_misc },
 		{ "capability ", ccs_write_capability },
-		{ "ipc signal ", ccs_write_ipc },
+		{ "ipc ptrace ", ccs_write_ipc },
 		{ "task ", ccs_write_task },
+		{ "use_group ", ccs_write_use_group_acl },
 	};
 	u8 i;
-	for (i = 0; i < 7; i++) {
-		if (!ccs_str_starts(param.data, ccs_callback[i].keyword))
+	/* Forced zero clear for using memcmp() at ccs_update_acl(). */
+	memset(&param.e, 0, sizeof(param.e));
+	param.e.acl_info.perm = 1;
+	for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
+		if (!ccs_str_starts2(&param.data, ccs_callback[i].keyword))
 			continue;
 		return ccs_callback[i].write(&param);
 	}
@@ -3882,21 +3421,28 @@
 }
 
 /**
- * ccs_delete_domain2 - Delete a domain from domain policy.
+ * ccs_delete_domain4 - Delete a domain.
  *
- * @domainname: Name of domain.
+ * @domainname: The name of domain.
  *
  * Returns nothing.
  */
-static void ccs_delete_domain2(const char *domainname)
+static void ccs_delete_domain4(char *domainname)
 {
-	struct ccs_domain2_info *domain;
+	struct ccs_domain_info4 *domain;
+	struct ccs_path_info name;
+	name.name = domainname;
+	ccs_fill_path_info(&name);
+	/* Is there an active domain? */
 	list_for_each_entry(domain, &ccs_domain_list, list) {
+		/* Never delete ccs_kernel_domain. */
 		if (domain == &ccs_kernel_domain)
 			continue;
-		if (strcmp(domain->domainname->name, domainname))
+		if (domain->is_deleted ||
+		    ccs_pathcmp(domain->domainname, &name))
 			continue;
 		domain->is_deleted = true;
+		break;
 	}
 }
 
@@ -3904,31 +3450,32 @@
  * ccs_write_domain - Write domain policy.
  *
  * Returns 0 on success, negative value otherwise.
+ *
+ * Caller holds ccs_read_lock().
  */
 static int ccs_write_domain(void)
 {
-	char *data = head.data;
+	char *data = head.write_buf;
 	struct ccs_policy_namespace *ns;
-	struct ccs_domain2_info *domain = head.domain;
-	const bool is_delete = head.is_delete;
-	const bool is_select = !is_delete && ccs_str_starts(data, "select ");
+	struct ccs_domain_info4 *domain = head.domain;
+	const _Bool is_delete = head.is_delete;
+	const _Bool is_select = !is_delete &&
+		ccs_str_starts2(&data, "select ");
 	unsigned int profile;
 	if (*data == '<') {
 		domain = NULL;
 		if (is_delete)
-			ccs_delete_domain2(data);
+			ccs_delete_domain4(data);
 		else if (is_select)
-			domain = ccs_find_domain2(data);
+			domain = ccs_find_domain4(data);
 		else
-			domain = ccs_assign_domain2(data);
+			domain = ccs_assign_domain4(data);
 		head.domain = domain;
 		return 0;
 	}
 	if (!domain)
 		return -EINVAL;
-	ns = ccs_assign_namespace(domain->domainname->name);
-	if (!ns)
-		return -EINVAL;
+	ns = domain->ns;
 	if (sscanf(data, "use_profile %u\n", &profile) == 1
 	    && profile < CCS_MAX_PROFILES) {
 		if (ns->profile_ptr[(u8) profile])
@@ -3936,20 +3483,27 @@
 				domain->profile = (u8) profile;
 		return 0;
 	}
-	if (sscanf(data, "use_group %u\n", &profile) == 1
-	    && profile < CCS_MAX_ACL_GROUPS) {
-		if (!is_delete)
-			domain->group = (u8) profile;
+	if (ccs_str_starts2(&data, "default_transition ")) {
+		const struct ccs_path_info *new_transition = NULL;
+		const struct ccs_path_info *old_transition;
+		if (is_delete)
+			return 0;
+		if (ccs_correct_domain(data) || ccs_correct_path(data) ||
+		    !strcmp(data, "keep") || !strcmp(data, "child"))
+			new_transition = ccs_savename(data);
+		if (!new_transition)
+			return -EINVAL;
+		old_transition = domain->default_transition;
+		domain->default_transition = new_transition;
+		ccs_put_name(old_transition);
 		return 0;
 	}
-	for (profile = 0; profile < CCS_MAX_DOMAIN_INFO_FLAGS; profile++) {
-		const char *cp = ccs_dif[profile];
-		if (strncmp(data, cp, strlen(cp) - 1))
-			continue;
-		domain->flags[profile] = !is_delete;
+	if (!strncmp(data, CCS_QUOTA_EXCEEDED,
+		     sizeof(CCS_QUOTA_EXCEEDED) - 2)) {
+		domain->quota_exceeded = !is_delete;
 		return 0;
 	}
-	return ccs_write_domain2(ns, &domain->acl_info_list, data, is_delete);
+	return ccs_write_acl(ns, &domain->acl_info_list, data, is_delete);
 }
 
 /**
@@ -3961,25 +3515,25 @@
  */
 static void ccs_print_name_union(const struct ccs_name_union *ptr)
 {
-	if (ptr->group)
-		cprintf(" @%s", ptr->group->group_name->name);
-	else
-		cprintf(" %s", ptr->filename->name);
+	ccs_set_space();
+	if (!ccs_print_group(ptr->is_not, ptr->group))
+		cprint(ptr->filename->name);
 }
 
 /**
  * ccs_print_name_union_quoted - Print a ccs_name_union with a quote.
  *
- * @ptr: Pointer to "struct ccs_name_union".
+ * @ptr:  Pointer to "struct ccs_name_union".
  *
  * Returns nothing.
  */
 static void ccs_print_name_union_quoted(const struct ccs_name_union *ptr)
 {
-	if (ptr->group)
-		cprintf("@%s", ptr->group->group_name->name);
-	else
-		cprintf("\"%s\"", ptr->filename->name);
+	if (!ccs_print_group(ptr->is_not, ptr->group)) {
+		cprint("\"");
+		cprint(ptr->filename->name);
+		cprint("\"");
+	}
 }
 
 /**
@@ -3991,9 +3545,7 @@
  */
 static void ccs_print_number_union_nospace(const struct ccs_number_union *ptr)
 {
-	if (ptr->group) {
-		cprintf("@%s", ptr->group->group_name->name);
-	} else {
+	if (!ccs_print_group(ptr->is_not, ptr->group)) {
 		int i;
 		unsigned long min = ptr->values[0];
 		const unsigned long max = ptr->values[1];
@@ -4023,13 +3575,13 @@
 /**
  * ccs_print_number_union - Print a ccs_number_union.
  *
- * @ptr: Pointer to "struct ccs_number_union".
+ * @ptr:  Pointer to "struct ccs_number_union".
  *
  * Returns nothing.
  */
 static void ccs_print_number_union(const struct ccs_number_union *ptr)
 {
-	cprintf(" ");
+	ccs_set_space();
 	ccs_print_number_union_nospace(ptr);
 }
 
@@ -4038,10 +3590,11 @@
  *
  * @cond: Pointer to "struct ccs_condition".
  *
- * Returns true on success, false otherwise.
+ * Returns nothing.
  */
 static void ccs_print_condition(const struct ccs_condition *cond)
 {
+	u16 i;
 	const u16 condc = cond->condc;
 	const struct ccs_condition_element *condp = (typeof(condp)) (cond + 1);
 	const struct ccs_number_union *numbers_p =
@@ -4051,15 +3604,12 @@
 	const struct ccs_argv *argv =
 		(typeof(argv)) (names_p + cond->names_count);
 	const struct ccs_envp *envp = (typeof(envp)) (argv + cond->argc);
-	u16 i;
-	if (cond->transit && cond->exec_transit)
-		cprintf(" %s", cond->transit->name);
 	for (i = 0; i < condc; i++) {
 		const u8 match = condp->equals;
 		const u8 left = condp->left;
 		const u8 right = condp->right;
 		condp++;
-		cprintf(" ");
+		ccs_set_space();
 		switch (left) {
 		case CCS_ARGV_ENTRY:
 			cprintf("exec.argv[%lu]%s=\"%s\"", argv->index,
@@ -4067,22 +3617,22 @@
 			argv++;
 			continue;
 		case CCS_ENVP_ENTRY:
-			cprintf("exec.envp[\"%s\"]%s=",
-				envp->name->name, envp->is_not ? "!" : "");
+			cprintf("exec.envp[\"%s\"]%s=", envp->name->name,
+				envp->is_not ? "!" : "");
 			if (envp->value)
 				cprintf("\"%s\"", envp->value->name);
 			else
-				cprintf("NULL");
+				cprint("NULL");
 			envp++;
 			continue;
 		case CCS_NUMBER_UNION:
 			ccs_print_number_union_nospace(numbers_p++);
 			break;
 		default:
-			cprintf("%s", ccs_condition_keyword[left]);
+			cprint(ccs_condition_keyword[left]);
 			break;
 		}
-		cprintf("%s", match ? "=" : "!=");
+		cprint(match ? "=" : "!=");
 		switch (right) {
 		case CCS_NAME_UNION:
 			ccs_print_name_union_quoted(names_p++);
@@ -4091,16 +3641,13 @@
 			ccs_print_number_union_nospace(numbers_p++);
 			break;
 		default:
-			cprintf("%s", ccs_condition_keyword[right]);
+			cprint(ccs_condition_keyword[right]);
 			break;
 		}
 	}
 	if (cond->grant_log != CCS_GRANTLOG_AUTO)
-		cprintf(" grant_log=%s",
-			ccs_yesno(cond->grant_log == CCS_GRANTLOG_YES));
-	if (cond->transit && !cond->exec_transit)
-		cprintf(" auto_domain_transition=\"%s\"",
-			cond->transit->name);
+		cprintf(" grant_log=%s", ccs_yesno(cond->grant_log ==
+						   CCS_GRANTLOG_YES));
 }
 
 /**
@@ -4112,11 +3659,15 @@
  */
 static void ccs_set_group(const char *category)
 {
-	if (head.type == CCS_EXCEPTIONPOLICY) {
-		ccs_print_namespace(head.ns);
-		cprintf("acl_group %u ", head.acl_group_index);
+	if (head.type == CCS_EXCEPTION_POLICY) {
+		ccs_print_namespace();
+		cprint("acl_group ");
+		cprint(head.acl_group_name->name);
+		ccs_set_space();
+	} else if (head.type == CCS_ACL_POLICY) {
+		cprint("allow ");
 	}
-	cprintf("%s", category);
+	cprint(category);
 }
 
 /**
@@ -4129,66 +3680,85 @@
 static void ccs_print_entry(const struct ccs_acl_info *acl)
 {
 	const u8 acl_type = acl->type;
-	const bool may_trigger_transition = acl->cond && acl->cond->transit;
-	bool first = true;
+	_Bool first = true;
 	u8 bit;
 	if (acl->is_deleted)
 		return;
-	if (acl_type == CCS_TYPE_PATH_ACL) {
-		struct ccs_path_acl *ptr
+	else if (acl_type == CCS_TYPE_EXECUTE_ACL) {
+		struct ccs_execute_acl *ptr
 			= container_of(acl, typeof(*ptr), head);
-		const u16 perm = ptr->perm;
-		for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
-			if (!(perm & (1 << bit)))
-				continue;
-			if (head.print_transition_related_only &&
-			    bit != CCS_TYPE_EXECUTE && !may_trigger_transition)
-				continue;
-			if (first) {
-				ccs_set_group("file ");
-				first = false;
-			} else {
-				cprintf("/");
-			}
-			cprintf("%s", ccs_path_keyword[bit]);
+		if (head.print_default_transition) {
+			ccs_print_namespace();
+			cprint("default_transition");
+		} else {
+			ccs_set_group("file ");
+			cprint("execute");
 		}
-		if (first)
-			return;
-		ccs_print_name_union(&ptr->name);
+		ccs_print_name_union(&ptr->program);
+		if (ptr->transit) {
+			ccs_set_space();
+			cprint(ptr->transit->name);
+		}
 	} else if (acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ||
 		   acl_type == CCS_TYPE_DENIED_EXECUTE_HANDLER) {
 		struct ccs_handler_acl *ptr
 			= container_of(acl, typeof(*ptr), head);
 		ccs_set_group("task ");
-		cprintf(acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER ?
-			"auto_execute_handler " : "denied_execute_handler ");
-		cprintf("%s", ptr->handler->name);
+		cprint(acl_type == CCS_TYPE_AUTO_EXECUTE_HANDLER
+			       ? "auto_execute_handler " :
+			       "denied_execute_handler ");
+		cprint(ptr->handler->name);
+		if (ptr->transit) {
+			ccs_set_space();
+			cprint(ptr->transit->name);
+		}
 	} else if (acl_type == CCS_TYPE_AUTO_TASK_ACL ||
 		   acl_type == CCS_TYPE_MANUAL_TASK_ACL) {
 		struct ccs_task_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
 		ccs_set_group("task ");
-		cprintf(acl_type == CCS_TYPE_AUTO_TASK_ACL ?
-			"auto_domain_transition " :
-			"manual_domain_transition ");
-		cprintf("%s", ptr->domainname->name);
-	} else if (head.print_transition_related_only &&
-		   !may_trigger_transition) {
+		cprint(acl_type == CCS_TYPE_AUTO_TASK_ACL ?
+			       "auto_domain_transition " :
+			       "manual_domain_transition ");
+		cprint(ptr->domainname->name);
+	} else if (acl_type == CCS_TYPE_USE_GROUP_ACL) {
+		struct ccs_use_group_acl *ptr =
+			container_of(acl, typeof(*ptr), head);
+		ccs_set_group("use_group ");
+		ccs_print_group(ptr->is_not, ptr->group);
+	} else if (head.print_transition_related_only) {
 		return;
+	} else if (acl_type == CCS_TYPE_PATH_ACL) {
+		struct ccs_path_acl *ptr
+			= container_of(acl, typeof(*ptr), head);
+		for (bit = 0; bit < CCS_MAX_PATH_OPERATION; bit++) {
+			if (!(acl->perm & (1 << bit)))
+				continue;
+			if (first) {
+				ccs_set_group("file ");
+				first = false;
+			} else {
+				ccs_set_slash();
+			}
+			cprint(ccs_mac_keywords[ccs_p2mac[bit]]);
+		}
+		if (first)
+			return;
+		ccs_print_name_union(&ptr->name);
 	} else if (acl_type == CCS_TYPE_MKDEV_ACL) {
 		struct ccs_mkdev_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		const u8 perm = ptr->perm;
 		for (bit = 0; bit < CCS_MAX_MKDEV_OPERATION; bit++) {
-			if (!(perm & (1 << bit)))
+			if (!(acl->perm & (1 << bit)))
 				continue;
 			if (first) {
 				ccs_set_group("file ");
 				first = false;
 			} else {
-				cprintf("/");
+				ccs_set_slash();
 			}
-			cprintf("%s", ccs_mac_keywords[ccs_pnnn2mac[bit]]);
+			cprint(ccs_mac_keywords
+				       [ccs_pnnn2mac[bit]]);
 		}
 		if (first)
 			return;
@@ -4199,17 +3769,17 @@
 	} else if (acl_type == CCS_TYPE_PATH2_ACL) {
 		struct ccs_path2_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		const u8 perm = ptr->perm;
 		for (bit = 0; bit < CCS_MAX_PATH2_OPERATION; bit++) {
-			if (!(perm & (1 << bit)))
+			if (!(acl->perm & (1 << bit)))
 				continue;
 			if (first) {
 				ccs_set_group("file ");
 				first = false;
 			} else {
-				cprintf("/");
+				ccs_set_slash();
 			}
-			cprintf("%s", ccs_mac_keywords[ccs_pp2mac[bit]]);
+			cprint(ccs_mac_keywords
+				       [ccs_pp2mac[bit]]);
 		}
 		if (first)
 			return;
@@ -4218,17 +3788,17 @@
 	} else if (acl_type == CCS_TYPE_PATH_NUMBER_ACL) {
 		struct ccs_path_number_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		const u8 perm = ptr->perm;
 		for (bit = 0; bit < CCS_MAX_PATH_NUMBER_OPERATION; bit++) {
-			if (!(perm & (1 << bit)))
+			if (!(acl->perm & (1 << bit)))
 				continue;
 			if (first) {
 				ccs_set_group("file ");
 				first = false;
 			} else {
-				cprintf("/");
+				ccs_set_slash();
 			}
-			cprintf("%s", ccs_mac_keywords[ccs_pn2mac[bit]]);
+			cprint(ccs_mac_keywords
+				       [ccs_pn2mac[bit]]);
 		}
 		if (first)
 			return;
@@ -4237,64 +3807,64 @@
 	} else if (acl_type == CCS_TYPE_ENV_ACL) {
 		struct ccs_env_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		ccs_set_group("misc env ");
-		cprintf("%s", ptr->env->name);
+		ccs_set_group("misc env");
+		ccs_print_name_union(&ptr->env);
 	} else if (acl_type == CCS_TYPE_CAPABILITY_ACL) {
 		struct ccs_capability_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
 		ccs_set_group("capability ");
-		cprintf("%s", ccs_mac_keywords[ccs_c2mac[ptr->operation]]);
+		cprint(ccs_mac_keywords
+			       [ccs_c2mac[ptr->operation]]);
 	} else if (acl_type == CCS_TYPE_INET_ACL) {
 		struct ccs_inet_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		const u8 perm = ptr->perm;
 		for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
-			if (!(perm & (1 << bit)))
+			if (!(acl->perm & (1 << bit)))
 				continue;
 			if (first) {
 				ccs_set_group("network inet ");
-				cprintf("%s ",
-					ccs_proto_keyword[ptr->protocol]);
+				cprint(ccs_proto_keyword
+					       [ptr->protocol]);
+				ccs_set_space();
 				first = false;
 			} else {
-				cprintf("/");
+				ccs_set_slash();
 			}
-			cprintf("%s", ccs_socket_keyword[bit]);
+			cprint(ccs_socket_keyword[bit]);
 		}
 		if (first)
 			return;
-		cprintf(" ");
-		if (ptr->address.group)
-			cprintf("@%s", ptr->address.group->group_name->name);
-		else
+		ccs_set_space();
+		if (!ccs_print_group(ptr->address.is_not,
+				     ptr->address.group))
 			ccs_print_ip(&ptr->address);
 		ccs_print_number_union(&ptr->port);
 	} else if (acl_type == CCS_TYPE_UNIX_ACL) {
 		struct ccs_unix_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		const u8 perm = ptr->perm;
 		for (bit = 0; bit < CCS_MAX_NETWORK_OPERATION; bit++) {
-			if (!(perm & (1 << bit)))
+			if (!(acl->perm & (1 << bit)))
 				continue;
 			if (first) {
 				ccs_set_group("network unix ");
-				cprintf("%s ",
-					ccs_proto_keyword[ptr->protocol]);
+				cprint(ccs_proto_keyword[ptr->protocol]);
+				ccs_set_space();
 				first = false;
 			} else {
-				cprintf("/");
+				ccs_set_slash();
 			}
-			cprintf("%s", ccs_socket_keyword[bit]);
+			cprint(ccs_socket_keyword[bit]);
 		}
 		if (first)
 			return;
 		ccs_print_name_union(&ptr->name);
-	} else if (acl_type == CCS_TYPE_SIGNAL_ACL) {
-		struct ccs_signal_acl *ptr =
+	} else if (acl_type == CCS_TYPE_PTRACE_ACL) {
+		struct ccs_ptrace_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
-		ccs_set_group("ipc signal ");
-		ccs_print_number_union_nospace(&ptr->sig);
-		cprintf(" %s", ptr->domainname->name);
+		ccs_set_group("ipc ptrace ");
+		ccs_print_number_union_nospace(&ptr->request);
+		ccs_set_space();
+		cprint(ptr->domainname->name);
 	} else if (acl_type == CCS_TYPE_MOUNT_ACL) {
 		struct ccs_mount_acl *ptr =
 			container_of(acl, typeof(*ptr), head);
@@ -4306,151 +3876,210 @@
 	}
 	if (acl->cond)
 		ccs_print_condition(acl->cond);
-	cprintf("\n");
+	ccs_set_lf();
 }
 
 /**
- * ccs_read_domain2 - Read domain policy.
+ * ccs_read_acl - Read "struct ccs_acl_info" list.
  *
  * @list: Pointer to "struct list_head".
  *
  * Returns nothing.
+ *
+ * Caller holds ccs_read_lock().
  */
-static void ccs_read_domain2(struct list_head *list)
+static void ccs_read_acl(struct list_head *list)
 {
 	struct ccs_acl_info *ptr;
-	list_for_each_entry(ptr, list, list)
+	list_for_each_entry(ptr, list, list) {
 		ccs_print_entry(ptr);
+	}
 }
 
 /**
  * ccs_read_domain - Read domain policy.
  *
  * Returns nothing.
+ *
+ * Caller holds ccs_read_lock().
  */
 static void ccs_read_domain(void)
 {
-	struct ccs_domain2_info *domain;
-	if (head.eof)
-		return;
+	struct ccs_domain_info4 *domain;
 	list_for_each_entry(domain, &ccs_domain_list, list) {
-		u8 i;
-		if (domain->is_deleted)
+		if (domain->is_deleted &&
+		    !head.print_this_domain_only)
 			continue;
-		if (head.print_this_domain_only &&
-		    head.print_this_domain_only != domain)
-			continue;
 		/* Print domainname and flags. */
-		cprintf("%s\n", domain->domainname->name);
+		cprint(domain->domainname->name);
+		ccs_set_lf();
 		cprintf("use_profile %u\n", domain->profile);
-		cprintf("use_group %u\n", domain->group);
-		for (i = 0; i < CCS_MAX_DOMAIN_INFO_FLAGS; i++)
-			if (domain->flags[i])
-				cprintf("%s", ccs_dif[i]);
-		cprintf("\n");
-		ccs_read_domain2(&domain->acl_info_list);
-		cprintf("\n");
+		cprintf("default_transition %s\n",
+			domain->default_transition->name);
+		if (domain->quota_exceeded)
+			cprint(CCS_QUOTA_EXCEEDED);
+		cprint("\n");
+		ccs_read_acl(&domain->acl_info_list);
+		ccs_set_lf();
+		if (head.print_this_domain_only)
+			break;
 	}
-	head.eof = true;
 }
 
 /**
- * ccs_same_path_group - Check for duplicated "struct ccs_path_group" entry.
+ * ccs_write_group - Write "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
  *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
+ * @param: Pointer to "struct ccs_acl_param".
+ * @type:  Type of this group.
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns 0 on success, negative value otherwise.
  */
-static bool ccs_same_path_group(const struct ccs_acl_head *a,
-				const struct ccs_acl_head *b)
+static int ccs_write_group(struct ccs_acl_param *param, const u8 type)
 {
-	return container_of(a, struct ccs_path_group, head)->member_name ==
-		container_of(b, struct ccs_path_group, head)->member_name;
+	int error = -EINVAL;
+	struct ccs_group *group = ccs_get_group(param, type);
+	if (!group || group == &ccs_group_any)
+		return -ENOMEM;
+	if (type != CCS_ACL_GROUP && ccs_group_type(&param->data))
+		goto out;
+	param->list = &group->member_list;
+	if (type == CCS_PATH_GROUP) {
+		struct ccs_path_group *e = &param->e.path_group;
+		e->member_name = ccs_savename(ccs_read_token(param));
+		if (!e->member_name) {
+			error = -ENOMEM;
+			goto out;
+		}
+		error = ccs_update_policy(sizeof(*e), param);
+		ccs_put_name(e->member_name);
+	} else if (type == CCS_NUMBER_GROUP) {
+		struct ccs_number_group *e = &param->e.number_group;
+		if (ccs_parse_number_union(param, &e->number))
+			error = ccs_update_policy(sizeof(*e), param);
+	} else if (type == CCS_ACL_GROUP) {
+		error = ccs_write_acl(param->ns, param->list, param->data,
+				      param->is_delete);
+	} else {
+		struct ccs_address_group *e = &param->e.address_group;
+		if (ccs_parse_ipaddr_union(param, &e->address))
+			error = ccs_update_policy(sizeof(*e), param);
+	}
+out:
+	ccs_put_group(group);
+	return error;
 }
 
 /**
- * ccs_same_number_group - Check for duplicated "struct ccs_number_group" entry.
+ * ccs_write_transition_control - Write default domain transition rules.
  *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
+ * @param: Pointer to "struct ccs_acl_param".
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns 0 on success, negative value otherwise.
  */
-static bool ccs_same_number_group(const struct ccs_acl_head *a,
-				  const struct ccs_acl_head *b)
+static int ccs_write_transition_control(struct ccs_acl_param *param)
 {
-	return !memcmp(&container_of(a, struct ccs_number_group, head)->number,
-		       &container_of(b, struct ccs_number_group, head)->number,
-		       sizeof(container_of(a, struct ccs_number_group, head)
-			      ->number));
+	param->list = &param->ns->default_transition_list;
+	return ccs_update_execute_acl(param);
 }
 
 /**
- * ccs_same_address_group - Check for duplicated "struct ccs_address_group" entry.
+ * ccs_update_domain_in_acl - Update "struct ccs_domain_info4" in "struct ccs_acl_info".
  *
- * @a: Pointer to "struct ccs_acl_head".
- * @b: Pointer to "struct ccs_acl_head".
+ * @acl:   Pointer to "struct ccs_acl_info".
+ * @param: Pointer to "struct ccs_acl_param".
  *
- * Returns true if @a == @b, false otherwise.
+ * Returns 0 on success, negative value otherwise.
  */
-static bool ccs_same_address_group(const struct ccs_acl_head *a,
-				   const struct ccs_acl_head *b)
+static int ccs_update_domain_in_acl(struct ccs_acl_info *acl,
+				    struct ccs_acl_param *param)
 {
-	const struct ccs_address_group *p1 = container_of(a, typeof(*p1),
-							  head);
-	const struct ccs_address_group *p2 = container_of(b, typeof(*p2),
-							  head);
-	return ccs_same_ipaddr_union(&p1->address, &p2->address);
+	struct ccs_domain_info4 *ptr;
+	struct ccs_domain_info4 domain = { };
+	int error = param->is_delete ? -ENOENT : -ENOMEM;
+	domain.domainname = ccs_get_domainname(param);
+	if (!domain.domainname)
+		return error;
+	if (param->data[0]) {
+		domain.cond = ccs_get_condition(param);
+		if (!domain.cond)
+			goto out;
+	}
+	list_for_each_entry(ptr, &acl->domain_list, list) {
+		if (ptr->cond != domain.cond ||
+		    ptr->domainname != domain.domainname)
+			continue;
+		ptr->is_deleted = param->is_delete;
+		error = 0;
+		break;
+	}
+	if (!param->is_delete && error) {
+		struct ccs_domain_info4 *entry =
+			ccs_commit_ok(&domain, sizeof(domain));
+		if (entry) {
+			INIT_LIST_HEAD(&entry->acl_info_list);
+			list_add_tail(&entry->list, &acl->domain_list);
+			error = 0;
+		}
+	}
+ out:
+	ccs_put_name(domain.domainname);
+	ccs_put_condition(domain.cond);
+	return error;
 }
 
 /**
- * ccs_write_group - Write "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
+ * ccs_write_acl_policy - Write inverse mode policy.
  *
- * @param: Pointer to "struct ccs_acl_param".
- * @type:  Type of this group.
- *
  * Returns 0 on success, negative value otherwise.
  */
-static int ccs_write_group(struct ccs_acl_param *param, const u8 type)
+static int ccs_write_acl_policy(void)
 {
-	struct ccs_group *group = ccs_get_group(param, type == CCS_PATH_GROUP ?
-						&ccs_path_group :
-						type == CCS_NUMBER_GROUP ?
-						&ccs_number_group :
-						&ccs_address_group);
-	int error = -EINVAL;
-	if (!group)
-		return -ENOMEM;
-	param->list = &group->member_list;
-	if (type == CCS_PATH_GROUP) {
-		struct ccs_path_group e = { };
-		e.member_name = ccs_get_name(ccs_read_token(param));
-		error = ccs_update_policy(&e.head, sizeof(e), param,
-					  ccs_same_path_group);
-		ccs_put_name(e.member_name);
-	} else if (type == CCS_NUMBER_GROUP) {
-		struct ccs_number_group e = { };
-		if (param->data[0] == '@' ||
-		    !ccs_parse_number_union(param, &e.number))
-			goto out;
-		error = ccs_update_policy(&e.head, sizeof(e), param,
-					  ccs_same_number_group);
-		/*
-		 * ccs_put_number_union() is not needed because
-		 * param->data[0] != '@'.
-		 */
-	} else {
-		struct ccs_address_group e = { };
-		if (param->data[0] == '@' ||
-		    !ccs_parse_ipaddr_union(param, &e.address))
-			goto out;
-		error = ccs_update_policy(&e.head, sizeof(e), param,
-					  ccs_same_address_group);
+	static const struct {
+		const char *keyword;
+		int (*write) (struct ccs_acl_param *);
+	} ccs_callback[] = {
+		{ "file ", ccs_write_file },
+		{ "network inet ", ccs_write_inet_network },
+		{ "network unix ", ccs_write_unix_network },
+		{ "misc ", ccs_write_misc },
+		{ "capability ", ccs_write_capability },
+		{ "ipc ptrace ", ccs_write_ipc },
+	};
+	struct ccs_acl_param param = {
+		.data = head.write_buf,
+		.is_delete = head.is_delete,
+		.e.acl_info.perm = 1,
+	};
+	u8 i;
+	if (ccs_str_starts2(&param.data, "by ")) {
+		if (!head.acl)
+			return -EINVAL;
+		return ccs_update_domain_in_acl(head.acl, &param);
 	}
-out:
-	ccs_put_group(group);
-	return error;
+	if (ccs_str_starts2(&param.data, "mode ")) {
+		u8 mode;
+		if (!head.acl)
+			return -EINVAL;
+		for (mode = 0; mode < CCS_CONFIG_MAX_MODE; mode++)
+			if (!strcmp(param.data, ccs_mode[mode])) {
+				head.acl->mode = mode;
+				return 0;
+			}
+		return -EINVAL;
+	}
+	head.acl = NULL;
+	if (!ccs_str_starts2(&param.data, "allow "))
+		return -EINVAL;
+	for (i = 0; i < ARRAY_SIZE(ccs_callback); i++) {
+		int error;
+		if (!ccs_str_starts2(&param.data, ccs_callback[i].keyword))
+			continue;
+		error = ccs_callback[i].write(&param);
+		if (!error && !head.is_delete)
+			head.acl = param.matched_entry;
+		return error;
+	}
+	return -EINVAL;
 }
 
 /**
@@ -4460,159 +4089,91 @@
  */
 static int ccs_write_exception(void)
 {
-	const bool is_delete = head.is_delete;
+	const _Bool is_delete = head.is_delete;
 	struct ccs_acl_param param = {
 		.ns = head.ns,
 		.is_delete = is_delete,
-		.data = head.data,
+		.data = head.write_buf,
 	};
 	u8 i;
-	if (ccs_str_starts(param.data, "aggregator "))
-		return ccs_write_aggregator(&param);
-	if (ccs_str_starts(param.data, "deny_autobind "))
-		return ccs_write_reserved_port(&param);
-	for (i = 0; i < CCS_MAX_TRANSITION_TYPE; i++)
-		if (ccs_str_starts(param.data, ccs_transition_type[i]))
-			return ccs_write_transition_control(&param, i);
+	/* Forced zero clear for using memcmp() at ccs_update_policy(). */
+	memset(&param.e, 0, sizeof(param.e));
+	param.e.acl_info.perm = 1;
+	if (ccs_str_starts2(&param.data, "default_transition "))
+		return ccs_write_transition_control(&param);
 	for (i = 0; i < CCS_MAX_GROUP; i++)
-		if (ccs_str_starts(param.data, ccs_group_name[i]))
+		if (ccs_str_starts2(&param.data, ccs_group_name[i]))
 			return ccs_write_group(&param, i);
-	if (ccs_str_starts(param.data, "acl_group ")) {
-		unsigned int group;
-		char *data;
-		group = strtoul(param.data, &data, 10);
-		if (group < CCS_MAX_ACL_GROUPS && *data++ == ' ')
-			return ccs_write_domain2(head.ns,
-						 &head.ns->acl_group[group],
-						 data, is_delete);
-	}
 	return -EINVAL;
 }
 
 /**
  * ccs_read_group - Read "struct ccs_path_group"/"struct ccs_number_group"/"struct ccs_address_group" list.
  *
- * @ns: Pointer to "struct ccs_policy_namespace".
+ * @idx: Index number.
  *
  * Returns nothing.
+ *
+ * Caller holds ccs_read_lock().
  */
-static void ccs_read_group(const struct ccs_policy_namespace *ns)
+static void ccs_read_group(const int idx)
 {
+	struct ccs_policy_namespace *ns = head.ns;
 	struct ccs_group *group;
-	list_for_each_entry(group, &ccs_path_group, head.list) {
-		struct ccs_acl_head *ptr;
-		list_for_each_entry(ptr, &group->member_list, list) {
-			if (group->ns != ns)
-				continue;
-			if (ptr->is_deleted)
-				continue;
-			ccs_print_namespace(group->ns);
-			cprintf("%s%s", ccs_group_name[CCS_PATH_GROUP],
-				group->group_name->name);
-			cprintf(" %s",
-				container_of(ptr, struct ccs_path_group,
-					     head)->member_name->name);
-			cprintf("\n");
+	if (idx == CCS_ACL_GROUP) {
+		list_for_each_entry(group, &ccs_inversed_acl_list, head.list) {
+			head.acl_group_name = group->group_name;
+			ccs_read_acl(&group->member_list);
 		}
+		head.acl_group_name = NULL;
+		return;
 	}
-	list_for_each_entry(group, &ccs_number_group, head.list) {
+	list_for_each_entry(group, &ns->group_list[idx], head.list) {
 		struct ccs_acl_head *ptr;
 		list_for_each_entry(ptr, &group->member_list, list) {
-			if (group->ns != ns)
-				continue;
 			if (ptr->is_deleted)
 				continue;
-			ccs_print_namespace(group->ns);
-			cprintf("%s%s", ccs_group_name[CCS_NUMBER_GROUP],
-				group->group_name->name);
-			ccs_print_number_union(&container_of
+			ccs_print_namespace();
+			cprint(ccs_group_name[idx]);
+			cprint(group->group_name->name);
+			if (idx == CCS_PATH_GROUP) {
+				ccs_set_space();
+				cprint(container_of
+				       (ptr, struct ccs_path_group,
+					head)->member_name->name);
+			} else if (idx == CCS_NUMBER_GROUP) {
+				ccs_print_number_union(&container_of
 					       (ptr, struct ccs_number_group,
 						head)->number);
-			cprintf("\n");
+			} else if (idx == CCS_ADDRESS_GROUP) {
+				struct ccs_address_group *member =
+					container_of(ptr, typeof(*member),
+							     head);
+				cprint(" ");
+				ccs_print_ip(&member->address);
+			}
+			ccs_set_lf();
 		}
 	}
-	list_for_each_entry(group, &ccs_address_group, head.list) {
-		struct ccs_acl_head *ptr;
-		list_for_each_entry(ptr, &group->member_list, list) {
-			if (group->ns != ns)
-				continue;
-			if (ptr->is_deleted)
-				continue;
-			ccs_print_namespace(group->ns);
-			cprintf("%s%s", ccs_group_name[CCS_ADDRESS_GROUP],
-				group->group_name->name);
-			cprintf(" ");
-			ccs_print_ip(&container_of
-				     (ptr, struct ccs_address_group, head)->
-				     address);
-			cprintf("\n");
-		}
-	}
 }
 
 /**
- * ccs_read_policy - Read "struct ccs_..._entry" list.
- *
- * @ns: Pointer to "struct ccs_policy_namespace".
- *
- * Returns nothing.
- */
-static void ccs_read_policy(const struct ccs_policy_namespace *ns)
-{
-	struct ccs_acl_head *acl;
-	if (head.print_transition_related_only)
-		goto transition_only;
-	list_for_each_entry(acl, &ccs_reserved_list, list) {
-		struct ccs_reserved *ptr =
-			container_of(acl, typeof(*ptr), head);
-		if (acl->is_deleted || ptr->ns != ns)
-			continue;
-		ccs_print_namespace(ptr->ns);
-		cprintf("deny_autobind ");
-		ccs_print_number_union_nospace(&ptr->port);
-		cprintf("\n");
-	}
-	list_for_each_entry(acl, &ccs_aggregator_list, list) {
-		struct ccs_aggregator *ptr =
-			container_of(acl, typeof(*ptr), head);
-		if (acl->is_deleted || ptr->ns != ns)
-			continue;
-		ccs_print_namespace(ptr->ns);
-		cprintf("aggregator %s %s\n", ptr->original_name->name,
-			ptr->aggregated_name->name);
-	}
-transition_only:
-	list_for_each_entry(acl, &ccs_transition_list, list) {
-		struct ccs_transition_control *ptr =
-			container_of(acl, typeof(*ptr), head);
-		if (acl->is_deleted || ptr->ns != ns)
-			continue;
-		ccs_print_namespace(ptr->ns);
-		cprintf("%s%s from %s\n", ccs_transition_type[ptr->type],
-			ptr->program ? ptr->program->name : "any",
-			ptr->domainname ? ptr->domainname->name : "any");
-	}
-}
-
-/**
  * ccs_read_exception - Read exception policy.
  *
  * Returns nothing.
+ *
+ * Caller holds ccs_read_lock().
  */
 static void ccs_read_exception(void)
 {
-	struct ccs_policy_namespace *ns;
-	if (head.eof)
-		return;
-	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
-		unsigned int i;
-		head.ns = ns;
-		ccs_read_policy(ns);
-		ccs_read_group(ns);
-		for (i = 0; i < CCS_MAX_ACL_GROUPS; i++)
-			ccs_read_domain2(&ns->acl_group[i]);
+	list_for_each_entry(head.ns, &ccs_namespace_list, namespace_list) {
+		u8 i;
+		for (i = 0; i < CCS_MAX_GROUP; i++)
+			ccs_read_group(i);
+		head.print_default_transition = true;
+		ccs_read_acl(&head.ns->default_transition_list);
+		head.print_default_transition = false;
 	}
-	head.eof = true;
 }
 
 /**
@@ -4623,12 +4184,18 @@
 static void ccs_read_stat(void)
 {
 	u8 i;
-	if (head.eof)
-		return;
-	for (i = 0; i < CCS_MAX_MEMORY_STAT; i++)
-		cprintf("Memory used by %-22s %10u\n", ccs_memory_headers[i],
-			ccs_memory_quota[i]);
-	head.eof = true;
+	unsigned int total = 0;
+	for (i = 0; i < CCS_MAX_MEMORY_STAT; i++) {
+		unsigned int used = ccs_memory_used[i];
+		total += used;
+		cprintf("Memory used by %-22s %10u",
+			ccs_memory_headers[i], used);
+		used = ccs_memory_quota[i];
+		if (used)
+			cprintf(" (Quota: %10u)", used);
+		ccs_set_lf();
+	}
+	cprintf("Total memory used:                    %10u\n", total);
 }
 
 /**
@@ -4638,16 +4205,155 @@
  */
 static int ccs_write_stat(void)
 {
-	char *data = head.data;
+	char *data = head.write_buf;
 	u8 i;
-	if (ccs_str_starts(data, "Memory used by "))
+	if (ccs_str_starts2(&data, "Memory used by "))
 		for (i = 0; i < CCS_MAX_MEMORY_STAT; i++)
-			if (ccs_str_starts(data, ccs_memory_headers[i]))
+			if (ccs_str_starts2(&data, ccs_memory_headers[i])) {
+				if (*data == ' ')
+					data++;
 				ccs_memory_quota[i] = strtoul(data, NULL, 10);
+			}
 	return 0;
 }
 
 /**
+ * ccs_find_namespace - Find specified namespace.
+ *
+ * @name: Name of namespace to find.
+ * @len:  Length of @name.
+ *
+ * Returns pointer to "struct ccs_policy_namespace" if found, NULL otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static struct ccs_policy_namespace *ccs_find_namespace(const char *name,
+						       const unsigned int len)
+{
+	struct ccs_policy_namespace *ns;
+	list_for_each_entry(ns, &ccs_namespace_list, namespace_list) {
+		if (strncmp(name, ns->name, len) ||
+		    (name[len] && name[len] != ' '))
+			continue;
+		return ns;
+	}
+	return NULL;
+}
+
+/**
+ * ccs_assign_namespace - Create a new namespace.
+ *
+ * @domainname: Name of namespace to create.
+ *
+ * Returns pointer to "struct ccs_policy_namespace" on success, NULL otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static struct ccs_policy_namespace *ccs_assign_namespace
+(const char *domainname)
+{
+	struct ccs_policy_namespace *ptr;
+	const char *cp = domainname;
+	unsigned int len = 0;
+	while (*cp && *cp++ != ' ')
+		len++;
+	ptr = ccs_find_namespace(domainname, len);
+	if (ptr)
+		return ptr;
+	if (len >= 4096 - 10 || !ccs_domain_def(domainname))
+		return NULL;
+	ptr = ccs_malloc(sizeof(*ptr) + len + 1);
+	{
+		char *name = (char *) (ptr + 1);
+		memmove(name, domainname, len);
+		name[len] = '\0';
+		ptr->name = name;
+		ccs_init_policy_namespace(ptr);
+	}
+	return ptr;
+}
+
+/**
+ * ccs_assign_domain4 - Create a domain or a namespace.
+ *
+ * @domainname: The name of domain.
+ *
+ * Returns pointer to "struct ccs_domain_info4" on success, NULL otherwise.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static struct ccs_domain_info4 *ccs_assign_domain4(const char *domainname)
+{
+	struct ccs_domain_info4 e = { };
+	struct ccs_domain_info4 *entry = ccs_find_domain4(domainname);
+	if (entry)
+		return entry;
+	/* Requested domain does not exist. */
+	/* Don't create requested domain if domainname is invalid. */
+	if (strlen(domainname) >= 4096 - 10 ||
+	    !ccs_correct_domain(domainname))
+		return NULL;
+	e.ns = ccs_assign_namespace(domainname);
+	if (!e.ns)
+		return NULL;
+	e.domainname = ccs_savename(domainname);
+	if (!e.domainname)
+		return NULL;
+	e.default_transition = ccs_savename("child");
+	if (!e.default_transition)
+		goto out;
+	entry = ccs_commit_ok(&e, sizeof(e));
+	if (entry) {
+		INIT_LIST_HEAD(&entry->acl_info_list);
+		list_add_tail(&entry->list, &ccs_domain_list);
+	}
+out:
+	ccs_put_name(e.domainname);
+	ccs_put_name(e.default_transition);
+	return entry;
+}
+
+/**
+ * ccs_read_domain_in_acl - Read domainname and condition.
+ *
+ * @list: Pointer to "struct list_head".
+ *
+ * Returns nothing.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static void ccs_read_domain_in_acl(struct list_head *list)
+{
+	struct ccs_domain_info4 *domain;
+	list_for_each_entry(domain, list, list) {
+		if (domain->is_deleted)
+			continue;
+		cprintf("    by %s", domain->domainname->name);
+		if (domain->cond)
+			ccs_print_condition(domain->cond);
+		ccs_set_lf();
+	}
+}
+
+/**
+ * ccs_read_inverse_policy - Read inversed mode policy.
+ *
+ * Caller holds ccs_read_lock().
+ */
+static void ccs_read_inverse_policy(void)
+{
+	struct ccs_acl_info *ptr;
+	list_for_each_entry(ptr, &ccs_inversed_acl_list, list) {
+		if (ptr->is_deleted)
+			continue;
+		ccs_print_entry(ptr);
+		cprintf("    mode %s\n", ccs_mode[ptr->mode]);
+		ccs_read_domain_in_acl(&ptr->domain_list);
+		ccs_set_lf();
+	}
+}
+
+/**
  * ccs_parse_policy - Parse a policy line.
  *
  * @line: Line to parse.
@@ -4661,7 +4367,7 @@
 	if (head.is_delete)
 		memmove(line, line + 7, strlen(line + 7) + 1);
 	/* Selecting namespace to update. */
-	if (head.type == CCS_EXCEPTIONPOLICY || head.type == CCS_PROFILE) {
+	if (head.type == CCS_EXCEPTION_POLICY || head.type == CCS_PROFILE) {
 		if (*line == '<') {
 			char *cp = strchr(line, ' ');
 			if (cp) {
@@ -4678,9 +4384,11 @@
 	}
 	/* Do the update. */
 	switch (head.type) {
-	case CCS_DOMAINPOLICY:
+	case CCS_DOMAIN_POLICY:
 		return ccs_write_domain();
-	case CCS_EXCEPTIONPOLICY:
+	case CCS_ACL_POLICY:
+		return ccs_write_acl_policy();
+	case CCS_EXCEPTION_POLICY:
 		return ccs_write_exception();
 	case CCS_STAT:
 		return ccs_write_stat();
@@ -4715,22 +4423,15 @@
 			continue;
 		line[line_len - 1] = '\0';
 		line_len = 0;
-		head.data = line;
+		head.write_buf = line;
 		ccs_normalize_line(line);
-		if (!strcmp(line, "reset")) {
-			const u8 type = head.type;
-			memset(&head, 0, sizeof(head));
-			head.reset = true;
-			head.type = type;
-			continue;
-		}
 		/* Don't allow updating policies by non manager programs. */
 		switch (head.type) {
-		case CCS_DOMAINPOLICY:
+		case CCS_DOMAIN_POLICY:
 			if (ccs_select_domain(line))
 				continue;
 			/* fall through */
-		case CCS_EXCEPTIONPOLICY:
+		case CCS_EXCEPTION_POLICY:
 			if (!strcmp(line, "select transition_only")) {
 				head.print_transition_related_only = true;
 				continue;
@@ -4748,23 +4449,26 @@
 static void ccs_editpolicy_offline_init(coid)
 {
 	static _Bool first = true;
-	int i;
 	if (!first)
 		return;
 	first = false;
 	memset(&head, 0, sizeof(head));
 	memset(&ccs_kernel_domain, 0, sizeof(ccs_kernel_domain));
 	memset(&ccs_kernel_namespace, 0, sizeof(ccs_kernel_namespace));
-	ccs_namespace_enabled = false;
+	{
+		static struct ccs_path_info any;
+		any.name = "any";
+		ccs_fill_path_info(&any);
+		ccs_group_any.group_name = &any;
+		INIT_LIST_HEAD(&ccs_group_any.head.list);
+		INIT_LIST_HEAD(&ccs_group_any.member_list);
+	}
 	ccs_kernel_namespace.name = "<kernel>";
-	for (i = 0; i < CCS_MAX_ACL_GROUPS; i++)
-		INIT_LIST_HEAD(&ccs_kernel_namespace.acl_group[i]);
-	list_add_tail(&ccs_kernel_namespace.namespace_list,
-		      &ccs_namespace_list);
-	for (i = 0; i < CCS_MAX_HASH; i++)
-		INIT_LIST_HEAD(&ccs_name_list[i]);
+	ccs_init_policy_namespace(&ccs_kernel_namespace);
+	ccs_kernel_domain.ns = &ccs_kernel_namespace;
 	INIT_LIST_HEAD(&ccs_kernel_domain.acl_info_list);
 	ccs_kernel_domain.domainname = ccs_savename("<kernel>");
+	ccs_kernel_domain.default_transition = ccs_savename("child");
 	list_add_tail(&ccs_kernel_domain.list, &ccs_domain_list);
 	memset(ccs_memory_quota, 0, sizeof(ccs_memory_quota));
 }
@@ -4793,9 +4497,11 @@
 	memset(&head, 0, sizeof(head));
 	head.reset = true;
 	if (!strcmp(buffer, CCS_PROC_POLICY_DOMAIN_POLICY))
-		head.type = CCS_DOMAINPOLICY;
+		head.type = CCS_DOMAIN_POLICY;
 	else if (!strcmp(buffer, CCS_PROC_POLICY_EXCEPTION_POLICY))
-		head.type = CCS_EXCEPTIONPOLICY;
+		head.type = CCS_EXCEPTION_POLICY;
+	else if (!strcmp(buffer, CCS_PROC_POLICY_ACL_POLICY))
+		head.type = CCS_ACL_POLICY;
 	else if (!strcmp(buffer, CCS_PROC_POLICY_PROFILE))
 		head.type = CCS_PROFILE;
 	else if (!strcmp(buffer, CCS_PROC_POLICY_MANAGER))
@@ -4824,10 +4530,13 @@
 			ccs_write_control(buffer, nonzero_len);
 		} else {
 			switch (head.type) {
-			case CCS_DOMAINPOLICY:
+			case CCS_DOMAIN_POLICY:
 				ccs_read_domain();
 				break;
-			case CCS_EXCEPTIONPOLICY:
+			case CCS_ACL_POLICY:
+				ccs_read_inverse_policy();
+				break;
+			case CCS_EXCEPTION_POLICY:
 				ccs_read_exception();
 				break;
 			case CCS_STAT:
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_optimizer.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_optimizer.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_optimizer.c	(working copy)
@@ -211,7 +211,7 @@
 	case CCS_DIRECTIVE_FILE_LINK:
 	case CCS_DIRECTIVE_FILE_RENAME:
 	case CCS_DIRECTIVE_FILE_PIVOT_ROOT:
-	case CCS_DIRECTIVE_IPC_SIGNAL:
+	case CCS_DIRECTIVE_IPC_PTRACE:
 		words = 2;
 		break;
 	case CCS_DIRECTIVE_FILE_EXECUTE:
@@ -239,7 +239,7 @@
 		w[i] = buffer;
 		if (!cp)
 			return;
-		if (index == CCS_DIRECTIVE_IPC_SIGNAL && i == 1 &&
+		if (index == CCS_DIRECTIVE_IPC_PTRACE && i == 1 &&
 		    ccs_domain_def(buffer)) {
 			cp = strchr(buffer, ' ');
 			if (!cp)
@@ -336,9 +336,7 @@
 	if (s_index == CCS_DIRECTIVE_NONE)
 		return;
 	/* Allow acl_group lines to be optimized. */
-	if (is_exception_list &&
-	    (s_index < CCS_DIRECTIVE_ACL_GROUP_000 ||
-	     s_index > CCS_DIRECTIVE_ACL_GROUP_255))
+	if (is_exception_list && s_index != CCS_DIRECTIVE_ACL_GROUP)
 		return;
 	cp = strdup(ccs_gacl_list[current].operand);
 	if (!cp)
@@ -388,10 +386,6 @@
 			fclose(fp);
 		}
 		switch (d_index) {
-			struct ccs_path_info sarg;
-			struct ccs_path_info darg;
-			char c;
-			int len;
 		case CCS_DIRECTIVE_FILE_MKBLOCK:
 		case CCS_DIRECTIVE_FILE_MKCHAR:
 			if (!ccs_compare_number(s[3], d[3]) ||
@@ -419,7 +413,7 @@
 		case CCS_DIRECTIVE_FILE_APPEND:
 		case CCS_DIRECTIVE_FILE_UNMOUNT:
 		case CCS_DIRECTIVE_FILE_CHROOT:
-		case CCS_DIRECTIVE_FILE_SYMLINK:
+		case CCS_DIRECTIVE_MISC_ENV:
 			if (!ccs_compare_path(s[0], d[0]))
 				continue;
 			break;
@@ -431,21 +425,18 @@
 		case CCS_DIRECTIVE_FILE_LINK:
 		case CCS_DIRECTIVE_FILE_RENAME:
 		case CCS_DIRECTIVE_FILE_PIVOT_ROOT:
+		case CCS_DIRECTIVE_FILE_SYMLINK:
 			if (!ccs_compare_path(s[1], d[1]) ||
 			    !ccs_compare_path(s[0], d[0]))
 				continue;
 			break;
-		case CCS_DIRECTIVE_IPC_SIGNAL:
-			/* Signal number component. */
+		case CCS_DIRECTIVE_IPC_PTRACE:
+			/* Command number component. */
 			if (strcmp(s[0], d[0]))
 				continue;
 			/* Domainname component. */
-			len = strlen(s[1]);
-			if (strncmp(s[1], d[1], len))
+			if (!ccs_compare_path(s[1], d[1]))
 				continue;
-			c = d[1][len];
-			if (c && c != ' ')
-				continue;
 			break;
 		case CCS_DIRECTIVE_NETWORK_INET:
 			if (strcmp(s[0], d[0]) || strcmp(s[1], d[1]) ||
@@ -458,20 +449,6 @@
 			    !ccs_compare_path(s[2], d[2]))
 				continue;
 			break;
-		case CCS_DIRECTIVE_MISC_ENV:
-			/* An environemnt variable name component. */
-			sarg.name = s[0];
-			ccs_fill_path_info(&sarg);
-			darg.name = d[0];
-			ccs_fill_path_info(&darg);
-			if (!ccs_pathcmp(&sarg, &darg))
-				break;
-			/* "misc env" doesn't interpret leading @ as
-			   path_group. */
-			if (darg.is_patterned ||
-			    !ccs_path_matches_pattern(&darg, &sarg))
-				continue;
-			break;
 		default:
 			continue;
 		}
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_keyword.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_keyword.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy_keyword.c	(working copy)
@@ -25,266 +25,12 @@
 
 /* keyword array for rewriting keywords upon display. */
 struct ccs_editpolicy_directive ccs_directives[CCS_MAX_DIRECTIVE_INDEX] = {
-	[CCS_DIRECTIVE_ACL_GROUP_000] = { "acl_group 0", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_001] = { "acl_group 1", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_002] = { "acl_group 2", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_003] = { "acl_group 3", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_004] = { "acl_group 4", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_005] = { "acl_group 5", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_006] = { "acl_group 6", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_007] = { "acl_group 7", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_008] = { "acl_group 8", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_009] = { "acl_group 9", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_010] = { "acl_group 10", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_011] = { "acl_group 11", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_012] = { "acl_group 12", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_013] = { "acl_group 13", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_014] = { "acl_group 14", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_015] = { "acl_group 15", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_016] = { "acl_group 16", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_017] = { "acl_group 17", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_018] = { "acl_group 18", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_019] = { "acl_group 19", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_020] = { "acl_group 20", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_021] = { "acl_group 21", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_022] = { "acl_group 22", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_023] = { "acl_group 23", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_024] = { "acl_group 24", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_025] = { "acl_group 25", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_026] = { "acl_group 26", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_027] = { "acl_group 27", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_028] = { "acl_group 28", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_029] = { "acl_group 29", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_030] = { "acl_group 30", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_031] = { "acl_group 31", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_032] = { "acl_group 32", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_033] = { "acl_group 33", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_034] = { "acl_group 34", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_035] = { "acl_group 35", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_036] = { "acl_group 36", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_037] = { "acl_group 37", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_038] = { "acl_group 38", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_039] = { "acl_group 39", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_040] = { "acl_group 40", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_041] = { "acl_group 41", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_042] = { "acl_group 42", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_043] = { "acl_group 43", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_044] = { "acl_group 44", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_045] = { "acl_group 45", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_046] = { "acl_group 46", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_047] = { "acl_group 47", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_048] = { "acl_group 48", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_049] = { "acl_group 49", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_050] = { "acl_group 50", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_051] = { "acl_group 51", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_052] = { "acl_group 52", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_053] = { "acl_group 53", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_054] = { "acl_group 54", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_055] = { "acl_group 55", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_056] = { "acl_group 56", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_057] = { "acl_group 57", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_058] = { "acl_group 58", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_059] = { "acl_group 59", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_060] = { "acl_group 60", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_061] = { "acl_group 61", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_062] = { "acl_group 62", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_063] = { "acl_group 63", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_064] = { "acl_group 64", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_065] = { "acl_group 65", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_066] = { "acl_group 66", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_067] = { "acl_group 67", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_068] = { "acl_group 68", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_069] = { "acl_group 69", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_070] = { "acl_group 70", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_071] = { "acl_group 71", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_072] = { "acl_group 72", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_073] = { "acl_group 73", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_074] = { "acl_group 74", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_075] = { "acl_group 75", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_076] = { "acl_group 76", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_077] = { "acl_group 77", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_078] = { "acl_group 78", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_079] = { "acl_group 79", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_080] = { "acl_group 80", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_081] = { "acl_group 81", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_082] = { "acl_group 82", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_083] = { "acl_group 83", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_084] = { "acl_group 84", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_085] = { "acl_group 85", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_086] = { "acl_group 86", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_087] = { "acl_group 87", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_088] = { "acl_group 88", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_089] = { "acl_group 89", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_090] = { "acl_group 90", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_091] = { "acl_group 91", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_092] = { "acl_group 92", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_093] = { "acl_group 93", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_094] = { "acl_group 94", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_095] = { "acl_group 95", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_096] = { "acl_group 96", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_097] = { "acl_group 97", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_098] = { "acl_group 98", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_099] = { "acl_group 99", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_100] = { "acl_group 100", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_101] = { "acl_group 101", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_102] = { "acl_group 102", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_103] = { "acl_group 103", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_104] = { "acl_group 104", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_105] = { "acl_group 105", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_106] = { "acl_group 106", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_107] = { "acl_group 107", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_108] = { "acl_group 108", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_109] = { "acl_group 109", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_110] = { "acl_group 110", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_111] = { "acl_group 111", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_112] = { "acl_group 112", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_113] = { "acl_group 113", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_114] = { "acl_group 114", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_115] = { "acl_group 115", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_116] = { "acl_group 116", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_117] = { "acl_group 117", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_118] = { "acl_group 118", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_119] = { "acl_group 119", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_120] = { "acl_group 120", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_121] = { "acl_group 121", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_122] = { "acl_group 122", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_123] = { "acl_group 123", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_124] = { "acl_group 124", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_125] = { "acl_group 125", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_126] = { "acl_group 126", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_127] = { "acl_group 127", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_128] = { "acl_group 128", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_129] = { "acl_group 129", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_130] = { "acl_group 130", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_131] = { "acl_group 131", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_132] = { "acl_group 132", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_133] = { "acl_group 133", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_134] = { "acl_group 134", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_135] = { "acl_group 135", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_136] = { "acl_group 136", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_137] = { "acl_group 137", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_138] = { "acl_group 138", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_139] = { "acl_group 139", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_140] = { "acl_group 140", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_141] = { "acl_group 141", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_142] = { "acl_group 142", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_143] = { "acl_group 143", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_144] = { "acl_group 144", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_145] = { "acl_group 145", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_146] = { "acl_group 146", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_147] = { "acl_group 147", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_148] = { "acl_group 148", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_149] = { "acl_group 149", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_150] = { "acl_group 150", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_151] = { "acl_group 151", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_152] = { "acl_group 152", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_153] = { "acl_group 153", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_154] = { "acl_group 154", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_155] = { "acl_group 155", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_156] = { "acl_group 156", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_157] = { "acl_group 157", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_158] = { "acl_group 158", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_159] = { "acl_group 159", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_160] = { "acl_group 160", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_161] = { "acl_group 161", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_162] = { "acl_group 162", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_163] = { "acl_group 163", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_164] = { "acl_group 164", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_165] = { "acl_group 165", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_166] = { "acl_group 166", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_167] = { "acl_group 167", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_168] = { "acl_group 168", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_169] = { "acl_group 169", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_170] = { "acl_group 170", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_171] = { "acl_group 171", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_172] = { "acl_group 172", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_173] = { "acl_group 173", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_174] = { "acl_group 174", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_175] = { "acl_group 175", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_176] = { "acl_group 176", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_177] = { "acl_group 177", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_178] = { "acl_group 178", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_179] = { "acl_group 179", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_180] = { "acl_group 180", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_181] = { "acl_group 181", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_182] = { "acl_group 182", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_183] = { "acl_group 183", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_184] = { "acl_group 184", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_185] = { "acl_group 185", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_186] = { "acl_group 186", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_187] = { "acl_group 187", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_188] = { "acl_group 188", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_189] = { "acl_group 189", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_190] = { "acl_group 190", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_191] = { "acl_group 191", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_192] = { "acl_group 192", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_193] = { "acl_group 193", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_194] = { "acl_group 194", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_195] = { "acl_group 195", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_196] = { "acl_group 196", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_197] = { "acl_group 197", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_198] = { "acl_group 198", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_199] = { "acl_group 199", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_200] = { "acl_group 200", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_201] = { "acl_group 201", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_202] = { "acl_group 202", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_203] = { "acl_group 203", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_204] = { "acl_group 204", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_205] = { "acl_group 205", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_206] = { "acl_group 206", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_207] = { "acl_group 207", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_208] = { "acl_group 208", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_209] = { "acl_group 209", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_210] = { "acl_group 210", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_211] = { "acl_group 211", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_212] = { "acl_group 212", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_213] = { "acl_group 213", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_214] = { "acl_group 214", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_215] = { "acl_group 215", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_216] = { "acl_group 216", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_217] = { "acl_group 217", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_218] = { "acl_group 218", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_219] = { "acl_group 219", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_220] = { "acl_group 220", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_221] = { "acl_group 221", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_222] = { "acl_group 222", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_223] = { "acl_group 223", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_224] = { "acl_group 224", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_225] = { "acl_group 225", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_226] = { "acl_group 226", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_227] = { "acl_group 227", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_228] = { "acl_group 228", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_229] = { "acl_group 229", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_230] = { "acl_group 230", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_231] = { "acl_group 231", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_232] = { "acl_group 232", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_233] = { "acl_group 233", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_234] = { "acl_group 234", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_235] = { "acl_group 235", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_236] = { "acl_group 236", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_237] = { "acl_group 237", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_238] = { "acl_group 238", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_239] = { "acl_group 239", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_240] = { "acl_group 240", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_241] = { "acl_group 241", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_242] = { "acl_group 242", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_243] = { "acl_group 243", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_244] = { "acl_group 244", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_245] = { "acl_group 245", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_246] = { "acl_group 246", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_247] = { "acl_group 247", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_248] = { "acl_group 248", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_249] = { "acl_group 249", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_250] = { "acl_group 250", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_251] = { "acl_group 251", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_252] = { "acl_group 252", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_253] = { "acl_group 253", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_254] = { "acl_group 254", NULL, 0, 0 },
-	[CCS_DIRECTIVE_ACL_GROUP_255] = { "acl_group 255", NULL, 0, 0 },
+	[CCS_DIRECTIVE_ACL_GROUP] = { "acl_group", NULL, 0, 0 },
 	[CCS_DIRECTIVE_ADDRESS_GROUP] = { "address_group", NULL, 0, 0 },
 	[CCS_DIRECTIVE_AGGREGATOR]    = { "aggregator", NULL, 0, 0 },
 	[CCS_DIRECTIVE_CAPABILITY]    = { "capability", NULL, 0, 0 },
-	[CCS_DIRECTIVE_DENY_AUTOBIND] = { "deny_autobind", NULL, 0, 0 },
+	[CCS_DIRECTIVE_DEFAULT_TRANSITION]
+	= { "default_transition", NULL, 0, 0 },
 	[CCS_DIRECTIVE_FILE_APPEND]   = { "file append", NULL, 0, 0 },
 	[CCS_DIRECTIVE_FILE_CHGRP]    = { "file chgrp", NULL, 0, 0 },
 	[CCS_DIRECTIVE_FILE_CHMOD]    = { "file chmod", NULL, 0, 0 },
@@ -310,22 +56,14 @@
 	[CCS_DIRECTIVE_FILE_UNLINK]   = { "file unlink", NULL, 0, 0 },
 	[CCS_DIRECTIVE_FILE_UNMOUNT]  = { "file unmount", NULL, 0, 0 },
 	[CCS_DIRECTIVE_FILE_WRITE]    = { "file write", NULL, 0, 0 },
-	[CCS_DIRECTIVE_INITIALIZE_DOMAIN]
-	= { "initialize_domain", NULL, 0, 0 },
-	[CCS_DIRECTIVE_IPC_SIGNAL]    = { "ipc signal", NULL, 0, 0 },
-	[CCS_DIRECTIVE_KEEP_DOMAIN]   = { "keep_domain", NULL, 0, 0 },
+	[CCS_DIRECTIVE_IPC_PTRACE]    = { "ipc ptrace", NULL, 0, 0 },
 	[CCS_DIRECTIVE_MISC_ENV]      = { "misc env", NULL, 0, 0 },
 	[CCS_DIRECTIVE_NETWORK_INET]  = { "network inet", NULL, 0, 0 },
 	[CCS_DIRECTIVE_NETWORK_UNIX]  = { "network unix", NULL, 0, 0 },
 	[CCS_DIRECTIVE_NONE]          = { "", NULL, 0, 0 },
-	[CCS_DIRECTIVE_NO_INITIALIZE_DOMAIN]
-	= { "no_initialize_domain", NULL, 0, 0 },
-	[CCS_DIRECTIVE_NO_KEEP_DOMAIN] = { "no_keep_domain", NULL, 0, 0 },
-	[CCS_DIRECTIVE_NO_RESET_DOMAIN] = { "no_reset_domain", NULL, 0, 0 },
 	[CCS_DIRECTIVE_NUMBER_GROUP]  = { "number_group", NULL, 0, 0 },
 	[CCS_DIRECTIVE_PATH_GROUP]    = { "path_group", NULL, 0, 0 },
 	[CCS_DIRECTIVE_QUOTA_EXCEEDED] = { "quota_exceeded", NULL, 0, 0 },
-	[CCS_DIRECTIVE_RESET_DOMAIN]  = { "reset_domain", NULL, 0, 0 },
 	[CCS_DIRECTIVE_TASK_AUTO_DOMAIN_TRANSITION]
 	= { "task auto_domain_transition", NULL, 0, 0 },
 	[CCS_DIRECTIVE_TASK_AUTO_EXECUTE_HANDLER]
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy.h
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy.h	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/editpolicy.h	(working copy)
@@ -35,279 +35,13 @@
 	CCS_MAXSCREEN
 };
 
-enum ccs_transition_type {
-	/* Do not change this order, */
-	CCS_TRANSITION_CONTROL_NO_RESET,
-	CCS_TRANSITION_CONTROL_RESET,
-	CCS_TRANSITION_CONTROL_NO_INITIALIZE,
-	CCS_TRANSITION_CONTROL_INITIALIZE,
-	CCS_TRANSITION_CONTROL_NO_KEEP,
-	CCS_TRANSITION_CONTROL_KEEP,
-	CCS_MAX_TRANSITION_TYPE
-};
-
 enum ccs_editpolicy_directives {
 	CCS_DIRECTIVE_NONE,
-	CCS_DIRECTIVE_ACL_GROUP_000,
-	CCS_DIRECTIVE_ACL_GROUP_001,
-	CCS_DIRECTIVE_ACL_GROUP_002,
-	CCS_DIRECTIVE_ACL_GROUP_003,
-	CCS_DIRECTIVE_ACL_GROUP_004,
-	CCS_DIRECTIVE_ACL_GROUP_005,
-	CCS_DIRECTIVE_ACL_GROUP_006,
-	CCS_DIRECTIVE_ACL_GROUP_007,
-	CCS_DIRECTIVE_ACL_GROUP_008,
-	CCS_DIRECTIVE_ACL_GROUP_009,
-	CCS_DIRECTIVE_ACL_GROUP_010,
-	CCS_DIRECTIVE_ACL_GROUP_011,
-	CCS_DIRECTIVE_ACL_GROUP_012,
-	CCS_DIRECTIVE_ACL_GROUP_013,
-	CCS_DIRECTIVE_ACL_GROUP_014,
-	CCS_DIRECTIVE_ACL_GROUP_015,
-	CCS_DIRECTIVE_ACL_GROUP_016,
-	CCS_DIRECTIVE_ACL_GROUP_017,
-	CCS_DIRECTIVE_ACL_GROUP_018,
-	CCS_DIRECTIVE_ACL_GROUP_019,
-	CCS_DIRECTIVE_ACL_GROUP_020,
-	CCS_DIRECTIVE_ACL_GROUP_021,
-	CCS_DIRECTIVE_ACL_GROUP_022,
-	CCS_DIRECTIVE_ACL_GROUP_023,
-	CCS_DIRECTIVE_ACL_GROUP_024,
-	CCS_DIRECTIVE_ACL_GROUP_025,
-	CCS_DIRECTIVE_ACL_GROUP_026,
-	CCS_DIRECTIVE_ACL_GROUP_027,
-	CCS_DIRECTIVE_ACL_GROUP_028,
-	CCS_DIRECTIVE_ACL_GROUP_029,
-	CCS_DIRECTIVE_ACL_GROUP_030,
-	CCS_DIRECTIVE_ACL_GROUP_031,
-	CCS_DIRECTIVE_ACL_GROUP_032,
-	CCS_DIRECTIVE_ACL_GROUP_033,
-	CCS_DIRECTIVE_ACL_GROUP_034,
-	CCS_DIRECTIVE_ACL_GROUP_035,
-	CCS_DIRECTIVE_ACL_GROUP_036,
-	CCS_DIRECTIVE_ACL_GROUP_037,
-	CCS_DIRECTIVE_ACL_GROUP_038,
-	CCS_DIRECTIVE_ACL_GROUP_039,
-	CCS_DIRECTIVE_ACL_GROUP_040,
-	CCS_DIRECTIVE_ACL_GROUP_041,
-	CCS_DIRECTIVE_ACL_GROUP_042,
-	CCS_DIRECTIVE_ACL_GROUP_043,
-	CCS_DIRECTIVE_ACL_GROUP_044,
-	CCS_DIRECTIVE_ACL_GROUP_045,
-	CCS_DIRECTIVE_ACL_GROUP_046,
-	CCS_DIRECTIVE_ACL_GROUP_047,
-	CCS_DIRECTIVE_ACL_GROUP_048,
-	CCS_DIRECTIVE_ACL_GROUP_049,
-	CCS_DIRECTIVE_ACL_GROUP_050,
-	CCS_DIRECTIVE_ACL_GROUP_051,
-	CCS_DIRECTIVE_ACL_GROUP_052,
-	CCS_DIRECTIVE_ACL_GROUP_053,
-	CCS_DIRECTIVE_ACL_GROUP_054,
-	CCS_DIRECTIVE_ACL_GROUP_055,
-	CCS_DIRECTIVE_ACL_GROUP_056,
-	CCS_DIRECTIVE_ACL_GROUP_057,
-	CCS_DIRECTIVE_ACL_GROUP_058,
-	CCS_DIRECTIVE_ACL_GROUP_059,
-	CCS_DIRECTIVE_ACL_GROUP_060,
-	CCS_DIRECTIVE_ACL_GROUP_061,
-	CCS_DIRECTIVE_ACL_GROUP_062,
-	CCS_DIRECTIVE_ACL_GROUP_063,
-	CCS_DIRECTIVE_ACL_GROUP_064,
-	CCS_DIRECTIVE_ACL_GROUP_065,
-	CCS_DIRECTIVE_ACL_GROUP_066,
-	CCS_DIRECTIVE_ACL_GROUP_067,
-	CCS_DIRECTIVE_ACL_GROUP_068,
-	CCS_DIRECTIVE_ACL_GROUP_069,
-	CCS_DIRECTIVE_ACL_GROUP_070,
-	CCS_DIRECTIVE_ACL_GROUP_071,
-	CCS_DIRECTIVE_ACL_GROUP_072,
-	CCS_DIRECTIVE_ACL_GROUP_073,
-	CCS_DIRECTIVE_ACL_GROUP_074,
-	CCS_DIRECTIVE_ACL_GROUP_075,
-	CCS_DIRECTIVE_ACL_GROUP_076,
-	CCS_DIRECTIVE_ACL_GROUP_077,
-	CCS_DIRECTIVE_ACL_GROUP_078,
-	CCS_DIRECTIVE_ACL_GROUP_079,
-	CCS_DIRECTIVE_ACL_GROUP_080,
-	CCS_DIRECTIVE_ACL_GROUP_081,
-	CCS_DIRECTIVE_ACL_GROUP_082,
-	CCS_DIRECTIVE_ACL_GROUP_083,
-	CCS_DIRECTIVE_ACL_GROUP_084,
-	CCS_DIRECTIVE_ACL_GROUP_085,
-	CCS_DIRECTIVE_ACL_GROUP_086,
-	CCS_DIRECTIVE_ACL_GROUP_087,
-	CCS_DIRECTIVE_ACL_GROUP_088,
-	CCS_DIRECTIVE_ACL_GROUP_089,
-	CCS_DIRECTIVE_ACL_GROUP_090,
-	CCS_DIRECTIVE_ACL_GROUP_091,
-	CCS_DIRECTIVE_ACL_GROUP_092,
-	CCS_DIRECTIVE_ACL_GROUP_093,
-	CCS_DIRECTIVE_ACL_GROUP_094,
-	CCS_DIRECTIVE_ACL_GROUP_095,
-	CCS_DIRECTIVE_ACL_GROUP_096,
-	CCS_DIRECTIVE_ACL_GROUP_097,
-	CCS_DIRECTIVE_ACL_GROUP_098,
-	CCS_DIRECTIVE_ACL_GROUP_099,
-	CCS_DIRECTIVE_ACL_GROUP_100,
-	CCS_DIRECTIVE_ACL_GROUP_101,
-	CCS_DIRECTIVE_ACL_GROUP_102,
-	CCS_DIRECTIVE_ACL_GROUP_103,
-	CCS_DIRECTIVE_ACL_GROUP_104,
-	CCS_DIRECTIVE_ACL_GROUP_105,
-	CCS_DIRECTIVE_ACL_GROUP_106,
-	CCS_DIRECTIVE_ACL_GROUP_107,
-	CCS_DIRECTIVE_ACL_GROUP_108,
-	CCS_DIRECTIVE_ACL_GROUP_109,
-	CCS_DIRECTIVE_ACL_GROUP_110,
-	CCS_DIRECTIVE_ACL_GROUP_111,
-	CCS_DIRECTIVE_ACL_GROUP_112,
-	CCS_DIRECTIVE_ACL_GROUP_113,
-	CCS_DIRECTIVE_ACL_GROUP_114,
-	CCS_DIRECTIVE_ACL_GROUP_115,
-	CCS_DIRECTIVE_ACL_GROUP_116,
-	CCS_DIRECTIVE_ACL_GROUP_117,
-	CCS_DIRECTIVE_ACL_GROUP_118,
-	CCS_DIRECTIVE_ACL_GROUP_119,
-	CCS_DIRECTIVE_ACL_GROUP_120,
-	CCS_DIRECTIVE_ACL_GROUP_121,
-	CCS_DIRECTIVE_ACL_GROUP_122,
-	CCS_DIRECTIVE_ACL_GROUP_123,
-	CCS_DIRECTIVE_ACL_GROUP_124,
-	CCS_DIRECTIVE_ACL_GROUP_125,
-	CCS_DIRECTIVE_ACL_GROUP_126,
-	CCS_DIRECTIVE_ACL_GROUP_127,
-	CCS_DIRECTIVE_ACL_GROUP_128,
-	CCS_DIRECTIVE_ACL_GROUP_129,
-	CCS_DIRECTIVE_ACL_GROUP_130,
-	CCS_DIRECTIVE_ACL_GROUP_131,
-	CCS_DIRECTIVE_ACL_GROUP_132,
-	CCS_DIRECTIVE_ACL_GROUP_133,
-	CCS_DIRECTIVE_ACL_GROUP_134,
-	CCS_DIRECTIVE_ACL_GROUP_135,
-	CCS_DIRECTIVE_ACL_GROUP_136,
-	CCS_DIRECTIVE_ACL_GROUP_137,
-	CCS_DIRECTIVE_ACL_GROUP_138,
-	CCS_DIRECTIVE_ACL_GROUP_139,
-	CCS_DIRECTIVE_ACL_GROUP_140,
-	CCS_DIRECTIVE_ACL_GROUP_141,
-	CCS_DIRECTIVE_ACL_GROUP_142,
-	CCS_DIRECTIVE_ACL_GROUP_143,
-	CCS_DIRECTIVE_ACL_GROUP_144,
-	CCS_DIRECTIVE_ACL_GROUP_145,
-	CCS_DIRECTIVE_ACL_GROUP_146,
-	CCS_DIRECTIVE_ACL_GROUP_147,
-	CCS_DIRECTIVE_ACL_GROUP_148,
-	CCS_DIRECTIVE_ACL_GROUP_149,
-	CCS_DIRECTIVE_ACL_GROUP_150,
-	CCS_DIRECTIVE_ACL_GROUP_151,
-	CCS_DIRECTIVE_ACL_GROUP_152,
-	CCS_DIRECTIVE_ACL_GROUP_153,
-	CCS_DIRECTIVE_ACL_GROUP_154,
-	CCS_DIRECTIVE_ACL_GROUP_155,
-	CCS_DIRECTIVE_ACL_GROUP_156,
-	CCS_DIRECTIVE_ACL_GROUP_157,
-	CCS_DIRECTIVE_ACL_GROUP_158,
-	CCS_DIRECTIVE_ACL_GROUP_159,
-	CCS_DIRECTIVE_ACL_GROUP_160,
-	CCS_DIRECTIVE_ACL_GROUP_161,
-	CCS_DIRECTIVE_ACL_GROUP_162,
-	CCS_DIRECTIVE_ACL_GROUP_163,
-	CCS_DIRECTIVE_ACL_GROUP_164,
-	CCS_DIRECTIVE_ACL_GROUP_165,
-	CCS_DIRECTIVE_ACL_GROUP_166,
-	CCS_DIRECTIVE_ACL_GROUP_167,
-	CCS_DIRECTIVE_ACL_GROUP_168,
-	CCS_DIRECTIVE_ACL_GROUP_169,
-	CCS_DIRECTIVE_ACL_GROUP_170,
-	CCS_DIRECTIVE_ACL_GROUP_171,
-	CCS_DIRECTIVE_ACL_GROUP_172,
-	CCS_DIRECTIVE_ACL_GROUP_173,
-	CCS_DIRECTIVE_ACL_GROUP_174,
-	CCS_DIRECTIVE_ACL_GROUP_175,
-	CCS_DIRECTIVE_ACL_GROUP_176,
-	CCS_DIRECTIVE_ACL_GROUP_177,
-	CCS_DIRECTIVE_ACL_GROUP_178,
-	CCS_DIRECTIVE_ACL_GROUP_179,
-	CCS_DIRECTIVE_ACL_GROUP_180,
-	CCS_DIRECTIVE_ACL_GROUP_181,
-	CCS_DIRECTIVE_ACL_GROUP_182,
-	CCS_DIRECTIVE_ACL_GROUP_183,
-	CCS_DIRECTIVE_ACL_GROUP_184,
-	CCS_DIRECTIVE_ACL_GROUP_185,
-	CCS_DIRECTIVE_ACL_GROUP_186,
-	CCS_DIRECTIVE_ACL_GROUP_187,
-	CCS_DIRECTIVE_ACL_GROUP_188,
-	CCS_DIRECTIVE_ACL_GROUP_189,
-	CCS_DIRECTIVE_ACL_GROUP_190,
-	CCS_DIRECTIVE_ACL_GROUP_191,
-	CCS_DIRECTIVE_ACL_GROUP_192,
-	CCS_DIRECTIVE_ACL_GROUP_193,
-	CCS_DIRECTIVE_ACL_GROUP_194,
-	CCS_DIRECTIVE_ACL_GROUP_195,
-	CCS_DIRECTIVE_ACL_GROUP_196,
-	CCS_DIRECTIVE_ACL_GROUP_197,
-	CCS_DIRECTIVE_ACL_GROUP_198,
-	CCS_DIRECTIVE_ACL_GROUP_199,
-	CCS_DIRECTIVE_ACL_GROUP_200,
-	CCS_DIRECTIVE_ACL_GROUP_201,
-	CCS_DIRECTIVE_ACL_GROUP_202,
-	CCS_DIRECTIVE_ACL_GROUP_203,
-	CCS_DIRECTIVE_ACL_GROUP_204,
-	CCS_DIRECTIVE_ACL_GROUP_205,
-	CCS_DIRECTIVE_ACL_GROUP_206,
-	CCS_DIRECTIVE_ACL_GROUP_207,
-	CCS_DIRECTIVE_ACL_GROUP_208,
-	CCS_DIRECTIVE_ACL_GROUP_209,
-	CCS_DIRECTIVE_ACL_GROUP_210,
-	CCS_DIRECTIVE_ACL_GROUP_211,
-	CCS_DIRECTIVE_ACL_GROUP_212,
-	CCS_DIRECTIVE_ACL_GROUP_213,
-	CCS_DIRECTIVE_ACL_GROUP_214,
-	CCS_DIRECTIVE_ACL_GROUP_215,
-	CCS_DIRECTIVE_ACL_GROUP_216,
-	CCS_DIRECTIVE_ACL_GROUP_217,
-	CCS_DIRECTIVE_ACL_GROUP_218,
-	CCS_DIRECTIVE_ACL_GROUP_219,
-	CCS_DIRECTIVE_ACL_GROUP_220,
-	CCS_DIRECTIVE_ACL_GROUP_221,
-	CCS_DIRECTIVE_ACL_GROUP_222,
-	CCS_DIRECTIVE_ACL_GROUP_223,
-	CCS_DIRECTIVE_ACL_GROUP_224,
-	CCS_DIRECTIVE_ACL_GROUP_225,
-	CCS_DIRECTIVE_ACL_GROUP_226,
-	CCS_DIRECTIVE_ACL_GROUP_227,
-	CCS_DIRECTIVE_ACL_GROUP_228,
-	CCS_DIRECTIVE_ACL_GROUP_229,
-	CCS_DIRECTIVE_ACL_GROUP_230,
-	CCS_DIRECTIVE_ACL_GROUP_231,
-	CCS_DIRECTIVE_ACL_GROUP_232,
-	CCS_DIRECTIVE_ACL_GROUP_233,
-	CCS_DIRECTIVE_ACL_GROUP_234,
-	CCS_DIRECTIVE_ACL_GROUP_235,
-	CCS_DIRECTIVE_ACL_GROUP_236,
-	CCS_DIRECTIVE_ACL_GROUP_237,
-	CCS_DIRECTIVE_ACL_GROUP_238,
-	CCS_DIRECTIVE_ACL_GROUP_239,
-	CCS_DIRECTIVE_ACL_GROUP_240,
-	CCS_DIRECTIVE_ACL_GROUP_241,
-	CCS_DIRECTIVE_ACL_GROUP_242,
-	CCS_DIRECTIVE_ACL_GROUP_243,
-	CCS_DIRECTIVE_ACL_GROUP_244,
-	CCS_DIRECTIVE_ACL_GROUP_245,
-	CCS_DIRECTIVE_ACL_GROUP_246,
-	CCS_DIRECTIVE_ACL_GROUP_247,
-	CCS_DIRECTIVE_ACL_GROUP_248,
-	CCS_DIRECTIVE_ACL_GROUP_249,
-	CCS_DIRECTIVE_ACL_GROUP_250,
-	CCS_DIRECTIVE_ACL_GROUP_251,
-	CCS_DIRECTIVE_ACL_GROUP_252,
-	CCS_DIRECTIVE_ACL_GROUP_253,
-	CCS_DIRECTIVE_ACL_GROUP_254,
-	CCS_DIRECTIVE_ACL_GROUP_255,
+	CCS_DIRECTIVE_ACL_GROUP,
 	CCS_DIRECTIVE_ADDRESS_GROUP,
 	CCS_DIRECTIVE_AGGREGATOR,
 	CCS_DIRECTIVE_CAPABILITY,
-	CCS_DIRECTIVE_DENY_AUTOBIND,
+	CCS_DIRECTIVE_DEFAULT_TRANSITION,
 	CCS_DIRECTIVE_FILE_APPEND,
 	CCS_DIRECTIVE_FILE_CHGRP,
 	CCS_DIRECTIVE_FILE_CHMOD,
@@ -333,19 +67,13 @@
 	CCS_DIRECTIVE_FILE_UNLINK,
 	CCS_DIRECTIVE_FILE_UNMOUNT,
 	CCS_DIRECTIVE_FILE_WRITE,
-	CCS_DIRECTIVE_INITIALIZE_DOMAIN,
-	CCS_DIRECTIVE_IPC_SIGNAL,
-	CCS_DIRECTIVE_KEEP_DOMAIN,
+	CCS_DIRECTIVE_IPC_PTRACE,
 	CCS_DIRECTIVE_MISC_ENV,
 	CCS_DIRECTIVE_NETWORK_INET,
 	CCS_DIRECTIVE_NETWORK_UNIX,
-	CCS_DIRECTIVE_NO_INITIALIZE_DOMAIN,
-	CCS_DIRECTIVE_NO_KEEP_DOMAIN,
-	CCS_DIRECTIVE_NO_RESET_DOMAIN,
 	CCS_DIRECTIVE_NUMBER_GROUP,
 	CCS_DIRECTIVE_PATH_GROUP,
 	CCS_DIRECTIVE_QUOTA_EXCEEDED,
-	CCS_DIRECTIVE_RESET_DOMAIN,
 	CCS_DIRECTIVE_TASK_AUTO_DOMAIN_TRANSITION,
 	CCS_DIRECTIVE_TASK_AUTO_EXECUTE_HANDLER,
 	CCS_DIRECTIVE_TASK_DENIED_EXECUTE_HANDLER,
@@ -374,13 +102,6 @@
 	CCS_DISP_ERR
 };
 
-struct ccs_transition_control_entry {
-	const struct ccs_path_info *ns;
-	const struct ccs_path_info *domainname;    /* This may be NULL */
-	const struct ccs_path_info *program;       /* This may be NULL */
-	u8 type;
-};
-
 struct ccs_generic_acl {
 	enum ccs_editpolicy_directives directive;
 	u8 selected;
@@ -451,12 +172,12 @@
 struct ccs_domain {
 	const struct ccs_path_info *domainname;
 	const struct ccs_path_info *target; /* This may be NULL */
-	const struct ccs_transition_control_entry *d_t; /* This may be NULL */
-	const struct ccs_path_info **string_ptr;
-	int string_count;
+	//const struct ccs_default_transition *d_t; /* This may be NULL */
+	//const struct ccs_path_info **string_ptr;
+	//int string_count;
 	int number;   /* domain number (-1 if target or is_dd) */
 	u8 profile;
-	u8 group;
+	//u8 group;
 	_Bool is_djt; /* domain jump target */
 	_Bool is_dk;  /* domain keeper */
 	_Bool is_du;  /* unreachable domain */
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-savepolicy.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-savepolicy.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/ccs-savepolicy.c	(working copy)
@@ -78,6 +78,8 @@
 	    !ccs_move_proc_to_file(CCS_PROC_POLICY_MANAGER, "manager.conf") ||
 	    !ccs_move_proc_to_file(CCS_PROC_POLICY_EXCEPTION_POLICY,
 				   "exception_policy.conf") ||
+	    !ccs_move_proc_to_file(CCS_PROC_POLICY_ACL_POLICY,
+				   "acl_policy.conf") ||
 	    !ccs_move_proc_to_file(CCS_PROC_POLICY_DOMAIN_POLICY,
 				   "domain_policy.conf") ||
 	    chdir("..") ||
@@ -117,8 +119,8 @@
 			ccs_network_mode = true;
 		} else if (*ptr++ == '-' && !target) {
 			target = *ptr++;
-			if (target != 'e' && target != 'd' && target != 'p' &&
-			    target != 'm' && target != 's')
+			if (target != 'e' && target != 'a' && target != 'd' &&
+			    target != 'p' && target != 'm' && target != 's')
 				goto usage;
 			if (*ptr || ccs_policy_dir) {
 				fprintf(stderr, "You cannot specify multiple "
@@ -149,6 +151,9 @@
 		case 'e':
 			file = CCS_PROC_POLICY_EXCEPTION_POLICY;
 			break;
+		case 'a':
+			file = CCS_PROC_POLICY_ACL_POLICY;
+			break;
 		case 'd':
 			file = CCS_PROC_POLICY_DOMAIN_POLICY;
 			break;
@@ -174,12 +179,13 @@
 	return !ccs_save_policy();
 usage:
 	printf("%s [policy_dir [remote_ip:remote_port]]\n"
-	       "%s [{-e|-d|-p|-m|-s} [remote_ip:remote_port]]\n\n"
+	       "%s [{-e|-a|-d|-p|-m|-s} [remote_ip:remote_port]]\n\n"
 	       "policy_dir : Use policy_dir rather than /etc/ccs/ directory.\n"
 	       "remote_ip:remote_port : Read from ccs-editpolicy-agent "
 	       "listening at remote_ip:remote_port rather than /proc/ccs/ "
 	       "directory.\n"
 	       "-e : Print /proc/ccs/exception_policy to stdout.\n"
+	       "-a : Print /proc/ccs/acl_policy to stdout.\n"
 	       "-d : Print /proc/ccs/domain_policy to stdout.\n"
 	       "-p : Print /proc/ccs/profile to stdout.\n"
 	       "-m : Print /proc/ccs/manager to stdout.\n"
Index: trunk/1.8.x/ccs-tools/ccstools/usr_sbin/Makefile
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_sbin/Makefile	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_sbin/Makefile	(working copy)
@@ -15,13 +15,13 @@
 	sleep 10
 
 libccstools.so: ccstools.c ccstools.h
-	$(CC) $(CFLAGS) -fPIC ccstools.c -shared -Wl,-soname,libccstools.so.3 -o libccstools.so.3.0.0
-	ln -sf libccstools.so.3.0.0 libccstools.so
+	$(CC) $(CFLAGS) -fPIC ccstools.c -shared -Wl,-soname,libccstools.so.4 -o libccstools.so.4.0.0
+	ln -sf libccstools.so.4.0.0 libccstools.so
 
 .c:
 	$(CC) $(CFLAGS) -o $@ $< -lccstools -L. 
 
-ccs-editpolicy: ccstools.h editpolicy*.c readline.h /usr/include/curses.h libccstools.so
+ccs-editpolicy: ccstools.h editpolicy*.c readline.h /usr/include/curses.h libccstools.so editpolicy.h
 	$(CC) $(CFLAGS) -o ccs-editpolicy editpolicy*.c -lncurses -lccstools -L. -DCOLOR_ON
 
 ccs-queryd: ccstools.h ccs-queryd.c readline.h /usr/include/curses.h libccstools.so
@@ -29,8 +29,8 @@
 
 install: all
 	mkdir -p -m 0755 $(INSTALLDIR)$(USRLIBDIR)
-	$(INSTALL) -m 0755 libccstools.so.3.0.0 $(INSTALLDIR)$(USRLIBDIR)
-	ln -sf libccstools.so.3.0.0 $(INSTALLDIR)$(USRLIBDIR)/libccstools.so.3
+	$(INSTALL) -m 0755 libccstools.so.4.0.0 $(INSTALLDIR)$(USRLIBDIR)
+	ln -sf libccstools.so.4.0.0 $(INSTALLDIR)$(USRLIBDIR)/libccstools.so.4
 ifeq ($(INSTALLDIR),)
 	ldconfig || true
 endif
Index: trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/init_policy.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/init_policy.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/init_policy.c	(working copy)
@@ -212,11 +212,10 @@
  *
  * If @str starts with "/proc/", it is converted with "proc:/".
  * If keyword is not NULL, keyword is printed before printing @str.
- * If keyword is "initialize_domain", " from any" is printed after printing
- * @str.
  */
 static void printf_encoded(const char *str)
 {
+	const char *str0 = str;
 	if (keyword)
 		fprintf(filp, "%s ", keyword);
 	if (!strncmp(str, "/proc/", 6)) {
@@ -237,8 +236,24 @@
 				((c >> 3) & 7) + '0', (c & 7) + '0');
 		}
 	}
-	if (keyword && !strcmp(keyword, "initialize_domain"))
-		fprintf(filp, " from any");
+	if (keyword && !strcmp(keyword, "default_transition")) {
+		str = str0;
+		fprintf(filp, " <kernel> ");
+		while (1) {
+			const char c = *str++;
+			if (!c)
+				break;
+			if (c == '\\') {
+				fputc('\\', filp);
+				fputc('\\', filp);
+			} else if (c > ' ' && c < 127) {
+				fputc(c, filp);
+			} else {
+				fprintf(filp, "\\%c%c%c", (c >> 6) + '0',
+					((c >> 3) & 7) + '0', (c & 7) + '0');
+			}
+		}
+	}
 	if (keyword)
 		fputc('\n', filp);
 }
@@ -247,7 +262,7 @@
 static char path[8192];
 
 /**
- * scan_init_scripts - Scan /etc/rc\?.d/ directories for initialize_domain entries.
+ * scan_init_scripts - Scan /etc/rc\?.d/ directories for default_transition entries.
  *
  * Returns nothing.
  */
@@ -277,7 +292,7 @@
 			path[len] = '\0';
 			if (entity) {
 				char *cp = strrchr(path, '/');
-				fprintf(filp, "aggregator ");
+				fprintf(filp, "default_transition ");
 				/*
 				 * Use /rc\?.d/ rather than /rc0.d/ /rc1.d/
 				 * /rc2.d/ /rc3.d/ /rc4.d/ /rc5.d/ /rc6.d/
@@ -295,6 +310,7 @@
 				fprintf(filp, "/\\?\\+\\+");
 				printf_encoded(name + 3);
 				fputc(' ', filp);
+				fprintf(filp, "<kernel> ");
 				printf_encoded(entity);
 				fputc('\n', filp);
 				free(entity);
@@ -306,13 +322,13 @@
 }
 
 /**
- * make_init_scripts_as_aggregators - Use realpath for startup/shutdown scripts in /etc/ directory.
+ * make_init_scripts_as_default_transitions - Use realpath for startup/shutdown scripts in /etc/ directory.
  *
  * Returns nothing.
  */
-static void make_init_scripts_as_aggregators(void)
+static void make_init_scripts_as_default_transitions(void)
 {
-	/* Mark symlinks under /etc/rc\?.d/ directory as aggregator. */
+	/* Mark symlinks under /etc/rc\?.d/ directory as default_transition. */
 	static const char * const dirs[] = {
 		"/etc/boot.d", "/etc/rc.d/boot.d", "/etc/init.d/boot.d",
 		"/etc/rc0.d", "/etc/rd1.d", "/etc/rc2.d", "/etc/rc3.d",
@@ -363,7 +379,7 @@
 }
 
 /**
- * scan_modprobe_and_hotplug - Mark modprobe and hotplug as initialize_domain entries.
+ * scan_modprobe_and_hotplug - Mark modprobe and hotplug as default_transition entries.
  *
  * Returns nothing.
  */
@@ -393,7 +409,7 @@
 			continue;
 		/* We ignore /bin/true if /proc/sys/kernel/modprobe said so. */
 		if (strcmp(cp, "/bin/true") && !access(cp, X_OK)) {
-			keyword = "initialize_domain";
+			keyword = "default_transition";
 			printf_encoded(cp);
 		}
 		free(cp);
@@ -417,7 +433,7 @@
 		"/usr/share/locale/locale.alias"
 	};
 	int i;
-	keyword = "acl_group 0 file read";
+	keyword = "acl_group GLOBALLY_GRANTED_PERMISSIONS file read";
 	for (i = 0; i < elementof(files); i++) {
 		char *cp = get_realpath(files[i]);
 		if (!cp)
@@ -435,8 +451,10 @@
 static void make_self_readable_files(void)
 {
 	/* Allow reading information for current process. */
-	echo("acl_group 0 file read proc:/self/\\*");
-	echo("acl_group 0 file read proc:/self/\\{\\*\\}/\\*");
+	echo("acl_group GLOBALLY_GRANTED_PERMISSIONS file read "
+	     "proc:/self/\\*");
+	echo("acl_group GLOBALLY_GRANTED_PERMISSIONS file read "
+	     "proc:/self/\\{\\*\\}/\\*");
 }
 
 /**
@@ -472,7 +490,8 @@
 		char *cp = get_realpath(dirs[i]);
 		if (!cp)
 			continue;
-		fprintf(filp, "acl_group 0 file read ");
+		fprintf(filp, "acl_group GLOBALLY_GRANTED_PERMISSIONS "
+			"file read ");
 		printf_encoded(cp);
 		fprintf(filp, "/lib\\*.so\\*\n");
 		free(cp);
@@ -501,7 +520,8 @@
 			const int len = strlen(cp);
 			char buf[16];
 			memset(buf, 0, sizeof(buf));
-			fprintf(filp, "acl_group 0 file read ");
+			fprintf(filp, "acl_group GLOBALLY_GRANTED_PERMISSIONS "
+				"file read ");
 			if (cp2 && !strncmp(cp2, "/ld-2.", 6) &&
 			    len > 3 && !strcmp(cp + len - 3, ".so"))
 				*(cp2 + 6) = '\0';
@@ -518,26 +538,26 @@
 }
 
 /**
- * make_init_dir_as_initializers - Mark programs under /etc/init.d/ directory as initialize_domain entries.
+ * make_init_dir_as_default_transitions - Mark programs under /etc/init.d/ directory as default_transition entries.
  *
  * Returns nothing.
  */
-static void make_init_dir_as_initializers(void)
+static void make_init_dir_as_default_transitions(void)
 {
 	char *dir = get_realpath("/etc/init.d/");
 	if (!dir)
 		return;
-	keyword = "initialize_domain";
+	keyword = "default_transition";
 	scan_executable_files(dir);
 	free(dir);
 }
 
 /**
- * make_initializers - Mark daemon programs as initialize_domain entries.
+ * make_daemons_as_default_transitions - Mark daemon programs as default_transition entries.
  *
  * Returns nothing.
  */
-static void make_initializers(void)
+static void make_daemons_as_default_transitions(void)
 {
 	static const char * const files[] = {
 		"/sbin/cardmgr",
@@ -592,7 +612,7 @@
 		"/usr/sbin/xinetd"
 	};
 	int i;
-	keyword = "initialize_domain";
+	keyword = "default_transition";
 	for (i = 0; i < elementof(files); i++) {
 		char *cp = get_realpath(files[i]);
 		if (!cp)
@@ -688,30 +708,6 @@
 }
 
 /**
- * make_path_group - Make path_group entries.
- *
- * Returns nothing.
- */
-static void make_path_group(void)
-{
-	echo("path_group ANY_PATHNAME /");
-	echo("path_group ANY_PATHNAME /\\*");
-	echo("path_group ANY_PATHNAME /\\{\\*\\}/");
-	echo("path_group ANY_PATHNAME /\\{\\*\\}/\\*");
-	echo("path_group ANY_PATHNAME \\*:/");
-	echo("path_group ANY_PATHNAME \\*:/\\*");
-	echo("path_group ANY_PATHNAME \\*:/\\{\\*\\}/");
-	echo("path_group ANY_PATHNAME \\*:/\\{\\*\\}/\\*");
-	echo("path_group ANY_PATHNAME \\*:[\\$]");
-	echo("path_group ANY_PATHNAME "
-	     "socket:[family=\\$:type=\\$:protocol=\\$]");
-	echo("path_group ANY_DIRECTORY /");
-	echo("path_group ANY_DIRECTORY /\\{\\*\\}/");
-	echo("path_group ANY_DIRECTORY \\*:/");
-	echo("path_group ANY_DIRECTORY \\*:/\\{\\*\\}/");
-}
-
-/**
  * make_number_group - Make number_group entries.
  *
  * Returns nothing.
@@ -728,7 +724,8 @@
  */
 static void make_ioctl(void)
 {
-	echo("acl_group 0 file ioctl @ANY_PATHNAME @COMMON_IOCTL_CMDS");
+	echo("acl_group GLOBALLY_GRANTED_PERMISSIONS file ioctl \\=any "
+	     "@COMMON_IOCTL_CMDS");
 }
 
 /**
@@ -738,7 +735,7 @@
  */
 static void make_getattr(void)
 {
-	echo("acl_group 0 file getattr @ANY_PATHNAME");
+	echo("acl_group GLOBALLY_GRANTED_PERMISSIONS file getattr \\=any");
 }
 
 /**
@@ -748,7 +745,8 @@
  */
 static void make_readdir(void)
 {
-	echo("acl_group 0 file read @ANY_DIRECTORY");
+	echo("acl_group GLOBALLY_GRANTED_PERMISSIONS file read \\=any "
+	     "path1.type=directory");
 }
 
 /**
@@ -805,17 +803,14 @@
 	make_globally_readable_files();
 	make_self_readable_files();
 	make_ldconfig_readable_files();
-	make_path_group();
 	make_number_group();
 	make_ioctl();
 	make_readdir();
 	make_getattr();
 	scan_modprobe_and_hotplug();
-	make_init_dir_as_initializers();
-	make_initializers();
-	make_init_scripts_as_aggregators();
-	/* Some applications do execve("/proc/self/exe"). */
-	fprintf(filp, "aggregator proc:/self/exe /proc/self/exe\n");
+	make_daemons_as_default_transitions();
+	make_init_dir_as_default_transitions();
+	make_init_scripts_as_default_transitions();
 	close_file(filp, chdir_policy(), "exception_policy.tmp",
 		   "exception_policy.conf");
 	filp = NULL;
@@ -913,8 +908,6 @@
 
 /* Which profile number does <kernel> domain use? */
 static unsigned char default_profile = 0;
-/* Which ACL group does <kernel> domain use? */
-static unsigned char default_group = 0;
 
 /**
  * make_domain_policy - Make /etc/ccs/policy/current/domain_policy.conf .
@@ -934,8 +927,9 @@
 		return;
 	}
 	fprintf(stderr, "Creating domain policy... ");
-	fprintf(fp, "<kernel>\nuse_profile %u\nuse_group %u\n",
-		default_profile, default_group);
+	fprintf(fp, "<kernel>\nuse_profile %u\n"
+		"use_group \\=GLOBALLY_GRANTED_PERMISSIONS\n",
+		default_profile);
 	close_file(fp, 1, "domain_policy.tmp", "domain_policy.conf");
 }
 
@@ -994,266 +988,10 @@
 "# This file contains configuration used by ccs-editpolicy command.\n"
 "\n"
 "# Keyword alias. ( directive-name = display-name )\n"
-"keyword_alias acl_group   0                 = acl_group   0\n"
-"keyword_alias acl_group   1                 = acl_group   1\n"
-"keyword_alias acl_group   2                 = acl_group   2\n"
-"keyword_alias acl_group   3                 = acl_group   3\n"
-"keyword_alias acl_group   4                 = acl_group   4\n"
-"keyword_alias acl_group   5                 = acl_group   5\n"
-"keyword_alias acl_group   6                 = acl_group   6\n"
-"keyword_alias acl_group   7                 = acl_group   7\n"
-"keyword_alias acl_group   8                 = acl_group   8\n"
-"keyword_alias acl_group   9                 = acl_group   9\n"
-"keyword_alias acl_group  10                 = acl_group  10\n"
-"keyword_alias acl_group  11                 = acl_group  11\n"
-"keyword_alias acl_group  12                 = acl_group  12\n"
-"keyword_alias acl_group  13                 = acl_group  13\n"
-"keyword_alias acl_group  14                 = acl_group  14\n"
-"keyword_alias acl_group  15                 = acl_group  15\n"
-"keyword_alias acl_group  16                 = acl_group  16\n"
-"keyword_alias acl_group  17                 = acl_group  17\n"
-"keyword_alias acl_group  18                 = acl_group  18\n"
-"keyword_alias acl_group  19                 = acl_group  19\n"
-"keyword_alias acl_group  20                 = acl_group  20\n"
-"keyword_alias acl_group  21                 = acl_group  21\n"
-"keyword_alias acl_group  22                 = acl_group  22\n"
-"keyword_alias acl_group  23                 = acl_group  23\n"
-"keyword_alias acl_group  24                 = acl_group  24\n"
-"keyword_alias acl_group  25                 = acl_group  25\n"
-"keyword_alias acl_group  26                 = acl_group  26\n"
-"keyword_alias acl_group  27                 = acl_group  27\n"
-"keyword_alias acl_group  28                 = acl_group  28\n"
-"keyword_alias acl_group  29                 = acl_group  29\n"
-"keyword_alias acl_group  30                 = acl_group  30\n"
-"keyword_alias acl_group  31                 = acl_group  31\n"
-"keyword_alias acl_group  32                 = acl_group  32\n"
-"keyword_alias acl_group  33                 = acl_group  33\n"
-"keyword_alias acl_group  34                 = acl_group  34\n"
-"keyword_alias acl_group  35                 = acl_group  35\n"
-"keyword_alias acl_group  36                 = acl_group  36\n"
-"keyword_alias acl_group  37                 = acl_group  37\n"
-"keyword_alias acl_group  38                 = acl_group  38\n"
-"keyword_alias acl_group  39                 = acl_group  39\n"
-"keyword_alias acl_group  40                 = acl_group  40\n"
-"keyword_alias acl_group  41                 = acl_group  41\n"
-"keyword_alias acl_group  42                 = acl_group  42\n"
-"keyword_alias acl_group  43                 = acl_group  43\n"
-"keyword_alias acl_group  44                 = acl_group  44\n"
-"keyword_alias acl_group  45                 = acl_group  45\n"
-"keyword_alias acl_group  46                 = acl_group  46\n"
-"keyword_alias acl_group  47                 = acl_group  47\n"
-"keyword_alias acl_group  48                 = acl_group  48\n"
-"keyword_alias acl_group  49                 = acl_group  49\n"
-"keyword_alias acl_group  50                 = acl_group  50\n"
-"keyword_alias acl_group  51                 = acl_group  51\n"
-"keyword_alias acl_group  52                 = acl_group  52\n"
-"keyword_alias acl_group  53                 = acl_group  53\n"
-"keyword_alias acl_group  54                 = acl_group  54\n"
-"keyword_alias acl_group  55                 = acl_group  55\n"
-"keyword_alias acl_group  56                 = acl_group  56\n"
-"keyword_alias acl_group  57                 = acl_group  57\n"
-"keyword_alias acl_group  58                 = acl_group  58\n"
-"keyword_alias acl_group  59                 = acl_group  59\n"
-"keyword_alias acl_group  60                 = acl_group  60\n"
-"keyword_alias acl_group  61                 = acl_group  61\n"
-"keyword_alias acl_group  62                 = acl_group  62\n"
-"keyword_alias acl_group  63                 = acl_group  63\n"
-"keyword_alias acl_group  64                 = acl_group  64\n"
-"keyword_alias acl_group  65                 = acl_group  65\n"
-"keyword_alias acl_group  66                 = acl_group  66\n"
-"keyword_alias acl_group  67                 = acl_group  67\n"
-"keyword_alias acl_group  68                 = acl_group  68\n"
-"keyword_alias acl_group  69                 = acl_group  69\n"
-"keyword_alias acl_group  70                 = acl_group  70\n"
-"keyword_alias acl_group  71                 = acl_group  71\n"
-"keyword_alias acl_group  72                 = acl_group  72\n"
-"keyword_alias acl_group  73                 = acl_group  73\n"
-"keyword_alias acl_group  74                 = acl_group  74\n"
-"keyword_alias acl_group  75                 = acl_group  75\n"
-"keyword_alias acl_group  76                 = acl_group  76\n"
-"keyword_alias acl_group  77                 = acl_group  77\n"
-"keyword_alias acl_group  78                 = acl_group  78\n"
-"keyword_alias acl_group  79                 = acl_group  79\n"
-"keyword_alias acl_group  80                 = acl_group  80\n"
-"keyword_alias acl_group  81                 = acl_group  81\n"
-"keyword_alias acl_group  82                 = acl_group  82\n"
-"keyword_alias acl_group  83                 = acl_group  83\n"
-"keyword_alias acl_group  84                 = acl_group  84\n"
-"keyword_alias acl_group  85                 = acl_group  85\n"
-"keyword_alias acl_group  86                 = acl_group  86\n"
-"keyword_alias acl_group  87                 = acl_group  87\n"
-"keyword_alias acl_group  88                 = acl_group  88\n"
-"keyword_alias acl_group  89                 = acl_group  89\n"
-"keyword_alias acl_group  90                 = acl_group  90\n"
-"keyword_alias acl_group  91                 = acl_group  91\n"
-"keyword_alias acl_group  92                 = acl_group  92\n"
-"keyword_alias acl_group  93                 = acl_group  93\n"
-"keyword_alias acl_group  94                 = acl_group  94\n"
-"keyword_alias acl_group  95                 = acl_group  95\n"
-"keyword_alias acl_group  96                 = acl_group  96\n"
-"keyword_alias acl_group  97                 = acl_group  97\n"
-"keyword_alias acl_group  98                 = acl_group  98\n"
-"keyword_alias acl_group  99                 = acl_group  99\n"
-"keyword_alias acl_group 100                 = acl_group 100\n"
-"keyword_alias acl_group 101                 = acl_group 101\n"
-"keyword_alias acl_group 102                 = acl_group 102\n"
-"keyword_alias acl_group 103                 = acl_group 103\n"
-"keyword_alias acl_group 104                 = acl_group 104\n"
-"keyword_alias acl_group 105                 = acl_group 105\n"
-"keyword_alias acl_group 106                 = acl_group 106\n"
-"keyword_alias acl_group 107                 = acl_group 107\n"
-"keyword_alias acl_group 108                 = acl_group 108\n"
-"keyword_alias acl_group 109                 = acl_group 109\n"
-"keyword_alias acl_group 110                 = acl_group 110\n"
-"keyword_alias acl_group 111                 = acl_group 111\n"
-"keyword_alias acl_group 112                 = acl_group 112\n"
-"keyword_alias acl_group 113                 = acl_group 113\n"
-"keyword_alias acl_group 114                 = acl_group 114\n"
-"keyword_alias acl_group 115                 = acl_group 115\n"
-"keyword_alias acl_group 116                 = acl_group 116\n"
-"keyword_alias acl_group 117                 = acl_group 117\n"
-"keyword_alias acl_group 118                 = acl_group 118\n"
-"keyword_alias acl_group 119                 = acl_group 119\n"
-"keyword_alias acl_group 120                 = acl_group 120\n"
-"keyword_alias acl_group 121                 = acl_group 121\n"
-"keyword_alias acl_group 122                 = acl_group 122\n"
-"keyword_alias acl_group 123                 = acl_group 123\n"
-"keyword_alias acl_group 124                 = acl_group 124\n"
-"keyword_alias acl_group 125                 = acl_group 125\n"
-"keyword_alias acl_group 126                 = acl_group 126\n"
-"keyword_alias acl_group 127                 = acl_group 127\n"
-"keyword_alias acl_group 128                 = acl_group 128\n"
-"keyword_alias acl_group 129                 = acl_group 129\n"
-"keyword_alias acl_group 130                 = acl_group 130\n"
-"keyword_alias acl_group 131                 = acl_group 131\n"
-"keyword_alias acl_group 132                 = acl_group 132\n"
-"keyword_alias acl_group 133                 = acl_group 133\n"
-"keyword_alias acl_group 134                 = acl_group 134\n"
-"keyword_alias acl_group 135                 = acl_group 135\n"
-"keyword_alias acl_group 136                 = acl_group 136\n"
-"keyword_alias acl_group 137                 = acl_group 137\n"
-"keyword_alias acl_group 138                 = acl_group 138\n"
-"keyword_alias acl_group 139                 = acl_group 139\n"
-"keyword_alias acl_group 140                 = acl_group 140\n"
-"keyword_alias acl_group 141                 = acl_group 141\n"
-"keyword_alias acl_group 142                 = acl_group 142\n"
-"keyword_alias acl_group 143                 = acl_group 143\n"
-"keyword_alias acl_group 144                 = acl_group 144\n"
-"keyword_alias acl_group 145                 = acl_group 145\n"
-"keyword_alias acl_group 146                 = acl_group 146\n"
-"keyword_alias acl_group 147                 = acl_group 147\n"
-"keyword_alias acl_group 148                 = acl_group 148\n"
-"keyword_alias acl_group 149                 = acl_group 149\n"
-"keyword_alias acl_group 150                 = acl_group 150\n"
-"keyword_alias acl_group 151                 = acl_group 151\n"
-"keyword_alias acl_group 152                 = acl_group 152\n"
-"keyword_alias acl_group 153                 = acl_group 153\n"
-"keyword_alias acl_group 154                 = acl_group 154\n"
-"keyword_alias acl_group 155                 = acl_group 155\n"
-"keyword_alias acl_group 156                 = acl_group 156\n"
-"keyword_alias acl_group 157                 = acl_group 157\n"
-"keyword_alias acl_group 158                 = acl_group 158\n"
-"keyword_alias acl_group 159                 = acl_group 159\n"
-"keyword_alias acl_group 160                 = acl_group 160\n"
-"keyword_alias acl_group 161                 = acl_group 161\n"
-"keyword_alias acl_group 162                 = acl_group 162\n"
-"keyword_alias acl_group 163                 = acl_group 163\n"
-"keyword_alias acl_group 164                 = acl_group 164\n"
-"keyword_alias acl_group 165                 = acl_group 165\n"
-"keyword_alias acl_group 166                 = acl_group 166\n"
-"keyword_alias acl_group 167                 = acl_group 167\n"
-"keyword_alias acl_group 168                 = acl_group 168\n"
-"keyword_alias acl_group 169                 = acl_group 169\n"
-"keyword_alias acl_group 170                 = acl_group 170\n"
-"keyword_alias acl_group 171                 = acl_group 171\n"
-"keyword_alias acl_group 172                 = acl_group 172\n"
-"keyword_alias acl_group 173                 = acl_group 173\n"
-"keyword_alias acl_group 174                 = acl_group 174\n"
-"keyword_alias acl_group 175                 = acl_group 175\n"
-"keyword_alias acl_group 176                 = acl_group 176\n"
-"keyword_alias acl_group 177                 = acl_group 177\n"
-"keyword_alias acl_group 178                 = acl_group 178\n"
-"keyword_alias acl_group 179                 = acl_group 179\n"
-"keyword_alias acl_group 180                 = acl_group 180\n"
-"keyword_alias acl_group 181                 = acl_group 181\n"
-"keyword_alias acl_group 182                 = acl_group 182\n"
-"keyword_alias acl_group 183                 = acl_group 183\n"
-"keyword_alias acl_group 184                 = acl_group 184\n"
-"keyword_alias acl_group 185                 = acl_group 185\n"
-"keyword_alias acl_group 186                 = acl_group 186\n"
-"keyword_alias acl_group 187                 = acl_group 187\n"
-"keyword_alias acl_group 188                 = acl_group 188\n"
-"keyword_alias acl_group 189                 = acl_group 189\n"
-"keyword_alias acl_group 190                 = acl_group 190\n"
-"keyword_alias acl_group 191                 = acl_group 191\n"
-"keyword_alias acl_group 192                 = acl_group 192\n"
-"keyword_alias acl_group 193                 = acl_group 193\n"
-"keyword_alias acl_group 194                 = acl_group 194\n"
-"keyword_alias acl_group 195                 = acl_group 195\n"
-"keyword_alias acl_group 196                 = acl_group 196\n"
-"keyword_alias acl_group 197                 = acl_group 197\n"
-"keyword_alias acl_group 198                 = acl_group 198\n"
-"keyword_alias acl_group 199                 = acl_group 199\n"
-"keyword_alias acl_group 200                 = acl_group 200\n"
-"keyword_alias acl_group 201                 = acl_group 201\n"
-"keyword_alias acl_group 202                 = acl_group 202\n"
-"keyword_alias acl_group 203                 = acl_group 203\n"
-"keyword_alias acl_group 204                 = acl_group 204\n"
-"keyword_alias acl_group 205                 = acl_group 205\n"
-"keyword_alias acl_group 206                 = acl_group 206\n"
-"keyword_alias acl_group 207                 = acl_group 207\n"
-"keyword_alias acl_group 208                 = acl_group 208\n"
-"keyword_alias acl_group 209                 = acl_group 209\n"
-"keyword_alias acl_group 210                 = acl_group 210\n"
-"keyword_alias acl_group 211                 = acl_group 211\n"
-"keyword_alias acl_group 212                 = acl_group 212\n"
-"keyword_alias acl_group 213                 = acl_group 213\n"
-"keyword_alias acl_group 214                 = acl_group 214\n"
-"keyword_alias acl_group 215                 = acl_group 215\n"
-"keyword_alias acl_group 216                 = acl_group 216\n"
-"keyword_alias acl_group 217                 = acl_group 217\n"
-"keyword_alias acl_group 218                 = acl_group 218\n"
-"keyword_alias acl_group 219                 = acl_group 219\n"
-"keyword_alias acl_group 220                 = acl_group 220\n"
-"keyword_alias acl_group 221                 = acl_group 221\n"
-"keyword_alias acl_group 222                 = acl_group 222\n"
-"keyword_alias acl_group 223                 = acl_group 223\n"
-"keyword_alias acl_group 224                 = acl_group 224\n"
-"keyword_alias acl_group 225                 = acl_group 225\n"
-"keyword_alias acl_group 226                 = acl_group 226\n"
-"keyword_alias acl_group 227                 = acl_group 227\n"
-"keyword_alias acl_group 228                 = acl_group 228\n"
-"keyword_alias acl_group 229                 = acl_group 229\n"
-"keyword_alias acl_group 230                 = acl_group 230\n"
-"keyword_alias acl_group 231                 = acl_group 231\n"
-"keyword_alias acl_group 232                 = acl_group 232\n"
-"keyword_alias acl_group 233                 = acl_group 233\n"
-"keyword_alias acl_group 234                 = acl_group 234\n"
-"keyword_alias acl_group 235                 = acl_group 235\n"
-"keyword_alias acl_group 236                 = acl_group 236\n"
-"keyword_alias acl_group 237                 = acl_group 237\n"
-"keyword_alias acl_group 238                 = acl_group 238\n"
-"keyword_alias acl_group 239                 = acl_group 239\n"
-"keyword_alias acl_group 240                 = acl_group 240\n"
-"keyword_alias acl_group 241                 = acl_group 241\n"
-"keyword_alias acl_group 242                 = acl_group 242\n"
-"keyword_alias acl_group 243                 = acl_group 243\n"
-"keyword_alias acl_group 244                 = acl_group 244\n"
-"keyword_alias acl_group 245                 = acl_group 245\n"
-"keyword_alias acl_group 246                 = acl_group 246\n"
-"keyword_alias acl_group 247                 = acl_group 247\n"
-"keyword_alias acl_group 248                 = acl_group 248\n"
-"keyword_alias acl_group 249                 = acl_group 249\n"
-"keyword_alias acl_group 250                 = acl_group 250\n"
-"keyword_alias acl_group 251                 = acl_group 251\n"
-"keyword_alias acl_group 252                 = acl_group 252\n"
-"keyword_alias acl_group 253                 = acl_group 253\n"
-"keyword_alias acl_group 254                 = acl_group 254\n"
-"keyword_alias acl_group 255                 = acl_group 255\n"
+"keyword_alias acl_group                     = acl_group\n"
 "keyword_alias address_group                 = address_group\n"
-"keyword_alias aggregator                    = aggregator\n"
 "keyword_alias capability                    = capability\n"
-"keyword_alias deny_autobind                 = deny_autobind\n"
+"keyword_alias default_transition            = default_transition\n"
 "keyword_alias file append                   = file append\n"
 "keyword_alias file chgrp                    = file chgrp\n"
 "keyword_alias file chmod                    = file chmod\n"
@@ -1279,24 +1017,17 @@
 "keyword_alias file unlink                   = file unlink\n"
 "keyword_alias file unmount                  = file unmount\n"
 "keyword_alias file write                    = file write\n"
-"keyword_alias initialize_domain             = initialize_domain\n"
-"keyword_alias ipc signal                    = ipc signal\n"
-"keyword_alias keep_domain                   = keep_domain\n"
+"keyword_alias ipc ptrace                    = ipc ptrace\n"
 "keyword_alias misc env                      = misc env\n"
 "keyword_alias network inet                  = network inet\n"
 "keyword_alias network unix                  = network unix\n"
-"keyword_alias no_initialize_domain          = no_initialize_domain\n"
-"keyword_alias no_keep_domain                = no_keep_domain\n"
-"keyword_alias no_reset_domain               = no_reset_domain\n"
 "keyword_alias number_group                  = number_group\n"
 "keyword_alias path_group                    = path_group\n"
 "keyword_alias quota_exceeded                = quota_exceeded\n"
-"keyword_alias reset_domain                  = reset_domain\n"
 "keyword_alias task auto_domain_transition   = task auto_domain_transition\n"
 "keyword_alias task auto_execute_handler     = task auto_execute_handler\n"
 "keyword_alias task denied_execute_handler   = task denied_execute_handler\n"
 "keyword_alias task manual_domain_transition = task manual_domain_transition\n"
-"keyword_alias transition_failed             = transition_failed\n"
 "keyword_alias use_group                     = use_group\n"
 "keyword_alias use_profile                   = use_profile\n"
 "\n"
@@ -1381,6 +1112,23 @@
 "header.contains granted=yes\n"
 "destination     /dev/null\n"
 "\n"
+"# Save rejected logs with profile=acl mode=learning to\n"
+"# /var/log/tomoyo/reject_learning_acl.log\n"
+"header.contains profile=acl\n"
+"header.contains mode=learning\n"
+"destination     /var/log/tomoyo/reject_learning_acl.log\n"
+"# Save rejected logs with profile=acl mode=permissive to\n"
+"# /var/log/tomoyo/reject_permissive_acl.log\n"
+"header.contains profile=acl\n"
+"header.contains mode=permissive\n"
+"destination     /var/log/tomoyo/reject_permissive_acl.log\n"
+"\n"
+"# Save rejected logs with profile=acl mode=enforcing to\n"
+"# /var/log/tomoyo/reject_acl.log\n"
+"header.contains profile=acl\n"
+"header.contains mode=enforcing\n"
+"destination     /var/log/tomoyo/reject_enforcing_acl.log\n"
+"\n"
 "# Save rejected logs with profile=0 to /var/log/tomoyo/reject_000.log\n"
 "header.contains profile=0\n"
 "destination     /var/log/tomoyo/reject_000.log\n"
@@ -1641,8 +1389,6 @@
 			module_name = arg + 12;
 		} else if (!strncmp(arg, "use_profile=", 12)) {
 			default_profile = atoi(arg + 12);
-		} else if (!strncmp(arg, "use_group=", 10)) {
-			default_group = atoi(arg + 10);
 		} else if (!strncmp(arg, "grant_log=", 10)) {
 			grant_log = arg + 10;
 		} else if (!strncmp(arg, "reject_log=", 11)) {
Index: trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/convert-audit-log.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/convert-audit-log.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/usr_lib_ccs/convert-audit-log.c	(working copy)
@@ -123,10 +123,7 @@
 			handle_path_condition("path2.parent.");
 		else if (!strcmp(buffer, "exec={"))
 			handle_exec_condition();
-		else if (!strncmp(buffer, "symlink.target=", 15)) {
-			realloc_buffer(strlen(buffer) + 2);
-			cond_len += sprintf(cond + cond_len, " %s", buffer);
-		} else if (buffer[0] == '<' /* ccs_domain_def(buffer) */) {
+		else if (buffer[0] == '<' /* ccs_domain_def(buffer) */) {
 			char *cp;
 			free(namespace);
 			namespace = strdup(buffer);
Index: trunk/1.8.x/ccs-tools/ccstools/sbin/ccs-init.c
===================================================================
--- trunk/1.8.x/ccs-tools/ccstools/sbin/ccs-init.c	(revision 5696)
+++ trunk/1.8.x/ccs-tools/ccstools/sbin/ccs-init.c	(working copy)
@@ -50,114 +50,15 @@
 
 #define policy_dir            "/etc/ccs/"
 #define proc_manager          "/proc/ccs/manager"
+#define proc_acl_policy       "/proc/ccs/acl_policy"
 #define proc_exception_policy "/proc/ccs/exception_policy"
 #define proc_domain_policy    "/proc/ccs/domain_policy"
 #define proc_profile          "/proc/ccs/profile"
 #define proc_stat             "/proc/ccs/stat"
-static const char *profile_name = "default";
-static _Bool ccs_noload = 0;
 static _Bool proc_unmount = 0;
-static _Bool chdir_ok = 0;
 
-static struct ns_profile {
-	char *namespace;
-	_Bool profile[256];
-} *ns_profile_list;
-static int ns_profile_list_len = 0;
 static char buffer[8192];
 
-static void check_arg(const char *arg)
-{
-	if (!strcmp(arg, "CCS=ask"))
-		profile_name = "ask";
-	else if (!strcmp(arg, "CCS=default"))
-		profile_name = "default";
-	else if (!strcmp(arg, "CCS=disabled"))
-		profile_name = "disable";
-	else if (!strncmp(arg, "CCS=", 4)) {
-		char buffer[1024];
-		memset(buffer, 0, sizeof(buffer));
-		snprintf(buffer, sizeof(buffer) - 1, "profile-%s.conf",
-			 arg + 4);
-		profile_name = strdup(buffer);
-		if (!profile_name)
-			panic();
-	} else if (!strcmp(arg, "CCS_NOLOAD"))
-		ccs_noload = 1;
-}
-
-static void ask_profile(void)
-{
-	static char input[128];
-	while (1) {
-		char *ret_ignored;
-		printf("CCSecurity: Select a profile from "
-		       "the following list.\n");
-		if (chdir_ok) {
-			/* Show profiles in policy directory. */
-			DIR *dir = opendir(".");
-			if (!access("profile.conf", R_OK))
-				printf("default\n");
-			while (1) {
-				struct dirent *entry = readdir(dir);
-				int len;
-				char *name;
-				if (!entry)
-					break;
-				name = entry->d_name;
-				if (strncmp(name, "profile-", 8))
-					continue;
-				if (!strcmp(name, "profile-default.conf") ||
-				    !strcmp(name, "profile-disable.conf"))
-					continue;
-				len = strlen(name);
-				if (len > 13 &&
-				    !strcmp(name + len - 5, ".conf")) {
-					int i;
-					for (i = 8; i < len - 5; i++)
-						putchar(name[i]);
-					putchar('\n');
-				}
-			}
-			closedir(dir);
-		}
-		printf("disable\n");
-		profile_name = "";
-		printf("> ");
-		memset(input, 0, sizeof(input));
-		ret_ignored = fgets(input, sizeof(input) - 1, stdin);
-		{
-			char *cp = strchr(input, '\n');
-			if (cp)
-				*cp = '\0';
-		}
-		if (chdir_ok) {
-			if (!strcmp(input, "default")) {
-				if (!access("profile.conf", R_OK)) {
-					profile_name = "default";
-					break;
-				}
-			} else if (strcmp(input, "disable")) {
-				memset(buffer, 0, sizeof(buffer));
-				snprintf(buffer, sizeof(buffer) - 1,
-					 "profile-%s.conf", input);
-				if (!access(buffer, R_OK)) {
-					profile_name = strdup(buffer);
-					if (!profile_name)
-						panic();
-					break;
-				}
-			}
-		}
-		if (!strcmp(input, "disable")) {
-			profile_name = "disable";
-			break;
-		}
-		if (!strcmp(input, "CCS_NOLOAD"))
-			ccs_noload = 1;
-	}
-}
-
 static void copy_files(const char *src, const char *dest)
 {
 	int sfd;
@@ -181,88 +82,6 @@
 	close(dfd);
 }
 
-static void scan_used_profile_index(void)
-{
-	static _Bool checked = 0;
-	unsigned int i;
-	FILE *fp;
-	struct ns_profile *ptr = NULL;
-	if (checked)
-		return;
-	checked = 1;
-	fp = fopen(proc_domain_policy, "r");
-	if (!fp)
-		panic();
-	while (memset(buffer, 0, sizeof(buffer)) &&
-	       fgets(buffer, sizeof(buffer) - 1, fp)) {
-		if (buffer[0] == '<') {
-			char *cp = strchr(buffer, ' ');
-			if (!cp)
-				cp = strchr(buffer, '\n');
-			if (cp)
-				*cp = '\0';
-			ptr = NULL;
-			for (i = 0; i < ns_profile_list_len; i++) {
-				if (strcmp(buffer,
-					   ns_profile_list[i].namespace))
-					continue;
-				ptr = &ns_profile_list[i];
-				break;
-			}
-			if (ptr)
-				continue;
-			ns_profile_list = realloc(ns_profile_list,
-						  sizeof(*ptr) *
-						  (ns_profile_list_len + 1));
-			if (!ns_profile_list)
-				panic();
-			ptr = &ns_profile_list[ns_profile_list_len++];
-			ptr->namespace = strdup(buffer);
-			if (!ptr->namespace)
-				panic();
-			memset(ptr->profile, 0, sizeof(ptr->profile));
-		} else if (ptr && sscanf(buffer, "use_profile %u", &i) == 1 &&
-			   i < 256)
-			ptr->profile[i] = 1;
-	}
-	fclose(fp);
-}
-
-static void disable_profile(void)
-{
-	FILE *fp_out = fopen(proc_profile, "w");
-	FILE *fp_in;
-	int i;
-	if (!fp_out)
-		panic();
-	scan_used_profile_index();
-	for (i = 0; i < ns_profile_list_len; i++) {
-		struct ns_profile *ptr = &ns_profile_list[i];
-		int j;
-		for (j = 0; j < 256; j++) {
-			if (!ptr->profile[j])
-				continue;
-			fprintf(fp_out, "%s %u-COMMENT=disabled\n",
-				ptr->namespace, j);
-		}
-	}
-	fclose(fp_out);
-	fp_in = fopen(proc_profile, "r");
-	fp_out = fopen(proc_profile, "w");
-	if (!fp_in || !fp_out)
-		panic();
-	while (memset(buffer, 0, sizeof(buffer)) &&
-	       fgets(buffer, sizeof(buffer) - 1, fp_in)) {
-		char *cp = strstr(buffer, "={ mode=");
-		if (!cp)
-			continue;
-		*(cp + 8) = '\0';
-		fprintf(fp_out, "%sdisabled }\n", buffer);
-	}
-	fclose(fp_in);
-	fclose(fp_out);
-}
-
 static void show_domain_usage(void)
 {
 	unsigned int domain = 0;
@@ -309,6 +128,23 @@
 	if (lstat("/proc/self/", &buf) || !S_ISDIR(buf.st_mode))
 		proc_unmount = !mount("/proc", "/proc/", "proc", 0, NULL);
 
+	/*
+	 * Open /dev/console if stdio are not connected.
+	 *
+	 * WARNING: Don't let this program be invoked implicitly
+	 * if you are not operating from console.
+	 * Otherwise, you will get unable to respond to prompt
+	 * if something went wrong.
+	 */
+	if (access("/proc/self/fd/0", R_OK)) {
+		close(0);
+		close(1);
+		close(2);
+		open("/dev/console", O_RDONLY);
+		open("/dev/console", O_WRONLY);
+		open("/dev/console", O_WRONLY);
+	}
+
 	/* Load kernel module if needed. */
 	if (lstat("/proc/ccs/", &buf) || !S_ISDIR(buf.st_mode)) {
 		if (!access("/etc/ccs/ccs-load-module", X_OK)) {
@@ -326,13 +162,20 @@
 		}
 	}
 
+	/* Stop if policy interface doesn't exist. */
+	if (lstat("/proc/ccs/", &buf) || !S_ISDIR(buf.st_mode)) {
+		printf("FATAL: Policy interface does not exist.\n");
+		fflush(stdout);
+		while (1)
+			sleep(100);
+	}
+
+	/*
+	 * Unmount /proc and execute /sbin/init if this program was executed by
+	 * passing init=/sbin/ccs-init . The kernel will try to execute this
+	 * program again with getpid() != 1 when /sbin/init starts.
+	 */
 	if (getpid() == 1) {
-		/*
-		 * Unmount /proc and execute /sbin/init if this program was
-		 * executed by passing init=/sbin/ccs-init . The kernel will
-		 * try to execute this program again with getpid() != 1 when
-		 * /sbin/init starts.
-		 */
 		if (proc_unmount)
 			umount("/proc/");
 		argv[0] = "/sbin/init";
@@ -343,101 +186,16 @@
 			sleep(100);
 	}
 
-	/* Unmount /proc and exit if policy interface doesn't exist. */
-	if (lstat("/proc/ccs/", &buf) || !S_ISDIR(buf.st_mode)) {
-		if (proc_unmount)
-			umount("/proc/");
-		return 1;
-	}
-
-	/*
-	 * Open /dev/console if stdio are not connected.
-	 *
-	 * WARNING: Don't let this program be invoked implicitly
-	 * if you are not operating from console.
-	 * Otherwise, you will get unable to respond to prompt
-	 * if something went wrong.
-	 */
-	if (access("/proc/self/fd/0", R_OK)) {
-		close(0);
-		close(1);
-		close(2);
-		open("/dev/console", O_RDONLY);
-		open("/dev/console", O_WRONLY);
-		open("/dev/console", O_WRONLY);
-	}
-
-	/* Check /proc/cmdline and /proc/self/cmdline */
-	{
-		char *cp;
-		int i;
-		int ret_ignored;
-		int fd = open("/proc/cmdline", O_RDONLY);
-		memset(buffer, 0, sizeof(buffer));
-		ret_ignored = read(fd, buffer, sizeof(buffer) - 1);
-		close(fd);
-		cp = strchr(buffer, '\n');
-		if (cp)
-			*cp = '\0';
-		while (1) {
-			char *cp = strchr(buffer, ' ');
-			if (cp)
-				*cp = '\0';
-			check_arg(buffer);
-			if (!cp)
-				break;
-			cp++;
-			memmove(buffer, cp, strlen(cp) + 1);
-		}
-		for (i = 1; i < argc; i++)
-			check_arg(argv[i]);
-	}
-
-	/* Does policy directory exist? */
-	if (!chdir(policy_dir))
-		chdir_ok = 1;
-	else
-		profile_name = "disable";
-
-	/* Does selected profile exist? */
-	if (chdir_ok) {
-		if (!strcmp(profile_name, "default")) {
-			if (access("profile.conf", R_OK)) {
-				printf("CCSecurity: Default profile "
-				       "doesn't exist.\n");
-				profile_name = "ask";
-			}
-		} else if (strcmp(profile_name, "ask") &&
-			   strcmp(profile_name, "disable")) {
-			if (access(profile_name, R_OK)) {
-				printf("CCSecurity: Specified profile "
-				       "doesn't exist.\n");
-				profile_name = "ask";
-			}
-		}
-	}
-
-	/* Show prompt if something went wrong or explicitly asked. */
-	if (!strcmp(profile_name, "ask"))
-		ask_profile();
-
 	/* Load policy. */
-	if (chdir_ok) {
+	if (!chdir(policy_dir)) {
 		copy_files("manager.conf", proc_manager);
+		copy_files("acl_policy.conf", proc_acl_policy);
 		copy_files("exception_policy.conf", proc_exception_policy);
-		if (!ccs_noload)
-			copy_files("domain_policy.conf", proc_domain_policy);
-		if (!strcmp(profile_name, "default"))
-			copy_files("profile.conf", proc_profile);
-		else if (strcmp(profile_name, "disable"))
-			copy_files(profile_name, proc_profile);
+		copy_files("domain_policy.conf", proc_domain_policy);
+		copy_files("profile.conf", proc_profile);
 		copy_files("stat.conf", proc_stat);
 	}
 
-	/* Use disabled mode? */
-	if (!strcmp(profile_name, "disable"))
-		disable_profile();
-
 	/* Do additional initialization. */
 	if (!access("/etc/ccs/ccs-post-init", X_OK)) {
 		const pid_t pid = fork();
