summaryrefslogtreecommitdiff
path: root/modules/pam_rootok/pam_rootok.c
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 21:22:21 -0800
committerSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 21:22:45 -0800
commit795badba7f95e737f979917859cd32c9bd47bcad (patch)
tree212a6a00baa11e9d0ca7bc27b12420d1dce6f07c /modules/pam_rootok/pam_rootok.c
parentc55c14c5c6762139ec6695d84ea0e2e917da5264 (diff)
parentba315ae8effdcad591608c99452dad05c4cf20ab (diff)
New upstream version 1.1.8
Diffstat (limited to 'modules/pam_rootok/pam_rootok.c')
-rw-r--r--modules/pam_rootok/pam_rootok.c65
1 files changed, 62 insertions, 3 deletions
diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c
index b2a249df..70579e5b 100644
--- a/modules/pam_rootok/pam_rootok.c
+++ b/modules/pam_rootok/pam_rootok.c
@@ -1,7 +1,7 @@
/* pam_rootok module */
/*
- * $Id: pam_rootok.c,v 1.8 2010/04/06 08:07:11 kukuk Exp $
+ * $Id$
*
* Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*/
@@ -28,7 +28,11 @@
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
-#include <selinux/av_permissions.h>
+#include <selinux/avc.h>
+#endif
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
#endif
/* argument parsing */
@@ -55,6 +59,61 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv)
return ctrl;
}
+#ifdef WITH_SELINUX
+static int
+log_callback (int type, const char *fmt, ...)
+{
+ int audit_fd;
+ va_list ap;
+
+ va_start(ap, fmt);
+#ifdef HAVE_LIBAUDIT
+ 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 int
+selinux_check_root (void)
+{
+ int status = -1;
+ security_context_t user_context;
+ union selinux_callback old_callback;
+
+ if (is_selinux_enabled() < 1)
+ return 0;
+
+ 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);
+ return status;
+ }
+
+ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL);
+
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
+ freecon(user_context);
+ return status;
+}
+#endif
+
static int
check_for_root (pam_handle_t *pamh, int ctrl)
{
@@ -62,7 +121,7 @@ check_for_root (pam_handle_t *pamh, int ctrl)
if (getuid() == 0)
#ifdef WITH_SELINUX
- if (is_selinux_enabled()<1 || checkPasswdAccess(PASSWD__ROOTOK)==0)
+ if (selinux_check_root() == 0 || security_getenforce() == 0)
#endif
retval = PAM_SUCCESS;