ytakagi / rpms / libselinux

Forked from rpms/libselinux 4 years ago
Clone

Blame SOURCES/libselinux-rhat.patch

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