diff --git a/.pam.metadata b/.pam.metadata index 90db943..201ea93 100644 --- a/.pam.metadata +++ b/.pam.metadata @@ -1,2 +1,2 @@ -09e618edc5dcda9a6eb435a31db742afca673ae1 SOURCES/pam-redhat-0.99.10-1.tar.bz2 f8ce53c67363f78d520392fa1c253c4978058be1 SOURCES/Linux-PAM-1.1.8.tar.bz2 +42206fe8319723ef23ab646b2eab496c86de3f5b SOURCES/pam-redhat-0.99.11.tar.bz2 diff --git a/SOURCES/20-nproc.conf b/SOURCES/20-nproc.conf new file mode 100644 index 0000000..d6e2578 --- /dev/null +++ b/SOURCES/20-nproc.conf @@ -0,0 +1,6 @@ +# Default limit for number of user's processes to prevent +# accidental fork bombs. +# See rhbz #432903 for reasoning. + +* soft nproc 4096 +root soft nproc unlimited diff --git a/SOURCES/90-nproc.conf b/SOURCES/90-nproc.conf deleted file mode 100644 index 104dffd..0000000 --- a/SOURCES/90-nproc.conf +++ /dev/null @@ -1,6 +0,0 @@ -# Default limit for number of user's processes to prevent -# accidental fork bombs. -# See rhbz #432903 for reasoning. - -* soft nproc 1024 -root soft nproc unlimited diff --git a/SOURCES/pam-1.1.0-console-fixes.patch b/SOURCES/pam-1.1.0-console-fixes.patch deleted file mode 100644 index fa5e79c..0000000 --- a/SOURCES/pam-1.1.0-console-fixes.patch +++ /dev/null @@ -1,72 +0,0 @@ -diff -up Linux-PAM-1.1.0/modules/pam_console/handlers.c.consolefix Linux-PAM-1.1.0/modules/pam_console/handlers.c ---- Linux-PAM-1.1.0/modules/pam_console/handlers.c.consolefix 2009-11-02 08:45:24.000000000 +0100 -+++ Linux-PAM-1.1.0/modules/pam_console/handlers.c 2009-11-02 08:50:19.000000000 +0100 -@@ -172,13 +172,13 @@ call_exec(struct console_handler *handle - const char *flagptr; - const char **argv; - int i = 0; -- argv = malloc(sizeof(*argv)*nparams+2); -- -+ argv = malloc(sizeof(*argv)*(nparams+2)); -+ - if (argv == NULL) - return; -- -+ - argv[i++] = handler->executable; -- -+ - for (flagptr = handler->flags; *flagptr != '\0'; flagptr += strlen(flagptr)+1) { - switch (testflag(flagptr)) { - case HF_LOGFAIL: -@@ -231,7 +231,7 @@ execute_handler(pam_handle_t *pamh, stru - } - - sighandler = signal(SIGCHLD, SIG_DFL); -- -+ - child = fork(); - switch (child) { - case -1: -@@ -246,30 +246,32 @@ execute_handler(pam_handle_t *pamh, stru - if (!wait_exit) { - switch(fork()) { - case 0: -- exit(0); -+ if(setsid() == -1) { -+ _exit(255); -+ } -+ break; - case -1: -- exit(255); -+ _exit(255); - default: -- if(setsid() == -1) { -- exit(255); -- } -+ _exit(0); - } - } - if (set_uid) { - struct passwd *pw; - pw = getpwnam(user); - if (pw == NULL) -- exit(255); -+ _exit(255); - if (setgid(pw->pw_gid) == -1 || -+ setgroups(0, NULL) == -1 || - setuid(pw->pw_uid) == -1) -- exit(255); -+ _exit(255); - } - call_exec(handler, nparams, user, tty); -- exit(255); -+ _exit(255); - default: - break; - } -- -+ - waitpid(child, &rv, 0); - - if (sighandler != SIG_ERR) diff --git a/SOURCES/pam-1.1.1-faillock.patch b/SOURCES/pam-1.1.1-faillock.patch index 46f3037..eaee896 100644 --- a/SOURCES/pam-1.1.1-faillock.patch +++ b/SOURCES/pam-1.1.1-faillock.patch @@ -421,7 +421,7 @@ diff -up Linux-PAM-1.1.1/modules/pam_faillock/faillock.8.xml.faillock Linux-PAM- diff -up Linux-PAM-1.1.1/modules/pam_faillock/main.c.faillock Linux-PAM-1.1.1/modules/pam_faillock/main.c --- Linux-PAM-1.1.1/modules/pam_faillock/main.c.faillock 2010-09-17 15:58:41.000000000 +0200 +++ Linux-PAM-1.1.1/modules/pam_faillock/main.c 2010-09-17 15:58:41.000000000 +0200 -@@ -0,0 +1,231 @@ +@@ -0,0 +1,233 @@ +/* + * Copyright (c) 2010 Tomas Mraz + * @@ -466,6 +466,8 @@ diff -up Linux-PAM-1.1.1/modules/pam_faillock/main.c.faillock Linux-PAM-1.1.1/mo +#include +#include +#include ++#include ++#include +#ifdef HAVE_LIBAUDIT +#include +#endif diff --git a/SOURCES/pam-1.1.3-console-abstract.patch b/SOURCES/pam-1.1.3-console-abstract.patch deleted file mode 100644 index 283edc5..0000000 --- a/SOURCES/pam-1.1.3-console-abstract.patch +++ /dev/null @@ -1,82 +0,0 @@ -diff -up Linux-PAM-1.1.3/modules/pam_console/pam_console.c.abstract Linux-PAM-1.1.3/modules/pam_console/pam_console.c ---- Linux-PAM-1.1.3/modules/pam_console/pam_console.c.abstract 2008-12-16 13:37:52.000000000 +0100 -+++ Linux-PAM-1.1.3/modules/pam_console/pam_console.c 2010-11-01 17:01:55.000000000 +0100 -@@ -34,6 +34,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -136,6 +138,32 @@ check_one_console_name(const char *name, - } - - static int -+try_xsocket(const char *path, size_t len) { -+ int fd; -+ union { -+ struct sockaddr sa; -+ struct sockaddr_un su; -+ } addr; -+ -+ fd = socket(AF_UNIX, SOCK_STREAM, 0); -+ if (fd < 0) -+ return 0; -+ -+ memset(&addr, 0, sizeof(addr)); -+ addr.su.sun_family = AF_UNIX; -+ -+ if (len > sizeof(addr.su.sun_path)) -+ return 0; -+ memcpy(addr.su.sun_path, path, len); -+ if (connect(fd, &addr.sa, sizeof(addr.su) - (sizeof(addr.su.sun_path) - len)) == 0) { -+ close(fd); -+ return 1; -+ } -+ close(fd); -+ return 0; -+} -+ -+static int - check_console_name(pam_handle_t *pamh, const char *consolename, int nonroot_ok, int on_set) { - int found = 0; - int statted = 0; -@@ -186,22 +214,29 @@ check_console_name(pam_handle_t *pamh, c - if (!statted && (consolename[0] == ':')) { - int l; - char *dot = NULL; -- strcpy(full_path, "/tmp/.X11-unix/X"); -- l = sizeof(full_path) - 1 - strlen(full_path); -+ char *path = full_path + 1; -+ -+ full_path[0] = '\0'; -+ strcpy(path, "/tmp/.X11-unix/X"); -+ l = sizeof(full_path) - 2 - strlen(path); - dot = strchr(consolename + 1, '.'); - if (dot != NULL) { - l = (l < dot - consolename - 1) ? l : dot - consolename - 1; - } -- strncat(full_path, consolename + 1, l); -+ strncat(path, consolename + 1, l); - full_path[sizeof(full_path) - 1] = '\0'; -- _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"", -- full_path); -- if (lstat(full_path, &st) != -1) { -+ _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible X socket \"%s\"", -+ path); -+ -+ /* this will work because st.st_uid is 0 */ -+ if (try_xsocket(full_path, strlen(path)+1)) { -+ statted = 1; -+ } else if (try_xsocket(path, strlen(path))) { - statted = 1; - } - else if (!on_set) { /* there is no X11 socket in case of X11 crash */ - _pam_log(pamh, LOG_DEBUG, TRUE, "can't find X11 socket to examine for %s probably due to X crash", consolename); -- statted = 1; /* this will work because st.st_uid is 0 */ -+ statted = 1; - } - } - diff --git a/SOURCES/pam-1.1.6-pwhistory-helper.patch b/SOURCES/pam-1.1.6-pwhistory-helper.patch deleted file mode 100644 index 1d85d79..0000000 --- a/SOURCES/pam-1.1.6-pwhistory-helper.patch +++ /dev/null @@ -1,765 +0,0 @@ -diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am -index 4bb4d6d..0d7cbea 100644 ---- a/modules/pam_pwhistory/Makefile.am -+++ b/modules/pam_pwhistory/Makefile.am -@@ -1,5 +1,6 @@ - # - # Copyright (c) 2008, 2009 Thorsten Kukuk -+# Copyright (c) 2013 Red Hat, Inc. - # - - CLEANFILES = *~ -@@ -9,25 +10,33 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_pwhistory - - TESTS = tst-pam_pwhistory - --man_MANS = pam_pwhistory.8 -+man_MANS = pam_pwhistory.8 pwhistory_helper.8 - --XMLS = README.xml pam_pwhistory.8.xml -+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml - - securelibdir = $(SECUREDIR) - secureconfdir = $(SCONFIGDIR) - --AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include --AM_LDFLAGS = -no-undefined -avoid-version -module -+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ -+ -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\" -+ -+pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module - if HAVE_VERSIONING -- AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map -+ pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map - endif - - noinst_HEADERS = opasswd.h - - securelib_LTLIBRARIES = pam_pwhistory.la -+pam_pwhistory_la_CFLAGS = $(AM_CFLAGS) - pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ - pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c - -+sbin_PROGRAMS = pwhistory_helper -+pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" -+pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c -+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ -+ - if ENABLE_REGENERATE_MAN - noinst_DATA = README - README: pam_pwhistory.8.xml -diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c -index 836d713..f1112ac 100644 ---- a/modules/pam_pwhistory/opasswd.c -+++ b/modules/pam_pwhistory/opasswd.c -@@ -38,6 +38,7 @@ - #endif - - #include -+#include - #include - #include - #include -@@ -47,6 +48,7 @@ - #include - #include - #include -+#include - #include - - #if defined (HAVE_XCRYPT_H) -@@ -55,7 +57,14 @@ - #include - #endif - -+#ifdef HELPER_COMPILE -+#define pam_modutil_getpwnam(h,n) getpwnam(n) -+#define pam_modutil_getspnam(h,n) getspnam(n) -+#define pam_syslog(h,a,...) helper_log_err(a,__VA_ARGS__) -+#else -+#include - #include -+#endif - #include - - #include "opasswd.h" -@@ -76,6 +85,19 @@ typedef struct { - char *old_passwords; - } opwd; - -+#ifdef HELPER_COMPILE -+void -+helper_log_err(int err, const char *format, ...) -+{ -+ va_list args; -+ -+ va_start(args, format); -+ openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV); -+ vsyslog(err, format, args); -+ va_end(args); -+ closelog(); -+} -+#endif - - static int - parse_entry (char *line, opwd *data) -@@ -112,8 +134,8 @@ compare_password(const char *newpass, const char *oldpass) - } - - /* Check, if the new password is already in the opasswd file. */ --int --check_old_pass (pam_handle_t *pamh, const char *user, -+PAMH_ARG_DECL(int -+check_old_pass, const char *user, - const char *newpass, int debug) - { - int retval = PAM_SUCCESS; -@@ -208,9 +230,9 @@ check_old_pass (pam_handle_t *pamh, const char *user, - return retval; - } - --int --save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid, -- const char *oldpass, int howmany, int debug UNUSED) -+PAMH_ARG_DECL(int -+save_old_pass, const char *user, -+ int howmany, int debug UNUSED) - { - char opasswd_tmp[] = TMP_PASSWORDS_FILE; - struct stat opasswd_stat; -@@ -221,10 +243,30 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid, - char *buf = NULL; - size_t buflen = 0; - int found = 0; -+ struct passwd *pwd; -+ const char *oldpass; -+ -+ pwd = pam_modutil_getpwnam (pamh, user); -+ if (pwd == NULL) -+ return PAM_USER_UNKNOWN; - - if (howmany <= 0) - return PAM_SUCCESS; - -+ if ((strcmp(pwd->pw_passwd, "x") == 0) || -+ ((pwd->pw_passwd[0] == '#') && -+ (pwd->pw_passwd[1] == '#') && -+ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0))) -+ { -+ struct spwd *spw = pam_modutil_getspnam (pamh, user); -+ -+ if (spw == NULL) -+ return PAM_USER_UNKNOWN; -+ oldpass = spw->sp_pwdp; -+ } -+ else -+ oldpass = pwd->pw_passwd; -+ - if (oldpass == NULL || *oldpass == '\0') - return PAM_SUCCESS; - -@@ -447,7 +489,7 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid, - { - char *out; - -- if (asprintf (&out, "%s:%d:1:%s\n", user, uid, oldpass) < 0) -+ if (asprintf (&out, "%s:%d:1:%s\n", user, pwd->pw_uid, oldpass) < 0) - { - retval = PAM_AUTHTOK_ERR; - if (oldpf) -diff --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h -index db3e656..21430be 100644 ---- a/modules/pam_pwhistory/opasswd.h -+++ b/modules/pam_pwhistory/opasswd.h -@@ -36,10 +36,25 @@ - #ifndef __OPASSWD_H__ - #define __OPASSWD_H__ - --extern int check_old_pass (pam_handle_t *pamh, const char *user, -- const char *newpass, int debug); --extern int save_old_pass (pam_handle_t *pamh, const char *user, -- uid_t uid, const char *oldpass, -- int howmany, int debug); -+#define PAM_PWHISTORY_RUN_HELPER PAM_CRED_INSUFFICIENT -+ -+#ifdef HELPER_COMPILE -+#define PAMH_ARG_DECL(fname, ...) fname(__VA_ARGS__) -+#define PAMH_ARG(...) __VA_ARGS__ -+#else -+#define PAMH_ARG_DECL(fname, ...) fname(pam_handle_t *pamh, __VA_ARGS__) -+#define PAMH_ARG(...) pamh, __VA_ARGS__ -+#endif -+ -+#ifdef HELPER_COMPILE -+void -+helper_log_err(int err, const char *format, ...); -+#endif -+ -+PAMH_ARG_DECL(int -+check_old_pass, const char *user, const char *newpass, int debug); -+ -+PAMH_ARG_DECL(int -+save_old_pass, const char *user, int howmany, int debug); - - #endif /* __OPASSWD_H__ */ -diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c -index 654edd3..f54fd2a 100644 ---- a/modules/pam_pwhistory/pam_pwhistory.c -+++ b/modules/pam_pwhistory/pam_pwhistory.c -@@ -46,10 +46,14 @@ - #include - #include - #include --#include - #include - #include - #include -+#include -+#include -+#include -+#include -+#include - - #include - #include -@@ -59,6 +63,7 @@ - #include "opasswd.h" - - #define DEFAULT_BUFLEN 2048 -+#define MAX_FD_NO 20000 - - struct options_t { - int debug; -@@ -102,6 +107,184 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options) - pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv); - } - -+static int -+run_save_helper(pam_handle_t *pamh, const char *user, -+ int howmany, int debug) -+{ -+ int retval, child; -+ struct sigaction newsa, oldsa; -+ -+ memset(&newsa, '\0', sizeof(newsa)); -+ newsa.sa_handler = SIG_DFL; -+ sigaction(SIGCHLD, &newsa, &oldsa); -+ -+ child = fork(); -+ if (child == 0) -+ { -+ int i = 0; -+ struct rlimit rlim; -+ int dummyfds[2]; -+ static char *envp[] = { NULL }; -+ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; -+ -+ /* replace std file descriptors with a dummy pipe */ -+ if (pipe2(dummyfds, O_NONBLOCK) == 0) -+ { -+ dup2(dummyfds[0], STDIN_FILENO); -+ dup2(dummyfds[1], STDOUT_FILENO); -+ dup2(dummyfds[1], STDERR_FILENO); -+ } -+ -+ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0) -+ { -+ if (rlim.rlim_max >= MAX_FD_NO) -+ rlim.rlim_max = MAX_FD_NO; -+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) -+ { -+ if (i != dummyfds[0]) -+ close(i); -+ } -+ } -+ -+ /* exec binary helper */ -+ args[0] = strdup(PWHISTORY_HELPER); -+ args[1] = strdup("save"); -+ args[2] = x_strdup(user); -+ asprintf(&args[3], "%d", howmany); -+ asprintf(&args[4], "%d", debug); -+ -+ execve(args[0], args, envp); -+ -+ _exit(PAM_SYSTEM_ERR); -+ } -+ else if (child > 0) -+ { -+ /* wait for child */ -+ int rc = 0; -+ rc = waitpid(child, &retval, 0); /* wait for helper to complete */ -+ if (rc < 0) -+ { -+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save waitpid returned %d: %m", rc); -+ retval = PAM_SYSTEM_ERR; -+ } -+ else if (!WIFEXITED(retval)) -+ { -+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save abnormal exit: %d", retval); -+ retval = PAM_SYSTEM_ERR; -+ } -+ else -+ { -+ retval = WEXITSTATUS(retval); -+ } -+ } -+ else -+ { -+ retval = PAM_SYSTEM_ERR; -+ } -+ -+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ -+ -+ return retval; -+} -+ -+static int -+run_check_helper(pam_handle_t *pamh, const char *user, -+ const char *newpass, int debug) -+{ -+ int retval, child, fds[2]; -+ struct sigaction newsa, oldsa; -+ -+ /* create a pipe for the password */ -+ if (pipe(fds) != 0) -+ return PAM_SYSTEM_ERR; -+ -+ memset(&newsa, '\0', sizeof(newsa)); -+ newsa.sa_handler = SIG_DFL; -+ sigaction(SIGCHLD, &newsa, &oldsa); -+ -+ child = fork(); -+ if (child == 0) -+ { -+ int i = 0; -+ struct rlimit rlim; -+ int dummyfds[2]; -+ static char *envp[] = { NULL }; -+ char *args[] = { NULL, NULL, NULL, NULL, NULL }; -+ -+ /* reopen stdin as pipe */ -+ dup2(fds[0], STDIN_FILENO); -+ -+ /* replace std file descriptors with a dummy pipe */ -+ if (pipe2(dummyfds, O_NONBLOCK) == 0) -+ { -+ dup2(dummyfds[1], STDOUT_FILENO); -+ dup2(dummyfds[1], STDERR_FILENO); -+ } -+ -+ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0) -+ { -+ if (rlim.rlim_max >= MAX_FD_NO) -+ rlim.rlim_max = MAX_FD_NO; -+ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) -+ { -+ if (i != dummyfds[0]) -+ close(i); -+ } -+ } -+ -+ /* exec binary helper */ -+ args[0] = strdup(PWHISTORY_HELPER); -+ args[1] = strdup("check"); -+ args[2] = x_strdup(user); -+ asprintf(&args[3], "%d", debug); -+ -+ execve(args[0], args, envp); -+ -+ _exit(PAM_SYSTEM_ERR); -+ } -+ else if (child > 0) -+ { -+ /* wait for child */ -+ int rc = 0; -+ if (newpass == NULL) -+ newpass = ""; -+ -+ /* send the password to the child */ -+ if (write(fds[1], newpass, strlen(newpass)+1) == -1) -+ { -+ pam_syslog(pamh, LOG_ERR, "Cannot send password to helper: %m"); -+ retval = PAM_SYSTEM_ERR; -+ } -+ newpass = NULL; -+ close(fds[0]); /* close here to avoid possible SIGPIPE above */ -+ close(fds[1]); -+ rc = waitpid(child, &retval, 0); /* wait for helper to complete */ -+ if (rc < 0) -+ { -+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check waitpid returned %d: %m", rc); -+ retval = PAM_SYSTEM_ERR; -+ } -+ else if (!WIFEXITED(retval)) -+ { -+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check abnormal exit: %d", retval); -+ retval = PAM_SYSTEM_ERR; -+ } -+ else -+ { -+ retval = WEXITSTATUS(retval); -+ } -+ } -+ else -+ { -+ close(fds[0]); -+ close(fds[1]); -+ retval = PAM_SYSTEM_ERR; -+ } -+ -+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ -+ -+ return retval; -+} - - /* This module saves the current crypted password in /etc/security/opasswd - and then compares the new password with all entries in this file. */ -@@ -109,7 +292,6 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options) - PAM_EXTERN int - pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) - { -- struct passwd *pwd; - const char *newpass; - const char *user; - int retval, tries; -@@ -154,31 +336,13 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) - return PAM_SUCCESS; - } - -- pwd = pam_modutil_getpwnam (pamh, user); -- if (pwd == NULL) -- return PAM_USER_UNKNOWN; -+ retval = save_old_pass (pamh, user, options.remember, options.debug); - -- if ((strcmp(pwd->pw_passwd, "x") == 0) || -- ((pwd->pw_passwd[0] == '#') && -- (pwd->pw_passwd[1] == '#') && -- (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0))) -- { -- struct spwd *spw = pam_modutil_getspnam (pamh, user); -- if (spw == NULL) -- return PAM_USER_UNKNOWN; -+ if (retval == PAM_PWHISTORY_RUN_HELPER) -+ retval = run_save_helper(pamh, user, options.remember, options.debug); - -- retval = save_old_pass (pamh, user, pwd->pw_uid, spw->sp_pwdp, -- options.remember, options.debug); -- if (retval != PAM_SUCCESS) -- return retval; -- } -- else -- { -- retval = save_old_pass (pamh, user, pwd->pw_uid, pwd->pw_passwd, -- options.remember, options.debug); -- if (retval != PAM_SUCCESS) -- return retval; -- } -+ if (retval != PAM_SUCCESS) -+ return retval; - - newpass = NULL; - tries = 0; -@@ -207,8 +371,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) - if (options.debug) - pam_syslog (pamh, LOG_DEBUG, "check against old password file"); - -- if (check_old_pass (pamh, user, newpass, -- options.debug) != PAM_SUCCESS) -+ retval = check_old_pass (pamh, user, newpass, options.debug); -+ if (retval == PAM_PWHISTORY_RUN_HELPER) -+ retval = run_check_helper(pamh, user, newpass, options.debug); -+ -+ if (retval != PAM_SUCCESS) - { - if (getuid() || options.enforce_for_root || - (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) -diff --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml -new file mode 100644 -index 0000000..5f14d39 ---- /dev/null -+++ b/modules/pam_pwhistory/pwhistory_helper.8.xml -@@ -0,0 +1,68 @@ -+ -+ -+ -+ -+ -+ -+ pwhistory_helper -+ 8 -+ Linux-PAM Manual -+ -+ -+ -+ pwhistory_helper -+ Helper binary that transfers password hashes from passwd or shadow to opasswd -+ -+ -+ -+ -+ pwhistory_helper -+ -+ ... -+ -+ -+ -+ -+ -+ -+ DESCRIPTION -+ -+ -+ pwhistory_helper is a helper program for the -+ pam_pwhistory module that transfers password hashes -+ from passwd or shadow file to the opasswd file and checks a password -+ supplied by user against the existing hashes in the opasswd file. -+ -+ -+ -+ The purpose of the helper is to enable tighter confinement of -+ login and password changing services. The helper is thus called only -+ when SELinux is enabled on the system. -+ -+ -+ -+ The interface of the helper - command line options, and input/output -+ data format are internal to the pam_pwhistory -+ module and it should not be called directly from applications. -+ -+ -+ -+ -+ SEE ALSO -+ -+ -+ pam_pwhistory8 -+ -+ -+ -+ -+ -+ AUTHOR -+ -+ Written by Tomas Mraz based on the code originally in -+ pam_pwhistory module. -+ -+ -+ -+ -diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c -new file mode 100644 -index 0000000..b07ab81 ---- /dev/null -+++ b/modules/pam_pwhistory/pwhistory_helper.c -@@ -0,0 +1,209 @@ -+/* -+ * Copyright (c) 2013 Red Hat, Inc. -+ * Author: Tomas Mraz -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, and the entire permission notice in its entirety, -+ * including the disclaimer of warranties. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 3. The name of the author may not be used to endorse or promote -+ * products derived from this software without specific prior -+ * written permission. -+ * -+ * ALTERNATIVELY, this product may be distributed under the terms of -+ * the GNU Public License, in which case the provisions of the GPL are -+ * required INSTEAD OF the above restrictions. (This clause is -+ * necessary due to a potential bad interaction between the GPL and -+ * the restrictions contained in a BSD-style copyright.) -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, -+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -+ * OF THE POSSIBILITY OF SUCH DAMAGE. -+ */ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "opasswd.h" -+ -+#define MAXPASS 200 -+ -+static void -+su_sighandler(int sig) -+{ -+#ifndef SA_RESETHAND -+ /* emulate the behaviour of the SA_RESETHAND flag */ -+ if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) { -+ struct sigaction sa; -+ memset(&sa, '\0', sizeof(sa)); -+ sa.sa_handler = SIG_DFL; -+ sigaction(sig, &sa, NULL); -+ } -+#endif -+ if (sig > 0) { -+ _exit(sig); -+ } -+} -+ -+static void -+setup_signals(void) -+{ -+ struct sigaction action; /* posix signal structure */ -+ -+ /* -+ * Setup signal handlers -+ */ -+ (void) memset((void *) &action, 0, sizeof(action)); -+ action.sa_handler = su_sighandler; -+#ifdef SA_RESETHAND -+ action.sa_flags = SA_RESETHAND; -+#endif -+ (void) sigaction(SIGILL, &action, NULL); -+ (void) sigaction(SIGTRAP, &action, NULL); -+ (void) sigaction(SIGBUS, &action, NULL); -+ (void) sigaction(SIGSEGV, &action, NULL); -+ action.sa_handler = SIG_IGN; -+ action.sa_flags = 0; -+ (void) sigaction(SIGTERM, &action, NULL); -+ (void) sigaction(SIGHUP, &action, NULL); -+ (void) sigaction(SIGINT, &action, NULL); -+ (void) sigaction(SIGQUIT, &action, NULL); -+} -+ -+static int -+read_passwords(int fd, int npass, char **passwords) -+{ -+ int rbytes = 0; -+ int offset = 0; -+ int i = 0; -+ char *pptr; -+ while (npass > 0) -+ { -+ rbytes = read(fd, passwords[i]+offset, MAXPASS-offset); -+ -+ if (rbytes < 0) -+ { -+ if (errno == EINTR) continue; -+ break; -+ } -+ if (rbytes == 0) -+ break; -+ -+ while (npass > 0 && (pptr=memchr(passwords[i]+offset, '\0', rbytes)) -+ != NULL) -+ { -+ rbytes -= pptr - (passwords[i]+offset) + 1; -+ i++; -+ offset = 0; -+ npass--; -+ if (rbytes > 0) -+ { -+ if (npass > 0) -+ memcpy(passwords[i], pptr+1, rbytes); -+ memset(pptr+1, '\0', rbytes); -+ } -+ } -+ offset += rbytes; -+ } -+ -+ /* clear up */ -+ if (offset > 0 && npass > 0) -+ memset(passwords[i], '\0', offset); -+ -+ return i; -+} -+ -+ -+static int -+check_history(const char *user, const char *debug) -+{ -+ char pass[MAXPASS + 1]; -+ char *passwords[] = { pass }; -+ int npass; -+ int dbg = atoi(debug); /* no need to be too fancy here */ -+ int retval; -+ -+ /* read the password from stdin (a pipe from the pam_pwhistory module) */ -+ npass = read_passwords(STDIN_FILENO, 1, passwords); -+ -+ if (npass != 1) -+ { /* is it a valid password? */ -+ helper_log_err(LOG_DEBUG, "no password supplied"); -+ return PAM_AUTHTOK_ERR; -+ } -+ -+ retval = check_old_pass(user, pass, dbg); -+ -+ memset(pass, '\0', MAXPASS); /* clear memory of the password */ -+ -+ return retval; -+} -+ -+static int -+save_history(const char *user, const char *howmany, const char *debug) -+{ -+ int num = atoi(howmany); -+ int dbg = atoi(debug); /* no need to be too fancy here */ -+ int retval; -+ -+ retval = save_old_pass(user, num, dbg); -+ -+ return retval; -+} -+ -+int -+main(int argc, char *argv[]) -+{ -+ const char *option; -+ const char *user; -+ -+ /* -+ * Catch or ignore as many signal as possible. -+ */ -+ setup_signals(); -+ -+ /* -+ * we establish that this program is running with non-tty stdin. -+ * this is to discourage casual use. -+ */ -+ -+ if (isatty(STDIN_FILENO) || argc < 4) -+ { -+ fprintf(stderr, -+ "This binary is not designed for running in this way.\n"); -+ sleep(10); /* this should discourage/annoy the user */ -+ return PAM_SYSTEM_ERR; -+ } -+ -+ option = argv[1]; -+ user = argv[2]; -+ -+ if (strcmp(option, "check") == 0 && argc == 4) -+ return check_history(user, argv[3]); -+ else if (strcmp(option, "save") == 0 && argc == 5) -+ return save_history(user, argv[3], argv[4]); -+ -+ return PAM_SYSTEM_ERR; -+} -+ diff --git a/SOURCES/pam-1.1.8-canonicalize-username.patch b/SOURCES/pam-1.1.8-canonicalize-username.patch new file mode 100644 index 0000000..a3786be --- /dev/null +++ b/SOURCES/pam-1.1.8-canonicalize-username.patch @@ -0,0 +1,21 @@ +diff -up Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c.canonicalize Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c +--- Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c.canonicalize 2013-06-18 16:11:21.000000000 +0200 ++++ Linux-PAM-1.1.8/modules/pam_selinux/pam_selinux.c 2014-03-06 12:03:54.429639972 +0100 +@@ -491,12 +491,17 @@ compute_exec_context(pam_handle_t *pamh, + char *level = NULL; + security_context_t *contextlist = NULL; + int num_contexts = 0; ++ const struct passwd *pwd; + + if (!(username = get_item(pamh, PAM_USER))) { + pam_syslog(pamh, LOG_ERR, "Cannot obtain the user name"); + return PAM_USER_UNKNOWN; + } + ++ if ((pwd = pam_modutil_getpwnam(pamh, username)) != NULL) { ++ username = pwd->pw_name; ++ } /* ignore error and keep using original username */ ++ + /* compute execute context */ + #ifdef HAVE_GETSEUSER + if (!(service = get_item(pamh, PAM_SERVICE))) { diff --git a/SOURCES/pam-1.1.8-cve-2013-7041.patch b/SOURCES/pam-1.1.8-cve-2013-7041.patch new file mode 100644 index 0000000..96fa916 --- /dev/null +++ b/SOURCES/pam-1.1.8-cve-2013-7041.patch @@ -0,0 +1,52 @@ +From 57a1e2b274d0a6376d92ada9926e5c5741e7da20 Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" +Date: Fri, 24 Jan 2014 22:18:32 +0000 +Subject: [PATCH] pam_userdb: fix password hash comparison + +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 +--- + 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"); + } + }; + +-- +1.8.3.1 + diff --git a/SOURCES/pam-1.1.8-cve-2014-2583.patch b/SOURCES/pam-1.1.8-cve-2014-2583.patch new file mode 100644 index 0000000..f2aa2de --- /dev/null +++ b/SOURCES/pam-1.1.8-cve-2014-2583.patch @@ -0,0 +1,56 @@ +From 9dcead87e6d7f66d34e7a56d11a30daca367dffb Mon Sep 17 00:00:00 2001 +From: "Dmitry V. Levin" +Date: Wed, 26 Mar 2014 22:17:23 +0000 +Subject: [PATCH] pam_timestamp: fix potential directory traversal issue + (ticket #27) + +pam_timestamp uses values of PAM_RUSER and PAM_TTY as components of +the timestamp pathname it creates, so extra care should be taken to +avoid potential directory traversal issues. + +* modules/pam_timestamp/pam_timestamp.c (check_tty): Treat +"." and ".." tty values as invalid. +(get_ruser): Treat "." and ".." ruser values, as well as any ruser +value containing '/', as invalid. + +Fixes CVE-2014-2583. + +Reported-by: Sebastian Krahmer +--- + modules/pam_timestamp/pam_timestamp.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c +index 5193733..b3f08b1 100644 +--- a/modules/pam_timestamp/pam_timestamp.c ++++ b/modules/pam_timestamp/pam_timestamp.c +@@ -158,7 +158,7 @@ check_tty(const char *tty) + tty = strrchr(tty, '/') + 1; + } + /* Make sure the tty wasn't actually a directory (no basename). */ +- if (strlen(tty) == 0) { ++ if (!strlen(tty) || !strcmp(tty, ".") || !strcmp(tty, "..")) { + return NULL; + } + return tty; +@@ -243,6 +243,17 @@ get_ruser(pam_handle_t *pamh, char *ruserbuf, size_t ruserbuflen) + if (pwd != NULL) { + ruser = pwd->pw_name; + } ++ } else { ++ /* ++ * This ruser is used by format_timestamp_name as a component ++ * of constructed timestamp pathname, so ".", "..", and '/' ++ * are disallowed to avoid potential path traversal issues. ++ */ ++ if (!strcmp(ruser, ".") || ++ !strcmp(ruser, "..") || ++ strchr(ruser, '/')) { ++ ruser = NULL; ++ } + } + if (ruser == NULL || strlen(ruser) >= ruserbuflen) { + *ruserbuf = '\0'; +-- +1.8.3.1 + diff --git a/SOURCES/pam-1.1.8-pwhistory-helper.patch b/SOURCES/pam-1.1.8-pwhistory-helper.patch new file mode 100644 index 0000000..8d08003 --- /dev/null +++ b/SOURCES/pam-1.1.8-pwhistory-helper.patch @@ -0,0 +1,812 @@ +diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am +index 4bb4d6d..9157b91 100644 +--- a/modules/pam_pwhistory/Makefile.am ++++ b/modules/pam_pwhistory/Makefile.am +@@ -1,5 +1,6 @@ + # + # Copyright (c) 2008, 2009 Thorsten Kukuk ++# Copyright (c) 2013 Red Hat, Inc. + # + + CLEANFILES = *~ +@@ -9,25 +10,33 @@ EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_pwhistory + + TESTS = tst-pam_pwhistory + +-man_MANS = pam_pwhistory.8 ++man_MANS = pam_pwhistory.8 pwhistory_helper.8 + +-XMLS = README.xml pam_pwhistory.8.xml ++XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml + + securelibdir = $(SECUREDIR) + secureconfdir = $(SCONFIGDIR) + +-AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +-AM_LDFLAGS = -no-undefined -avoid-version -module ++AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ ++ -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\" ++ ++pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module + if HAVE_VERSIONING +- AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map ++ pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map + endif + + noinst_HEADERS = opasswd.h + + securelib_LTLIBRARIES = pam_pwhistory.la +-pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ ++pam_pwhistory_la_CFLAGS = $(AM_CFLAGS) ++pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@ + pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c + ++sbin_PROGRAMS = pwhistory_helper ++pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" ++pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c ++pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ ++ + if ENABLE_REGENERATE_MAN + noinst_DATA = README + README: pam_pwhistory.8.xml +diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c +index 836d713..e319ff3 100644 +--- a/modules/pam_pwhistory/opasswd.c ++++ b/modules/pam_pwhistory/opasswd.c +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2008 Thorsten Kukuk ++ * Copyright (c) 2013 Red Hat, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -38,6 +39,7 @@ + #endif + + #include ++#include + #include + #include + #include +@@ -47,6 +49,7 @@ + #include + #include + #include ++#include + #include + + #if defined (HAVE_XCRYPT_H) +@@ -55,7 +58,14 @@ + #include + #endif + ++#ifdef HELPER_COMPILE ++#define pam_modutil_getpwnam(h,n) getpwnam(n) ++#define pam_modutil_getspnam(h,n) getspnam(n) ++#define pam_syslog(h,a,...) helper_log_err(a,__VA_ARGS__) ++#else ++#include + #include ++#endif + #include + + #include "opasswd.h" +@@ -76,6 +86,19 @@ typedef struct { + char *old_passwords; + } opwd; + ++#ifdef HELPER_COMPILE ++void ++helper_log_err(int err, const char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV); ++ vsyslog(err, format, args); ++ va_end(args); ++ closelog(); ++} ++#endif + + static int + parse_entry (char *line, opwd *data) +@@ -112,8 +135,8 @@ compare_password(const char *newpass, const char *oldpass) + } + + /* Check, if the new password is already in the opasswd file. */ +-int +-check_old_pass (pam_handle_t *pamh, const char *user, ++PAMH_ARG_DECL(int ++check_old_pass, const char *user, + const char *newpass, int debug) + { + int retval = PAM_SUCCESS; +@@ -123,6 +146,11 @@ check_old_pass (pam_handle_t *pamh, const char *user, + opwd entry; + int found = 0; + ++#ifndef HELPER_COMPILE ++ if (SELINUX_ENABLED) ++ return PAM_PWHISTORY_RUN_HELPER; ++#endif ++ + if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL) + { + if (errno != ENOENT) +@@ -208,9 +236,9 @@ check_old_pass (pam_handle_t *pamh, const char *user, + return retval; + } + +-int +-save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid, +- const char *oldpass, int howmany, int debug UNUSED) ++PAMH_ARG_DECL(int ++save_old_pass, const char *user, ++ int howmany, int debug UNUSED) + { + char opasswd_tmp[] = TMP_PASSWORDS_FILE; + struct stat opasswd_stat; +@@ -221,10 +249,35 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid, + char *buf = NULL; + size_t buflen = 0; + int found = 0; ++ struct passwd *pwd; ++ const char *oldpass; ++ ++ pwd = pam_modutil_getpwnam (pamh, user); ++ if (pwd == NULL) ++ return PAM_USER_UNKNOWN; + + if (howmany <= 0) + return PAM_SUCCESS; + ++#ifndef HELPER_COMPILE ++ if (SELINUX_ENABLED) ++ return PAM_PWHISTORY_RUN_HELPER; ++#endif ++ ++ if ((strcmp(pwd->pw_passwd, "x") == 0) || ++ ((pwd->pw_passwd[0] == '#') && ++ (pwd->pw_passwd[1] == '#') && ++ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0))) ++ { ++ struct spwd *spw = pam_modutil_getspnam (pamh, user); ++ ++ if (spw == NULL) ++ return PAM_USER_UNKNOWN; ++ oldpass = spw->sp_pwdp; ++ } ++ else ++ oldpass = pwd->pw_passwd; ++ + if (oldpass == NULL || *oldpass == '\0') + return PAM_SUCCESS; + +@@ -447,7 +500,7 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid, + { + char *out; + +- if (asprintf (&out, "%s:%d:1:%s\n", user, uid, oldpass) < 0) ++ if (asprintf (&out, "%s:%d:1:%s\n", user, pwd->pw_uid, oldpass) < 0) + { + retval = PAM_AUTHTOK_ERR; + if (oldpf) +diff --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h +index db3e656..1b08699 100644 +--- a/modules/pam_pwhistory/opasswd.h ++++ b/modules/pam_pwhistory/opasswd.h +@@ -1,5 +1,6 @@ + /* + * Copyright (c) 2008 Thorsten Kukuk ++ * Copyright (c) 2013 Red Hat, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -36,10 +37,32 @@ + #ifndef __OPASSWD_H__ + #define __OPASSWD_H__ + +-extern int check_old_pass (pam_handle_t *pamh, const char *user, +- const char *newpass, int debug); +-extern int save_old_pass (pam_handle_t *pamh, const char *user, +- uid_t uid, const char *oldpass, +- int howmany, int debug); ++#define PAM_PWHISTORY_RUN_HELPER PAM_CRED_INSUFFICIENT ++ ++#ifdef WITH_SELINUX ++#include ++#define SELINUX_ENABLED is_selinux_enabled()>0 ++#else ++#define SELINUX_ENABLED 0 ++#endif ++ ++#ifdef HELPER_COMPILE ++#define PAMH_ARG_DECL(fname, ...) fname(__VA_ARGS__) ++#define PAMH_ARG(...) __VA_ARGS__ ++#else ++#define PAMH_ARG_DECL(fname, ...) fname(pam_handle_t *pamh, __VA_ARGS__) ++#define PAMH_ARG(...) pamh, __VA_ARGS__ ++#endif ++ ++#ifdef HELPER_COMPILE ++void ++helper_log_err(int err, const char *format, ...); ++#endif ++ ++PAMH_ARG_DECL(int ++check_old_pass, const char *user, const char *newpass, int debug); ++ ++PAMH_ARG_DECL(int ++save_old_pass, const char *user, int howmany, int debug); + + #endif /* __OPASSWD_H__ */ +diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c +index 654edd3..d6c5c47 100644 +--- a/modules/pam_pwhistory/pam_pwhistory.c ++++ b/modules/pam_pwhistory/pam_pwhistory.c +@@ -1,6 +1,7 @@ + /* + * Copyright (c) 2008, 2012 Thorsten Kukuk + * Author: Thorsten Kukuk ++ * Copyright (c) 2013 Red Hat, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions +@@ -46,10 +47,14 @@ + #include + #include + #include +-#include + #include + #include + #include ++#include ++#include ++#include ++#include ++#include + + #include + #include +@@ -59,6 +64,7 @@ + #include "opasswd.h" + + #define DEFAULT_BUFLEN 2048 ++#define MAX_FD_NO 20000 + + struct options_t { + int debug; +@@ -102,6 +108,184 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options) + pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv); + } + ++static int ++run_save_helper(pam_handle_t *pamh, const char *user, ++ int howmany, int debug) ++{ ++ int retval, child; ++ struct sigaction newsa, oldsa; ++ ++ memset(&newsa, '\0', sizeof(newsa)); ++ newsa.sa_handler = SIG_DFL; ++ sigaction(SIGCHLD, &newsa, &oldsa); ++ ++ child = fork(); ++ if (child == 0) ++ { ++ int i = 0; ++ struct rlimit rlim; ++ int dummyfds[2]; ++ static char *envp[] = { NULL }; ++ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; ++ ++ /* replace std file descriptors with a dummy pipe */ ++ if (pipe2(dummyfds, O_NONBLOCK) == 0) ++ { ++ dup2(dummyfds[0], STDIN_FILENO); ++ dup2(dummyfds[1], STDOUT_FILENO); ++ dup2(dummyfds[1], STDERR_FILENO); ++ } ++ ++ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0) ++ { ++ if (rlim.rlim_max >= MAX_FD_NO) ++ rlim.rlim_max = MAX_FD_NO; ++ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) ++ { ++ if (i != dummyfds[0]) ++ close(i); ++ } ++ } ++ ++ /* exec binary helper */ ++ args[0] = strdup(PWHISTORY_HELPER); ++ args[1] = strdup("save"); ++ args[2] = x_strdup(user); ++ asprintf(&args[3], "%d", howmany); ++ asprintf(&args[4], "%d", debug); ++ ++ execve(args[0], args, envp); ++ ++ _exit(PAM_SYSTEM_ERR); ++ } ++ else if (child > 0) ++ { ++ /* wait for child */ ++ int rc = 0; ++ rc = waitpid(child, &retval, 0); /* wait for helper to complete */ ++ if (rc < 0) ++ { ++ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save waitpid returned %d: %m", rc); ++ retval = PAM_SYSTEM_ERR; ++ } ++ else if (!WIFEXITED(retval)) ++ { ++ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save abnormal exit: %d", retval); ++ retval = PAM_SYSTEM_ERR; ++ } ++ else ++ { ++ retval = WEXITSTATUS(retval); ++ } ++ } ++ else ++ { ++ retval = PAM_SYSTEM_ERR; ++ } ++ ++ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ ++ ++ return retval; ++} ++ ++static int ++run_check_helper(pam_handle_t *pamh, const char *user, ++ const char *newpass, int debug) ++{ ++ int retval, child, fds[2]; ++ struct sigaction newsa, oldsa; ++ ++ /* create a pipe for the password */ ++ if (pipe(fds) != 0) ++ return PAM_SYSTEM_ERR; ++ ++ memset(&newsa, '\0', sizeof(newsa)); ++ newsa.sa_handler = SIG_DFL; ++ sigaction(SIGCHLD, &newsa, &oldsa); ++ ++ child = fork(); ++ if (child == 0) ++ { ++ int i = 0; ++ struct rlimit rlim; ++ int dummyfds[2]; ++ static char *envp[] = { NULL }; ++ char *args[] = { NULL, NULL, NULL, NULL, NULL }; ++ ++ /* reopen stdin as pipe */ ++ dup2(fds[0], STDIN_FILENO); ++ ++ /* replace std file descriptors with a dummy pipe */ ++ if (pipe2(dummyfds, O_NONBLOCK) == 0) ++ { ++ dup2(dummyfds[1], STDOUT_FILENO); ++ dup2(dummyfds[1], STDERR_FILENO); ++ } ++ ++ if (getrlimit(RLIMIT_NOFILE,&rlim) == 0) ++ { ++ if (rlim.rlim_max >= MAX_FD_NO) ++ rlim.rlim_max = MAX_FD_NO; ++ for (i = STDERR_FILENO + 1; i < (int)rlim.rlim_max; i++) ++ { ++ if (i != dummyfds[0]) ++ close(i); ++ } ++ } ++ ++ /* exec binary helper */ ++ args[0] = strdup(PWHISTORY_HELPER); ++ args[1] = strdup("check"); ++ args[2] = x_strdup(user); ++ asprintf(&args[3], "%d", debug); ++ ++ execve(args[0], args, envp); ++ ++ _exit(PAM_SYSTEM_ERR); ++ } ++ else if (child > 0) ++ { ++ /* wait for child */ ++ int rc = 0; ++ if (newpass == NULL) ++ newpass = ""; ++ ++ /* send the password to the child */ ++ if (write(fds[1], newpass, strlen(newpass)+1) == -1) ++ { ++ pam_syslog(pamh, LOG_ERR, "Cannot send password to helper: %m"); ++ retval = PAM_SYSTEM_ERR; ++ } ++ newpass = NULL; ++ close(fds[0]); /* close here to avoid possible SIGPIPE above */ ++ close(fds[1]); ++ rc = waitpid(child, &retval, 0); /* wait for helper to complete */ ++ if (rc < 0) ++ { ++ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check waitpid returned %d: %m", rc); ++ retval = PAM_SYSTEM_ERR; ++ } ++ else if (!WIFEXITED(retval)) ++ { ++ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check abnormal exit: %d", retval); ++ retval = PAM_SYSTEM_ERR; ++ } ++ else ++ { ++ retval = WEXITSTATUS(retval); ++ } ++ } ++ else ++ { ++ close(fds[0]); ++ close(fds[1]); ++ retval = PAM_SYSTEM_ERR; ++ } ++ ++ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ ++ ++ return retval; ++} + + /* This module saves the current crypted password in /etc/security/opasswd + and then compares the new password with all entries in this file. */ +@@ -109,7 +293,6 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options) + PAM_EXTERN int + pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) + { +- struct passwd *pwd; + const char *newpass; + const char *user; + int retval, tries; +@@ -154,31 +337,13 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) + return PAM_SUCCESS; + } + +- pwd = pam_modutil_getpwnam (pamh, user); +- if (pwd == NULL) +- return PAM_USER_UNKNOWN; ++ retval = save_old_pass (pamh, user, options.remember, options.debug); + +- if ((strcmp(pwd->pw_passwd, "x") == 0) || +- ((pwd->pw_passwd[0] == '#') && +- (pwd->pw_passwd[1] == '#') && +- (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0))) +- { +- struct spwd *spw = pam_modutil_getspnam (pamh, user); +- if (spw == NULL) +- return PAM_USER_UNKNOWN; ++ if (retval == PAM_PWHISTORY_RUN_HELPER) ++ retval = run_save_helper(pamh, user, options.remember, options.debug); + +- retval = save_old_pass (pamh, user, pwd->pw_uid, spw->sp_pwdp, +- options.remember, options.debug); +- if (retval != PAM_SUCCESS) +- return retval; +- } +- else +- { +- retval = save_old_pass (pamh, user, pwd->pw_uid, pwd->pw_passwd, +- options.remember, options.debug); +- if (retval != PAM_SUCCESS) +- return retval; +- } ++ if (retval != PAM_SUCCESS) ++ return retval; + + newpass = NULL; + tries = 0; +@@ -207,8 +372,11 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) + if (options.debug) + pam_syslog (pamh, LOG_DEBUG, "check against old password file"); + +- if (check_old_pass (pamh, user, newpass, +- options.debug) != PAM_SUCCESS) ++ retval = check_old_pass (pamh, user, newpass, options.debug); ++ if (retval == PAM_PWHISTORY_RUN_HELPER) ++ retval = run_check_helper(pamh, user, newpass, options.debug); ++ ++ if (retval != PAM_SUCCESS) + { + if (getuid() || options.enforce_for_root || + (flags & PAM_CHANGE_EXPIRED_AUTHTOK)) +diff --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml +new file mode 100644 +index 0000000..a030176 +--- /dev/null ++++ b/modules/pam_pwhistory/pwhistory_helper.8.xml +@@ -0,0 +1,68 @@ ++ ++ ++ ++ ++ ++ ++ pwhistory_helper ++ 8 ++ Linux-PAM Manual ++ ++ ++ ++ pwhistory_helper ++ Helper binary that transfers password hashes from passwd or shadow to opasswd ++ ++ ++ ++ ++ pwhistory_helper ++ ++ ... ++ ++ ++ ++ ++ ++ ++ DESCRIPTION ++ ++ ++ pwhistory_helper is a helper program for the ++ pam_pwhistory module that transfers password hashes ++ from passwd or shadow file to the opasswd file and checks a password ++ supplied by user against the existing hashes in the opasswd file. ++ ++ ++ ++ The purpose of the helper is to enable tighter confinement of ++ login and password changing services. The helper is thus called only ++ when SELinux is enabled on the system. ++ ++ ++ ++ The interface of the helper - command line options, and input/output ++ data format are internal to the pam_pwhistory ++ module and it should not be called directly from applications. ++ ++ ++ ++ ++ SEE ALSO ++ ++ ++ pam_pwhistory8 ++ ++ ++ ++ ++ ++ AUTHOR ++ ++ Written by Tomas Mraz based on the code originally in ++ pam_pwhistory and pam_unix modules. ++ ++ ++ ++ +diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c +new file mode 100644 +index 0000000..b07ab81 +--- /dev/null ++++ b/modules/pam_pwhistory/pwhistory_helper.c +@@ -0,0 +1,209 @@ ++/* ++ * Copyright (c) 2013 Red Hat, Inc. ++ * Author: Tomas Mraz ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, and the entire permission notice in its entirety, ++ * including the disclaimer of warranties. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote ++ * products derived from this software without specific prior ++ * written permission. ++ * ++ * ALTERNATIVELY, this product may be distributed under the terms of ++ * the GNU Public License, in which case the provisions of the GPL are ++ * required INSTEAD OF the above restrictions. (This clause is ++ * necessary due to a potential bad interaction between the GPL and ++ * the restrictions contained in a BSD-style copyright.) ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "opasswd.h" ++ ++#define MAXPASS 200 ++ ++static void ++su_sighandler(int sig) ++{ ++#ifndef SA_RESETHAND ++ /* emulate the behaviour of the SA_RESETHAND flag */ ++ if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) { ++ struct sigaction sa; ++ memset(&sa, '\0', sizeof(sa)); ++ sa.sa_handler = SIG_DFL; ++ sigaction(sig, &sa, NULL); ++ } ++#endif ++ if (sig > 0) { ++ _exit(sig); ++ } ++} ++ ++static void ++setup_signals(void) ++{ ++ struct sigaction action; /* posix signal structure */ ++ ++ /* ++ * Setup signal handlers ++ */ ++ (void) memset((void *) &action, 0, sizeof(action)); ++ action.sa_handler = su_sighandler; ++#ifdef SA_RESETHAND ++ action.sa_flags = SA_RESETHAND; ++#endif ++ (void) sigaction(SIGILL, &action, NULL); ++ (void) sigaction(SIGTRAP, &action, NULL); ++ (void) sigaction(SIGBUS, &action, NULL); ++ (void) sigaction(SIGSEGV, &action, NULL); ++ action.sa_handler = SIG_IGN; ++ action.sa_flags = 0; ++ (void) sigaction(SIGTERM, &action, NULL); ++ (void) sigaction(SIGHUP, &action, NULL); ++ (void) sigaction(SIGINT, &action, NULL); ++ (void) sigaction(SIGQUIT, &action, NULL); ++} ++ ++static int ++read_passwords(int fd, int npass, char **passwords) ++{ ++ int rbytes = 0; ++ int offset = 0; ++ int i = 0; ++ char *pptr; ++ while (npass > 0) ++ { ++ rbytes = read(fd, passwords[i]+offset, MAXPASS-offset); ++ ++ if (rbytes < 0) ++ { ++ if (errno == EINTR) continue; ++ break; ++ } ++ if (rbytes == 0) ++ break; ++ ++ while (npass > 0 && (pptr=memchr(passwords[i]+offset, '\0', rbytes)) ++ != NULL) ++ { ++ rbytes -= pptr - (passwords[i]+offset) + 1; ++ i++; ++ offset = 0; ++ npass--; ++ if (rbytes > 0) ++ { ++ if (npass > 0) ++ memcpy(passwords[i], pptr+1, rbytes); ++ memset(pptr+1, '\0', rbytes); ++ } ++ } ++ offset += rbytes; ++ } ++ ++ /* clear up */ ++ if (offset > 0 && npass > 0) ++ memset(passwords[i], '\0', offset); ++ ++ return i; ++} ++ ++ ++static int ++check_history(const char *user, const char *debug) ++{ ++ char pass[MAXPASS + 1]; ++ char *passwords[] = { pass }; ++ int npass; ++ int dbg = atoi(debug); /* no need to be too fancy here */ ++ int retval; ++ ++ /* read the password from stdin (a pipe from the pam_pwhistory module) */ ++ npass = read_passwords(STDIN_FILENO, 1, passwords); ++ ++ if (npass != 1) ++ { /* is it a valid password? */ ++ helper_log_err(LOG_DEBUG, "no password supplied"); ++ return PAM_AUTHTOK_ERR; ++ } ++ ++ retval = check_old_pass(user, pass, dbg); ++ ++ memset(pass, '\0', MAXPASS); /* clear memory of the password */ ++ ++ return retval; ++} ++ ++static int ++save_history(const char *user, const char *howmany, const char *debug) ++{ ++ int num = atoi(howmany); ++ int dbg = atoi(debug); /* no need to be too fancy here */ ++ int retval; ++ ++ retval = save_old_pass(user, num, dbg); ++ ++ return retval; ++} ++ ++int ++main(int argc, char *argv[]) ++{ ++ const char *option; ++ const char *user; ++ ++ /* ++ * Catch or ignore as many signal as possible. ++ */ ++ setup_signals(); ++ ++ /* ++ * we establish that this program is running with non-tty stdin. ++ * this is to discourage casual use. ++ */ ++ ++ if (isatty(STDIN_FILENO) || argc < 4) ++ { ++ fprintf(stderr, ++ "This binary is not designed for running in this way.\n"); ++ sleep(10); /* this should discourage/annoy the user */ ++ return PAM_SYSTEM_ERR; ++ } ++ ++ option = argv[1]; ++ user = argv[2]; ++ ++ if (strcmp(option, "check") == 0 && argc == 4) ++ return check_history(user, argv[3]); ++ else if (strcmp(option, "save") == 0 && argc == 5) ++ return save_history(user, argv[3], argv[4]); ++ ++ return PAM_SYSTEM_ERR; ++} ++ diff --git a/SOURCES/pam-1.1.8-translation-updates.patch b/SOURCES/pam-1.1.8-translation-updates.patch new file mode 100644 index 0000000..4c0c7f8 --- /dev/null +++ b/SOURCES/pam-1.1.8-translation-updates.patch @@ -0,0 +1,1519 @@ +diff -urN a/Linux-PAM-1.1.8/po/bn_IN.po b/Linux-PAM-1.1.8/po/bn_IN.po +--- a/Linux-PAM-1.1.8/po/bn_IN.po 2013-11-28 17:24:14.190596598 +0530 ++++ b/Linux-PAM-1.1.8/po/bn_IN.po 2013-11-28 17:27:02.136118296 +0530 +@@ -1,314 +1,335 @@ + # SOME DESCRIPTIVE TITLE. + # Copyright (C) YEAR Linux-PAM Project + # This file is distributed under the same license as the PACKAGE package. +-# ++# + # Translators: + # Runa Bhattacharjee , 2009. + # Runa Bhattacharjee , 2007, 2008. + # , 2012. ++# sray , 2013. #zanata + msgid "" + msgstr "" + "Project-Id-Version: Linux-PAM\n" + "Report-Msgid-Bugs-To: http://sourceforge.net/projects/pam\n" +-"POT-Creation-Date: 2013-09-19 10:02+0200\n" +-"PO-Revision-Date: 2012-02-28 10:38+0000\n" +-"Last-Translator: runa \n" ++"POT-Creation-Date: 2012-08-17 11:35+0200\n" ++"PO-Revision-Date: 2013-10-03 02:24-0400\n" ++"Last-Translator: sray \n" + "Language-Team: Bengali (India) \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"Language: bn_IN\n" ++"Language: bn-IN\n" + "Plural-Forms: nplurals=2; plural=(n != 1)\n" ++"X-Generator: Zanata 3.1.2\n" + +-#: libpam_misc/misc_conv.c:33 ++#. * external timeout definitions - these can be overriden by the ++#. * application. ++#. time when we warn ++#. time when we timeout ++#: .././libpam_misc/misc_conv.c:33 + msgid "...Time is running out...\n" + msgstr "...সময় সমাপ্তির পথে...\n" + +-#: libpam_misc/misc_conv.c:34 ++#: .././libpam_misc/misc_conv.c:34 + msgid "...Sorry, your time is up!\n" + msgstr "...দুঃখিত, সময় সমাপ্ত!\n" + +-#: libpam_misc/misc_conv.c:342 ++#: .././libpam_misc/misc_conv.c:342 + #, c-format + msgid "erroneous conversation (%d)\n" + msgstr "ত্রুটিপূর্ণ তথ্যবিনিময় (conversation) (%d)\n" + +-#: libpam/pam_get_authtok.c:39 modules/pam_exec/pam_exec.c:170 +-#: modules/pam_unix/pam_unix_auth.c:160 modules/pam_userdb/pam_userdb.c:64 ++#. get this user's authentication token ++#: .././libpam/pam_get_authtok.c:39 ++#: .././modules/pam_exec/pam_exec.c:142 ++#: .././modules/pam_unix/pam_unix_auth.c:160 ++#: .././modules/pam_userdb/pam_userdb.c:64 + msgid "Password: " + msgstr "পাসওয়ার্ড: " + +-#: libpam/pam_get_authtok.c:41 modules/pam_cracklib/pam_cracklib.c:68 ++#. For Translators: "%s%s" could be replaced with " " or "". ++#: .././libpam/pam_get_authtok.c:41 ++#: .././modules/pam_cracklib/pam_cracklib.c:68 + #, c-format + msgid "New %s%spassword: " + msgstr "নতুন %s%s পাসওয়ার্ড: " + +-#: libpam/pam_get_authtok.c:43 modules/pam_cracklib/pam_cracklib.c:70 ++#. For Translators: "%s%s" could be replaced with " " or "". ++#: .././libpam/pam_get_authtok.c:43 ++#: .././modules/pam_cracklib/pam_cracklib.c:70 + #, c-format + msgid "Retype new %s%spassword: " + msgstr "নতুন %s%s পাসওয়ার্ড পুনরায় লিখুন: " + +-#: libpam/pam_get_authtok.c:44 modules/pam_cracklib/pam_cracklib.c:71 ++#: .././libpam/pam_get_authtok.c:44 ++#: .././modules/pam_cracklib/pam_cracklib.c:71 + msgid "Sorry, passwords do not match." + msgstr "দুঃখিত, পাসওয়ার্ড দুটি এক নয়।" + +-#: libpam/pam_get_authtok.c:135 libpam/pam_get_authtok.c:211 ++#: .././libpam/pam_get_authtok.c:135 ++#: .././libpam/pam_get_authtok.c:211 + #, c-format + msgid "Retype %s" + msgstr "%s পুনরায় লিখুন" + +-#: libpam/pam_get_authtok.c:155 libpam/pam_get_authtok.c:227 ++#. We want to abort the password change ++#: .././libpam/pam_get_authtok.c:155 ++#: .././libpam/pam_get_authtok.c:227 + msgid "Password change aborted." + msgstr "পাসওয়ার্ড পরিবর্তনের কর্ম পরিত্যাগ করা হয়েছে।" + +-#: libpam/pam_item.c:311 ++#: .././libpam/pam_item.c:311 + msgid "login:" + msgstr "লগ-ইন:" + +-#: libpam/pam_strerror.c:40 ++#: .././libpam/pam_strerror.c:40 + msgid "Success" + msgstr "সফল" + +-#: libpam/pam_strerror.c:42 ++#: .././libpam/pam_strerror.c:42 + msgid "Critical error - immediate abort" + msgstr "গুরুতব সমস্যা - এই মুহূর্তে পরিত্যাগ করা হবে" + +-#: libpam/pam_strerror.c:44 ++#: .././libpam/pam_strerror.c:44 + msgid "Failed to load module" + msgstr "মডিউল লোড করতে ব্যর্থ" + +-#: libpam/pam_strerror.c:46 ++#: .././libpam/pam_strerror.c:46 + msgid "Symbol not found" + msgstr "চিহ্ন পাওয়া যায়নি" + +-#: libpam/pam_strerror.c:48 ++#: .././libpam/pam_strerror.c:48 + msgid "Error in service module" + msgstr "পরিসেবা মডিউলে সমস্যা" + +-#: libpam/pam_strerror.c:50 ++#: .././libpam/pam_strerror.c:50 + msgid "System error" + msgstr "সিস্টেম সংক্রান্ত সমস্যা" + +-#: libpam/pam_strerror.c:52 ++#: .././libpam/pam_strerror.c:52 + msgid "Memory buffer error" + msgstr "মেমরি বাফার সংক্রান্ত সমস্যা" + +-#: libpam/pam_strerror.c:54 ++#: .././libpam/pam_strerror.c:54 + msgid "Permission denied" + msgstr "অনুমতি প্রদান করা হয়নি" + +-#: libpam/pam_strerror.c:56 ++#: .././libpam/pam_strerror.c:56 + msgid "Authentication failure" + msgstr "অনুমোদন ব্যর্থ" + +-#: libpam/pam_strerror.c:58 ++#: .././libpam/pam_strerror.c:58 + msgid "Insufficient credentials to access authentication data" + msgstr "অনুমোদন সংক্রান্ত তথ্য প্রাপ্ত করার জন্য পর্যাপ্ত প্রমাণ উপলব্ধ নেই" + +-#: libpam/pam_strerror.c:60 ++#: .././libpam/pam_strerror.c:60 + msgid "Authentication service cannot retrieve authentication info" + msgstr "অনুমোদন পরিসেবা দ্বারা অনুমোদন সংক্রান্ত তথ্য উদ্ধার করা সম্ভব হয়নি" + +-#: libpam/pam_strerror.c:62 ++#: .././libpam/pam_strerror.c:62 + msgid "User not known to the underlying authentication module" + msgstr "পটভূমিতে চলমান অনুমোদন ব্যবস্থায় ব্যবহারকারী পরিচিত নন।" + +-#: libpam/pam_strerror.c:64 ++#: .././libpam/pam_strerror.c:64 + msgid "Have exhausted maximum number of retries for service" + msgstr "পরিসেবায় উপলব্ধ সর্বাধিক প্রচেষ্টার সুযোগ সংখ্যা সমাপ্ত" + +-#: libpam/pam_strerror.c:66 ++#: .././libpam/pam_strerror.c:66 + msgid "Authentication token is no longer valid; new one required" + msgstr "অনুমোদনের টোকেন বৈধ নয়; নতুন টোকেন ব্যবহার করা আবশ্যক" + +-#: libpam/pam_strerror.c:68 ++#: .././libpam/pam_strerror.c:68 + msgid "User account has expired" + msgstr "ব্যবহারকারী অ্যাকাউন্টের মেয়াদ পূর্ণ হয়েছে" + +-#: libpam/pam_strerror.c:70 ++#: .././libpam/pam_strerror.c:70 + msgid "Cannot make/remove an entry for the specified session" + msgstr "সুনির্দিষ্ট সেশানের জন্য কোনো এন্ট্রি নির্মাণ/অপসারণ করা সম্ভব নয়" + +-#: libpam/pam_strerror.c:72 ++#: .././libpam/pam_strerror.c:72 + msgid "Authentication service cannot retrieve user credentials" + msgstr "অনুমোদন পরিসেবা দ্বারা প্রয়োজনীয় প্রমাণ উদ্ধার করা সম্ভব হয়নি" + +-#: libpam/pam_strerror.c:74 ++#: .././libpam/pam_strerror.c:74 + msgid "User credentials expired" + msgstr "ব্যবহারকারীর পরিচয়প্রমাণের তথ্যের মেয়াদ পূর্ণ হয়েছে" + +-#: libpam/pam_strerror.c:76 ++#: .././libpam/pam_strerror.c:76 + msgid "Failure setting user credentials" + msgstr "ব্যবহারকারীর পরিচয়প্রমাণের তথ্য নির্ধারণ করতে ব্যর্থ" + +-#: libpam/pam_strerror.c:78 ++#: .././libpam/pam_strerror.c:78 + msgid "No module specific data is present" + msgstr "মডিউল সংক্রান্ত কোনো তথ্য উপস্থিত নেই" + +-#: libpam/pam_strerror.c:80 ++#: .././libpam/pam_strerror.c:80 + msgid "Bad item passed to pam_*_item()" + msgstr "pam_*_item()-এ সঠিক মান প্রেরিত হয়নি" + +-#: libpam/pam_strerror.c:82 ++#: .././libpam/pam_strerror.c:82 + msgid "Conversation error" + msgstr "Conversation অর্থাৎ তথ্য বিনিময়কালীন সমস্যা" + +-#: libpam/pam_strerror.c:84 ++#: .././libpam/pam_strerror.c:84 + msgid "Authentication token manipulation error" + msgstr "অনুমোদন টোকেন ব্যবস্থাপনা করতে সমস্যা" + +-#: libpam/pam_strerror.c:86 ++#: .././libpam/pam_strerror.c:86 + msgid "Authentication information cannot be recovered" + msgstr "অনুমোদন সংক্রান্ত তথ্য পুনরুদ্ধার করতে ব্যর্থ" + +-#: libpam/pam_strerror.c:88 ++#: .././libpam/pam_strerror.c:88 + msgid "Authentication token lock busy" + msgstr "অনুমোদন টোকেনের লক ব্যস্ত" + +-#: libpam/pam_strerror.c:90 ++#: .././libpam/pam_strerror.c:90 + msgid "Authentication token aging disabled" + msgstr "অনুমোদন টোকেনের মেয়াদ পূর্তী ব্যবস্থা নিষ্ক্রিয়" + +-#: libpam/pam_strerror.c:92 ++#: .././libpam/pam_strerror.c:92 + msgid "Failed preliminary check by password service" + msgstr "পাসওয়ার্ড পরিসেবা দ্বারা প্রারম্ভিক পরীক্ষা ব্যর্থ" + +-#: libpam/pam_strerror.c:94 ++#: .././libpam/pam_strerror.c:94 + msgid "The return value should be ignored by PAM dispatch" + msgstr "উৎপন্ন মান PAM dispatch দ্বারা অগ্রাহ্য করা হবে" + +-#: libpam/pam_strerror.c:96 ++#: .././libpam/pam_strerror.c:96 + msgid "Module is unknown" + msgstr "মডিউল অজানা" + +-#: libpam/pam_strerror.c:98 ++#: .././libpam/pam_strerror.c:98 + msgid "Authentication token expired" + msgstr "অনুমোদন টোকেনের মেয়াদ পূর্ণ হয়েছে" + +-#: libpam/pam_strerror.c:100 ++#: .././libpam/pam_strerror.c:100 + msgid "Conversation is waiting for event" +-msgstr "Conversation অর্থাৎ তথ্য বিনিময় প্রক্রিয়া একটি ইভেন্টের অপেক্ষায় রয়েছে" ++msgstr "" ++"Conversation অর্থাৎ তথ্য বিনিময় প্রক্রিয়া একটি ইভেন্টের অপেক্ষায় রয়েছে" + +-#: libpam/pam_strerror.c:102 ++#: .././libpam/pam_strerror.c:102 + msgid "Application needs to call libpam again" + msgstr "অ্যাপ্লিকেশন দ্বারা পুনরায় libpam আরম্ভ করা আবশ্যক" + +-#: libpam/pam_strerror.c:105 ++#: .././libpam/pam_strerror.c:105 + msgid "Unknown PAM error" + msgstr "PAM সংক্রান্ত অজানা ত্রুটি" + +-#: modules/pam_cracklib/pam_cracklib.c:618 ++#: .././modules/pam_cracklib/pam_cracklib.c:618 + msgid "is the same as the old one" + msgstr "পুরোনোটির অনুরূপ" + +-#: modules/pam_cracklib/pam_cracklib.c:624 +-#: modules/pam_cracklib/pam_cracklib.c:628 +-#: modules/pam_cracklib/pam_cracklib.c:638 ++#: .././modules/pam_cracklib/pam_cracklib.c:624 ++#: .././modules/pam_cracklib/pam_cracklib.c:628 ++#: .././modules/pam_cracklib/pam_cracklib.c:638 + msgid "memory allocation error" + msgstr "মেমরি বরাদ্দ করতে সমস্যা" + +-#: modules/pam_cracklib/pam_cracklib.c:643 ++#: .././modules/pam_cracklib/pam_cracklib.c:643 + msgid "is a palindrome" + msgstr "উভমুখী শব্দ" + +-#: modules/pam_cracklib/pam_cracklib.c:646 ++#: .././modules/pam_cracklib/pam_cracklib.c:646 + msgid "case changes only" + msgstr "শুধুমাত্র হরফের ছাঁদ পরিবর্তন করা হয়েছে" + +-#: modules/pam_cracklib/pam_cracklib.c:649 ++#: .././modules/pam_cracklib/pam_cracklib.c:649 + msgid "is too similar to the old one" + msgstr "পুরোনো পাসওয়ার্ডের সমতূল্য" + +-#: modules/pam_cracklib/pam_cracklib.c:652 ++#: .././modules/pam_cracklib/pam_cracklib.c:652 + msgid "is too simple" + msgstr "জটিল নয়" + +-#: modules/pam_cracklib/pam_cracklib.c:655 ++#: .././modules/pam_cracklib/pam_cracklib.c:655 + msgid "is rotated" + msgstr "ঘোরানো হয়েছে" + +-#: modules/pam_cracklib/pam_cracklib.c:658 ++#: .././modules/pam_cracklib/pam_cracklib.c:658 + msgid "not enough character classes" + msgstr "পর্যাপ্ত অক্ষর শ্রেণী উপস্থিত নেই" + +-#: modules/pam_cracklib/pam_cracklib.c:661 ++#: .././modules/pam_cracklib/pam_cracklib.c:661 + msgid "contains too many same characters consecutively" + msgstr "একই অক্ষর অত্যাধিক বার ক্রমাগত ব্যবহার করা হয়েছে" + +-#: modules/pam_cracklib/pam_cracklib.c:664 +-#, fuzzy ++#: .././modules/pam_cracklib/pam_cracklib.c:664 + msgid "contains too long of a monotonic character sequence" + msgstr "একই অক্ষর অত্যাধিক বার ক্রমাগত ব্যবহার করা হয়েছে" + +-#: modules/pam_cracklib/pam_cracklib.c:667 ++#: .././modules/pam_cracklib/pam_cracklib.c:667 + msgid "contains the user name in some form" + msgstr "কোনো রূপে ব্যবহারকারী নাম অন্তর্ভুক্ত হয়েছে" + +-#: modules/pam_cracklib/pam_cracklib.c:701 +-#: modules/pam_unix/pam_unix_passwd.c:496 ++#: .././modules/pam_cracklib/pam_cracklib.c:701 ++#: .././modules/pam_unix/pam_unix_passwd.c:502 + msgid "No password supplied" + msgstr "কোনো পাসওয়ার্ড উল্লিখিত হয়নি" + +-#: modules/pam_cracklib/pam_cracklib.c:701 +-#: modules/pam_unix/pam_unix_passwd.c:496 ++#: .././modules/pam_cracklib/pam_cracklib.c:701 ++#: .././modules/pam_unix/pam_unix_passwd.c:502 + msgid "Password unchanged" + msgstr "পাসওয়ার্ড পরিবর্তন করা হয়নি" + +-#: modules/pam_cracklib/pam_cracklib.c:721 +-#: modules/pam_cracklib/pam_cracklib.c:803 ++#: .././modules/pam_cracklib/pam_cracklib.c:721 ++#: .././modules/pam_cracklib/pam_cracklib.c:803 + #, c-format + msgid "BAD PASSWORD: %s" + msgstr "পাসওয়ার্ড ভাল নয়: %s" + +-#: modules/pam_exec/pam_exec.c:273 ++#: .././modules/pam_exec/pam_exec.c:215 + #, c-format + msgid "%s failed: exit code %d" + msgstr "%s বিফল: প্রস্থানকালীন কোড %d" + +-#: modules/pam_exec/pam_exec.c:282 ++#: .././modules/pam_exec/pam_exec.c:224 + #, c-format + msgid "%s failed: caught signal %d%s" + msgstr "%s বিফল: %d%s সিগনাল প্রাপ্ত" + +-#: modules/pam_exec/pam_exec.c:291 ++#: .././modules/pam_exec/pam_exec.c:233 + #, c-format + msgid "%s failed: unknown status 0x%x" + msgstr "%s বিফল: অজানা অবস্থা 0x%x" + + #. TRANSLATORS: "strftime options for date of last login" +-#: modules/pam_lastlog/pam_lastlog.c:282 modules/pam_lastlog/pam_lastlog.c:496 ++#: .././modules/pam_lastlog/pam_lastlog.c:282 ++#: .././modules/pam_lastlog/pam_lastlog.c:496 + msgid " %a %b %e %H:%M:%S %Z %Y" + msgstr " %a %b %e %H:%M:%S %Z %Y" + + #. TRANSLATORS: " from " +-#: modules/pam_lastlog/pam_lastlog.c:291 modules/pam_lastlog/pam_lastlog.c:505 ++#: .././modules/pam_lastlog/pam_lastlog.c:291 ++#: .././modules/pam_lastlog/pam_lastlog.c:505 + #, c-format + msgid " from %.*s" + msgstr " %.*s থেকে" + + #. TRANSLATORS: " on " +-#: modules/pam_lastlog/pam_lastlog.c:303 modules/pam_lastlog/pam_lastlog.c:517 ++#: .././modules/pam_lastlog/pam_lastlog.c:303 ++#: .././modules/pam_lastlog/pam_lastlog.c:517 + #, c-format + msgid " on %.*s" + msgstr " %.*s -র উপর" + + #. TRANSLATORS: "Last login: from on " +-#: modules/pam_lastlog/pam_lastlog.c:313 ++#: .././modules/pam_lastlog/pam_lastlog.c:313 + #, c-format + msgid "Last login:%s%s%s" + msgstr "সর্বশেষ লগ-ইন:%s%s%s" + +-#: modules/pam_lastlog/pam_lastlog.c:319 ++#: .././modules/pam_lastlog/pam_lastlog.c:319 + msgid "Welcome to your new account!" + msgstr "নতুন অ্যাকাউন্টে স্বাগতম!" + + #. TRANSLATORS: "Last failed login: from on " +-#: modules/pam_lastlog/pam_lastlog.c:527 ++#: .././modules/pam_lastlog/pam_lastlog.c:527 + #, c-format + msgid "Last failed login:%s%s%s" + msgstr "সর্বশেষ বিফল লগ-ইন:%s%s%s" + +-#: modules/pam_lastlog/pam_lastlog.c:536 modules/pam_lastlog/pam_lastlog.c:543 ++#: .././modules/pam_lastlog/pam_lastlog.c:536 ++#: .././modules/pam_lastlog/pam_lastlog.c:543 + #, c-format + msgid "There was %d failed login attempt since the last successful login." + msgid_plural "" +@@ -317,199 +338,209 @@ + msgstr[1] "সর্বশেষ সফল লগ-ইনের পরে %d-টি ব্যর্থ লগ-ইনের প্রচেষ্টা করা হয়েছে।" + + #. TRANSLATORS: only used if dngettext is not supported +-#: modules/pam_lastlog/pam_lastlog.c:548 ++#: .././modules/pam_lastlog/pam_lastlog.c:548 + #, c-format + msgid "There were %d failed login attempts since the last successful login." + msgstr "সর্বশেষ সফল লগ-ইনের পরে %d-টি ব্যর্থ লগ-ইনের প্রচেষ্টা করা হয়েছে।" + +-#: modules/pam_limits/pam_limits.c:1079 ++#: .././modules/pam_limits/pam_limits.c:1079 + #, c-format + msgid "Too many logins for '%s'." + msgstr "'%s'-র ক্ষেত্রে অত্যাধিক লগ-ইন" + +-#: modules/pam_mail/pam_mail.c:297 ++#: .././modules/pam_mail/pam_mail.c:297 + msgid "No mail." + msgstr "কোনো মেইল নেই।" + +-#: modules/pam_mail/pam_mail.c:300 ++#: .././modules/pam_mail/pam_mail.c:300 + msgid "You have new mail." + msgstr "নতুন মেইল প্রাপ্ত।" + +-#: modules/pam_mail/pam_mail.c:303 ++#: .././modules/pam_mail/pam_mail.c:303 + msgid "You have old mail." + msgstr "পুরোনো মেইল রয়েছে।" + +-#: modules/pam_mail/pam_mail.c:307 ++#: .././modules/pam_mail/pam_mail.c:307 + msgid "You have mail." + msgstr "মেইল রয়েছে।" + +-#: modules/pam_mail/pam_mail.c:314 ++#: .././modules/pam_mail/pam_mail.c:314 + #, c-format + msgid "You have no mail in folder %s." + msgstr "%s ফোল্ডারে কোনো মেইল উপস্থিত নেই।" + +-#: modules/pam_mail/pam_mail.c:318 ++#: .././modules/pam_mail/pam_mail.c:318 + #, c-format + msgid "You have new mail in folder %s." + msgstr "%s ফোল্ডারে নতুন মেইল উপস্থিত।" + +-#: modules/pam_mail/pam_mail.c:322 ++#: .././modules/pam_mail/pam_mail.c:322 + #, c-format + msgid "You have old mail in folder %s." + msgstr "%s ফোল্ডারে পুরোনো মেইল উপস্থিত রয়েছে।" + +-#: modules/pam_mail/pam_mail.c:327 ++#: .././modules/pam_mail/pam_mail.c:327 + #, c-format + msgid "You have mail in folder %s." + msgstr "%s ফোল্ডারে মেইল উপস্থিত রয়েছে।" + +-#: modules/pam_mkhomedir/pam_mkhomedir.c:113 ++#: .././modules/pam_mkhomedir/pam_mkhomedir.c:114 + #, c-format + msgid "Creating directory '%s'." + msgstr "'%s' ডিরেক্টরি নির্মাণ করা হচ্ছে।" + +-#: modules/pam_mkhomedir/pam_mkhomedir.c:183 ++#: .././modules/pam_mkhomedir/pam_mkhomedir.c:192 + #, c-format + msgid "Unable to create and initialize directory '%s'." + msgstr "ডিরেক্টরি '%s' নির্মাণ ও আরম্ভ করতে ব্যর্থ।" + +-#: modules/pam_pwhistory/pam_pwhistory.c:217 +-#: modules/pam_unix/pam_unix_passwd.c:517 ++#: .././modules/pam_pwhistory/pam_pwhistory.c:384 ++#: .././modules/pam_unix/pam_unix_passwd.c:523 + msgid "Password has been already used. Choose another." + msgstr "পাসওয়ার্ড পূর্বে ব্যবহৃত হয়েছে। একটি পৃথক পাসওয়ার্ড নির্বাচন করুন।" + +-#: modules/pam_pwhistory/pam_pwhistory.c:224 +-#, fuzzy ++#: .././modules/pam_pwhistory/pam_pwhistory.c:391 + msgid "Password has been already used." +-msgstr "পাসওয়ার্ড পূর্বে ব্যবহৃত হয়েছে। একটি পৃথক পাসওয়ার্ড নির্বাচন করুন।" ++msgstr "পাসওয়ার্ড পূর্বে ব্যবহৃত হয়েছে।" + +-#: modules/pam_selinux/pam_selinux.c:210 ++#: .././modules/pam_selinux/pam_selinux.c:210 + #, c-format + msgid "Default Security Context %s\n" + msgstr "ডিফল্ট Security Context %s\n" + +-#: modules/pam_selinux/pam_selinux.c:214 ++#: .././modules/pam_selinux/pam_selinux.c:214 + msgid "Would you like to enter a different role or level?" + msgstr "ভিন্ন role অথবা level লিখতে ইচ্ছুক কি?" + +-#: modules/pam_selinux/pam_selinux.c:227 ++#. Allow the user to enter role and level individually ++#: .././modules/pam_selinux/pam_selinux.c:227 + msgid "role:" + msgstr "role: " + +-#: modules/pam_selinux/pam_selinux.c:230 ++#: .././modules/pam_selinux/pam_selinux.c:230 + #, c-format + msgid "No default type for role %s\n" + msgstr "role %s-র জন্য কোনো ডিফল্ট type উপস্থিত নেই\n" + +-#: modules/pam_selinux/pam_selinux.c:262 ++#: .././modules/pam_selinux/pam_selinux.c:262 + msgid "level:" + msgstr "level: " + +-#: modules/pam_selinux/pam_selinux.c:295 ++#: .././modules/pam_selinux/pam_selinux.c:295 + msgid "Not a valid security context" + msgstr "বৈধ নিরাপত্তা সংক্রান্ত context নয়" + +-#: modules/pam_selinux/pam_selinux.c:539 ++#: .././modules/pam_selinux/pam_selinux.c:539 + #, c-format + msgid "Unable to get valid context for %s" + msgstr "%s-র বৈধ context প্রাপ্ত করতে ব্যর্থ" + +-#: modules/pam_selinux/pam_selinux.c:658 ++#: .././modules/pam_selinux/pam_selinux.c:658 + #, c-format + msgid "Security Context %s Assigned" + msgstr "Security Context %s ধার্য করা হয়েছে" + +-#: modules/pam_selinux/pam_selinux.c:674 ++#: .././modules/pam_selinux/pam_selinux.c:674 + #, c-format + msgid "Key Creation Context %s Assigned" + msgstr "কি নির্মাণের Context %s ধার্য করা হয়েছে" + +-#: modules/pam_selinux/pam_selinux_check.c:99 ++#: .././modules/pam_selinux/pam_selinux_check.c:99 + #, c-format + msgid "failed to initialize PAM\n" + msgstr "PAM আরম্ভ করতে ব্যর্থ\n" + +-#: modules/pam_selinux/pam_selinux_check.c:105 ++#: .././modules/pam_selinux/pam_selinux_check.c:105 + #, c-format + msgid "failed to pam_set_item()\n" + msgstr "pam_set_item() করতে ব্যর্থ\n" + +-#: modules/pam_selinux/pam_selinux_check.c:133 ++#. error in fork() ++#: .././modules/pam_selinux/pam_selinux_check.c:133 + #, c-format + msgid "login: failure forking: %m" + msgstr "লগ-ইন: fork করতে ব্যর্থ: %m" + +-#: modules/pam_stress/pam_stress.c:476 ++#: .././modules/pam_stress/pam_stress.c:476 + #, c-format + msgid "Changing STRESS password for %s." + msgstr "%s-র STRESS পাসওয়ার্ড পরিবর্তন করা হচ্ছে।" + +-#: modules/pam_stress/pam_stress.c:490 ++#: .././modules/pam_stress/pam_stress.c:490 + msgid "Enter new STRESS password: " + msgstr "নতুন STRESS পাসওয়ার্ড লিখুন: " + +-#: modules/pam_stress/pam_stress.c:493 ++#: .././modules/pam_stress/pam_stress.c:493 + msgid "Retype new STRESS password: " + msgstr "নতুন STRESS পাসওয়ার্ড পুনরায় লিখুন: " + +-#: modules/pam_stress/pam_stress.c:522 ++#: .././modules/pam_stress/pam_stress.c:522 + msgid "Verification mis-typed; password unchanged" + msgstr "নিশ্চায়ন কাল ভুল টাইপ করা হয়েছে; পাসওয়ার্ড পরিবর্তন করা হয়নি" + +-#: modules/pam_tally/pam_tally.c:541 modules/pam_tally2/pam_tally2.c:599 ++#: .././modules/pam_tally/pam_tally.c:541 ++#: .././modules/pam_tally2/pam_tally2.c:599 + #, c-format + msgid "Account temporary locked (%ld seconds left)" + msgstr "সাময়িকরূপে অ্যাকাউন্ট লক করা হয়েছে (%ld সেকেন্ড অবশিষ্ট)" + +-#: modules/pam_tally/pam_tally.c:566 modules/pam_tally2/pam_tally2.c:578 ++#: .././modules/pam_tally/pam_tally.c:566 ++#: .././modules/pam_tally2/pam_tally2.c:578 + #, c-format + msgid "Account locked due to %u failed logins" + msgstr "%u ব্যর্থ লগ-ইনের ফলে অ্যাকাউন্ট লক করা হয়েছে" + +-#: modules/pam_tally/pam_tally.c:777 modules/pam_tally2/pam_tally2.c:887 ++#: .././modules/pam_tally/pam_tally.c:777 ++#: .././modules/pam_tally2/pam_tally2.c:887 + msgid "Authentication error" + msgstr "অনুমোদন সংক্রান্ত সমস্যা" + +-#: modules/pam_tally/pam_tally.c:778 modules/pam_tally2/pam_tally2.c:888 ++#: .././modules/pam_tally/pam_tally.c:778 ++#: .././modules/pam_tally2/pam_tally2.c:888 + msgid "Service error" + msgstr "পরিসেবা সংক্রান্ত সমস্যা" + +-#: modules/pam_tally/pam_tally.c:779 modules/pam_tally2/pam_tally2.c:889 ++#: .././modules/pam_tally/pam_tally.c:779 ++#: .././modules/pam_tally2/pam_tally2.c:889 + msgid "Unknown user" + msgstr "অজানা ব্যবহারকারী" + +-#: modules/pam_tally/pam_tally.c:780 modules/pam_tally2/pam_tally2.c:890 ++#: .././modules/pam_tally/pam_tally.c:780 ++#: .././modules/pam_tally2/pam_tally2.c:890 + msgid "Unknown error" + msgstr "অজানা সমস্যা" + +-#: modules/pam_tally/pam_tally.c:796 modules/pam_tally2/pam_tally2.c:909 ++#: .././modules/pam_tally/pam_tally.c:796 ++#: .././modules/pam_tally2/pam_tally2.c:909 + #, c-format + msgid "%s: Bad number given to --reset=\n" + msgstr "%s: --reset= এর জন্য ভুল সংখ্যা উল্লিখিত\n" + +-#: modules/pam_tally/pam_tally.c:800 modules/pam_tally2/pam_tally2.c:913 ++#: .././modules/pam_tally/pam_tally.c:800 ++#: .././modules/pam_tally2/pam_tally2.c:913 + #, c-format + msgid "%s: Unrecognised option %s\n" + msgstr "%s: অজানা বিকল্প %s\n" + +-#: modules/pam_tally/pam_tally.c:812 ++#: .././modules/pam_tally/pam_tally.c:812 + #, c-format + msgid "" + "%s: [--file rooted-filename] [--user username] [--reset[=n]] [--quiet]\n" + msgstr "" + "%s: [--file rooted-filename] [--user username] [--reset[=n]] [--quiet]\n" + +-#: modules/pam_tally/pam_tally.c:886 modules/pam_tally2/pam_tally2.c:1039 ++#: .././modules/pam_tally/pam_tally.c:886 ++#: .././modules/pam_tally2/pam_tally2.c:1039 + #, c-format + msgid "%s: Can't reset all users to non-zero\n" + msgstr "%s: সব ব্যবহারকারীর জন্য শূণ্য-ভিন্ন মান ধার্য করতে ব্যর্থ\n" + +-#: modules/pam_tally2/pam_tally2.c:940 ++#: .././modules/pam_tally2/pam_tally2.c:940 + #, c-format + msgid "Login Failures Latest failure From\n" + msgstr "লগ-ইন বিফলতা সর্বশেষ বিফলতা চিহ্নিত স্থান থেকে\n" + +-#: modules/pam_tally2/pam_tally2.c:956 ++#: .././modules/pam_tally2/pam_tally2.c:956 + #, c-format + msgid "" + "%s: [-f rooted-filename] [--file rooted-filename]\n" +@@ -520,26 +551,31 @@ + " [-u username] [--user username]\n" + " [-r] [--reset[=n]] [--quiet]\n" + +-#: modules/pam_timestamp/pam_timestamp.c:345 ++#: .././modules/pam_timestamp/pam_timestamp.c:345 + #, c-format + msgid "Access granted (last access was %ld seconds ago)." + msgstr "প্রবেশাধিকার প্রদান করা হয়েছে (%ld পূর্বে সর্বশেষ লগ-ইন করা হয়েছে)।" + +-#: modules/pam_unix/pam_unix_acct.c:247 modules/pam_unix/pam_unix_acct.c:269 ++#: .././modules/pam_unix/pam_unix_acct.c:249 ++#: .././modules/pam_unix/pam_unix_acct.c:271 + msgid "Your account has expired; please contact your system administrator" + msgstr "" +-"আপনার অ্যাকাউন্টের মেয়াদপূর্ণ হয়েছে; অনুগ্রহ করে সিস্টেম অ্যাডমিনিস্ট্রেটরের সাথে " +-"যোগাযোগ করুন।" ++"আপনার অ্যাকাউন্টের মেয়াদপূর্ণ হয়েছে; অনুগ্রহ করে সিস্টেম অ্যাডমিনিস্ট্রেটরের " ++"সাথে যোগাযোগ করুন।" + +-#: modules/pam_unix/pam_unix_acct.c:255 ++#: .././modules/pam_unix/pam_unix_acct.c:257 + msgid "You are required to change your password immediately (root enforced)" +-msgstr "আপনার পাসওয়ার্ড এই মুহূর্তে পরিবর্তন করা আবশ্যক (root দ্বারা কার্যকরী)" ++msgstr "" ++"আপনার পাসওয়ার্ড এই মুহূর্তে পরিবর্তন করা আবশ্যক (root দ্বারা কার্যকরী)" + +-#: modules/pam_unix/pam_unix_acct.c:261 ++#: .././modules/pam_unix/pam_unix_acct.c:263 + msgid "You are required to change your password immediately (password aged)" +-msgstr "আপনার পাসওয়ার্ড এই মুহূর্তে পরিবর্তন করা আবশ্যক (password-র মেয়াদ পূর্ণ হয়েছে)" ++msgstr "" ++"আপনার পাসওয়ার্ড এই মুহূর্তে পরিবর্তন করা আবশ্যক (password-র মেয়াদ পূর্ণ " ++"হয়েছে)" + +-#: modules/pam_unix/pam_unix_acct.c:282 modules/pam_unix/pam_unix_acct.c:289 ++#: .././modules/pam_unix/pam_unix_acct.c:284 ++#: .././modules/pam_unix/pam_unix_acct.c:291 + #, c-format + msgid "Warning: your password will expire in %d day" + msgid_plural "Warning: your password will expire in %d days" +@@ -547,39 +583,37 @@ + msgstr[1] "সতর্কবাণী: %d দিন পরে পাসওয়ার্ডের মেয়াদপূর্ণ হবে" + + #. TRANSLATORS: only used if dngettext is not supported +-#: modules/pam_unix/pam_unix_acct.c:294 ++#: .././modules/pam_unix/pam_unix_acct.c:296 + #, c-format + msgid "Warning: your password will expire in %d days" + msgstr "সতর্কবাণী: %d দিন পরে পাসওয়ার্ডের মেয়াদপূর্ণ হবে" + +-#: modules/pam_unix/pam_unix_passwd.c:398 ++#: .././modules/pam_unix/pam_unix_passwd.c:404 + msgid "NIS password could not be changed." + msgstr "NIS পাসওয়ার্ড পরিবর্তন করা সম্ভব হয়নি।" + +-#: modules/pam_unix/pam_unix_passwd.c:513 ++#: .././modules/pam_unix/pam_unix_passwd.c:519 + msgid "You must choose a longer password" + msgstr "চিহ্নিত পাসওয়ার্ডের থেকে লম্বা পাসওয়ার্ড উল্লেখ করা আবশ্যক" + +-#: modules/pam_unix/pam_unix_passwd.c:619 ++#. instruct user what is happening ++#: .././modules/pam_unix/pam_unix_passwd.c:625 + #, c-format + msgid "Changing password for %s." + msgstr "%s-র পাসওয়ার্ড পরিবর্তন করা হচ্ছে।" + +-#: modules/pam_unix/pam_unix_passwd.c:630 ++#: .././modules/pam_unix/pam_unix_passwd.c:636 + msgid "(current) UNIX password: " + msgstr "(বর্তমান) UNIX পাসওয়ার্ড: " + +-#: modules/pam_unix/pam_unix_passwd.c:665 ++#: .././modules/pam_unix/pam_unix_passwd.c:671 + msgid "You must wait longer to change your password" + msgstr "কিছু কাল পরে পাসওয়ার্ড পরিবর্তন করা সম্ভব হবে" + +-#: modules/pam_unix/pam_unix_passwd.c:725 ++#: .././modules/pam_unix/pam_unix_passwd.c:731 + msgid "Enter new UNIX password: " + msgstr "নতুন UNIX পাসওয়ার্ড উল্লেখ করুন: " + +-#: modules/pam_unix/pam_unix_passwd.c:726 ++#: .././modules/pam_unix/pam_unix_passwd.c:732 + msgid "Retype new UNIX password: " + msgstr "নতুন UNIX পাসওয়ার্ড পুনরায় লিখুন: " +- +-#~ msgid "Would you like to enter a security context? [N] " +-#~ msgstr "নিরাপত্তা সংক্রান্ত context উল্লেখ করতে ইচ্ছুক কি? [N] " +diff -urN a/Linux-PAM-1.1.8/po/pt_BR.po b/Linux-PAM-1.1.8/po/pt_BR.po +--- a/Linux-PAM-1.1.8/po/pt_BR.po 2013-11-28 17:24:14.193596625 +0530 ++++ b/Linux-PAM-1.1.8/po/pt_BR.po 2013-11-28 17:27:02.137118305 +0530 +@@ -1,315 +1,335 @@ + # SOME DESCRIPTIVE TITLE. + # Copyright (C) YEAR Linux-PAM Project + # This file is distributed under the same license as the PACKAGE package. +-# ++# + # Translators: + # Diego Búrigo Zacarão , 2008. + # Elder Marco , 2012. + # Glaucia Cintra , 2007. + # Taylon Silmer , 2008, 2009. ++# gcintra , 2013. #zanata + msgid "" + msgstr "" + "Project-Id-Version: Linux-PAM\n" + "Report-Msgid-Bugs-To: http://sourceforge.net/projects/pam\n" +-"POT-Creation-Date: 2013-09-19 10:02+0200\n" +-"PO-Revision-Date: 2012-02-21 12:49+0000\n" +-"Last-Translator: Elder Marco \n" ++"POT-Creation-Date: 2012-08-17 11:35+0200\n" ++"PO-Revision-Date: 2013-09-30 08:32-0400\n" ++"Last-Translator: gcintra \n" + "Language-Team: Portuguese (Brazil) \n" + "MIME-Version: 1.0\n" + "Content-Type: text/plain; charset=UTF-8\n" + "Content-Transfer-Encoding: 8bit\n" +-"Language: pt_BR\n" ++"Language: pt-BR\n" + "Plural-Forms: nplurals=2; plural=(n > 1)\n" ++"X-Generator: Zanata 3.1.2\n" + +-#: libpam_misc/misc_conv.c:33 ++#. * external timeout definitions - these can be overriden by the ++#. * application. ++#. time when we warn ++#. time when we timeout ++#: .././libpam_misc/misc_conv.c:33 + msgid "...Time is running out...\n" + msgstr "...O tempo está acabando...\n" + +-#: libpam_misc/misc_conv.c:34 ++#: .././libpam_misc/misc_conv.c:34 + msgid "...Sorry, your time is up!\n" + msgstr "...Desculpe, seu tempo está aumentando!\n" + +-#: libpam_misc/misc_conv.c:342 ++#: .././libpam_misc/misc_conv.c:342 + #, c-format + msgid "erroneous conversation (%d)\n" + msgstr "conversação errônea (%d)\n" + +-#: libpam/pam_get_authtok.c:39 modules/pam_exec/pam_exec.c:170 +-#: modules/pam_unix/pam_unix_auth.c:160 modules/pam_userdb/pam_userdb.c:64 ++#. get this user's authentication token ++#: .././libpam/pam_get_authtok.c:39 ++#: .././modules/pam_exec/pam_exec.c:142 ++#: .././modules/pam_unix/pam_unix_auth.c:160 ++#: .././modules/pam_userdb/pam_userdb.c:64 + msgid "Password: " + msgstr "Senha:" + +-#: libpam/pam_get_authtok.c:41 modules/pam_cracklib/pam_cracklib.c:68 ++#. For Translators: "%s%s" could be replaced with " " or "". ++#: .././libpam/pam_get_authtok.c:41 ++#: .././modules/pam_cracklib/pam_cracklib.c:68 + #, c-format + msgid "New %s%spassword: " + msgstr "Nova %s%ssenha:" + +-#: libpam/pam_get_authtok.c:43 modules/pam_cracklib/pam_cracklib.c:70 ++#. For Translators: "%s%s" could be replaced with " " or "". ++#: .././libpam/pam_get_authtok.c:43 ++#: .././modules/pam_cracklib/pam_cracklib.c:70 + #, c-format + msgid "Retype new %s%spassword: " + msgstr "Redigite a nova %s%ssenha:" + +-#: libpam/pam_get_authtok.c:44 modules/pam_cracklib/pam_cracklib.c:71 ++#: .././libpam/pam_get_authtok.c:44 ++#: .././modules/pam_cracklib/pam_cracklib.c:71 + msgid "Sorry, passwords do not match." + msgstr "As senhas não são iguais." + +-#: libpam/pam_get_authtok.c:135 libpam/pam_get_authtok.c:211 ++#: .././libpam/pam_get_authtok.c:135 ++#: .././libpam/pam_get_authtok.c:211 + #, c-format + msgid "Retype %s" + msgstr "Redigite %s" + +-#: libpam/pam_get_authtok.c:155 libpam/pam_get_authtok.c:227 ++#. We want to abort the password change ++#: .././libpam/pam_get_authtok.c:155 ++#: .././libpam/pam_get_authtok.c:227 + msgid "Password change aborted." + msgstr "A alteração de senha foi abortada." + +-#: libpam/pam_item.c:311 ++#: .././libpam/pam_item.c:311 + msgid "login:" + msgstr "login:" + +-#: libpam/pam_strerror.c:40 ++#: .././libpam/pam_strerror.c:40 + msgid "Success" + msgstr "Sucesso" + +-#: libpam/pam_strerror.c:42 ++#: .././libpam/pam_strerror.c:42 + msgid "Critical error - immediate abort" + msgstr "Erro crítico - abortar imediatamente" + +-#: libpam/pam_strerror.c:44 ++#: .././libpam/pam_strerror.c:44 + msgid "Failed to load module" + msgstr "Falha ao carregar módulo" + +-#: libpam/pam_strerror.c:46 ++#: .././libpam/pam_strerror.c:46 + msgid "Symbol not found" + msgstr "Símbolo não encontrado" + +-#: libpam/pam_strerror.c:48 ++#: .././libpam/pam_strerror.c:48 + msgid "Error in service module" + msgstr "Erro no módulo de serviço" + +-#: libpam/pam_strerror.c:50 ++#: .././libpam/pam_strerror.c:50 + msgid "System error" + msgstr "Erro do sistema" + +-#: libpam/pam_strerror.c:52 ++#: .././libpam/pam_strerror.c:52 + msgid "Memory buffer error" + msgstr "Erro do buffer de memória" + +-#: libpam/pam_strerror.c:54 ++#: .././libpam/pam_strerror.c:54 + msgid "Permission denied" + msgstr "Permissão negada" + +-#: libpam/pam_strerror.c:56 ++#: .././libpam/pam_strerror.c:56 + msgid "Authentication failure" + msgstr "Falha de autenticação" + +-#: libpam/pam_strerror.c:58 ++#: .././libpam/pam_strerror.c:58 + msgid "Insufficient credentials to access authentication data" + msgstr "Credenciais insuficientes para acessar dados de autenticação" + +-#: libpam/pam_strerror.c:60 ++#: .././libpam/pam_strerror.c:60 + msgid "Authentication service cannot retrieve authentication info" + msgstr "O serviço de autenticação não recuperou informações de autenticação" + +-#: libpam/pam_strerror.c:62 ++#: .././libpam/pam_strerror.c:62 + msgid "User not known to the underlying authentication module" + msgstr "Usuário desconhecido para o módulo de autenticação subjacente" + +-#: libpam/pam_strerror.c:64 ++#: .././libpam/pam_strerror.c:64 + msgid "Have exhausted maximum number of retries for service" + msgstr "Esgotado o número máximo de tentativas para serviço" + +-#: libpam/pam_strerror.c:66 ++#: .././libpam/pam_strerror.c:66 + msgid "Authentication token is no longer valid; new one required" + msgstr "O token de autenticação não é mais válido; é necessario um novo token" + +-#: libpam/pam_strerror.c:68 ++#: .././libpam/pam_strerror.c:68 + msgid "User account has expired" + msgstr "A conta do usuário expirou" + +-#: libpam/pam_strerror.c:70 ++#: .././libpam/pam_strerror.c:70 + msgid "Cannot make/remove an entry for the specified session" + msgstr "Impossível fazer/remover uma entrada para a sessão específica" + +-#: libpam/pam_strerror.c:72 ++#: .././libpam/pam_strerror.c:72 + msgid "Authentication service cannot retrieve user credentials" + msgstr "O serviço de autenticação não recuperou as credenciais do usuário" + +-#: libpam/pam_strerror.c:74 ++#: .././libpam/pam_strerror.c:74 + msgid "User credentials expired" + msgstr "Credenciais do usuário expiradas" + +-#: libpam/pam_strerror.c:76 ++#: .././libpam/pam_strerror.c:76 + msgid "Failure setting user credentials" + msgstr "Falha ao definir credenciais do usuário" + +-#: libpam/pam_strerror.c:78 ++#: .././libpam/pam_strerror.c:78 + msgid "No module specific data is present" + msgstr "Não há nenhum dado específico para o módulo " + +-#: libpam/pam_strerror.c:80 ++#: .././libpam/pam_strerror.c:80 + msgid "Bad item passed to pam_*_item()" + msgstr "Ítem incorreto passado para pam_*_item()" + +-#: libpam/pam_strerror.c:82 ++#: .././libpam/pam_strerror.c:82 + msgid "Conversation error" + msgstr "Erro de conversação" + +-#: libpam/pam_strerror.c:84 ++#: .././libpam/pam_strerror.c:84 + msgid "Authentication token manipulation error" + msgstr "Erro de manipulação de token de autenticação" + +-#: libpam/pam_strerror.c:86 ++#: .././libpam/pam_strerror.c:86 + msgid "Authentication information cannot be recovered" + msgstr "Impossível recuperar informações de autenticação" + +-#: libpam/pam_strerror.c:88 ++#: .././libpam/pam_strerror.c:88 + msgid "Authentication token lock busy" + msgstr "Bloqueio de token de autenticação ocupado" + +-#: libpam/pam_strerror.c:90 ++#: .././libpam/pam_strerror.c:90 + msgid "Authentication token aging disabled" + msgstr "Validade do token de autenticação desabilitado" + +-#: libpam/pam_strerror.c:92 ++#: .././libpam/pam_strerror.c:92 + msgid "Failed preliminary check by password service" + msgstr "Falha na verificação preliminar por serviço de senha" + +-#: libpam/pam_strerror.c:94 ++#: .././libpam/pam_strerror.c:94 + msgid "The return value should be ignored by PAM dispatch" + msgstr "O valor de retorno deve ser ignorado pelo despacho PAM" + +-#: libpam/pam_strerror.c:96 ++#: .././libpam/pam_strerror.c:96 + msgid "Module is unknown" + msgstr "Módulo desconhecido" + +-#: libpam/pam_strerror.c:98 ++#: .././libpam/pam_strerror.c:98 + msgid "Authentication token expired" + msgstr "Token de autenticação expirado" + +-#: libpam/pam_strerror.c:100 ++#: .././libpam/pam_strerror.c:100 + msgid "Conversation is waiting for event" + msgstr "Conversação aguardando por evento" + +-#: libpam/pam_strerror.c:102 ++#: .././libpam/pam_strerror.c:102 + msgid "Application needs to call libpam again" + msgstr "O aplicativo precisa chamar libpam novamente" + +-#: libpam/pam_strerror.c:105 ++#: .././libpam/pam_strerror.c:105 + msgid "Unknown PAM error" + msgstr "Erro desconhecido no PAM" + +-#: modules/pam_cracklib/pam_cracklib.c:618 ++#: .././modules/pam_cracklib/pam_cracklib.c:618 + msgid "is the same as the old one" + msgstr "é igual à antiga senha" + +-#: modules/pam_cracklib/pam_cracklib.c:624 +-#: modules/pam_cracklib/pam_cracklib.c:628 +-#: modules/pam_cracklib/pam_cracklib.c:638 ++#: .././modules/pam_cracklib/pam_cracklib.c:624 ++#: .././modules/pam_cracklib/pam_cracklib.c:628 ++#: .././modules/pam_cracklib/pam_cracklib.c:638 + msgid "memory allocation error" + msgstr "Erro de alocação de memória" + +-#: modules/pam_cracklib/pam_cracklib.c:643 ++#: .././modules/pam_cracklib/pam_cracklib.c:643 + msgid "is a palindrome" + msgstr "é um palíndromo" + +-#: modules/pam_cracklib/pam_cracklib.c:646 ++#: .././modules/pam_cracklib/pam_cracklib.c:646 + msgid "case changes only" + msgstr "mudou apenas maiúsculas/minúsculas" + +-#: modules/pam_cracklib/pam_cracklib.c:649 ++#: .././modules/pam_cracklib/pam_cracklib.c:649 + msgid "is too similar to the old one" + msgstr "é muito semelhante à antiga" + +-#: modules/pam_cracklib/pam_cracklib.c:652 ++#: .././modules/pam_cracklib/pam_cracklib.c:652 + msgid "is too simple" + msgstr "é simples demais" + +-#: modules/pam_cracklib/pam_cracklib.c:655 ++#: .././modules/pam_cracklib/pam_cracklib.c:655 + msgid "is rotated" + msgstr "foi invertida" + +-#: modules/pam_cracklib/pam_cracklib.c:658 ++#: .././modules/pam_cracklib/pam_cracklib.c:658 + msgid "not enough character classes" + msgstr "classes de caractere insuficientes" + +-#: modules/pam_cracklib/pam_cracklib.c:661 ++#: .././modules/pam_cracklib/pam_cracklib.c:661 + msgid "contains too many same characters consecutively" + msgstr "contém muitos caracteres igual consecutivamente" + +-#: modules/pam_cracklib/pam_cracklib.c:664 +-#, fuzzy ++#: .././modules/pam_cracklib/pam_cracklib.c:664 + msgid "contains too long of a monotonic character sequence" +-msgstr "contém muitos caracteres igual consecutivamente" ++msgstr "contém uma sequência de caracteres monotônica muito longa" + +-#: modules/pam_cracklib/pam_cracklib.c:667 ++#: .././modules/pam_cracklib/pam_cracklib.c:667 + msgid "contains the user name in some form" + msgstr "contém o nome de usuário em algum formulário" + +-#: modules/pam_cracklib/pam_cracklib.c:701 +-#: modules/pam_unix/pam_unix_passwd.c:496 ++#: .././modules/pam_cracklib/pam_cracklib.c:701 ++#: .././modules/pam_unix/pam_unix_passwd.c:502 + msgid "No password supplied" + msgstr "Nenhuma senha informada" + +-#: modules/pam_cracklib/pam_cracklib.c:701 +-#: modules/pam_unix/pam_unix_passwd.c:496 ++#: .././modules/pam_cracklib/pam_cracklib.c:701 ++#: .././modules/pam_unix/pam_unix_passwd.c:502 + msgid "Password unchanged" + msgstr "Senha inalterada" + +-#: modules/pam_cracklib/pam_cracklib.c:721 +-#: modules/pam_cracklib/pam_cracklib.c:803 ++#: .././modules/pam_cracklib/pam_cracklib.c:721 ++#: .././modules/pam_cracklib/pam_cracklib.c:803 + #, c-format + msgid "BAD PASSWORD: %s" + msgstr "SENHA INCORRETA: %s" + +-#: modules/pam_exec/pam_exec.c:273 ++#: .././modules/pam_exec/pam_exec.c:215 + #, c-format + msgid "%s failed: exit code %d" + msgstr "%s falhou: código de saída %d" + +-#: modules/pam_exec/pam_exec.c:282 ++#: .././modules/pam_exec/pam_exec.c:224 + #, c-format + msgid "%s failed: caught signal %d%s" + msgstr "%s falhou: detectou sinal %d%s" + +-#: modules/pam_exec/pam_exec.c:291 ++#: .././modules/pam_exec/pam_exec.c:233 + #, c-format + msgid "%s failed: unknown status 0x%x" + msgstr "%s falhou: status desconhecido 0x%x" + + #. TRANSLATORS: "strftime options for date of last login" +-#: modules/pam_lastlog/pam_lastlog.c:282 modules/pam_lastlog/pam_lastlog.c:496 ++#: .././modules/pam_lastlog/pam_lastlog.c:282 ++#: .././modules/pam_lastlog/pam_lastlog.c:496 + msgid " %a %b %e %H:%M:%S %Z %Y" + msgstr "%a %b %e %H:%M:%S %Z %Y" + + #. TRANSLATORS: " from " +-#: modules/pam_lastlog/pam_lastlog.c:291 modules/pam_lastlog/pam_lastlog.c:505 ++#: .././modules/pam_lastlog/pam_lastlog.c:291 ++#: .././modules/pam_lastlog/pam_lastlog.c:505 + #, c-format + msgid " from %.*s" + msgstr "de %.*s" + + #. TRANSLATORS: " on " +-#: modules/pam_lastlog/pam_lastlog.c:303 modules/pam_lastlog/pam_lastlog.c:517 ++#: .././modules/pam_lastlog/pam_lastlog.c:303 ++#: .././modules/pam_lastlog/pam_lastlog.c:517 + #, c-format + msgid " on %.*s" + msgstr "em %.*s" + + #. TRANSLATORS: "Last login: from on " +-#: modules/pam_lastlog/pam_lastlog.c:313 ++#: .././modules/pam_lastlog/pam_lastlog.c:313 + #, c-format + msgid "Last login:%s%s%s" + msgstr "Último login:%s%s%s" + +-#: modules/pam_lastlog/pam_lastlog.c:319 ++#: .././modules/pam_lastlog/pam_lastlog.c:319 + msgid "Welcome to your new account!" + msgstr "Bem-vindo à sua nova conta!" + + #. TRANSLATORS: "Last failed login: from on " +-#: modules/pam_lastlog/pam_lastlog.c:527 ++#: .././modules/pam_lastlog/pam_lastlog.c:527 + #, c-format + msgid "Last failed login:%s%s%s" + msgstr "Falha no último login:%s%s%s" + +-#: modules/pam_lastlog/pam_lastlog.c:536 modules/pam_lastlog/pam_lastlog.c:543 ++#: .././modules/pam_lastlog/pam_lastlog.c:536 ++#: .././modules/pam_lastlog/pam_lastlog.c:543 + #, c-format + msgid "There was %d failed login attempt since the last successful login." + msgid_plural "" +@@ -318,199 +338,209 @@ + msgstr[1] "Houveram %d falhas de login desde o último login bem sucedido." + + #. TRANSLATORS: only used if dngettext is not supported +-#: modules/pam_lastlog/pam_lastlog.c:548 ++#: .././modules/pam_lastlog/pam_lastlog.c:548 + #, c-format + msgid "There were %d failed login attempts since the last successful login." + msgstr "Houveram %d falhas de login desde o último login bem sucedido." + +-#: modules/pam_limits/pam_limits.c:1079 ++#: .././modules/pam_limits/pam_limits.c:1079 + #, c-format + msgid "Too many logins for '%s'." + msgstr "Há logins demais para '%s'." + +-#: modules/pam_mail/pam_mail.c:297 ++#: .././modules/pam_mail/pam_mail.c:297 + msgid "No mail." + msgstr "Não há mensagens." + +-#: modules/pam_mail/pam_mail.c:300 ++#: .././modules/pam_mail/pam_mail.c:300 + msgid "You have new mail." + msgstr "Há novas mensagens." + +-#: modules/pam_mail/pam_mail.c:303 ++#: .././modules/pam_mail/pam_mail.c:303 + msgid "You have old mail." + msgstr "Há mensagens antigas." + +-#: modules/pam_mail/pam_mail.c:307 ++#: .././modules/pam_mail/pam_mail.c:307 + msgid "You have mail." + msgstr "Há mensagens." + +-#: modules/pam_mail/pam_mail.c:314 ++#: .././modules/pam_mail/pam_mail.c:314 + #, c-format + msgid "You have no mail in folder %s." + msgstr "Não há mensagens na pasta %s." + +-#: modules/pam_mail/pam_mail.c:318 ++#: .././modules/pam_mail/pam_mail.c:318 + #, c-format + msgid "You have new mail in folder %s." + msgstr "Há novas mensagens na pasta %s." + +-#: modules/pam_mail/pam_mail.c:322 ++#: .././modules/pam_mail/pam_mail.c:322 + #, c-format + msgid "You have old mail in folder %s." + msgstr "Há mensagens antigas na pasta %s." + +-#: modules/pam_mail/pam_mail.c:327 ++#: .././modules/pam_mail/pam_mail.c:327 + #, c-format + msgid "You have mail in folder %s." + msgstr "Há mensagens na pasta %s." + +-#: modules/pam_mkhomedir/pam_mkhomedir.c:113 ++#: .././modules/pam_mkhomedir/pam_mkhomedir.c:114 + #, c-format + msgid "Creating directory '%s'." + msgstr "Criando o diretório '%s'." + +-#: modules/pam_mkhomedir/pam_mkhomedir.c:183 ++#: .././modules/pam_mkhomedir/pam_mkhomedir.c:192 + #, c-format + msgid "Unable to create and initialize directory '%s'." + msgstr "Impossível criar e inicializar o diretório \"%s\"." + +-#: modules/pam_pwhistory/pam_pwhistory.c:217 +-#: modules/pam_unix/pam_unix_passwd.c:517 ++#: .././modules/pam_pwhistory/pam_pwhistory.c:384 ++#: .././modules/pam_unix/pam_unix_passwd.c:523 + msgid "Password has been already used. Choose another." + msgstr "A senha já foi usada. Escolha outra." + +-#: modules/pam_pwhistory/pam_pwhistory.c:224 +-#, fuzzy ++#: .././modules/pam_pwhistory/pam_pwhistory.c:391 + msgid "Password has been already used." +-msgstr "A senha já foi usada. Escolha outra." ++msgstr "A senha já foi usada." + +-#: modules/pam_selinux/pam_selinux.c:210 ++#: .././modules/pam_selinux/pam_selinux.c:210 + #, c-format + msgid "Default Security Context %s\n" + msgstr "Contexto de Segurança Padrão %s\n" + +-#: modules/pam_selinux/pam_selinux.c:214 ++#: .././modules/pam_selinux/pam_selinux.c:214 + msgid "Would you like to enter a different role or level?" + msgstr "Deseja digitar uma função ou nível diferente?" + +-#: modules/pam_selinux/pam_selinux.c:227 ++#. Allow the user to enter role and level individually ++#: .././modules/pam_selinux/pam_selinux.c:227 + msgid "role:" + msgstr "função:" + +-#: modules/pam_selinux/pam_selinux.c:230 ++#: .././modules/pam_selinux/pam_selinux.c:230 + #, c-format + msgid "No default type for role %s\n" + msgstr "Não existe tipo padrão para a função %s\n" + +-#: modules/pam_selinux/pam_selinux.c:262 ++#: .././modules/pam_selinux/pam_selinux.c:262 + msgid "level:" + msgstr "nível:" + +-#: modules/pam_selinux/pam_selinux.c:295 ++#: .././modules/pam_selinux/pam_selinux.c:295 + msgid "Not a valid security context" + msgstr "Não é um contexto de segurança válido" + +-#: modules/pam_selinux/pam_selinux.c:539 ++#: .././modules/pam_selinux/pam_selinux.c:539 + #, c-format + msgid "Unable to get valid context for %s" + msgstr "Impossível obter um contexto válido para %s" + +-#: modules/pam_selinux/pam_selinux.c:658 ++#: .././modules/pam_selinux/pam_selinux.c:658 + #, c-format + msgid "Security Context %s Assigned" + msgstr "Contexto de segurança %s atribuído" + +-#: modules/pam_selinux/pam_selinux.c:674 ++#: .././modules/pam_selinux/pam_selinux.c:674 + #, c-format + msgid "Key Creation Context %s Assigned" + msgstr "Contexto de criação de chave %s atribuído" + +-#: modules/pam_selinux/pam_selinux_check.c:99 ++#: .././modules/pam_selinux/pam_selinux_check.c:99 + #, c-format + msgid "failed to initialize PAM\n" + msgstr "falha ao inicializar PAM\n" + +-#: modules/pam_selinux/pam_selinux_check.c:105 ++#: .././modules/pam_selinux/pam_selinux_check.c:105 + #, c-format + msgid "failed to pam_set_item()\n" + msgstr "falha em pam_set_item()\n" + +-#: modules/pam_selinux/pam_selinux_check.c:133 ++#. error in fork() ++#: .././modules/pam_selinux/pam_selinux_check.c:133 + #, c-format + msgid "login: failure forking: %m" + msgstr "login: falha na bifurcação: %m" + +-#: modules/pam_stress/pam_stress.c:476 ++#: .././modules/pam_stress/pam_stress.c:476 + #, c-format + msgid "Changing STRESS password for %s." + msgstr "Mudando senha STRESS para %s." + +-#: modules/pam_stress/pam_stress.c:490 ++#: .././modules/pam_stress/pam_stress.c:490 + msgid "Enter new STRESS password: " + msgstr "Digite a nova senha STRESS:" + +-#: modules/pam_stress/pam_stress.c:493 ++#: .././modules/pam_stress/pam_stress.c:493 + msgid "Retype new STRESS password: " + msgstr "Digite novamente a nova senha STRESS:" + +-#: modules/pam_stress/pam_stress.c:522 ++#: .././modules/pam_stress/pam_stress.c:522 + msgid "Verification mis-typed; password unchanged" + msgstr "Verificação digitada incorretamente; senha inalterada" + +-#: modules/pam_tally/pam_tally.c:541 modules/pam_tally2/pam_tally2.c:599 ++#: .././modules/pam_tally/pam_tally.c:541 ++#: .././modules/pam_tally2/pam_tally2.c:599 + #, c-format + msgid "Account temporary locked (%ld seconds left)" + msgstr "Conta temporariamente bloqueada (restam %ld segundos)" + +-#: modules/pam_tally/pam_tally.c:566 modules/pam_tally2/pam_tally2.c:578 ++#: .././modules/pam_tally/pam_tally.c:566 ++#: .././modules/pam_tally2/pam_tally2.c:578 + #, c-format + msgid "Account locked due to %u failed logins" + msgstr "Conta bloqueada devido a %u falhas de login" + +-#: modules/pam_tally/pam_tally.c:777 modules/pam_tally2/pam_tally2.c:887 ++#: .././modules/pam_tally/pam_tally.c:777 ++#: .././modules/pam_tally2/pam_tally2.c:887 + msgid "Authentication error" + msgstr "Erro de autenticação" + +-#: modules/pam_tally/pam_tally.c:778 modules/pam_tally2/pam_tally2.c:888 ++#: .././modules/pam_tally/pam_tally.c:778 ++#: .././modules/pam_tally2/pam_tally2.c:888 + msgid "Service error" + msgstr "Erro de serviço" + +-#: modules/pam_tally/pam_tally.c:779 modules/pam_tally2/pam_tally2.c:889 ++#: .././modules/pam_tally/pam_tally.c:779 ++#: .././modules/pam_tally2/pam_tally2.c:889 + msgid "Unknown user" + msgstr "Usuário desconhecido" + +-#: modules/pam_tally/pam_tally.c:780 modules/pam_tally2/pam_tally2.c:890 ++#: .././modules/pam_tally/pam_tally.c:780 ++#: .././modules/pam_tally2/pam_tally2.c:890 + msgid "Unknown error" + msgstr "Erro desconhecido" + +-#: modules/pam_tally/pam_tally.c:796 modules/pam_tally2/pam_tally2.c:909 ++#: .././modules/pam_tally/pam_tally.c:796 ++#: .././modules/pam_tally2/pam_tally2.c:909 + #, c-format + msgid "%s: Bad number given to --reset=\n" + msgstr "%s: Número insuficiente fornecido para --reset=\n" + +-#: modules/pam_tally/pam_tally.c:800 modules/pam_tally2/pam_tally2.c:913 ++#: .././modules/pam_tally/pam_tally.c:800 ++#: .././modules/pam_tally2/pam_tally2.c:913 + #, c-format + msgid "%s: Unrecognised option %s\n" + msgstr "%s: Opção não reconhecida %s\n" + +-#: modules/pam_tally/pam_tally.c:812 ++#: .././modules/pam_tally/pam_tally.c:812 + #, c-format + msgid "" + "%s: [--file rooted-filename] [--user username] [--reset[=n]] [--quiet]\n" + msgstr "" + "%s: [--file rooted-filename] [--user username] [--reset[=n]] [--quiet]\n" + +-#: modules/pam_tally/pam_tally.c:886 modules/pam_tally2/pam_tally2.c:1039 ++#: .././modules/pam_tally/pam_tally.c:886 ++#: .././modules/pam_tally2/pam_tally2.c:1039 + #, c-format + msgid "%s: Can't reset all users to non-zero\n" + msgstr "%s: Impossível redefinir todos os usuários para não-zero\n" + +-#: modules/pam_tally2/pam_tally2.c:940 ++#: .././modules/pam_tally2/pam_tally2.c:940 + #, c-format + msgid "Login Failures Latest failure From\n" + msgstr "Login Falhas Último falha De\n" + +-#: modules/pam_tally2/pam_tally2.c:956 ++#: .././modules/pam_tally2/pam_tally2.c:956 + #, c-format + msgid "" + "%s: [-f rooted-filename] [--file rooted-filename]\n" +@@ -521,24 +551,26 @@ + " [-u username] [--user username]\n" + " [-r] [--reset[=n]] [--quiet]\n" + +-#: modules/pam_timestamp/pam_timestamp.c:345 ++#: .././modules/pam_timestamp/pam_timestamp.c:345 + #, c-format + msgid "Access granted (last access was %ld seconds ago)." + msgstr "Acesso concedido (o último acesso foi a %ld segundos atrás)." + +-#: modules/pam_unix/pam_unix_acct.c:247 modules/pam_unix/pam_unix_acct.c:269 ++#: .././modules/pam_unix/pam_unix_acct.c:249 ++#: .././modules/pam_unix/pam_unix_acct.c:271 + msgid "Your account has expired; please contact your system administrator" + msgstr "Sua conta expirou; entre em contato com o administrador do sistema" + +-#: modules/pam_unix/pam_unix_acct.c:255 ++#: .././modules/pam_unix/pam_unix_acct.c:257 + msgid "You are required to change your password immediately (root enforced)" + msgstr "Mude sua senha imediatamente (aplicado pela raiz)" + +-#: modules/pam_unix/pam_unix_acct.c:261 ++#: .././modules/pam_unix/pam_unix_acct.c:263 + msgid "You are required to change your password immediately (password aged)" + msgstr "Mude sua senha imediatamente (senha expirada)" + +-#: modules/pam_unix/pam_unix_acct.c:282 modules/pam_unix/pam_unix_acct.c:289 ++#: .././modules/pam_unix/pam_unix_acct.c:284 ++#: .././modules/pam_unix/pam_unix_acct.c:291 + #, c-format + msgid "Warning: your password will expire in %d day" + msgid_plural "Warning: your password will expire in %d days" +@@ -546,39 +578,37 @@ + msgstr[1] "Aviso: sua senha irá expirar em %d dias" + + #. TRANSLATORS: only used if dngettext is not supported +-#: modules/pam_unix/pam_unix_acct.c:294 ++#: .././modules/pam_unix/pam_unix_acct.c:296 + #, c-format + msgid "Warning: your password will expire in %d days" + msgstr "Aviso: sua senha irá expirar em %d dias" + +-#: modules/pam_unix/pam_unix_passwd.c:398 ++#: .././modules/pam_unix/pam_unix_passwd.c:404 + msgid "NIS password could not be changed." + msgstr "A senha NIS não pôde ser mudada." + +-#: modules/pam_unix/pam_unix_passwd.c:513 ++#: .././modules/pam_unix/pam_unix_passwd.c:519 + msgid "You must choose a longer password" + msgstr "Escolha uma senha mais longa" + +-#: modules/pam_unix/pam_unix_passwd.c:619 ++#. instruct user what is happening ++#: .././modules/pam_unix/pam_unix_passwd.c:625 + #, c-format + msgid "Changing password for %s." + msgstr "Mudando senha para %s." + +-#: modules/pam_unix/pam_unix_passwd.c:630 ++#: .././modules/pam_unix/pam_unix_passwd.c:636 + msgid "(current) UNIX password: " + msgstr "Senha UNIX (atual):" + +-#: modules/pam_unix/pam_unix_passwd.c:665 ++#: .././modules/pam_unix/pam_unix_passwd.c:671 + msgid "You must wait longer to change your password" + msgstr "Aguarde mais tempo para mudar a senha" + +-#: modules/pam_unix/pam_unix_passwd.c:725 ++#: .././modules/pam_unix/pam_unix_passwd.c:731 + msgid "Enter new UNIX password: " + msgstr "Digite a nova senha UNIX:" + +-#: modules/pam_unix/pam_unix_passwd.c:726 ++#: .././modules/pam_unix/pam_unix_passwd.c:732 + msgid "Retype new UNIX password: " + msgstr "Redigite a nova senha UNIX:" +- +-#~ msgid "Would you like to enter a security context? [N] " +-#~ msgstr "Deseja digitar um contexto de segurança? [N]" diff --git a/SPECS/pam.spec b/SPECS/pam.spec index 9684313..4fd99ba 100644 --- a/SPECS/pam.spec +++ b/SPECS/pam.spec @@ -1,9 +1,9 @@ -%define pam_redhat_version 0.99.10-1 +%define pam_redhat_version 0.99.11 Summary: An extensible library which provides authentication for applications Name: pam Version: 1.1.8 -Release: 1%{?dist} +Release: 9%{?dist} # The library is BSD licensed with option to relicense as GPLv2+ # - this option is redundant as the BSD license allows that anyway. # pam_timestamp, pam_loginuid, and pam_console modules are GPLv2+. @@ -23,7 +23,7 @@ Source10: config-util.pamd Source11: dlopen.sh Source12: system-auth.5 Source13: config-util.5 -Source14: 90-nproc.conf +Source14: 20-nproc.conf Source15: pamtmp.conf Source16: postlogin.pamd Source17: postlogin.5 @@ -31,20 +31,22 @@ Patch1: pam-1.0.90-redhat-modules.patch Patch2: pam-1.1.6-std-noclose.patch Patch4: pam-1.1.0-console-nochmod.patch Patch5: pam-1.1.0-notally.patch -Patch7: pam-1.1.0-console-fixes.patch Patch8: pam-1.1.1-faillock.patch Patch9: pam-1.1.6-noflex.patch Patch10: pam-1.1.3-nouserenv.patch -Patch11: pam-1.1.3-console-abstract.patch Patch12: pam-1.1.3-faillock-screensaver.patch Patch13: pam-1.1.6-limits-user.patch Patch15: pam-1.1.6-full-relro.patch # FIPS related - non upstreamable Patch20: pam-1.1.5-unix-no-fallback.patch # Upstreamed partially -Patch29: pam-1.1.6-pwhistory-helper.patch +Patch29: pam-1.1.8-pwhistory-helper.patch Patch31: pam-1.1.6-use-links.patch Patch32: pam-1.1.7-tty-audit-init.patch +Patch33: pam-1.1.8-translation-updates.patch +Patch34: pam-1.1.8-canonicalize-username.patch +Patch35: pam-1.1.8-cve-2013-7041.patch +Patch36: pam-1.1.8-cve-2014-2583.patch %define _pamlibdir %{_libdir} %define _moduledir %{_libdir}/security @@ -57,6 +59,7 @@ Patch32: pam-1.1.7-tty-audit-init.patch %if %{?WITH_AUDIT:0}%{!?WITH_AUDIT:1} %define WITH_AUDIT 1 %endif +%global _performance_build 1 Requires: cracklib-dicts >= 2.8 Requires: libpwquality >= 0.9.9 @@ -110,11 +113,9 @@ mv pam-redhat-%{pam_redhat_version}/* modules %patch2 -p1 -b .std-noclose %patch4 -p1 -b .nochmod %patch5 -p1 -b .notally -%patch7 -p1 -b .console-fixes %patch8 -p1 -b .faillock %patch9 -p1 -b .noflex %patch10 -p1 -b .nouserenv -%patch11 -p1 -b .abstract %patch12 -p1 -b .screensaver %patch13 -p1 -b .limits %patch15 -p1 -b .relro @@ -122,6 +123,10 @@ mv pam-redhat-%{pam_redhat_version}/* modules %patch29 -p1 -b .pwhhelper %patch31 -p1 -b .links %patch32 -p1 -b .tty-audit-init +%patch33 -p2 -b .translations +%patch34 -p1 -b .canonicalize +%patch35 -p1 -b .case +%patch36 -p1 -b .timestamp-ruser %build autoreconf -i @@ -136,6 +141,7 @@ autoreconf -i %endif --disable-static \ --disable-prelude +make -C po update-gmo make # we do not use _smp_mflags because the build of sources in yacc/flex fails @@ -167,7 +173,7 @@ install -m 644 %{SOURCE8} $RPM_BUILD_ROOT%{_pamconfdir}/fingerprint-auth install -m 644 %{SOURCE9} $RPM_BUILD_ROOT%{_pamconfdir}/smartcard-auth install -m 644 %{SOURCE10} $RPM_BUILD_ROOT%{_pamconfdir}/config-util install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_pamconfdir}/postlogin -install -m 644 %{SOURCE14} $RPM_BUILD_ROOT%{_secconfdir}/limits.d/90-nproc.conf +install -m 644 %{SOURCE14} $RPM_BUILD_ROOT%{_secconfdir}/limits.d/20-nproc.conf install -m 600 /dev/null $RPM_BUILD_ROOT%{_secconfdir}/opasswd install -d -m 755 $RPM_BUILD_ROOT/var/log install -m 600 /dev/null $RPM_BUILD_ROOT/var/log/tallylog @@ -338,7 +344,7 @@ fi %config(noreplace) %{_secconfdir}/group.conf %config(noreplace) %{_secconfdir}/limits.conf %dir %{_secconfdir}/limits.d -%config(noreplace) %{_secconfdir}/limits.d/90-nproc.conf +%config(noreplace) %{_secconfdir}/limits.d/20-nproc.conf %config(noreplace) %{_secconfdir}/namespace.conf %dir %{_secconfdir}/namespace.d %attr(755,root,root) %config(noreplace) %{_secconfdir}/namespace.init @@ -369,6 +375,32 @@ fi %doc doc/adg/*.txt doc/adg/html %changelog +* Mon Mar 31 2014 Tomáš Mráz 1.1.8-9 +- fix CVE-2014-2583: potential path traversal issue in pam_timestamp +- pam_pwhistory: call the helper if SELinux enabled + +* Tue Mar 11 2014 Tomáš Mráz 1.1.8-8 +- fix CVE-2013-7041: use case sensitive comparison in pam_userdb + +* Mon Mar 10 2014 Tomáš Mráz 1.1.8-7 +- rename the 90-nproc.conf to 20-nproc.conf (#1071618) +- canonicalize user name in pam_selinux (#1071010) + +* Fri Jan 31 2014 Tomáš Mráz 1.1.8-6 +- refresh the pam-redhat tarball + +* Fri Jan 24 2014 Daniel Mach - 1.1.8-5 +- Mass rebuild 2014-01-24 + +* Wed Jan 15 2014 Tomáš Mráz 1.1.8-4 +- rebuild with -O3 on ppc64 architecture + +* Fri Dec 27 2013 Daniel Mach - 1.1.8-3 +- Mass rebuild 2013-12-27 + +* Tue Dec 3 2013 Tomáš Mráz 1.1.8-2 +- updated translations + * Mon Oct 14 2013 Tomáš Mráz 1.1.8-1 - new upstream release