[linux-pam] #4: [PATCH] po/ja.po: Fix some wrong translations and so on
by fedora-badges
#4: [PATCH] po/ja.po: Fix some wrong translations and so on
--------------------+-------------------------------------------------------
Reporter: fumiyas | Owner: pam-developers(a)lists.fedorahosted.org
Type: defect | Status: new
Priority: major | Component: library
Version: 1.1.x | Keywords: l10n
--------------------+-------------------------------------------------------
I've updated po/ja.po to fix some wrong translations and so on.
Please see and commit the attached patch to master repository if you feel
good.
Should I contact the original translator (Kiyoto Hashida
<khashida(a)redhat.com>) to check and confirm this patch?
--
Ticket URL: <https://fedorahosted.org/linux-pam/ticket/4>
linux-pam <http://fedorahosted.org/linux-pam>
The Linux-PAM (Pluggable Authentication Modules) project
8 years, 10 months
[linux-pam] #24: [PATCH] pam_env: Expand @{HOME} and @{SHELL}
by fedora-badges
#24: [PATCH] pam_env: Expand @{HOME} and @{SHELL}
--------------------------+------------------------------
Reporter: chrisse | Owner: pam-developers@…
Type: enhancement | Status: new
Priority: major | Component: modules
Version: | Keywords:
Blocked By: | Blocking:
--------------------------+------------------------------
I came across the problem of trying to modify XDG_DATA_HOME etc. to some
other value. pam_env seems to be the ideal point to set those variables,
and pam_env.conf supports expansions.
However, as already explained in the configuration examples, the ${HOME}
environment variable is only set later from the process calling PAM, so
there is currently no possibility to actually use this feature.
The following patch adds support to expand @{SHELL} and @{HOME}. It does
so by looking up the password database entry corresponding to the user and
returning the pw_dir and pw_shell fields.
The patch works, but it is not complete, since it does not update the
documentation. I consider it to be a proof of concept, since I didn't know
where exactly to fit in this functionality in the existing code.
--
Ticket URL: <https://fedorahosted.org/linux-pam/ticket/24>
linux-pam <http://fedorahosted.org/linux-pam>
The Linux-PAM (Pluggable Authentication Modules) project
9 years
[linux-pam] #20: compilation warnings
by fedora-badges
#20: compilation warnings
---------------------+------------------------------
Reporter: mirraz | Owner: pam-developers@…
Type: defect | Status: new
Priority: minor | Component: library
Version: | Keywords:
Blocked By: | Blocking:
---------------------+------------------------------
Building pam-1.1.6 I'v got this compilation warnings:
{{{
md5.c:145:2: warning: dereferencing type-punned pointer will break strict-
aliasing rules [-Wstrict-aliasing]
md5.c:146:2: warning: dereferencing type-punned pointer will break strict-
aliasing rules [-Wstrict-aliasing]
misc_conv.c:213:22: warning: the address of ‘line’ will always evaluate as
‘true’ [-Waddress]
misc_conv.c:325:15: warning: the address of ‘binary_prompt’ will always
evaluate as ‘true’ [-Waddress]
}}}
--
Ticket URL: <https://fedorahosted.org/linux-pam/ticket/20>
linux-pam <http://fedorahosted.org/linux-pam>
The Linux-PAM (Pluggable Authentication Modules) project
9 years
[linux-pam] #9: Allow pam_lastlog to write to utmp as an option
by fedora-badges
#9: Allow pam_lastlog to write to utmp as an option
-------------------------+-------------------------------------------------
Reporter: | Owner: pam-developers@…
shadowkyogre | Status: new
Type: | Component: modules
enhancement | Keywords: pam_lastlog utmp update patch
Priority: major | prototype
Version: 1.1.x | Blocking:
Blocked By: |
-------------------------+-------------------------------------------------
The following patch for pam_lastlog allows it to write to utmp as well as
wtmp. Part of the code is from xorg-sessreg to help make a utmp entry. I
only tested this on my desktop, which is running Arch Linux, so some
modifications may need to be made in order to make it more portable.
--
Ticket URL: <https://fedorahosted.org/linux-pam/ticket/9>
linux-pam <http://fedorahosted.org/linux-pam>
The Linux-PAM (Pluggable Authentication Modules) project
9 years
[PATCH 2/2] Modernize AM_INIT_AUTOMAKE invocation
by Dmitry V. Levin
Before this change, automake complained that two- and three-arguments
forms of AM_INIT_AUTOMAKE are deprecated.
* configure.in: Pass PACKAGE and VERSION arguments to AC_INIT instead
of AM_INIT_AUTOMAKE.
---
configure.in | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure.in b/configure.in
index f16020b..a161e20 100644
--- a/configure.in
+++ b/configure.in
@@ -1,8 +1,8 @@
dnl Process this file with autoconf to produce a configure script.
-AC_INIT
+AC_INIT([Linux-PAM], [1.1.8])
AC_CONFIG_SRCDIR([conf/pam_conv1/pam_conv_y.y])
AC_CONFIG_AUX_DIR([build-aux])
-AM_INIT_AUTOMAKE("Linux-PAM", 1.1.8)
+AM_INIT_AUTOMAKE
AC_PREREQ([2.61])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
--
ldv
10 years, 2 months
[PATCH] Introduce pam_modutil_sanitize_helper_fds
by Dmitry V. Levin
This change introduces pam_modutil_sanitize_helper_fds - a new function
that redirects standard descriptors and closes all other descriptors.
pam_modutil_sanitize_helper_fds supports three types of input and output
redirection:
- PAM_MODUTIL_IGNORE_FD: do not redirect at all.
- PAM_MODUTIL_PIPE_FD: redirect to a pipe. For stdin, it is implemented
by creating a pipe, closing its write end, and redirecting stdin to
its read end. Likewise, for stdout/stderr it is implemented by
creating a pipe, closing its read end, and redirecting to its write
end. Unlike stdin redirection, stdout/stderr redirection to a pipe
has a side effect that a process writing to such descriptor should be
prepared to handle SIGPIPE appropriately.
- PAM_MODUTIL_NULL_FD: redirect to /dev/null. For stdin, it is
implemented via PAM_MODUTIL_PIPE_FD because there is no functional
difference. For stdout/stderr, it is classic redirection to
/dev/null.
PAM_MODUTIL_PIPE_FD is usually more suitable due to linux kernel
security restrictions, but when the helper process might be writing to
the corresponding descriptor and termination of the helper process by
SIGPIPE is not desirable, one should choose PAM_MODUTIL_NULL_FD.
* libpam/pam_modutil_sanitize.c: New file.
* libpam/Makefile.am (libpam_la_SOURCES): Add it.
* libpam/include/security/pam_modutil.h (pam_modutil_redirect_fd,
pam_modutil_sanitize_helper_fds): New declarations.
* libpam/libpam.map (LIBPAM_MODUTIL_1.1.9): New interface.
* modules/pam_exec/pam_exec.c (call_exec): Use
pam_modutil_sanitize_helper_fds.
* modules/pam_mkhomedir/pam_mkhomedir.c (create_homedir): Likewise.
* modules/pam_unix/pam_unix_acct.c (_unix_run_verify_binary): Likewise.
* modules/pam_unix/pam_unix_passwd.c (_unix_run_update_binary):
Likewise.
* modules/pam_unix/support.c (_unix_run_helper_binary): Likewise.
* modules/pam_xauth/pam_xauth.c (run_coprocess): Likewise.
* modules/pam_unix/support.h (MAX_FD_NO): Remove.
---
There were different attempts to sanitize descriptors of helper processes
in pam modules, but neither of them was flawless. Maybe this would be the
first one? :)
Please have a look.
libpam/Makefile.am | 2 +-
libpam/include/security/pam_modutil.h | 13 +++
libpam/libpam.map | 5 +
libpam/pam_modutil_sanitize.c | 175 ++++++++++++++++++++++++++++++++++
modules/pam_exec/pam_exec.c | 34 ++-----
modules/pam_mkhomedir/pam_mkhomedir.c | 15 +--
modules/pam_unix/pam_unix_acct.c | 23 ++---
modules/pam_unix/pam_unix_passwd.c | 20 ++--
modules/pam_unix/support.c | 20 ++--
modules/pam_unix/support.h | 2 -
modules/pam_xauth/pam_xauth.c | 26 +++--
11 files changed, 251 insertions(+), 84 deletions(-)
create mode 100644 libpam/pam_modutil_sanitize.c
diff --git a/libpam/Makefile.am b/libpam/Makefile.am
index 417ca77..685a797 100644
--- a/libpam/Makefile.am
+++ b/libpam/Makefile.am
@@ -43,4 +43,4 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \
pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \
pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \
pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \
- pam_modutil_priv.c
+ pam_modutil_priv.c pam_modutil_sanitize.c
diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h
index 8087ba1..4ce8c55 100644
--- a/libpam/include/security/pam_modutil.h
+++ b/libpam/include/security/pam_modutil.h
@@ -129,6 +129,19 @@ extern int PAM_NONNULL((1,2))
pam_modutil_regain_priv(pam_handle_t *pamh,
struct pam_modutil_privs *p);
+enum pam_modutil_redirect_fd {
+ PAM_MODUTIL_IGNORE_FD, /* do not redirect */
+ PAM_MODUTIL_PIPE_FD, /* redirect to a pipe */
+ PAM_MODUTIL_NULL_FD, /* redirect to /dev/null */
+};
+
+/* redirect standard descriptors, close all other descriptors. */
+extern int PAM_NONNULL((1))
+pam_modutil_sanitize_helper_fds(pam_handle_t *pamh,
+ enum pam_modutil_redirect_fd redirect_stdin,
+ enum pam_modutil_redirect_fd redirect_stdout,
+ enum pam_modutil_redirect_fd redirect_stderr);
+
#ifdef __cplusplus
}
#endif
diff --git a/libpam/libpam.map b/libpam/libpam.map
index b0885d6..d6835b4 100644
--- a/libpam/libpam.map
+++ b/libpam/libpam.map
@@ -67,3 +67,8 @@ LIBPAM_MODUTIL_1.1.3 {
pam_modutil_drop_priv;
pam_modutil_regain_priv;
} LIBPAM_MODUTIL_1.1;
+
+LIBPAM_MODUTIL_1.1.9 {
+ global:
+ pam_modutil_sanitize_helper_fds;
+} LIBPAM_MODUTIL_1.1.3;
diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c
new file mode 100644
index 0000000..65f85d0
--- /dev/null
+++ b/libpam/pam_modutil_sanitize.c
@@ -0,0 +1,175 @@
+/*
+ * This file implements the following functions:
+ * pam_modutil_sanitize_helper_fds:
+ * redirects standard descriptors, closes all other descriptors.
+ */
+
+#include "pam_modutil_private.h"
+#include <security/pam_ext.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <sys/resource.h>
+
+/*
+ * Creates a pipe, closes its write end, redirects fd to its read end.
+ * Returns fd on success, -1 otherwise.
+ */
+static int
+redirect_in_pipe(pam_handle_t *pamh, int fd, const char *name)
+{
+ int in[2];
+
+ if (pipe(in) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
+ return -1;
+ }
+
+ close(in[1]);
+
+ if (in[0] == fd)
+ return fd;
+
+ if (dup2(in[0], fd) != fd) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name);
+ fd = -1;
+ }
+
+ close(in[0]);
+ return fd;
+}
+
+/*
+ * Creates a pipe, closes its read end, redirects fd to its write end.
+ * Returns fd on success, -1 otherwise.
+ */
+static int
+redirect_out_pipe(pam_handle_t *pamh, int fd, const char *name)
+{
+ int out[2];
+
+ if (pipe(out) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
+ return -1;
+ }
+
+ close(out[0]);
+
+ if (out[1] == fd)
+ return fd;
+
+ if (dup2(out[1], fd) != fd) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name);
+ fd = -1;
+ }
+
+ close(out[1]);
+ return fd;
+}
+
+/*
+ * Opens /dev/null for writing, redirects fd there.
+ * Returns fd on success, -1 otherwise.
+ */
+static int
+redirect_out_null(pam_handle_t *pamh, int fd, const char *name)
+{
+ int null = open("/dev/null", O_WRONLY);
+
+ if (null < 0) {
+ pam_syslog(pamh, LOG_ERR, "open of %s failed: %m", "/dev/null");
+ return -1;
+ }
+
+ if (null == fd)
+ return fd;
+
+ if (dup2(null, fd) != fd) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name);
+ fd = -1;
+ }
+
+ close(null);
+ return fd;
+}
+
+static int
+redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode,
+ int fd, const char *name)
+{
+ switch (mode) {
+ case PAM_MODUTIL_PIPE_FD:
+ if (redirect_out_pipe(pamh, fd, name) < 0)
+ return -1;
+ break;
+ case PAM_MODUTIL_NULL_FD:
+ if (redirect_out_null(pamh, fd, name) < 0)
+ return -1;
+ break;
+ case PAM_MODUTIL_IGNORE_FD:
+ break;
+ }
+ return fd;
+}
+
+/* Closes all descriptors after stderr. */
+static void
+close_fds(void)
+{
+ /*
+ * An arbitrary upper limit for the maximum file descriptor number
+ * returned by RLIMIT_NOFILE.
+ */
+ const int MAX_FD_NO = 65535;
+
+ /* The lower limit is the same as for _POSIX_OPEN_MAX. */
+ const int MIN_FD_NO = 20;
+
+ int fd;
+ struct rlimit rlim;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO)
+ fd = MAX_FD_NO;
+ else if (rlim.rlim_max < MIN_FD_NO)
+ fd = MIN_FD_NO;
+ else
+ fd = rlim.rlim_max - 1;
+
+ for (; fd > STDERR_FILENO; --fd)
+ close(fd);
+}
+
+int
+pam_modutil_sanitize_helper_fds(pam_handle_t *pamh,
+ enum pam_modutil_redirect_fd stdin_mode,
+ enum pam_modutil_redirect_fd stdout_mode,
+ enum pam_modutil_redirect_fd stderr_mode)
+{
+ if (stdin_mode != PAM_MODUTIL_IGNORE_FD &&
+ redirect_in_pipe(pamh, STDIN_FILENO, "stdin") < 0) {
+ return -1;
+ }
+
+ if (redirect_out(pamh, stdout_mode, STDOUT_FILENO, "stdout") < 0)
+ return -1;
+
+ /*
+ * If stderr should not be ignored and
+ * redirect mode for stdout and stderr are the same,
+ * optimize by redirecting stderr to stdout.
+ */
+ if (stderr_mode != PAM_MODUTIL_IGNORE_FD &&
+ stdout_mode == stderr_mode) {
+ if (dup2(STDOUT_FILENO, STDERR_FILENO) != STDERR_FILENO) {
+ pam_syslog(pamh, LOG_ERR,
+ "dup2 of %s failed: %m", "stderr");
+ return -1;
+ }
+ } else {
+ if (redirect_out(pamh, stderr_mode, STDERR_FILENO, "stderr") < 0)
+ return -1;
+ }
+
+ close_fds();
+ return 0;
+}
diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c
index b56e4b2..12c4444 100644
--- a/modules/pam_exec/pam_exec.c
+++ b/modules/pam_exec/pam_exec.c
@@ -302,6 +302,10 @@ call_exec (const char *pam_type, pam_handle_t *pamh,
char **envlist, **tmp;
int envlen, nitems;
char *envstr;
+ enum pam_modutil_redirect_fd redirect_stdin =
+ expose_authtok ? PAM_MODUTIL_IGNORE_FD : PAM_MODUTIL_PIPE_FD;
+ enum pam_modutil_redirect_fd redirect_stdout =
+ (use_stdout || logfile) ? PAM_MODUTIL_IGNORE_FD : PAM_MODUTIL_NULL_FD;
/* First, move all the pipes off of stdin, stdout, and stderr, to ensure
* that calls to dup2 won't close them. */
@@ -330,18 +334,6 @@ call_exec (const char *pam_type, pam_handle_t *pamh,
_exit (err);
}
}
- else
- {
- close (STDIN_FILENO);
-
- /* New stdin. */
- if ((i = open ("/dev/null", O_RDWR)) < 0)
- {
- int err = errno;
- pam_syslog (pamh, LOG_ERR, "open of /dev/null failed: %m");
- _exit (err);
- }
- }
/* Set up stdout. */
@@ -374,26 +366,18 @@ call_exec (const char *pam_type, pam_handle_t *pamh,
free (buffer);
}
}
- else
- {
- close (STDOUT_FILENO);
- if ((i = open ("/dev/null", O_RDWR)) < 0)
- {
- int err = errno;
- pam_syslog (pamh, LOG_ERR, "open of /dev/null failed: %m");
- _exit (err);
- }
- }
- if (dup2 (STDOUT_FILENO, STDERR_FILENO) == -1)
+ if ((use_stdout || logfile) &&
+ dup2 (STDOUT_FILENO, STDERR_FILENO) == -1)
{
int err = errno;
pam_syslog (pamh, LOG_ERR, "dup2 failed: %m");
_exit (err);
}
- for (i = 3; i < sysconf (_SC_OPEN_MAX); i++)
- close (i);
+ if (pam_modutil_sanitize_helper_fds(pamh, redirect_stdin,
+ redirect_stdout, redirect_stdout) < 0)
+ _exit(1);
if (call_setuid)
if (setuid (geteuid ()) == -1)
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c
index 0b5fc75..14fa3a3 100644
--- a/modules/pam_mkhomedir/pam_mkhomedir.c
+++ b/modules/pam_mkhomedir/pam_mkhomedir.c
@@ -58,8 +58,6 @@
#include <security/pam_modutil.h>
#include <security/pam_ext.h>
-#define MAX_FD_NO 10000
-
/* argument parsing */
#define MKHOMEDIR_DEBUG 020 /* be verbose about things */
#define MKHOMEDIR_QUIET 040 /* keep quiet about things */
@@ -131,18 +129,13 @@ create_homedir (pam_handle_t *pamh, options_t *opt,
/* fork */
child = fork();
if (child == 0) {
- int i;
- struct rlimit rlim;
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL, NULL };
- if (getrlimit(RLIMIT_NOFILE, &rlim)==0) {
- if (rlim.rlim_max >= MAX_FD_NO)
- rlim.rlim_max = MAX_FD_NO;
- for (i=0; i < (int)rlim.rlim_max; i++) {
- close(i);
- }
- }
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0)
+ _exit(PAM_SYSTEM_ERR);
/* exec the mkhomedir helper */
args[0] = x_strdup(MKHOMEDIR_HELPER);
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c
index 8ec4449..82bc13f 100644
--- a/modules/pam_unix/pam_unix_acct.c
+++ b/modules/pam_unix/pam_unix_acct.c
@@ -98,24 +98,21 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl,
/* fork */
child = fork();
if (child == 0) {
- int i=0;
- struct rlimit rlim;
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL };
- /* reopen stdout as pipe */
- dup2(fds[1], STDOUT_FILENO);
-
/* XXX - should really tidy up PAM here too */
- if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
- if (rlim.rlim_max >= MAX_FD_NO)
- rlim.rlim_max = MAX_FD_NO;
- for (i=0; i < (int)rlim.rlim_max; i++) {
- if (i != STDOUT_FILENO) {
- close(i);
- }
- }
+ /* reopen stdout as pipe */
+ if (dup2(fds[1], STDOUT_FILENO) != STDOUT_FILENO) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdout");
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0) {
+ _exit(PAM_AUTHINFO_UNAVAIL);
}
if (geteuid() == 0) {
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index 0cfc0f4..04c5403 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -201,8 +201,6 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const
/* fork */
child = fork();
if (child == 0) {
- int i=0;
- struct rlimit rlim;
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
char buffer[16];
@@ -210,15 +208,15 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const
/* XXX - should really tidy up PAM here too */
/* reopen stdin as pipe */
- dup2(fds[0], STDIN_FILENO);
-
- if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
- if (rlim.rlim_max >= MAX_FD_NO)
- rlim.rlim_max = MAX_FD_NO;
- for (i=0; i < (int)rlim.rlim_max; i++) {
- if (i != STDIN_FILENO)
- close(i);
- }
+ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0) {
+ _exit(PAM_AUTHINFO_UNAVAIL);
}
/* exec binary helper */
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
index 19d72e6..741ec44 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -564,23 +564,21 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
/* fork */
child = fork();
if (child == 0) {
- int i=0;
- struct rlimit rlim;
static char *envp[] = { NULL };
char *args[] = { NULL, NULL, NULL, NULL };
/* XXX - should really tidy up PAM here too */
/* reopen stdin as pipe */
- dup2(fds[0], STDIN_FILENO);
-
- if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
- if (rlim.rlim_max >= MAX_FD_NO)
- rlim.rlim_max = MAX_FD_NO;
- for (i=0; i < (int)rlim.rlim_max; i++) {
- if (i != STDIN_FILENO)
- close(i);
- }
+ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0) {
+ _exit(PAM_AUTHINFO_UNAVAIL);
}
if (geteuid() == 0) {
diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h
index 6f5b2eb..cd6ddb7 100644
--- a/modules/pam_unix/support.h
+++ b/modules/pam_unix/support.h
@@ -141,8 +141,6 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
-#define MAX_FD_NO 2000000
-
/* use this to free strings. ESPECIALLY password strings */
#define _pam_delete(xx) \
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c
index 32adcf6..f710295 100644
--- a/modules/pam_xauth/pam_xauth.c
+++ b/modules/pam_xauth/pam_xauth.c
@@ -129,7 +129,6 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output,
size_t j;
char *args[10];
const char *tmp;
- int maxopened;
/* Drop privileges. */
if (setgid(gid) == -1)
{
@@ -151,19 +150,26 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output,
(unsigned long) geteuid ());
_exit (err);
}
- /* Initialize the argument list. */
- memset(args, 0, sizeof(args));
/* Set the pipe descriptors up as stdin and stdout, and close
* everything else, including the original values for the
* descriptors. */
- dup2(ipipe[0], STDIN_FILENO);
- dup2(opipe[1], STDOUT_FILENO);
- maxopened = (int)sysconf(_SC_OPEN_MAX);
- for (i = 0; i < maxopened; i++) {
- if ((i != STDIN_FILENO) && (i != STDOUT_FILENO)) {
- close(i);
- }
+ if (dup2(ipipe[0], STDIN_FILENO) != STDIN_FILENO) {
+ int err = errno;
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(err);
}
+ if (dup2(opipe[1], STDOUT_FILENO) != STDOUT_FILENO) {
+ int err = errno;
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdout");
+ _exit(err);
+ }
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_NULL_FD) < 0) {
+ _exit(1);
+ }
+ /* Initialize the argument list. */
+ memset(args, 0, sizeof(args));
/* Convert the varargs list into a regular array of strings. */
va_start(ap, command);
args[0] = strdup(command);
--
ldv
10 years, 2 months
[PATCH] pam_loginuid: log significant loginuid write errors
by Dmitry V. Levin
* modules/pam_loginuid/pam_loginuid.c (set_loginuid): Log those errors
during /proc/self/loginuid update that are not ignored.
---
modules/pam_loginuid/pam_loginuid.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c
index c476f7b..73c42f9 100644
--- a/modules/pam_loginuid/pam_loginuid.c
+++ b/modules/pam_loginuid/pam_loginuid.c
@@ -75,8 +75,8 @@ static int set_loginuid(pam_handle_t *pamh, uid_t uid)
rc = PAM_IGNORE;
}
if (rc != PAM_IGNORE) {
- pam_syslog(pamh, LOG_ERR,
- "Cannot open /proc/self/loginuid: %m");
+ pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
+ "/proc/self/loginuid");
}
return rc;
}
@@ -88,8 +88,14 @@ static int set_loginuid(pam_handle_t *pamh, uid_t uid)
goto done; /* already correct */
}
if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 &&
- pam_modutil_write(fd, loginuid, count) == count)
+ pam_modutil_write(fd, loginuid, count) == count) {
rc = PAM_SUCCESS;
+ } else {
+ if (rc != PAM_IGNORE) {
+ pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
+ "/proc/self/loginuid");
+ }
+ }
done:
close(fd);
return rc;
--
ldv
10 years, 2 months
[PATCH] pam_userdb: fix password hash comparison
by Dmitry V. Levin
Starting with commit Linux-PAM-0-77-28-g0b3e583 that introduced hashed
passwords support in pam_userdb, hashes are compared case-insensitively.
This bug leads to accepting hashes for completely different passwords in
addition to those that should be accepted.
Additionally, commit Linux-PAM-1_1_6-13-ge2a8187 that added support for
modern password hashes with different lengths and settings, did not
update the hash comparison accordingly, which leads to accepting
computed hashes longer than stored hashes when the latter is a prefix
of the former.
* modules/pam_userdb/pam_userdb.c (user_lookup): Reject the computed
hash whose length differs from the stored hash length.
Compare computed and stored hashes case-sensitively.
Fixes CVE-2013-7041.
Bug-Debian: http://bugs.debian.org/731368
---
I'm not an advocate for keeping pam_userdb in the tree,
but while it's in the tree, these bugs have to be fixed.
modules/pam_userdb/pam_userdb.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
index de8b5b1..ff040e6 100644
--- a/modules/pam_userdb/pam_userdb.c
+++ b/modules/pam_userdb/pam_userdb.c
@@ -222,12 +222,15 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
} else {
cryptpw = crypt (pass, data.dptr);
- if (cryptpw) {
- compare = strncasecmp (data.dptr, cryptpw, data.dsize);
+ if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
+ compare = memcmp(data.dptr, cryptpw, data.dsize);
} else {
compare = -2;
if (ctrl & PAM_DEBUG_ARG) {
- pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
+ if (cryptpw)
+ pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
+ else
+ pam_syslog(pamh, LOG_INFO, "crypt() returned NULL");
}
};
--
ldv
10 years, 2 months