diff --git a/policy/modules/apps/vlock.fc b/policy/modules/apps/vlock.fc
new file mode 100644
index 000000000..621d5fdac
--- /dev/null
+++ b/policy/modules/apps/vlock.fc
@@ -0,0 +1 @@
+/usr/sbin/vlock-main -- gen_context(system_u:object_r:vlock_exec_t,s0)
diff --git a/policy/modules/apps/vlock.if b/policy/modules/apps/vlock.if
new file mode 100644
index 000000000..264293ab6
--- /dev/null
+++ b/policy/modules/apps/vlock.if
@@ -0,0 +1,46 @@
+## Lock one or more sessions on the Linux console.
+
+#######################################
+##
+## Execute vlock in the vlock domain.
+##
+##
+##
+## Domain allowed to transition.
+##
+##
+#
+interface(`vlock_domtrans_vlock',`
+ gen_require(`
+ type vlock_t, vlock_exec_t;
+ ')
+
+ corecmd_search_bin($1)
+ domtrans_pattern($1, vlock_exec_t, vlock_t)
+')
+
+########################################
+##
+## Execute vlock in the vlock domain, and
+## allow the specified role the vlock domain.
+##
+##
+##
+## Domain allowed to transition.
+##
+##
+##
+##
+## Role allowed to access.
+##
+##
+##
+#
+interface(`vlock_run_vlock',`
+ gen_require(`
+ type vlock_t;
+ ')
+
+ vlock_domtrans_vlock($1)
+ role $2 types vlock_t;
+')
diff --git a/policy/modules/apps/vlock.te b/policy/modules/apps/vlock.te
new file mode 100644
index 000000000..06d0fb824
--- /dev/null
+++ b/policy/modules/apps/vlock.te
@@ -0,0 +1,57 @@
+policy_module(vlock, 1.0.0)
+
+########################################
+#
+# Declarations
+#
+
+type vlock_t;
+type vlock_exec_t;
+application_domain(vlock_t, vlock_exec_t)
+
+
+########################################
+#
+# Local policy
+#
+
+dontaudit vlock_t self:capability { setuid setgid };
+allow vlock_t self:fd use;
+allow vlock_t self:fifo_file rw_fifo_file_perms;
+allow vlock_t self:netlink_audit_socket { create_netlink_socket_perms nlmsg_relay };
+allow vlock_t self:unix_dgram_socket { create connect };
+
+corecmd_list_bin(vlock_t)
+corecmd_read_bin_symlinks(vlock_t)
+
+# Must call this interface otherwise PAM session will fail
+# with message of "terminal=? res=failed"
+domain_use_interactive_fds(vlock_t)
+
+files_dontaudit_search_home(vlock_t)
+files_read_etc_files(vlock_t)
+
+term_use_all_user_ttys(vlock_t)
+term_use_all_user_ptys(vlock_t)
+
+kernel_read_system_state(vlock_t)
+
+selinux_dontaudit_getattr_fs(vlock_t)
+
+auth_domtrans_chk_passwd(vlock_t)
+
+init_dontaudit_rw_utmp(vlock_t)
+
+logging_send_syslog_msg(vlock_t)
+
+miscfiles_read_localization(vlock_t)
+
+userdom_dontaudit_search_user_home_dirs(vlock_t)
+userdom_use_user_terminals(vlock_t)
+
+# pam_tally2 module could be used by vlock for authentication,
+# /var/log/tallylog's SL is usually s0, while the caller's SL could
+# be higher than s0.
+ifdef(`enable_mls',`
+ mls_file_write_all_levels(vlock_t)
+')
diff --git a/policy/modules/roles/staff.te b/policy/modules/roles/staff.te
index e0e255030..cb938879b 100644
--- a/policy/modules/roles/staff.te
+++ b/policy/modules/roles/staff.te
@@ -47,6 +47,10 @@ optional_policy(`
userdom_dontaudit_use_user_terminals(staff_t)
')
+optional_policy(`
+ vlock_run_vlock(staff_t, staff_r)
+')
+
optional_policy(`
xserver_role(staff_r, staff_t)
')
diff --git a/policy/modules/roles/sysadm.te b/policy/modules/roles/sysadm.te
index 6b5441684..96a7dbb36 100644
--- a/policy/modules/roles/sysadm.te
+++ b/policy/modules/roles/sysadm.te
@@ -388,6 +388,10 @@ optional_policy(`
wireshark_role(sysadm_r, sysadm_t)
')
+optional_policy(`
+ vlock_run_vlock(sysadm_t, sysadm_r)
+')
+
optional_policy(`
xserver_role(sysadm_r, sysadm_t)
')
diff --git a/policy/modules/roles/unprivuser.te b/policy/modules/roles/unprivuser.te
index 183ea8e5d..d1a9d1b45 100644
--- a/policy/modules/roles/unprivuser.te
+++ b/policy/modules/roles/unprivuser.te
@@ -20,6 +20,10 @@ optional_policy(`
screen_role_template(user, user_r, user_t)
')
+optional_policy(`
+ vlock_run_vlock(user_t, user_r)
+')
+
optional_policy(`
xserver_role(user_r, user_t)
')