|
|
fa2969 |
diff -up shadow-4.1.5.1/src/chgpasswd.c.selinux-perms shadow-4.1.5.1/src/chgpasswd.c
|
|
|
fa2969 |
--- shadow-4.1.5.1/src/chgpasswd.c.selinux-perms 2016-05-04 13:44:55.633787764 +0200
|
|
|
fa2969 |
+++ shadow-4.1.5.1/src/chgpasswd.c 2016-05-30 12:01:30.421587253 +0200
|
|
|
fa2969 |
@@ -39,6 +39,13 @@
|
|
|
fa2969 |
#include <pwd.h>
|
|
|
fa2969 |
#include <stdio.h>
|
|
|
fa2969 |
#include <stdlib.h>
|
|
|
fa2969 |
+#ifdef WITH_SELINUX
|
|
|
fa2969 |
+#include <selinux/selinux.h>
|
|
|
fa2969 |
+#include <selinux/avc.h>
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+#ifdef WITH_LIBAUDIT
|
|
|
fa2969 |
+#include <libaudit.h>
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
#ifdef ACCT_TOOLS_SETUID
|
|
|
fa2969 |
#ifdef USE_PAM
|
|
|
fa2969 |
#include "pam_defs.h"
|
|
|
fa2969 |
@@ -76,6 +83,9 @@ static bool sgr_locked = false;
|
|
|
fa2969 |
#endif
|
|
|
fa2969 |
static bool gr_locked = false;
|
|
|
fa2969 |
|
|
|
fa2969 |
+/* The name of the caller */
|
|
|
fa2969 |
+static char *myname = NULL;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
/* local function prototypes */
|
|
|
fa2969 |
static void fail_exit (int code);
|
|
|
fa2969 |
static /*@noreturn@*/void usage (int status);
|
|
|
fa2969 |
@@ -300,6 +310,63 @@ static void check_perms (void)
|
|
|
fa2969 |
#endif /* ACCT_TOOLS_SETUID */
|
|
|
fa2969 |
}
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_SELINUX
|
|
|
fa2969 |
+static int
|
|
|
fa2969 |
+log_callback (int type, const char *fmt, ...)
|
|
|
fa2969 |
+{
|
|
|
fa2969 |
+ int audit_fd;
|
|
|
fa2969 |
+ va_list ap;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ va_start(ap, fmt);
|
|
|
fa2969 |
+#ifdef WITH_AUDIT
|
|
|
fa2969 |
+ audit_fd = audit_open();
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ if (audit_fd >= 0) {
|
|
|
fa2969 |
+ char *buf;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ if (vasprintf (&buf, fmt, ap) < 0)
|
|
|
fa2969 |
+ goto ret;
|
|
|
fa2969 |
+ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
|
|
|
fa2969 |
+ NULL, 0);
|
|
|
fa2969 |
+ audit_close(audit_fd);
|
|
|
fa2969 |
+ free(buf);
|
|
|
fa2969 |
+ goto ret;
|
|
|
fa2969 |
+ }
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+ vsyslog (LOG_USER | LOG_INFO, fmt, ap);
|
|
|
fa2969 |
+ret:
|
|
|
fa2969 |
+ va_end(ap);
|
|
|
fa2969 |
+ return 0;
|
|
|
fa2969 |
+}
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+static void
|
|
|
fa2969 |
+selinux_check_root (void)
|
|
|
fa2969 |
+{
|
|
|
fa2969 |
+ int status = -1;
|
|
|
fa2969 |
+ security_context_t user_context;
|
|
|
fa2969 |
+ union selinux_callback old_callback;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ if (is_selinux_enabled() < 1)
|
|
|
fa2969 |
+ return;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ old_callback = selinux_get_callback(SELINUX_CB_LOG);
|
|
|
fa2969 |
+ /* setup callbacks */
|
|
|
fa2969 |
+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback);
|
|
|
fa2969 |
+ if ((status = getprevcon(&user_context)) < 0) {
|
|
|
fa2969 |
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
|
|
|
fa2969 |
+ exit(1);
|
|
|
fa2969 |
+ }
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL);
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
|
|
|
fa2969 |
+ freecon(user_context);
|
|
|
fa2969 |
+ if (status != 0 && security_getenforce() != 0)
|
|
|
fa2969 |
+ exit(1);
|
|
|
fa2969 |
+}
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+
|
|
|
fa2969 |
/*
|
|
|
fa2969 |
* open_files - lock and open the group databases
|
|
|
fa2969 |
*/
|
|
|
fa2969 |
@@ -393,6 +460,7 @@ int main (int argc, char **argv)
|
|
|
fa2969 |
|
|
|
fa2969 |
const struct group *gr;
|
|
|
fa2969 |
struct group newgr;
|
|
|
fa2969 |
+ struct passwd *pw = NULL;
|
|
|
fa2969 |
int errors = 0;
|
|
|
fa2969 |
int line = 0;
|
|
|
fa2969 |
|
|
|
fa2969 |
@@ -408,8 +476,33 @@ int main (int argc, char **argv)
|
|
|
fa2969 |
|
|
|
fa2969 |
OPENLOG ("chgpasswd");
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_AUDIT
|
|
|
fa2969 |
+ audit_help_open ();
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ /*
|
|
|
fa2969 |
+ * Determine the name of the user that invoked this command. This
|
|
|
fa2969 |
+ * is really hit or miss because there are so many ways that command
|
|
|
fa2969 |
+ * can be executed and so many ways to trip up the routines that
|
|
|
fa2969 |
+ * report the user name.
|
|
|
fa2969 |
+ */
|
|
|
fa2969 |
+ pw = get_my_pwent ();
|
|
|
fa2969 |
+ if (NULL == pw) {
|
|
|
fa2969 |
+ fprintf (stderr, _("%s: Cannot determine your user name.\n"),
|
|
|
fa2969 |
+ Prog);
|
|
|
fa2969 |
+ SYSLOG ((LOG_WARN,
|
|
|
fa2969 |
+ "Cannot determine the user name of the caller (UID %lu)",
|
|
|
fa2969 |
+ (unsigned long) getuid ()));
|
|
|
fa2969 |
+ exit (E_NOPERM);
|
|
|
fa2969 |
+ }
|
|
|
fa2969 |
+ myname = xstrdup (pw->pw_name);
|
|
|
fa2969 |
+
|
|
|
fa2969 |
check_perms ();
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_SELINUX
|
|
|
fa2969 |
+ selinux_check_root ();
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+
|
|
|
fa2969 |
#ifdef SHADOWGRP
|
|
|
fa2969 |
is_shadow_grp = sgr_file_present ();
|
|
|
fa2969 |
#endif
|
|
|
fa2969 |
@@ -533,6 +626,15 @@ int main (int argc, char **argv)
|
|
|
fa2969 |
newgr.gr_passwd = cp;
|
|
|
fa2969 |
}
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_AUDIT
|
|
|
fa2969 |
+ {
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog,
|
|
|
fa2969 |
+ "change-password",
|
|
|
fa2969 |
+ myname, AUDIT_NO_ID, gr->gr_name,
|
|
|
fa2969 |
+ SHADOW_AUDIT_SUCCESS);
|
|
|
fa2969 |
+ }
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
/*
|
|
|
fa2969 |
* The updated group file entry is then put back and will
|
|
|
fa2969 |
* be written to the group file later, after all the
|
|
|
fa2969 |
diff -up shadow-4.1.5.1/src/chpasswd.c.selinux-perms shadow-4.1.5.1/src/chpasswd.c
|
|
|
fa2969 |
--- shadow-4.1.5.1/src/chpasswd.c.selinux-perms 2016-05-04 13:44:55.633787764 +0200
|
|
|
fa2969 |
+++ shadow-4.1.5.1/src/chpasswd.c 2016-05-30 12:01:42.877859957 +0200
|
|
|
fa2969 |
@@ -39,6 +39,13 @@
|
|
|
fa2969 |
#include <pwd.h>
|
|
|
fa2969 |
#include <stdio.h>
|
|
|
fa2969 |
#include <stdlib.h>
|
|
|
fa2969 |
+#ifdef WITH_SELINUX
|
|
|
fa2969 |
+#include <selinux/selinux.h>
|
|
|
fa2969 |
+#include <selinux/avc.h>
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+#ifdef WITH_LIBAUDIT
|
|
|
fa2969 |
+#include <libaudit.h>
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
#ifdef USE_PAM
|
|
|
fa2969 |
#include "pam_defs.h"
|
|
|
fa2969 |
#endif /* USE_PAM */
|
|
|
fa2969 |
@@ -297,6 +304,63 @@ static void check_perms (void)
|
|
|
fa2969 |
#endif /* USE_PAM */
|
|
|
fa2969 |
}
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_SELINUX
|
|
|
fa2969 |
+static int
|
|
|
fa2969 |
+log_callback (int type, const char *fmt, ...)
|
|
|
fa2969 |
+{
|
|
|
fa2969 |
+ int audit_fd;
|
|
|
fa2969 |
+ va_list ap;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ va_start(ap, fmt);
|
|
|
fa2969 |
+#ifdef WITH_AUDIT
|
|
|
fa2969 |
+ audit_fd = audit_open();
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ if (audit_fd >= 0) {
|
|
|
fa2969 |
+ char *buf;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ if (vasprintf (&buf, fmt, ap) < 0)
|
|
|
fa2969 |
+ goto ret;
|
|
|
fa2969 |
+ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
|
|
|
fa2969 |
+ NULL, 0);
|
|
|
fa2969 |
+ audit_close(audit_fd);
|
|
|
fa2969 |
+ free(buf);
|
|
|
fa2969 |
+ goto ret;
|
|
|
fa2969 |
+ }
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+ vsyslog (LOG_USER | LOG_INFO, fmt, ap);
|
|
|
fa2969 |
+ret:
|
|
|
fa2969 |
+ va_end(ap);
|
|
|
fa2969 |
+ return 0;
|
|
|
fa2969 |
+}
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+static void
|
|
|
fa2969 |
+selinux_check_root (void)
|
|
|
fa2969 |
+{
|
|
|
fa2969 |
+ int status = -1;
|
|
|
fa2969 |
+ security_context_t user_context;
|
|
|
fa2969 |
+ union selinux_callback old_callback;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ if (is_selinux_enabled() < 1)
|
|
|
fa2969 |
+ return;
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ old_callback = selinux_get_callback(SELINUX_CB_LOG);
|
|
|
fa2969 |
+ /* setup callbacks */
|
|
|
fa2969 |
+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback);
|
|
|
fa2969 |
+ if ((status = getprevcon(&user_context)) < 0) {
|
|
|
fa2969 |
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
|
|
|
fa2969 |
+ exit(1);
|
|
|
fa2969 |
+ }
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL);
|
|
|
fa2969 |
+
|
|
|
fa2969 |
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
|
|
|
fa2969 |
+ freecon(user_context);
|
|
|
fa2969 |
+ if (status != 0 && security_getenforce() != 0)
|
|
|
fa2969 |
+ exit(1);
|
|
|
fa2969 |
+}
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+
|
|
|
fa2969 |
/*
|
|
|
fa2969 |
* open_files - lock and open the password databases
|
|
|
fa2969 |
*/
|
|
|
fa2969 |
@@ -405,8 +469,16 @@ int main (int argc, char **argv)
|
|
|
fa2969 |
|
|
|
fa2969 |
OPENLOG ("chpasswd");
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_AUDIT
|
|
|
fa2969 |
+ audit_help_open ();
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+
|
|
|
fa2969 |
check_perms ();
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_SELINUX
|
|
|
fa2969 |
+ selinux_check_root ();
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
+
|
|
|
fa2969 |
#ifdef USE_PAM
|
|
|
fa2969 |
if (!use_pam)
|
|
|
fa2969 |
#endif /* USE_PAM */
|
|
|
fa2969 |
@@ -563,6 +635,11 @@ int main (int argc, char **argv)
|
|
|
fa2969 |
newpw.pw_passwd = cp;
|
|
|
fa2969 |
}
|
|
|
fa2969 |
|
|
|
fa2969 |
+#ifdef WITH_AUDIT
|
|
|
fa2969 |
+ audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
|
|
fa2969 |
+ "updating-password",
|
|
|
fa2969 |
+ pw->pw_name, (unsigned int) pw->pw_uid, 1);
|
|
|
fa2969 |
+#endif
|
|
|
fa2969 |
/*
|
|
|
fa2969 |
* The updated password file entry is then put back and will
|
|
|
fa2969 |
* be written to the password file later, after all the
|
|
|
fa2969 |
diff -up shadow-4.1.5.1/src/Makefile.am.selinux-perms shadow-4.1.5.1/src/Makefile.am
|
|
|
fa2969 |
--- shadow-4.1.5.1/src/Makefile.am.selinux-perms 2016-05-04 13:44:55.647788082 +0200
|
|
|
fa2969 |
+++ shadow-4.1.5.1/src/Makefile.am 2016-05-27 16:04:49.446582632 +0200
|
|
|
fa2969 |
@@ -79,9 +79,9 @@ endif
|
|
|
fa2969 |
|
|
|
fa2969 |
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
|
|
fa2969 |
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
|
|
fa2969 |
-chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
|
|
|
fa2969 |
+chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
|
|
|
fa2969 |
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
|
|
fa2969 |
-chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
|
|
|
fa2969 |
+chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
|
|
|
fa2969 |
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT)
|
|
|
fa2969 |
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
|
|
fa2969 |
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
|
|
fa2969 |
diff -up shadow-4.1.5.1/src/Makefile.in.selinux-perms shadow-4.1.5.1/src/Makefile.in
|
|
|
fa2969 |
--- shadow-4.1.5.1/src/Makefile.in.selinux-perms 2016-05-04 13:44:55.647788082 +0200
|
|
|
fa2969 |
+++ shadow-4.1.5.1/src/Makefile.in 2016-05-27 16:04:49.447582654 +0200
|
|
|
fa2969 |
@@ -437,9 +437,9 @@ AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/l
|
|
|
fa2969 |
@USE_PAM_TRUE@LIBCRYPT_NOPAM =
|
|
|
fa2969 |
chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
|
|
fa2969 |
chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
|
|
fa2969 |
-chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
|
|
|
fa2969 |
+chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
|
|
|
fa2969 |
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
|
|
fa2969 |
-chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
|
|
|
fa2969 |
+chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT)
|
|
|
fa2969 |
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT)
|
|
|
fa2969 |
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
|
|
fa2969 |
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|