ade34f3
diff --git a/libselinux/include/selinux/selinux.h b/libselinux/include/selinux/selinux.h
cc9c7dd
index a4079aa..0b122af 100644
ade34f3
--- a/libselinux/include/selinux/selinux.h
ade34f3
+++ b/libselinux/include/selinux/selinux.h
0781a5c
@@ -177,6 +177,7 @@ extern void selinux_set_callback(int type, union selinux_callback cb);
0781a5c
 #define SELINUX_WARNING		1
0781a5c
 #define SELINUX_INFO		2
0781a5c
 #define SELINUX_AVC		3
0781a5c
+#define SELINUX_TRANS_DIR	"/var/run/setrans"
0781a5c
 
0781a5c
 /* Compute an access decision. */
0781a5c
 extern int security_compute_av(const security_context_t scon,
cc9c7dd
@@ -496,8 +497,15 @@ extern int selinux_getpolicytype(char **policytype);
cc9c7dd
  */
cc9c7dd
 extern const char *selinux_policy_root(void);
ade34f3
 
cc9c7dd
+/*
cc9c7dd
+  selinux_set_policy_root sets an alternate policy root directory path under 
cc9c7dd
+  which the compiled policy file and context configuration files exist.
cc9c7dd
+ */
cc9c7dd
+extern int selinux_set_policy_root(const char *rootpath);
cc9c7dd
+
ade34f3
 /* These functions return the paths to specific files under the 
ade34f3
    policy root directory. */
ade34f3
+extern const char *selinux_current_policy_path(void);
ade34f3
 extern const char *selinux_binary_policy_path(void);
ade34f3
 extern const char *selinux_failsafe_context_path(void);
ade34f3
 extern const char *selinux_removable_context_path(void);
e27f806
diff --git a/libselinux/man/man3/security_compute_av.3 b/libselinux/man/man3/security_compute_av.3
e27f806
index c6837fc..de62d26 100644
e27f806
--- a/libselinux/man/man3/security_compute_av.3
e27f806
+++ b/libselinux/man/man3/security_compute_av.3
e27f806
@@ -37,9 +37,9 @@ the SELinux policy database in the kernel
e27f806
 .sp
e27f806
 .BI "int security_compute_user_raw(security_context_t "scon ", const char *" username ", security_context_t **" con );
e27f806
 .sp
e27f806
-.BI "int security_get_initial_context(const char *" name ", security_context_t " con );
e27f806
+.BI "int security_get_initial_context(const char *" name ", security_context_t *" con );
e27f806
 .sp
e27f806
-.BI "int security_get_initial_context_raw(const char *" name ", security_context_t " con );
e27f806
+.BI "int security_get_initial_context_raw(const char *" name ", security_context_t *" con );
e27f806
 .sp
e27f806
 .BI "int selinux_check_access(const security_context_t " scon ", const security_context_t " tcon ", const char *" class ", const char *" perm ", void *" auditdata);
e27f806
 .sp
876a4a8
diff --git a/libselinux/man/man3/security_disable.3 b/libselinux/man/man3/security_disable.3
876a4a8
index aeb78da..c75ce0d 100644
876a4a8
--- a/libselinux/man/man3/security_disable.3
876a4a8
+++ b/libselinux/man/man3/security_disable.3
876a4a8
@@ -17,7 +17,7 @@ and then unmounts
876a4a8
 This function can only be called at runtime and prior to the initial policy
876a4a8
 load. After the initial policy load, the SELinux kernel code cannot be disabled,
876a4a8
 but only placed in "permissive" mode by using
876a4a8
-.BR setenforce (1).
876a4a8
+.BR security_setenforce(3).
876a4a8
 .
876a4a8
 .SH "RETURN VALUE"
876a4a8
 .BR security_disable ()
876a4a8
@@ -27,4 +27,4 @@ returns zero on success or \-1 on error.
876a4a8
 This manual page has been written by Guido Trentalancia <guido@trentalancia.com>
876a4a8
 .
876a4a8
 .SH "SEE ALSO"
876a4a8
-.BR selinux (8), " setenforce "(3)
876a4a8
+.BR selinux (8), " setenforce "(8)
876a4a8
diff --git a/libselinux/man/man3/security_load_policy.3 b/libselinux/man/man3/security_load_policy.3
876a4a8
index c4439bf..af56163 100644
876a4a8
--- a/libselinux/man/man3/security_load_policy.3
876a4a8
+++ b/libselinux/man/man3/security_load_policy.3
876a4a8
@@ -43,7 +43,7 @@ unmounted using a call to
876a4a8
 .BR security_disable (3).
876a4a8
 Therefore, after the initial policy load, the only operational changes
876a4a8
 are those permitted by
876a4a8
-.BR setenforce (3)
876a4a8
+.BR security_setenforce (3)
876a4a8
 (i.e. eventually setting the framework in permissive mode rather than
876a4a8
 in enforcing one).
876a4a8
 .
876a4a8
@@ -54,4 +54,4 @@ Returns zero on success or \-1 on error.
876a4a8
 This manual page has been written by Guido Trentalancia <guido@trentalancia.com>
876a4a8
 .
876a4a8
 .SH "SEE ALSO"
876a4a8
-.BR selinux "(8), " security_disable "(3), " setenforce "(1)
876a4a8
+.BR selinux "(8), " security_disable "(3), " setenforce "(8)
ade34f3
diff --git a/libselinux/man/man3/selinux_binary_policy_path.3 b/libselinux/man/man3/selinux_binary_policy_path.3
ade34f3
index ec97dcf..503c52c 100644
ade34f3
--- a/libselinux/man/man3/selinux_binary_policy_path.3
ade34f3
+++ b/libselinux/man/man3/selinux_binary_policy_path.3
ade34f3
@@ -1,6 +1,6 @@
ade34f3
 .TH "selinux_binary_policy_path" "3" "15 November 2004" "dwalsh@redhat.com" "SELinux API Documentation"
ade34f3
 .SH "NAME"
ade34f3
-selinux_path, selinux_policy_root, selinux_binary_policy_path,
ade34f3
+selinux_path, selinux_policy_root, selinux_binary_policy_path, selinux_current_policy_path,
ade34f3
 selinux_failsafe_context_path, selinux_removable_context_path,
ade34f3
 selinux_default_context_path, selinux_user_contexts_path,
ade34f3
 selinux_file_context_path, selinux_media_context_path,
ade34f3
@@ -17,6 +17,8 @@ directories and files
ade34f3
 .sp
ade34f3
 .B const char *selinux_binary_policy_path(void);
ade34f3
 .sp
ade34f3
+.B const char *selinux_current_policy_path(void);
ade34f3
+.sp
ade34f3
 .B const char *selinux_failsafe_context_path(void);
ade34f3
 .sp
ade34f3
 .B const char *selinux_removable_context_path(void);
ade34f3
@@ -55,6 +57,9 @@ returns the top-level policy directory.
ade34f3
 .BR selinux_binary_policy_path ()
ade34f3
 returns the binary policy file loaded into kernel.
ade34f3
 .sp
ade34f3
+.BR selinux_current_policy_path ()
ade34f3
+returns the currently loaded policy file from the kernel.
ade34f3
+.sp
ade34f3
 .BR selinux_default_type_path ()
ade34f3
 returns the context file mapping roles to default types.
ade34f3
 .sp
ade34f3
diff --git a/libselinux/man/man3/selinux_current_policy_path.3 b/libselinux/man/man3/selinux_current_policy_path.3
ade34f3
new file mode 100644
ade34f3
index 0000000..175a611
ade34f3
--- /dev/null
ade34f3
+++ b/libselinux/man/man3/selinux_current_policy_path.3
ade34f3
@@ -0,0 +1 @@
ade34f3
+.so man3/selinux_binary_policy_path.3
cc9c7dd
diff --git a/libselinux/man/man3/selinux_policy_root.3 b/libselinux/man/man3/selinux_policy_root.3
cc9c7dd
index a6ccf86..63dc901 100644
cc9c7dd
--- a/libselinux/man/man3/selinux_policy_root.3
cc9c7dd
+++ b/libselinux/man/man3/selinux_policy_root.3
cc9c7dd
@@ -1,21 +1,34 @@
cc9c7dd
 .TH "selinux_policy_root" "3" "25 May 2004" "dwalsh@redhat.com" "SELinux API documentation"
cc9c7dd
 .SH "NAME"
cc9c7dd
 selinux_policy_root \- return the path of the SELinux policy files for this machine
cc9c7dd
+selinux_set_policy_root \- Set an alternate SELinux root path for the SELinux policy files for this machine.
cc9c7dd
 .
cc9c7dd
 .SH "SYNOPSIS"
cc9c7dd
 .B #include <selinux/selinux.h>
cc9c7dd
 .sp
cc9c7dd
 .B const char *selinux_policy_root(void);
cc9c7dd
 .
cc9c7dd
+.sp
cc9c7dd
+.B int selinux_set_policy_root(const char *policypath);
cc9c7dd
+.
cc9c7dd
 .SH "DESCRIPTION"
cc9c7dd
 .BR selinux_policy_root ()
cc9c7dd
 reads the contents of the
cc9c7dd
 .I /etc/selinux/config
cc9c7dd
 file to determine which policy files should be used for this machine.
cc9c7dd
 .
cc9c7dd
+.BR selinux_set_policy_root ()
cc9c7dd
+sets up all all policy paths based on the alternate root
cc9c7dd
+
cc9c7dd
+.I /etc/selinux/config
cc9c7dd
+file to determine which policy files should be used for this machine.
cc9c7dd
+.
cc9c7dd
 .SH "RETURN VALUE"
cc9c7dd
-On success, returns a directory path containing the SELinux policy files.
cc9c7dd
-On failure, NULL is returned.
cc9c7dd
+On success, selinux_policy_root returns a directory path containing the SELinux policy files.
cc9c7dd
+On failure, selinux_policy_root returns NULL.
cc9c7dd
+
cc9c7dd
+On success, selinux_set_policy_root returns 0 on success -1 on failure.
cc9c7dd
+
cc9c7dd
 .
cc9c7dd
 .SH "SEE ALSO"
cc9c7dd
 .BR selinux "(8)"
cc9c7dd
diff --git a/libselinux/man/man3/selinux_set_policy_root.3 b/libselinux/man/man3/selinux_set_policy_root.3
cc9c7dd
new file mode 100644
cc9c7dd
index 0000000..8077658
cc9c7dd
--- /dev/null
cc9c7dd
+++ b/libselinux/man/man3/selinux_set_policy_root.3
cc9c7dd
@@ -0,0 +1 @@
cc9c7dd
+.so man3/selinux_policy_root.3
4ab41c3
diff --git a/libselinux/man/man5/secolor.conf.5 b/libselinux/man/man5/secolor.conf.5
4ab41c3
deleted file mode 100644
4ab41c3
index b834577..0000000
4ab41c3
--- a/libselinux/man/man5/secolor.conf.5
4ab41c3
+++ /dev/null
4ab41c3
@@ -1,178 +0,0 @@
4ab41c3
-.TH "secolor.conf" "5" "08 April 2011" "SELinux API documentation"
4ab41c3
-.SH "NAME"
4ab41c3
-secolor.conf \- The SELinux color configuration file
4ab41c3
-.
4ab41c3
-.SH "DESCRIPTION"
4ab41c3
-This optional file controls the color to be associated to the context components associated to the 
4ab41c3
-.I raw
4ab41c3
-context passed by 
4ab41c3
-.BR selinux_raw_context_to_color "(3),"
4ab41c3
-when context related information is to be displayed in color by an SELinux-aware application. 
4ab41c3
-.sp
4ab41c3
-.BR selinux_raw_context_to_color "(3)"
4ab41c3
-obtains this color information from the active policy 
4ab41c3
-.B secolor.conf
4ab41c3
-file as returned by 
4ab41c3
-.BR selinux_colors_path "(3)."
4ab41c3
-.
4ab41c3
-.SH "FILE FORMAT"
4ab41c3
-The file format is as follows:
4ab41c3
-.RS
4ab41c3
-.B color
4ab41c3
-.I color_name
4ab41c3
-.BI "= #"color_mask
4ab41c3
-.br
4ab41c3
-[...]
4ab41c3
-.sp
4ab41c3
-.I context_component string
4ab41c3
-.B =
4ab41c3
-.I fg_color_name bg_color_name
4ab41c3
-.br
4ab41c3
-[...]
4ab41c3
-.sp 
4ab41c3
-.RE
4ab41c3
-
4ab41c3
-Where:
4ab41c3
-.br
4ab41c3
-.B color
4ab41c3
-.RS
4ab41c3
-The color keyword. Each color entry is on a new line.
4ab41c3
-.RE
4ab41c3
-.I color_name
4ab41c3
-.RS
4ab41c3
-A single word name for the color (e.g. red).
4ab41c3
-.RE
4ab41c3
-.I color_mask
4ab41c3
-.RS
4ab41c3
-A color mask starting with a hash (#) that describes the hexadecimal RGB colors with black being #000000 and white being #ffffff.
4ab41c3
-.RE
4ab41c3
-.I context_component
4ab41c3
-.RS
4ab41c3
-The context component name that must be one of the following:
4ab41c3
-.br
4ab41c3
-.RS
4ab41c3
-user, role, type or range 
4ab41c3
-.RE
4ab41c3
-Each
4ab41c3
-.IR context_component " " string " ..."
4ab41c3
-entry is on a new line.
4ab41c3
-.RE
4ab41c3
-.I string
4ab41c3
-.RS
4ab41c3
-This is the 
4ab41c3
-.I context_component
4ab41c3
-string that will be matched with the 
4ab41c3
-.I raw
4ab41c3
-context component passed by
4ab41c3
-.BR selinux_raw_context_to_color "(3)."
4ab41c3
-.br
4ab41c3
-A wildcard '*' may be used to match any undefined string for the user, role and type 
4ab41c3
-.I context_component
4ab41c3
-entries only.
4ab41c3
-.RE
4ab41c3
-
4ab41c3
-.I fg_color_name
4ab41c3
-.RS
4ab41c3
-The color_name string that will be used as the foreground color.
4ab41c3
-A 
4ab41c3
-.I color_mask
4ab41c3
-may also be used.
4ab41c3
-.RE
4ab41c3
-.I bg_color_name
4ab41c3
-.RS
4ab41c3
-The color_name string that will be used as the background color.
4ab41c3
-A 
4ab41c3
-.I color_mask
4ab41c3
-may also be used.
4ab41c3
-.RE
4ab41c3
-.
4ab41c3
-.SH "EXAMPLES"
4ab41c3
-Example 1 entries are:
4ab41c3
-.RS
4ab41c3
-color black  = #000000
4ab41c3
-.br
4ab41c3
-color green  = #008000
4ab41c3
-.br
4ab41c3
-color yellow = #ffff00
4ab41c3
-.br
4ab41c3
-color blue   = #0000ff
4ab41c3
-.br
4ab41c3
-color white  = #ffffff
4ab41c3
-.br
4ab41c3
-color red    = #ff0000
4ab41c3
-.br
4ab41c3
-color orange = #ffa500
4ab41c3
-.br
4ab41c3
-color tan    = #D2B48C
4ab41c3
-.sp
4ab41c3
-user * = black white
4ab41c3
-.br
4ab41c3
-role * = white black
4ab41c3
-.br
4ab41c3
-type * = tan orange
4ab41c3
-.br
4ab41c3
-range s0\-s0:c0.c1023 = black green
4ab41c3
-.br
4ab41c3
-range s1\-s1:c0.c1023 = white green
4ab41c3
-.br
4ab41c3
-range s3\-s3:c0.c1023 = black tan
4ab41c3
-.br
4ab41c3
-range s5\-s5:c0.c1023 = white blue
4ab41c3
-.br
4ab41c3
-range s7\-s7:c0.c1023 = black red
4ab41c3
-.br
4ab41c3
-range s9\-s9:c0.c1023 = black orange
4ab41c3
-.br
4ab41c3
-range s15:c0.c1023   = black yellow
4ab41c3
-.RE
4ab41c3
-
4ab41c3
-.sp
4ab41c3
-Example 2 entries are:
4ab41c3
-.RS
4ab41c3
-color black  = #000000
4ab41c3
-.br
4ab41c3
-color green  = #008000
4ab41c3
-.br
4ab41c3
-color yellow = #ffff00
4ab41c3
-.br
4ab41c3
-color blue   = #0000ff
4ab41c3
-.br
4ab41c3
-color white  = #ffffff
4ab41c3
-.br
4ab41c3
-color red    = #ff0000
4ab41c3
-.br
4ab41c3
-color orange = #ffa500
4ab41c3
-.br
4ab41c3
-color tan    = #d2b48c
4ab41c3
-.sp
4ab41c3
-user unconfined_u = #ff0000 green
4ab41c3
-.br
4ab41c3
-role unconfined_r = red #ffffff
4ab41c3
-.br
4ab41c3
-type unconfined_t = red orange
4ab41c3
-.br
4ab41c3
-user user_u       = black green
4ab41c3
-.br
4ab41c3
-role user_r       = white black
4ab41c3
-.br
4ab41c3
-type user_t       = tan red
4ab41c3
-.br
4ab41c3
-user xguest_u     = black yellow
4ab41c3
-.br
4ab41c3
-role xguest_r     = black red
4ab41c3
-.br
4ab41c3
-type xguest_t     = black green
4ab41c3
-.br
4ab41c3
-user sysadm_u     = white black
4ab41c3
-.br
4ab41c3
-range s0:c0.c1023 = black white
4ab41c3
-.br
4ab41c3
-user *            = black white
4ab41c3
-.br
4ab41c3
-role *            = black white
4ab41c3
-.br
4ab41c3
-type *            = black white
4ab41c3
-.RE
4ab41c3
-.
4ab41c3
-.SH "SEE ALSO"
4ab41c3
-.BR selinux "(8), " selinux_raw_context_to_color "(3), " selinux_colors_path "(3)"
876a4a8
diff --git a/libselinux/man/man8/getenforce.8 b/libselinux/man/man8/getenforce.8
876a4a8
index 906279f..e0924d8 100644
876a4a8
--- a/libselinux/man/man8/getenforce.8
876a4a8
+++ b/libselinux/man/man8/getenforce.8
876a4a8
@@ -1,4 +1,4 @@
876a4a8
-.TH "getenforce" "1" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
+.TH "getenforce" "8" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
 .SH "NAME"
876a4a8
 getenforce \- get the current mode of SELinux
876a4a8
 .
cc9c7dd
diff --git a/libselinux/man/man8/matchpathcon.8 b/libselinux/man/man8/matchpathcon.8
cc9c7dd
index 368991f..5d60789 100644
cc9c7dd
--- a/libselinux/man/man8/matchpathcon.8
cc9c7dd
+++ b/libselinux/man/man8/matchpathcon.8
cc9c7dd
@@ -13,6 +13,8 @@ matchpathcon \- get the default SELinux security context for the specified path
cc9c7dd
 .IR file_contexts_file ]
cc9c7dd
 .RB [ \-p
cc9c7dd
 .IR prefix ]
cc9c7dd
+.RB [ \-P
cc9c7dd
+.IR policy_root_path ]
cc9c7dd
 .I filepath...
cc9c7dd
 .
cc9c7dd
 .SH "DESCRIPTION"
cc9c7dd
@@ -46,6 +48,9 @@ Use alternate file_context file
cc9c7dd
 .BI \-p " prefix"
cc9c7dd
 Use prefix to speed translations
cc9c7dd
 .TP
cc9c7dd
+.BI \-P " policy_root_path"
cc9c7dd
+Use alternate policy root path
cc9c7dd
+.TP
cc9c7dd
 .B \-V
cc9c7dd
 Verify file context on disk matches defaults
cc9c7dd
 .
876a4a8
diff --git a/libselinux/man/man8/sefcontext_compile.8 b/libselinux/man/man8/sefcontext_compile.8
876a4a8
new file mode 100644
876a4a8
index 0000000..c37ed4a
876a4a8
--- /dev/null
876a4a8
+++ b/libselinux/man/man8/sefcontext_compile.8
876a4a8
@@ -0,0 +1,19 @@
876a4a8
+.TH "sefcontext_compile" "8" "27 Jun 2013" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
+.SH "NAME"
876a4a8
+sefcontext_compile \- compile file context regular expression files
876a4a8
+.
876a4a8
+.SH "SYNOPSIS"
876a4a8
+.B sefcontext_compile inputfile
876a4a8
+.
876a4a8
+.SH "DESCRIPTION"
876a4a8
+sefcontext_compile is used libsemanage to compile file context regular expressions into prce format.  sefcontext_compile writes the compiled prce file with the .bin suffix appended "inputfile".bin.  This compiled file is used by libselinux file labeling functions.
876a4a8
+
876a4a8
+.SH "EXAMPLE"
876a4a8
+sefcontext_compile /etc/selinux/targeted/contexts/files/file_contexts
876a4a8
+.
876a4a8
+.SH AUTHOR	
876a4a8
+Dan Walsh, <dwalsh@redhat.com>
876a4a8
+.
876a4a8
+.SH "SEE ALSO"
876a4a8
+.BR selinux (8),
876a4a8
+.BR semanage (8),
e27f806
diff --git a/libselinux/man/man8/selinux.8 b/libselinux/man/man8/selinux.8
e27f806
index a328866..50868e4 100644
e27f806
--- a/libselinux/man/man8/selinux.8
e27f806
+++ b/libselinux/man/man8/selinux.8
e27f806
@@ -37,20 +37,22 @@ The
e27f806
 configuration file also controls what policy
e27f806
 is active on the system.  SELinux allows for multiple policies to be
e27f806
 installed on the system, but only one policy may be active at any
e27f806
-given time.  At present, two kinds of SELinux policy exist: targeted
e27f806
-and strict.  The targeted policy is designed as a policy where most
e27f806
-processes operate without restrictions, and only specific services are
e27f806
+given time.  At present, multiple kinds of SELinux policy exist: targeted, 
e27f806
+mls for example.  The targeted policy is designed as a policy where most
e27f806
+user processes operate without restrictions, and only specific services are
e27f806
 placed into distinct security domains that are confined by the policy.
e27f806
 For example, the user would run in a completely unconfined domain
e27f806
 while the named daemon or apache daemon would run in a specific domain
e27f806
-tailored to its operation.  The strict policy is designed as a policy
e27f806
-where all processes are partitioned into fine-grained security domains
e27f806
-and confined by policy.  It is anticipated in the future that other
e27f806
-policies will be created (Multi-Level Security for example).  You can
e27f806
+tailored to its operation.  The MLS (Multi-Level Security) policy is designed 
e27f806
+as a policy where all processes are partitioned into fine-grained security 
e27f806
+domains and confined by policy.  MLS also supports the Bell And LaPadula model, where processes are not only confined by the type but also the level of the data.
e27f806
+
e27f806
+You can
e27f806
 define which policy you will run by setting the
e27f806
 .B SELINUXTYPE
e27f806
 environment variable within
e27f806
 .IR /etc/selinux/config .
e27f806
+You must reboot and possibly relabel if you change the policy type to have it take effect on the system.
e27f806
 The corresponding
e27f806
 policy configuration for each such policy must be installed in the
e27f806
 .I /etc/selinux/{SELINUXTYPE}/
e27f806
@@ -58,7 +60,7 @@ directories.
e27f806
 
e27f806
 A given SELinux policy can be customized further based on a set of
e27f806
 compile-time tunable options and a set of runtime policy booleans.
e27f806
-.B \%system\-config\-securitylevel
e27f806
+.B \%system\-config\-selinux
e27f806
 allows customization of these booleans and tunables.
e27f806
 
e27f806
 Many domains that are protected by SELinux also include SELinux man pages explaining how to customize their policy.  
e27f806
@@ -86,11 +88,13 @@ This manual page was written by Dan Walsh <dwalsh@redhat.com>.
e27f806
 .nh
e27f806
 .BR booleans (8),
e27f806
 .BR setsebool (8),
e27f806
-.BR selinuxenabled (8),
e27f806
+.BR sepolicy (8),
e27f806
+.BR system-config-selinux (8),
e27f806
 .BR togglesebool (8),
e27f806
 .BR restorecon (8),
e27f806
+.BR fixfiles (8),
e27f806
 .BR setfiles (8),
e27f806
-.BR semange (8),
e27f806
+.BR semanage (8),
e27f806
 .BR sepolicy(8)
e27f806
 
e27f806
 Every confined service on the system has a man page in the following format:
876a4a8
diff --git a/libselinux/man/man8/selinuxenabled.8 b/libselinux/man/man8/selinuxenabled.8
876a4a8
index e0b5201..ac20587 100644
876a4a8
--- a/libselinux/man/man8/selinuxenabled.8
876a4a8
+++ b/libselinux/man/man8/selinuxenabled.8
876a4a8
@@ -1,4 +1,4 @@
876a4a8
-.TH "selinuxenabled" "1" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
+.TH "selinuxenabled" "8" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
 .SH "NAME"
876a4a8
 selinuxenabled \- tool to be used within shell scripts to determine if selinux is enabled
876a4a8
 .
876a4a8
diff --git a/libselinux/man/man8/selinuxexeccon.8 b/libselinux/man/man8/selinuxexeccon.8
876a4a8
index 765cf8c..30c20ed 100644
876a4a8
--- a/libselinux/man/man8/selinuxexeccon.8
876a4a8
+++ b/libselinux/man/man8/selinuxexeccon.8
876a4a8
@@ -1,4 +1,4 @@
876a4a8
-.TH "selinuxexeccon" "1" "14 May 2011" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
+.TH "selinuxexeccon" "8" "14 May 2011" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
 .SH "NAME"
876a4a8
 selinuxexeccon \- report SELinux context used for this executable
876a4a8
 .
876a4a8
diff --git a/libselinux/man/man8/setenforce.8 b/libselinux/man/man8/setenforce.8
876a4a8
index b038da0..8a24f1c 100644
876a4a8
--- a/libselinux/man/man8/setenforce.8
876a4a8
+++ b/libselinux/man/man8/setenforce.8
876a4a8
@@ -1,4 +1,4 @@
876a4a8
-.TH "setenforce" "1" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
+.TH "setenforce" "8" "7 April 2004" "dwalsh@redhat.com" "SELinux Command Line documentation"
876a4a8
 .SH "NAME"
876a4a8
 setenforce \- modify the mode SELinux is running in
876a4a8
 .
876a4a8
diff --git a/libselinux/man/man8/togglesebool.8 b/libselinux/man/man8/togglesebool.8
876a4a8
index 948aff1..598dc94 100644
876a4a8
--- a/libselinux/man/man8/togglesebool.8
876a4a8
+++ b/libselinux/man/man8/togglesebool.8
876a4a8
@@ -1,4 +1,4 @@
876a4a8
-.TH "togglesebool" "1" "26 Oct 2004" "sgrubb@redhat.com" "SELinux Command Line documentation"
876a4a8
+.TH "togglesebool" "8" "26 Oct 2004" "sgrubb@redhat.com" "SELinux Command Line documentation"
876a4a8
 .SH "NAME"
876a4a8
 togglesebool \- flip the current value of a SELinux boolean
876a4a8
 .
876a4a8
diff --git a/libselinux/src/Makefile b/libselinux/src/Makefile
876a4a8
index c4f5d4c..8f557a1 100644
876a4a8
--- a/libselinux/src/Makefile
876a4a8
+++ b/libselinux/src/Makefile
876a4a8
@@ -18,9 +18,7 @@ RUBYLIBVER ?= $(shell $(RUBY) -e 'print RUBY_VERSION.split(".")[0..1].join(".")'
876a4a8
 RUBYPLATFORM ?= $(shell $(RUBY) -e 'print RUBY_PLATFORM')
876a4a8
 RUBYINC ?= $(shell pkg-config --cflags ruby)
876a4a8
 RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM)
876a4a8
-LIBBASE=$(shell basename $(LIBDIR))
876a4a8
-
876a4a8
-LDFLAGS ?= -lpcre -lpthread
876a4a8
+LIBBASE ?= $(shell basename $(LIBDIR))
876a4a8
 
876a4a8
 VERSION = $(shell cat ../VERSION)
876a4a8
 LIBVERSION = 1
876a4a8
@@ -116,7 +114,7 @@ $(LIBA): $(OBJS)
876a4a8
 	$(RANLIB) $@
876a4a8
 
876a4a8
 $(LIBSO): $(LOBJS)
876a4a8
-	$(CC) $(CFLAGS) -shared -o $@ $^ -ldl $(LDFLAGS) -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
876a4a8
+	$(CC) $(CFLAGS) -shared -o $@ $^ -lpcre -lpthread -ldl $(LDFLAGS) -L$(LIBDIR) -Wl,-soname,$(LIBSO),-z,defs,-z,relro
876a4a8
 	ln -sf $@ $(TARGET) 
876a4a8
 
876a4a8
 $(LIBPC): $(LIBPC).in ../VERSION
ce3cc63
diff --git a/libselinux/src/audit2why.c b/libselinux/src/audit2why.c
ade34f3
index ffe381b..560bc25 100644
ce3cc63
--- a/libselinux/src/audit2why.c
ce3cc63
+++ b/libselinux/src/audit2why.c
ade34f3
@@ -210,27 +210,12 @@ static int __policy_init(const char *init_path)
ade34f3
 			return 1;
ade34f3
 		}
ade34f3
 	} else {
ade34f3
-		vers = sepol_policy_kern_vers_max();
ade34f3
-		if (vers < 0) {
ade34f3
-			snprintf(errormsg, sizeof(errormsg), 
ade34f3
-				 "Could not get policy version:  %s\n",
ade34f3
-				 strerror(errno));
ade34f3
-			PyErr_SetString( PyExc_ValueError, errormsg);
ade34f3
-			return 1;
ade34f3
-		}
ade34f3
-		snprintf(path, PATH_MAX, "%s.%d",
ade34f3
-			 selinux_binary_policy_path(), vers);
ade34f3
-		fp = fopen(path, "r");
ade34f3
-		while (!fp && errno == ENOENT && --vers) {
ade34f3
-			snprintf(path, PATH_MAX, "%s.%d",
ade34f3
-				 selinux_binary_policy_path(), vers);
ade34f3
-			fp = fopen(path, "r");
ade34f3
-		}
ade34f3
+		fp = fopen(selinux_current_policy_path(), "r");
ade34f3
 		if (!fp) {
ade34f3
 			snprintf(errormsg, sizeof(errormsg), 
ade34f3
-				 "unable to open %s.%d:  %s\n",
ade34f3
-				 selinux_binary_policy_path(),
ade34f3
-				 security_policyvers(), strerror(errno));
ade34f3
+				 "unable to open %s:  %s\n",
ade34f3
+				 selinux_current_policy_path(),
ade34f3
+				 strerror(errno));
ade34f3
 			PyErr_SetString( PyExc_ValueError, errormsg);
ade34f3
 			return 1;
ade34f3
 		}
ade34f3
@@ -310,10 +295,12 @@ static PyObject *init(PyObject *self __attribute__((unused)), PyObject *args) {
e7604b1
 }
e7604b1
 
e7604b1
 #define RETURN(X) \
e7604b1
-	PyTuple_SetItem(result, 0, Py_BuildValue("i", X));	\
e7604b1
-	return result;						
e7604b1
+	{ \
e7604b1
+		return Py_BuildValue("iO", (X), Py_None);	\
e7604b1
+	}					
edd5aaa
 
edd5aaa
 static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args) {
edd5aaa
+	char *reason_buf = NULL;
edd5aaa
 	security_context_t scon; 
edd5aaa
 	security_context_t tcon;
edd5aaa
 	char *tclassstr; 
ade34f3
@@ -328,10 +315,6 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
e7604b1
 	struct sepol_av_decision avd;
e7604b1
 	int rc;
e7604b1
 	int i=0;
e7604b1
-	PyObject *result = PyTuple_New(2);
e7604b1
-	if (!result) return NULL;
e7604b1
-	Py_INCREF(Py_None);
e7604b1
-	PyTuple_SetItem(result, 1, Py_None);
e7604b1
 
e7604b1
 	if (!PyArg_ParseTuple(args,(char *)"sssO!:audit2why",&scon,&tcon,&tclassstr,&PyList_Type, &listObj)) 
e7604b1
 		return NULL;
ade34f3
@@ -342,22 +325,21 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
e7604b1
 	/* should raise an error here. */
e7604b1
 	if (numlines < 0)	return NULL; /* Not a list */
e7604b1
 
e7604b1
-	if (!avc) {
e7604b1
+	if (!avc)
e7604b1
 		RETURN(NOPOLICY)
e7604b1
-	}
e7604b1
 
e7604b1
 	rc = sepol_context_to_sid(scon, strlen(scon) + 1, &ssid);
e7604b1
-	if (rc < 0) {
e7604b1
+	if (rc < 0)
e7604b1
 		RETURN(BADSCON)
e7604b1
-	}
e7604b1
+
e7604b1
 	rc = sepol_context_to_sid(tcon, strlen(tcon) + 1, &tsid);
e7604b1
-	if (rc < 0) {
e7604b1
+	if (rc < 0)
e7604b1
 		RETURN(BADTCON)
e7604b1
-	}
e7604b1
+
e7604b1
 	tclass = string_to_security_class(tclassstr);
e7604b1
-	if (!tclass) {
e7604b1
+	if (!tclass)
e7604b1
 		RETURN(BADTCLASS)
e7604b1
-	}
e7604b1
+
e7604b1
 	/* Convert the permission list to an AV. */
e7604b1
 	av = 0;
e7604b1
 
ade34f3
@@ -377,21 +359,20 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
e7604b1
 #endif
e7604b1
 		
e7604b1
 		perm = string_to_av_perm(tclass, permstr);
e7604b1
-		if (!perm) {
e7604b1
+		if (!perm)
e7604b1
 			RETURN(BADPERM)
e7604b1
-		}
e7604b1
+
e7604b1
 		av |= perm;
edd5aaa
 	}
edd5aaa
 
edd5aaa
 	/* Reproduce the computation. */
edd5aaa
-	rc = sepol_compute_av_reason(ssid, tsid, tclass, av, &avd, &reason);
e7604b1
-	if (rc < 0) {
3fdab66
+	rc = sepol_compute_av_reason_buffer(ssid, tsid, tclass, av, &avd, &reason, &reason_buf, 0);
e7604b1
+	if (rc < 0)
edd5aaa
 		RETURN(BADCOMPUTE)
e7604b1
-	}
e7604b1
 
e7604b1
-	if (!reason) {
e7604b1
+	if (!reason)
e7604b1
 		RETURN(ALLOW)
e7604b1
-	}
e7604b1
+
e7604b1
 	if (reason & SEPOL_COMPUTEAV_TE) {
e7604b1
 		avc->ssid = ssid;
e7604b1
 		avc->tsid = tsid;
ade34f3
@@ -404,28 +385,34 @@ static PyObject *analyze(PyObject *self __attribute__((unused)) , PyObject *args
e7604b1
 				RETURN(TERULE)
e7604b1
 			}
e7604b1
 		} else {
e7604b1
-			PyTuple_SetItem(result, 0, Py_BuildValue("i", BOOLEAN));
e7604b1
+			PyObject *outboollist;
e7604b1
 			struct boolean_t *b = bools;
e7604b1
 			int len=0;
e7604b1
 			while (b->name) {
e7604b1
 				len++; b++;
e7604b1
 			}
e7604b1
 			b = bools;
e7604b1
-			PyObject *outboollist = PyTuple_New(len);
e7604b1
+			outboollist = PyList_New(len);
e7604b1
 			len=0;
e7604b1
 			while(b->name) {
e7604b1
-				PyObject *bool = Py_BuildValue("(si)", b->name, b->active);
e7604b1
-				PyTuple_SetItem(outboollist, len++, bool);
e7604b1
+				PyObject *bool_ = Py_BuildValue("(si)", b->name, b->active);
e7604b1
+				PyList_SetItem(outboollist, len++, bool_);
e7604b1
 				b++;
e7604b1
 			}
e7604b1
 			free(bools);
e7604b1
-			PyTuple_SetItem(result, 1, outboollist);
e7604b1
-			return result;
e7604b1
+			/* 'N' steals the reference to outboollist */
e7604b1
+			return Py_BuildValue("iN", BOOLEAN, outboollist);
e7604b1
 		}
edd5aaa
 	}
edd5aaa
 
edd5aaa
 	if (reason & SEPOL_COMPUTEAV_CONS) {
e7604b1
-		RETURN(CONSTRAINT);
e7604b1
+		if (reason_buf) {
e7604b1
+			PyObject *result = NULL;
e7604b1
+			result = Py_BuildValue("is", CONSTRAINT, reason_buf);
e7604b1
+			free(reason_buf);
e7604b1
+			return result;
e7604b1
+		} 
e7604b1
+		RETURN(CONSTRAINT)
edd5aaa
 	}
edd5aaa
 
c1553db
 	if (reason & SEPOL_COMPUTEAV_RBAC)
ce3cc63
diff --git a/libselinux/src/avc.c b/libselinux/src/avc.c
ce3cc63
index 802a07f..6ff83a7 100644
ce3cc63
--- a/libselinux/src/avc.c
ce3cc63
+++ b/libselinux/src/avc.c
ce3cc63
@@ -827,6 +827,7 @@ int avc_has_perm(security_id_t ssid, security_id_t tsid,
ce3cc63
 	errsave = errno;
ce3cc63
 	avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata);
ce3cc63
 	errno = errsave;
ce3cc63
+	if (!avc_enforcing) return 0;
ce3cc63
 	return rc;
ce3cc63
 }
80c334b
 
c1553db
diff --git a/libselinux/src/get_context_list.c b/libselinux/src/get_context_list.c
c1553db
index b9e8002..355730a 100644
c1553db
--- a/libselinux/src/get_context_list.c
c1553db
+++ b/libselinux/src/get_context_list.c
c1553db
@@ -426,7 +426,7 @@ int get_ordered_context_list(const char *user,
c1553db
 	/* Initialize ordering array. */
c1553db
 	ordering = malloc(nreach * sizeof(unsigned int));
c1553db
 	if (!ordering)
c1553db
-		goto oom_order;
c1553db
+		goto failsafe;
c1553db
 	for (i = 0; i < nreach; i++)
c1553db
 		ordering[i] = nreach;
10e77a8
 
c1553db
@@ -435,7 +435,7 @@ int get_ordered_context_list(const char *user,
c1553db
 	fname_len = strlen(user_contexts_path) + strlen(user) + 2;
c1553db
 	fname = malloc(fname_len);
c1553db
 	if (!fname)
c1553db
-		goto oom_order;
c1553db
+		goto failsafe;
c1553db
 	snprintf(fname, fname_len, "%s%s", user_contexts_path, user);
c1553db
 	fp = fopen(fname, "r");
c1553db
 	if (fp) {
c1553db
@@ -465,31 +465,28 @@ int get_ordered_context_list(const char *user,
c1553db
 		}
c1553db
 	}
10e77a8
 
c1553db
+	if (!nordered)
c1553db
+		goto failsafe;
976da17
+
c1553db
 	/* Apply the ordering. */
c1553db
-	if (nordered) {
c1553db
-		co = malloc(nreach * sizeof(struct context_order));
c1553db
-		if (!co)
c1553db
-			goto oom_order;
c1553db
-		for (i = 0; i < nreach; i++) {
c1553db
-			co[i].con = reachable[i];
c1553db
-			co[i].order = ordering[i];
c1553db
-		}
c1553db
-		qsort(co, nreach, sizeof(struct context_order), order_compare);
c1553db
-		for (i = 0; i < nreach; i++)
c1553db
-			reachable[i] = co[i].con;
c1553db
-		free(co);
c1553db
+	co = malloc(nreach * sizeof(struct context_order));
c1553db
+	if (!co)
c1553db
+		goto failsafe;
c1553db
+	for (i = 0; i < nreach; i++) {
c1553db
+		co[i].con = reachable[i];
c1553db
+		co[i].order = ordering[i];
c1553db
 	}
c1553db
+	qsort(co, nreach, sizeof(struct context_order), order_compare);
c1553db
+	for (i = 0; i < nreach; i++)
c1553db
+		reachable[i] = co[i].con;
c1553db
+	free(co);
10e77a8
 
c1553db
-	/* Return the ordered list. 
c1553db
-	   If we successfully ordered it, then only report the ordered entries
c1553db
-	   to the caller.  Otherwise, fall back to the entire reachable list. */
c1553db
-	if (nordered && nordered < nreach) {
c1553db
+	/* Only report the ordered entries to the caller. */
c1553db
+	if (nordered < nreach) {
c1553db
 		for (i = nordered; i < nreach; i++)
c1553db
 			free(reachable[i]);
c1553db
 		reachable[nordered] = NULL;
c1553db
 		rc = nordered;
c1553db
-	} else {
c1553db
-		rc = nreach;
c1553db
 	}
01a1f70
 
3fdab66
       out:
c1553db
@@ -523,14 +520,6 @@ int get_ordered_context_list(const char *user,
3fdab66
 	}
c1553db
 	rc = 1;			/* one context in the list */
c1553db
 	goto out;
c1553db
-
c1553db
-      oom_order:
c1553db
-	/* Unable to order context list due to OOM condition.
c1553db
-	   Fall back to unordered reachable context list. */
c1553db
-	fprintf(stderr, "%s:  out of memory, unable to order list\n",
c1553db
-		__FUNCTION__);
c1553db
-	rc = nreach;
c1553db
-	goto out;
c1553db
 }
c1553db
 
c1553db
 hidden_def(get_ordered_context_list)
def2153
diff --git a/libselinux/src/label.c b/libselinux/src/label.c
4720ddb
index 11f6e96..f5cb52a 100644
def2153
--- a/libselinux/src/label.c
def2153
+++ b/libselinux/src/label.c
4720ddb
@@ -43,12 +43,18 @@ static void selabel_subs_fini(struct selabel_sub *ptr)
4720ddb
 static char *selabel_sub(struct selabel_sub *ptr, const char *src)
4720ddb
 {
4720ddb
 	char *dst = NULL;
4720ddb
+	int len;
4720ddb
 
4720ddb
 	while (ptr) {
def2153
 		if (strncmp(src, ptr->src, ptr->slen) == 0 ) {
def2153
 			if (src[ptr->slen] == '/' || 
def2153
 			    src[ptr->slen] == 0) {
4720ddb
-				if (asprintf(&dst, "%s%s", ptr->dst, &src[ptr->slen]) < 0)
def2153
+				if ((src[ptr->slen] == '/') && 
def2153
+				    (strcmp(ptr->dst, "/") == 0))
4720ddb
+					len = ptr->slen + 1;
4720ddb
+				else
4720ddb
+					len = ptr->slen;
4720ddb
+				if (asprintf(&dst, "%s%s", ptr->dst, &src[len]) < 0)
def2153
 					return NULL;
def2153
 				return dst;
4720ddb
 			}
cc9c7dd
diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
cc9c7dd
index 5f697f3..9b0d6b0 100644
cc9c7dd
--- a/libselinux/src/label_file.c
cc9c7dd
+++ b/libselinux/src/label_file.c
cc9c7dd
@@ -649,6 +649,8 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
cc9c7dd
 				break;
cc9c7dd
 			} else if (rc == PCRE_ERROR_NOMATCH)
cc9c7dd
 				continue;
cc9c7dd
+
cc9c7dd
+			errno = ENOENT;
cc9c7dd
 			/* else it's an error */
cc9c7dd
 			goto finish;
cc9c7dd
 		}
cc9c7dd
@@ -660,6 +662,7 @@ static struct selabel_lookup_rec *lookup(struct selabel_handle *rec,
cc9c7dd
 		goto finish;
cc9c7dd
 	}
cc9c7dd
 
cc9c7dd
+	errno = 0;
cc9c7dd
 	ret = &spec_arr[i].lr;
cc9c7dd
 
cc9c7dd
 finish:
ca9cea7
diff --git a/libselinux/src/matchpathcon.c b/libselinux/src/matchpathcon.c
01a1f70
index 2d7369e..2a00807 100644
ca9cea7
--- a/libselinux/src/matchpathcon.c
ca9cea7
+++ b/libselinux/src/matchpathcon.c
495b754
@@ -2,6 +2,7 @@
974a6e4
 #include <string.h>
974a6e4
 #include <errno.h>
974a6e4
 #include <stdio.h>
974a6e4
+#include <syslog.h>
974a6e4
 #include "selinux_internal.h"
974a6e4
 #include "label_internal.h"
974a6e4
 #include "callbacks.h"
495b754
@@ -62,7 +63,7 @@ static void
974a6e4
 {
974a6e4
 	va_list ap;
974a6e4
 	va_start(ap, fmt);
974a6e4
-	vfprintf(stderr, fmt, ap);
974a6e4
+	vsyslog(LOG_ERR, fmt, ap);
974a6e4
 	va_end(ap);
974a6e4
 }
b5b41bc
 
9df78f0
diff --git a/libselinux/src/procattr.c b/libselinux/src/procattr.c
1961617
index 6c5b45a..f6b896e 100644
9df78f0
--- a/libselinux/src/procattr.c
9df78f0
+++ b/libselinux/src/procattr.c
1961617
@@ -9,13 +9,15 @@
1961617
 #include "selinux_internal.h"
1961617
 #include "policy.h"
1961617
 
1961617
+#define UNSET (const security_context_t) -1
1961617
+
1961617
 static __thread pid_t cpid;
1961617
 static __thread pid_t tid;
1961617
-static __thread security_context_t prev_current;
1961617
-static __thread security_context_t prev_exec;
1961617
-static __thread security_context_t prev_fscreate;
1961617
-static __thread security_context_t prev_keycreate;
1961617
-static __thread security_context_t prev_sockcreate;
1961617
+static __thread security_context_t prev_current = UNSET;
1961617
+static __thread security_context_t prev_exec = UNSET;
1961617
+static __thread security_context_t prev_fscreate = UNSET;
1961617
+static __thread security_context_t prev_keycreate = UNSET;
1961617
+static __thread security_context_t prev_sockcreate = UNSET;
1961617
 
1961617
 static pthread_once_t once = PTHREAD_ONCE_INIT;
1961617
 static pthread_key_t destructor_key;
1961617
@@ -29,11 +31,16 @@ static pid_t gettid(void)
1961617
 
1961617
 static void procattr_thread_destructor(void __attribute__((unused)) *unused)
1961617
 {
1961617
-	free(prev_current);
1961617
-	free(prev_exec);
1961617
-	free(prev_fscreate);
1961617
-	free(prev_keycreate);
1961617
-	free(prev_sockcreate);
1961617
+	if (prev_current != UNSET)
1961617
+		free(prev_current);
1961617
+	if (prev_exec != UNSET)
1961617
+		free(prev_exec);
1961617
+	if (prev_fscreate != UNSET)
1961617
+		free(prev_fscreate);
1961617
+	if (prev_keycreate != UNSET)
1961617
+		free(prev_keycreate);
1961617
+	if (prev_sockcreate != UNSET)
1961617
+		free(prev_sockcreate);
1961617
 }
1961617
 
1961617
 static void free_procattr(void)
1961617
@@ -41,7 +48,7 @@ static void free_procattr(void)
1961617
 	procattr_thread_destructor(NULL);
1961617
 	tid = 0;
1961617
 	cpid = getpid();
1961617
-	prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = NULL;
1961617
+	prev_current = prev_exec = prev_fscreate = prev_keycreate = prev_sockcreate = UNSET;
1961617
 }
1961617
 
1961617
 void __attribute__((destructor)) procattr_destructor(void);
1961617
@@ -131,7 +138,7 @@ static int getprocattrcon_raw(security_context_t * context,
1961617
 			return -1;
1961617
 	};
1961617
 
1961617
-	if (prev_context) {
1961617
+	if (prev_context && prev_context != UNSET) {
1961617
 		*context = strdup(prev_context);
1961617
 		if (!(*context)) {
1961617
 			return -1;
1961617
@@ -230,7 +237,8 @@ static int setprocattrcon_raw(security_context_t context,
1961617
 
1961617
 	if (!context && !*prev_context)
1961617
 		return 0;
1961617
-	if (context && *prev_context && !strcmp(context, *prev_context))
1961617
+	if (context && *prev_context && *prev_context != UNSET 
1961617
+	    && !strcmp(context, *prev_context))
1961617
 		return 0;
1961617
 
1961617
 	fd = openattr(pid, attr, O_RDWR);
1961617
@@ -257,6 +265,8 @@ out:
9df78f0
 		free(context);
9df78f0
 		return -1;
9df78f0
 	} else {
1961617
+		if (*prev_context != UNSET)
1961617
+			free(*prev_context);
9df78f0
 		*prev_context = context;
9df78f0
 		return 0;
9df78f0
 	}
ade34f3
diff --git a/libselinux/src/selinux_config.c b/libselinux/src/selinux_config.c
58f9722
index 296f357..9aee32f 100644
ade34f3
--- a/libselinux/src/selinux_config.c
ade34f3
+++ b/libselinux/src/selinux_config.c
cc9c7dd
@@ -8,6 +8,8 @@
ade34f3
 #include <limits.h>
ade34f3
 #include <unistd.h>
ade34f3
 #include <pthread.h>
cc9c7dd
+#include <errno.h>
ade34f3
+#include "policy.h"
ade34f3
 #include "selinux_internal.h"
ade34f3
 #include "get_default_type_internal.h"
ade34f3
 
cc9c7dd
@@ -138,6 +140,13 @@ int selinux_getpolicytype(char **type)
cc9c7dd
 
cc9c7dd
 hidden_def(selinux_getpolicytype)
cc9c7dd
 
cc9c7dd
+static int setpolicytype(const char *type)
cc9c7dd
+{
cc9c7dd
+	free(selinux_policytype);
cc9c7dd
+	selinux_policytype = strdup(type);
cc9c7dd
+	return selinux_policytype ? 0 : -1;
cc9c7dd
+}
cc9c7dd
+
cc9c7dd
 static char *selinux_policyroot = NULL;
cc9c7dd
 static const char *selinux_rootpath = SELINUXDIR;
cc9c7dd
 
cc9c7dd
@@ -261,6 +270,37 @@ const char *selinux_policy_root(void)
cc9c7dd
 	return selinux_policyroot;
cc9c7dd
 }
cc9c7dd
 
cc9c7dd
+int selinux_set_policy_root(const char *path)
cc9c7dd
+{
cc9c7dd
+	int i;
58f9722
+	char *policy_type = strrchr(path, '/');
cc9c7dd
+	if (!policy_type) {
cc9c7dd
+		errno = EINVAL;
cc9c7dd
+		return -1;
cc9c7dd
+	}
cc9c7dd
+	policy_type++;
cc9c7dd
+
cc9c7dd
+	fini_selinuxmnt();
cc9c7dd
+	fini_selinux_policyroot();
cc9c7dd
+
cc9c7dd
+	selinux_policyroot = strdup(path);
cc9c7dd
+	if (! selinux_policyroot) 
cc9c7dd
+		return -1;
cc9c7dd
+
cc9c7dd
+	if (setpolicytype(policy_type) != 0)
cc9c7dd
+		return -1;
cc9c7dd
+
cc9c7dd
+	for (i = 0; i < NEL; i++)
cc9c7dd
+		if (asprintf(&file_paths[i], "%s%s",
cc9c7dd
+			     selinux_policyroot,
cc9c7dd
+			     file_path_suffixes_data.str +
cc9c7dd
+			     file_path_suffixes_idx[i])
cc9c7dd
+		    == -1)
cc9c7dd
+			return -1;
cc9c7dd
+
cc9c7dd
+	return 0;
cc9c7dd
+}
cc9c7dd
+
cc9c7dd
 const char *selinux_path(void)
cc9c7dd
 {
cc9c7dd
 	return selinux_rootpath;
cc9c7dd
@@ -303,6 +343,31 @@ const char *selinux_binary_policy_path(void)
ade34f3
 
ade34f3
 hidden_def(selinux_binary_policy_path)
ade34f3
 
ade34f3
+const char *selinux_current_policy_path(void)
ade34f3
+{
ade34f3
+	int rc = 0;
ade34f3
+	int vers = 0;
ade34f3
+	static char policy_path[PATH_MAX];
ade34f3
+
cc9c7dd
+	if (selinux_mnt) {
cc9c7dd
+		snprintf(policy_path, sizeof(policy_path), "%s/policy", selinux_mnt);
cc9c7dd
+		if (access(policy_path, F_OK) == 0 ) {
cc9c7dd
+			return policy_path;
cc9c7dd
+		}
ade34f3
+	}
cc9c7dd
+	vers = security_policyvers();
cc9c7dd
+	do {
cc9c7dd
+		/* Check prior versions to see if old policy is available */
cc9c7dd
+		snprintf(policy_path, sizeof(policy_path), "%s.%d",
cc9c7dd
+			 selinux_binary_policy_path(), vers);
cc9c7dd
+	} while ((rc = access(policy_path, F_OK)) && --vers > 0);
cc9c7dd
+	
cc9c7dd
+	if (rc) return NULL;
ade34f3
+	return policy_path;
ade34f3
+}
ade34f3
+
ade34f3
+hidden_def(selinux_current_policy_path)
ade34f3
+
ade34f3
 const char *selinux_file_context_path(void)
ade34f3
 {
ade34f3
 	return get_path(FILE_CONTEXTS);
ade34f3
diff --git a/libselinux/src/selinux_internal.h b/libselinux/src/selinux_internal.h
ade34f3
index 2c7c85c..4a4aebc 100644
ade34f3
--- a/libselinux/src/selinux_internal.h
ade34f3
+++ b/libselinux/src/selinux_internal.h
ade34f3
@@ -60,6 +60,7 @@ hidden_proto(selinux_mkload_policy)
ade34f3
     hidden_proto(security_setenforce)
ade34f3
     hidden_proto(security_deny_unknown)
ade34f3
     hidden_proto(selinux_boolean_sub)
ade34f3
+    hidden_proto(selinux_current_policy_path)
ade34f3
     hidden_proto(selinux_binary_policy_path)
ade34f3
     hidden_proto(selinux_booleans_subs_path)
ade34f3
     hidden_proto(selinux_default_context_path)
70712b9
diff --git a/libselinux/src/selinuxswig_python.i b/libselinux/src/selinuxswig_python.i
70712b9
index 359bd02..0ab0bae 100644
70712b9
--- a/libselinux/src/selinuxswig_python.i
70712b9
+++ b/libselinux/src/selinuxswig_python.i
70712b9
@@ -74,6 +74,10 @@ def install(src, dest):
70712b9
   $1 = &tem;;
70712b9
 }
70712b9
 
70712b9
+%typemap(in, numinputs=0) void *(char *temp=NULL) {
70712b9
+	$1 = temp;
70712b9
+}
70712b9
+
70712b9
 /* Makes security_compute_user() return a Python list of contexts */
70712b9
 %typemap(argout) (security_context_t **con) {
70712b9
 	PyObject* plist;
0781a5c
diff --git a/libselinux/src/setrans_internal.h b/libselinux/src/setrans_internal.h
0781a5c
index a801ee8..b3bdca2 100644
0781a5c
--- a/libselinux/src/setrans_internal.h
0781a5c
+++ b/libselinux/src/setrans_internal.h
0781a5c
@@ -1,6 +1,7 @@
0781a5c
 /* Author: Trusted Computer Solutions, Inc. */
0781a5c
+#include <selinux/selinux.h>
0781a5c
 
0781a5c
-#define SETRANS_UNIX_SOCKET "/var/run/setrans/.setrans-unix"
0781a5c
+#define SETRANS_UNIX_SOCKET SELINUX_TRANS_DIR "/.setrans-unix"
0781a5c
 
0781a5c
 #define RAW_TO_TRANS_CONTEXT		2
0781a5c
 #define TRANS_TO_RAW_CONTEXT		3
cc9c7dd
diff --git a/libselinux/utils/matchpathcon.c b/libselinux/utils/matchpathcon.c
cc9c7dd
index dd5aaa3..9d3ff3a 100644
cc9c7dd
--- a/libselinux/utils/matchpathcon.c
cc9c7dd
+++ b/libselinux/utils/matchpathcon.c
cc9c7dd
@@ -12,11 +12,10 @@
cc9c7dd
 #include <limits.h>
cc9c7dd
 #include <stdlib.h>
cc9c7dd
 
cc9c7dd
-
cc9c7dd
 static void usage(const char *progname)
cc9c7dd
 {
cc9c7dd
 	fprintf(stderr,
cc9c7dd
-		"usage:  %s [-N] [-n] [-f file_contexts] [-p prefix] [-Vq] path...\n",
cc9c7dd
+		"usage:  %s [-N] [-n] [-f file_contexts] [ -P policy_root_path ] [-p prefix] [-Vq] path...\n",
cc9c7dd
 		progname);
cc9c7dd
 	exit(1);
cc9c7dd
 }
cc9c7dd
@@ -78,7 +77,7 @@ int main(int argc, char **argv)
cc9c7dd
 	if (argc < 2)
cc9c7dd
 		usage(argv[0]);
cc9c7dd
 
cc9c7dd
-	while ((opt = getopt(argc, argv, "m:Nnf:p:Vq")) > 0) {
cc9c7dd
+	while ((opt = getopt(argc, argv, "m:Nnf:P:p:Vq")) > 0) {
cc9c7dd
 		switch (opt) {
cc9c7dd
 		case 'n':
cc9c7dd
 			header = 0;
cc9c7dd
@@ -113,6 +112,15 @@ int main(int argc, char **argv)
cc9c7dd
 				exit(1);
cc9c7dd
 			}
cc9c7dd
 			break;
cc9c7dd
+		case 'P':
cc9c7dd
+			if (selinux_set_policy_root(optarg) < 0 ) {
cc9c7dd
+				fprintf(stderr,
cc9c7dd
+					"Error setting policy root  %s:  %s\n",
cc9c7dd
+					optarg,
cc9c7dd
+					errno ? strerror(errno) : "invalid");
cc9c7dd
+				exit(1);
cc9c7dd
+			}
cc9c7dd
+			break;
cc9c7dd
 		case 'p':
cc9c7dd
 			if (init) {
cc9c7dd
 				fprintf(stderr,
8047eef
diff --git a/libselinux/utils/sefcontext_compile.c b/libselinux/utils/sefcontext_compile.c
cc9c7dd
index 6f79dd6..e019a07 100644
8047eef
--- a/libselinux/utils/sefcontext_compile.c
8047eef
+++ b/libselinux/utils/sefcontext_compile.c
cc9c7dd
@@ -145,7 +145,7 @@ static int process_file(struct saved_data *data, const char *filename)
cc9c7dd
  *	u32  - data length of the pcre regex study daya
cc9c7dd
  *	char - a buffer holding the raw pcre regex study data
cc9c7dd
  */
cc9c7dd
-static int write_binary_file(struct saved_data *data, char *filename)
cc9c7dd
+static int write_binary_file(struct saved_data *data, int fd)
cc9c7dd
 {
cc9c7dd
 	struct spec *specs = data->spec_arr;
cc9c7dd
 	FILE *bin_file;
cc9c7dd
@@ -155,7 +155,7 @@ static int write_binary_file(struct saved_data *data, char *filename)
cc9c7dd
 	uint32_t i;
cc9c7dd
 	int rc;
8047eef
 
cc9c7dd
-	bin_file = fopen(filename, "w");
cc9c7dd
+	bin_file = fdopen(fd, "w");
cc9c7dd
 	if (!bin_file) {
cc9c7dd
 		perror("fopen output_file");
cc9c7dd
 		exit(EXIT_FAILURE);
cc9c7dd
@@ -321,7 +321,9 @@ int main(int argc, char *argv[])
8047eef
 	const char *path;
8047eef
 	char stack_path[PATH_MAX + 1];
8047eef
 	int rc;
8047eef
-
cc9c7dd
+	char *tmp= NULL;
cc9c7dd
+	int fd;
8047eef
+	
8047eef
 	if (argc != 2) {
8047eef
 		fprintf(stderr, "usage: %s input_file\n", argv[0]);
8047eef
 		exit(EXIT_FAILURE);
cc9c7dd
@@ -342,13 +344,29 @@ int main(int argc, char *argv[])
8047eef
 	rc = snprintf(stack_path, sizeof(stack_path), "%s.bin", path);
8047eef
 	if (rc < 0 || rc >= sizeof(stack_path))
8047eef
 		return rc;
8047eef
-	rc = write_binary_file(&data, stack_path);
cc9c7dd
+
cc9c7dd
+	if (asprintf(&tmp, "%sXXXXXX", stack_path) < 0)
cc9c7dd
+		return -1;
cc9c7dd
+
cc9c7dd
+	fd  = mkstemp(tmp);
cc9c7dd
+	if (fd < 0) 
cc9c7dd
+		goto err;
cc9c7dd
+
cc9c7dd
+	rc = write_binary_file(&data, fd);
cc9c7dd
+
cc9c7dd
 	if (rc < 0)
8047eef
-		return rc;
cc9c7dd
+		goto err;
8047eef
 
8047eef
+	rename(tmp, stack_path);
8047eef
 	rc = free_specs(&data);
8047eef
 	if (rc < 0)
cc9c7dd
-		return rc;
cc9c7dd
+		goto err;
cc9c7dd
 
cc9c7dd
-	return 0;
cc9c7dd
+	rc = 0;
cc9c7dd
+out:
cc9c7dd
+	free(tmp);
cc9c7dd
+	return rc;
cc9c7dd
+err:
cc9c7dd
+	rc = -1;
cc9c7dd
+	goto out;
cc9c7dd
 }