chgpasswd: do not remove it

- chpasswd, chgpasswd: add selinux_check_access call (#1336902)
This commit is contained in:
Tomas Mraz 2016-05-26 21:05:16 +02:00
parent a359c84a6e
commit f884cd4c94
3 changed files with 292 additions and 20 deletions

View file

@ -73,7 +73,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
<para>The following configuration items are provided:</para>
<variablelist remap='IP'>
@@ -252,26 +263,6 @@
@@ -252,16 +263,6 @@
</listitem>
</varlistentry>
<varlistentry>
@ -87,20 +87,10 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
- </listitem>
- </varlistentry>
- <varlistentry>
- <term>chgpasswd</term>
- <listitem>
- <para>
- ENCRYPT_METHOD MAX_MEMBERS_PER_GROUP MD5_CRYPT_ENAB
- <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
- SHA_CRYPT_MIN_ROUNDS</phrase>
- </para>
- </listitem>
- </varlistentry>
- <varlistentry>
<term>chpasswd</term>
<term>chgpasswd</term>
<listitem>
<para>
@@ -282,14 +273,6 @@
@@ -282,14 +283,6 @@
</para>
</listitem>
</varlistentry>
@ -115,7 +105,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
<!-- expiry: no variables (CONSOLE_GROUPS linked, but not used) -->
<!-- faillog: no variables -->
<varlistentry>
@@ -350,34 +333,6 @@
@@ -350,34 +342,6 @@
</varlistentry>
<!-- id: no variables -->
<!-- lastlog: no variables -->
@ -150,7 +140,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
<!-- logoutd: no variables -->
<varlistentry>
<term>newgrp / sg</term>
@@ -405,17 +360,6 @@
@@ -405,17 +370,6 @@
</listitem>
</varlistentry>
<!-- nologin: no variables -->
@ -168,7 +158,7 @@ diff -up shadow-4.2.1/man/login.defs.5.xml.manfix shadow-4.2.1/man/login.defs.5.
<varlistentry>
<term>pwck</term>
<listitem>
@@ -442,32 +386,6 @@
@@ -442,32 +396,6 @@
</para>
</listitem>
</varlistentry>

View file

@ -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 <pwd.h>
#include <stdio.h>
#include <stdlib.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/avc.h>
+#endif
+#ifdef WITH_LIBAUDIT
+#include <libaudit.h>
+#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 <pwd.h>
#include <stdio.h>
#include <stdlib.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/avc.h>
+#endif
+#ifdef WITH_LIBAUDIT
+#include <libaudit.h>
+#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)

View file

@ -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 <tmraz@redhat.com> - 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 <tmraz@redhat.com> - 2:4.2.1-8
- userdel: fix userdel -f with /etc/subuid present (#1316168)