diff --git a/shadow-4.2.1-manfix.patch b/shadow-4.2.1-manfix.patch
index 04fcb4a..2ca84b3 100644
--- a/shadow-4.2.1-manfix.patch
+++ b/shadow-4.2.1-manfix.patch
@@ -73,7 +73,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
The following configuration items are provided:
-@@ -252,26 +263,6 @@
+@@ -252,16 +263,6 @@
@@ -87,20 +87,10 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
-
-
-
-- chgpasswd
--
--
-- ENCRYPT_METHOD MAX_MEMBERS_PER_GROUP MD5_CRYPT_ENAB
-- SHA_CRYPT_MAX_ROUNDS
-- SHA_CRYPT_MIN_ROUNDS
--
--
--
--
- chpasswd
+ chgpasswd
-@@ -282,14 +273,6 @@
+@@ -282,14 +283,6 @@
@@ -115,7 +105,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
-@@ -350,34 +333,6 @@
+@@ -350,34 +342,6 @@
@@ -150,7 +140,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
newgrp / sg
-@@ -405,17 +360,6 @@
+@@ -405,17 +370,6 @@
@@ -168,7 +158,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
pwck
-@@ -442,32 +386,6 @@
+@@ -442,32 +396,6 @@
diff --git a/shadow-4.2.1-selinux-perms.patch b/shadow-4.2.1-selinux-perms.patch
new file mode 100644
index 0000000..eb18aeb
--- /dev/null
+++ b/shadow-4.2.1-selinux-perms.patch
@@ -0,0 +1,277 @@
+diff -up shadow-4.2.1/src/chgpasswd.c.selinux-perms shadow-4.2.1/src/chgpasswd.c
+--- shadow-4.2.1/src/chgpasswd.c.selinux-perms 2014-03-01 19:59:51.000000000 +0100
++++ shadow-4.2.1/src/chgpasswd.c 2016-05-26 20:56:56.723676087 +0200
+@@ -39,6 +39,13 @@
+ #include
+ #include
+ #include
++#ifdef WITH_SELINUX
++#include
++#include
++#endif
++#ifdef WITH_LIBAUDIT
++#include
++#endif
+ #ifdef ACCT_TOOLS_SETUID
+ #ifdef USE_PAM
+ #include "pam_defs.h"
+@@ -76,6 +83,9 @@ static bool sgr_locked = false;
+ #endif
+ static bool gr_locked = false;
+
++/* The name of the caller */
++static char *myname = NULL;
++
+ /* local function prototypes */
+ static void fail_exit (int code);
+ static /*@noreturn@*/void usage (int status);
+@@ -300,6 +310,62 @@ static void check_perms (void)
+ #endif /* ACCT_TOOLS_SETUID */
+ }
+
++#ifdef WITH_SELINUX
++static int
++log_callback (int type, const char *fmt, ...)
++{
++ int audit_fd;
++ va_list ap;
++
++ va_start(ap, fmt);
++#ifdef WITH_AUDIT
++ audit_fd = audit_open();
++
++ if (audit_fd >= 0) {
++ char *buf;
++
++ if (vasprintf (&buf, fmt, ap) < 0)
++ return 0;
++ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
++ NULL, 0);
++ audit_close(audit_fd);
++ free(buf);
++ return 0;
++ }
++
++#endif
++ vsyslog (LOG_USER | LOG_INFO, fmt, ap);
++ va_end(ap);
++ return 0;
++}
++
++static void
++selinux_check_root (void)
++{
++ int status = -1;
++ security_context_t user_context;
++ union selinux_callback old_callback;
++
++ if (is_selinux_enabled() < 1)
++ return;
++
++ old_callback = selinux_get_callback(SELINUX_CB_LOG);
++ /* setup callbacks */
++ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback);
++ if ((status = getprevcon(&user_context)) < 0) {
++ selinux_set_callback(SELINUX_CB_LOG, old_callback);
++ exit(1);
++ }
++
++ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL);
++
++ selinux_set_callback(SELINUX_CB_LOG, old_callback);
++ freecon(user_context);
++ if (status != 0 && security_getenforce() != 0)
++ exit(1);
++}
++#endif
++
+ /*
+ * open_files - lock and open the group databases
+ */
+@@ -393,6 +459,7 @@ int main (int argc, char **argv)
+
+ const struct group *gr;
+ struct group newgr;
++ struct passwd *pw = NULL;
+ int errors = 0;
+ int line = 0;
+
+@@ -408,8 +475,29 @@ int main (int argc, char **argv)
+
+ OPENLOG ("chgpasswd");
+
++ /*
++ * Determine the name of the user that invoked this command. This
++ * is really hit or miss because there are so many ways that command
++ * can be executed and so many ways to trip up the routines that
++ * report the user name.
++ */
++ pw = get_my_pwent ();
++ if (NULL == pw) {
++ fprintf (stderr, _("%s: Cannot determine your user name.\n"),
++ Prog);
++ SYSLOG ((LOG_WARN,
++ "Cannot determine the user name of the caller (UID %lu)",
++ (unsigned long) getuid ()));
++ exit (E_NOPERM);
++ }
++ myname = xstrdup (pw->pw_name);
++
+ check_perms ();
+
++#ifdef WITH_SELINUX
++ selinux_check_root ();
++#endif
++
+ #ifdef SHADOWGRP
+ is_shadow_grp = sgr_file_present ();
+ #endif
+@@ -536,6 +624,15 @@ int main (int argc, char **argv)
+ newgr.gr_passwd = cp;
+ }
+
++#ifdef WITH_AUDIT
++ {
++
++ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog,
++ "change-password",
++ myname, AUDIT_NO_ID, gr->gr_name,
++ SHADOW_AUDIT_SUCCESS);
++ }
++#endif
+ /*
+ * The updated group file entry is then put back and will
+ * be written to the group file later, after all the
+diff -up shadow-4.2.1/src/chpasswd.c.selinux-perms shadow-4.2.1/src/chpasswd.c
+--- shadow-4.2.1/src/chpasswd.c.selinux-perms 2014-03-01 19:59:51.000000000 +0100
++++ shadow-4.2.1/src/chpasswd.c 2016-05-26 20:40:56.190224029 +0200
+@@ -39,6 +39,13 @@
+ #include
+ #include
+ #include
++#ifdef WITH_SELINUX
++#include
++#include
++#endif
++#ifdef WITH_LIBAUDIT
++#include
++#endif
+ #ifdef USE_PAM
+ #include "pam_defs.h"
+ #endif /* USE_PAM */
+@@ -297,6 +304,62 @@ static void check_perms (void)
+ #endif /* USE_PAM */
+ }
+
++#ifdef WITH_SELINUX
++static int
++log_callback (int type, const char *fmt, ...)
++{
++ int audit_fd;
++ va_list ap;
++
++ va_start(ap, fmt);
++#ifdef WITH_AUDIT
++ audit_fd = audit_open();
++
++ if (audit_fd >= 0) {
++ char *buf;
++
++ if (vasprintf (&buf, fmt, ap) < 0)
++ return 0;
++ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
++ NULL, 0);
++ audit_close(audit_fd);
++ free(buf);
++ return 0;
++ }
++
++#endif
++ vsyslog (LOG_USER | LOG_INFO, fmt, ap);
++ va_end(ap);
++ return 0;
++}
++
++static void
++selinux_check_root (void)
++{
++ int status = -1;
++ security_context_t user_context;
++ union selinux_callback old_callback;
++
++ if (is_selinux_enabled() < 1)
++ return;
++
++ old_callback = selinux_get_callback(SELINUX_CB_LOG);
++ /* setup callbacks */
++ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback);
++ if ((status = getprevcon(&user_context)) < 0) {
++ selinux_set_callback(SELINUX_CB_LOG, old_callback);
++ exit(1);
++ }
++
++ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL);
++
++ selinux_set_callback(SELINUX_CB_LOG, old_callback);
++ freecon(user_context);
++ if (status != 0 && security_getenforce() != 0)
++ exit(1);
++}
++#endif
++
+ /*
+ * open_files - lock and open the password databases
+ */
+@@ -407,6 +470,10 @@ int main (int argc, char **argv)
+
+ check_perms ();
+
++#ifdef WITH_SELINUX
++ selinux_check_root ();
++#endif
++
+ #ifdef USE_PAM
+ if (!use_pam)
+ #endif /* USE_PAM */
+@@ -566,6 +633,11 @@ int main (int argc, char **argv)
+ newpw.pw_passwd = cp;
+ }
+
++#ifdef WITH_AUDIT
++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
++ "updating-password",
++ pw->pw_name, (unsigned int) pw->pw_uid, 1);
++#endif
+ /*
+ * The updated password file entry is then put back and will
+ * be written to the password file later, after all the
+diff -up shadow-4.2.1/src/Makefile.am.selinux-perms shadow-4.2.1/src/Makefile.am
+--- shadow-4.2.1/src/Makefile.am.selinux-perms 2016-05-26 19:02:07.000000000 +0200
++++ shadow-4.2.1/src/Makefile.am 2016-05-26 20:38:52.738468738 +0200
+@@ -84,9 +84,9 @@ chage_LDADD = $(LDADD) $(LIBPAM_SUID)
+ newuidmap_LDADD = $(LDADD) $(LIBSELINUX)
+ newgidmap_LDADD = $(LDADD) $(LIBSELINUX)
+ chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
+-chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
++chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
+ chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
+-chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
++chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
+ gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT)
+ groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
+ groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
+diff -up shadow-4.2.1/src/Makefile.in.selinux-perms shadow-4.2.1/src/Makefile.in
+--- shadow-4.2.1/src/Makefile.in.selinux-perms 2016-05-26 19:02:07.000000000 +0200
++++ shadow-4.2.1/src/Makefile.in 2016-05-26 20:40:03.547049098 +0200
+@@ -521,9 +521,9 @@ chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(
+ newuidmap_LDADD = $(LDADD) $(LIBSELINUX)
+ newgidmap_LDADD = $(LDADD) $(LIBSELINUX)
+ chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
+-chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
++chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
+ chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
+-chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
++chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
+ gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT)
+ groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
+ groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
diff --git a/shadow-utils.spec b/shadow-utils.spec
index b47ae15..f8fb4aa 100644
--- a/shadow-utils.spec
+++ b/shadow-utils.spec
@@ -1,7 +1,7 @@
Summary: Utilities for managing accounts and shadow password files
Name: shadow-utils
Version: 4.2.1
-Release: 8%{?dist}
+Release: 9%{?dist}
Epoch: 2
URL: http://pkg-shadow.alioth.debian.org/
Source0: http://pkg-shadow.alioth.debian.org/releases/shadow-%{version}.tar.xz
@@ -35,6 +35,7 @@ Patch24: shadow-4.2.1-no-lock-dos.patch
Patch25: shadow-4.2.1-defs-chroot.patch
Patch26: shadow-4.2.1-lastlog-unexpire.patch
Patch27: shadow-4.2.1-user-busy.patch
+Patch28: shadow-4.2.1-selinux-perms.patch
License: BSD and GPLv2+
Group: System Environment/Base
@@ -90,6 +91,7 @@ are used for managing group accounts.
%patch25 -p1 -b .defs-chroot
%patch26 -p1 -b .unexpire
%patch27 -p1 -b .user-busy
+%patch28 -p1 -b .selinux-perms
iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8
cp -f doc/HOWTO.utf8 doc/HOWTO
@@ -156,7 +158,6 @@ rm $RPM_BUILD_ROOT/%{_sysconfdir}/login.access
rm $RPM_BUILD_ROOT/%{_sysconfdir}/limits
rm $RPM_BUILD_ROOT/%{_sbindir}/logoutd
rm $RPM_BUILD_ROOT/%{_sbindir}/nologin
-rm $RPM_BUILD_ROOT/%{_sbindir}/chgpasswd
rm $RPM_BUILD_ROOT/%{_mandir}/man1/chfn.*
rm $RPM_BUILD_ROOT/%{_mandir}/*/man1/chfn.*
rm $RPM_BUILD_ROOT/%{_mandir}/man1/chsh.*
@@ -185,8 +186,6 @@ rm $RPM_BUILD_ROOT/%{_mandir}/man8/logoutd.*
rm $RPM_BUILD_ROOT/%{_mandir}/*/man8/logoutd.*
rm $RPM_BUILD_ROOT/%{_mandir}/man8/nologin.*
rm $RPM_BUILD_ROOT/%{_mandir}/*/man8/nologin.*
-rm $RPM_BUILD_ROOT/%{_mandir}/man8/chgpasswd.*
-rm $RPM_BUILD_ROOT/%{_mandir}/*/man8/chgpasswd.*
rm $RPM_BUILD_ROOT/%{_mandir}/man3/getspnam.*
rm $RPM_BUILD_ROOT/%{_mandir}/*/man3/getspnam.*
rm $RPM_BUILD_ROOT/%{_mandir}/man5/faillog.*
@@ -228,6 +227,7 @@ rm -rf $RPM_BUILD_ROOT
%{_sbindir}/pwck
%{_sbindir}/*conv
%{_sbindir}/chpasswd
+%{_sbindir}/chgpasswd
%{_sbindir}/newusers
%{_sbindir}/vipw
%{_sbindir}/vigr
@@ -249,6 +249,7 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man8/pwck.8*
%{_mandir}/man8/grpck.8*
%{_mandir}/man8/chpasswd.8*
+%{_mandir}/man8/chgpasswd.8*
%{_mandir}/man8/newusers.8*
%{_mandir}/man8/*conv.8*
%{_mandir}/man8/lastlog.8*
@@ -256,6 +257,10 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man8/vigr.8*
%changelog
+* Thu May 26 2016 Tomáš Mráz - 2:4.2.1-9
+- chgpasswd: do not remove it
+- chpasswd, chgpasswd: add selinux_check_access call (#1336902)
+
* Thu Mar 17 2016 Tomáš Mráz - 2:4.2.1-8
- userdel: fix userdel -f with /etc/subuid present (#1316168)