diff --git a/SOURCES/passwd-0.79-auditing.patch b/SOURCES/passwd-0.79-auditing.patch new file mode 100644 index 0000000..b387115 --- /dev/null +++ b/SOURCES/passwd-0.79-auditing.patch @@ -0,0 +1,157 @@ +diff --git a/passwd.c b/passwd.c +index 45acf02..27ad6fe 100644 +--- a/passwd.c ++++ b/passwd.c +@@ -63,7 +63,6 @@ + #ifdef WITH_AUDIT + #include + #else +-#define audit_log_user_message(d,ty,m,h,a,t,r) do { ; } while(0) + #define audit_log_acct_message(d,ty,p,o,n,i,h,a,t,r) do { ; } while(0) + static int audit_open(void) { errno = EPROTONOSUPPORT; return -1; } + #endif +@@ -274,13 +273,10 @@ parse_args(int argc, const char **argv, + /* The only flag which unprivileged users get to use is -k. */ + if ((passwd_flags & ~PASSWD_KEEP) && + (getuid() != 0)) { +- if (passwd_flags & PASSWD_STATUS) { ++ /* Auditing is not needed for displaying status */ ++ if (passwd_flags != PASSWD_STATUS) { + audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "password status display", +- NULL, getuid(), NULL, NULL, NULL, 0); +- } else { +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "password attribute change", ++ NULL, "attempted-to-change-password-attribute", + NULL, getuid(), NULL, NULL, NULL, 0); + } + fprintf(stderr, _("Only root can do that.\n")); +@@ -293,8 +289,8 @@ parse_args(int argc, const char **argv, + if (getuid() != 0) { + /* The invoking user was not root. */ + audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "password change", extraArgs[0], +- getuid(), NULL, NULL, NULL, 0); ++ NULL, "attempted-to-change-password", ++ extraArgs[0], getuid(), NULL, NULL, NULL, 0); + fprintf(stderr, + _("%s: Only root can specify a user name.\n"), + progname); +@@ -392,7 +388,7 @@ main(int argc, const char **argv) + fprintf(stderr, _("%s: SELinux denying access due to security policy.\n"), progname); + + audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "change password", NULL, pwd->pw_uid, ++ NULL, "attempted-to-change-password", NULL, pwd->pw_uid, + NULL, NULL, NULL, 0); + exit(1); + } +@@ -404,8 +400,8 @@ main(int argc, const char **argv) + printf("%s: %s\n", progname, + retval == + 0 ? _("Success") : _("Error (password not set?)")); +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "lock password", NULL, pwd->pw_uid, ++ audit_log_acct_message(audit_fd, AUDIT_ACCT_LOCK, ++ NULL, "locked-password", NULL, pwd->pw_uid, + NULL, NULL, NULL, retval == 0); + return retval; + } +@@ -419,8 +415,8 @@ main(int argc, const char **argv) + retval == + -2 ? _("Unsafe operation (use -f to force)") : + _("Error (password not set?)")); +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "unlock password", NULL, pwd->pw_uid, ++ audit_log_acct_message(audit_fd, AUDIT_ACCT_UNLOCK, ++ NULL, "unlocked-password", NULL, pwd->pw_uid, + NULL, NULL, NULL, retval == 0); + return retval; + } +@@ -431,8 +427,8 @@ main(int argc, const char **argv) + printf("%s: %s\n", progname, + retval == + 0 ? _("Success") : _("Error")); +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "expire password", NULL, pwd->pw_uid, ++ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, ++ NULL, "expired-password", NULL, pwd->pw_uid, + NULL, NULL, NULL, retval == 0); + return retval; + } +@@ -443,16 +439,14 @@ main(int argc, const char **argv) + printf("%s: %s\n", progname, + (retval == 0) ? _("Success") : _("Error")); + audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "delete password", NULL, pwd->pw_uid, ++ NULL, "deleted-password", NULL, pwd->pw_uid, + NULL, NULL, NULL, retval == 0); + return retval; + } + /* Display account status. */ + if (passwd_flags & PASSWD_STATUS) { ++ /* Auditing is not needed for displaying status */ + retval = pwdb_display_status(username); +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "password status displayed for user", +- NULL, pwd->pw_uid, NULL, NULL, NULL, retval == 0); + return retval; + } + /* Adjust aging parameters. */ +@@ -462,12 +456,12 @@ main(int argc, const char **argv) + retval = pwdb_update_aging(username, min, max, warn, inact, -2); + printf("%s: %s\n", progname, + (retval == 0) ? _("Success") : _("Error")); +- snprintf(aubuf, sizeof(aubuf), "password aging data updated " +- "- acct=%s, uid=%u, min=%li, max=%li," +- " warn=%li, inact=%li", username, +- pwd->pw_uid, min, max, warn, inact); +- audit_log_user_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- aubuf, NULL, NULL, NULL, retval == 0); ++ snprintf(aubuf, sizeof(aubuf), "changed-password-aging" ++ " min=%li max=%li warn=%li inact=%li", ++ min, max, warn, inact); ++ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, ++ NULL, aubuf, NULL, pwd->pw_uid, ++ NULL, NULL, NULL, retval == 0); + return retval; + } + +@@ -548,33 +542,22 @@ main(int argc, const char **argv) + } + #endif + +- /* Go for it. */ ++ /* Go for it. Note: pam will send audit event. */ + retval = pam_chauthtok(pamh, + (passwd_flags & PASSWD_KEEP) ? + PAM_CHANGE_EXPIRED_AUTHTOK : 0); + if (retval == PAM_SUCCESS) { + /* We're done. Tell the invoking user that it worked. */ + retval = pam_end(pamh, PAM_SUCCESS); +- if (passwd_flags & PASSWD_KEEP) { +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "change expired password", NULL, +- pwd->pw_uid, NULL, NULL, NULL, +- retval == PAM_SUCCESS); ++ if (passwd_flags & PASSWD_KEEP) + printf(_("%s: expired authentication tokens updated successfully.\n"), + progname); +- } else { +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "change password", NULL, pwd->pw_uid, +- NULL, NULL, NULL, retval == PAM_SUCCESS); ++ else + printf(_("%s: all authentication tokens updated successfully.\n"), + progname); +- } + retval = 0; + } else { + /* Horrors! It failed. Relay the bad news. */ +- audit_log_acct_message(audit_fd, AUDIT_USER_CHAUTHTOK, +- NULL, "change password", NULL, pwd->pw_uid, +- NULL, NULL, NULL, retval == PAM_SUCCESS); + fprintf(stderr, "%s: %s\n", progname, + pam_strerror(pamh, retval)); + pam_end(pamh, retval); diff --git a/SOURCES/passwd-0.79-document-S-option.patch b/SOURCES/passwd-0.79-document-S-option.patch new file mode 100644 index 0000000..602319b --- /dev/null +++ b/SOURCES/passwd-0.79-document-S-option.patch @@ -0,0 +1,93 @@ +From 02d4478318297d24799b03fa53312da5e3f14a40 Mon Sep 17 00:00:00 2001 +From: Jiri Kucera +Date: Mar 28 2018 14:26:48 +0000 +Subject: Updated man page + + +Added more info about -S option: +* described status information fields +* added note about displaying the last password change date value +Added exit codes description. + +--- + +diff --git a/man/passwd.1 b/man/passwd.1 +index b72ffb9..a962c77 100644 +--- a/man/passwd.1 ++++ b/man/passwd.1 +@@ -153,7 +153,23 @@ root only. + .TP + \fB\-S\fR, \fB\-\-status\fR + This will output a short information about the status of the password +-for a given account. Available to root user only. ++for a given account. The status information consists of 7 fields. The ++first field is the user's login name. The second field indicates if the ++user account has a locked password (LK), has no password (NP), or has a ++usable password (PS). The third field gives the date of the last password ++change. The next four fields are the minimum age, maximum age, warning ++period, and inactivity period for the password. These ages are expressed ++in days. ++.sp ++\fBNotes:\fR ++The date of the last password change is stored as a number of days ++since epoch. Depending on the current time zone, the ++\fBpasswd \-S\fR ++\fIusername\fR ++may show the date of the last password change that is different ++from the real date of the last password change by ±1 day. ++.sp ++This option is available to root only. + + .SH "Remember the following two principles" + +@@ -195,10 +211,46 @@ Vigilance on your part will make the system much more secure. + + .SH "EXIT CODE" + +-On successful completion of its task, ++The + .B passwd +-will complete with exit code 0. An exit code of 1 indicates an error +-occurred. Textual errors are written to the standard error stream. ++command exits with the following codes: ++.PP ++\fI0\fR ++.RS 4 ++success ++.RE ++.PP ++\fI1\fR ++.RS 4 ++passwd/libuser operation failed ++.RE ++.PP ++\fI2\fR ++.RS 4 ++unknown user ++.RE ++.PP ++\fI252\fR ++.RS 4 ++unknown user name ++.RE ++.PP ++\fI253\fR ++.RS 4 ++bad arguments or passwordless account ++.RE ++.PP ++\fI254\fR ++.RS 4 ++invalid application of arguments ++.RE ++.PP ++\fI255\fR ++.RS 4 ++libuser operation failed ++.RE ++.PP ++Error messages are written to the standard error stream. + + .SH "CONFORMING TO" + .br + diff --git a/SOURCES/passwd-0.79-no-length-limit-stdin-passwords.patch b/SOURCES/passwd-0.79-no-length-limit-stdin-passwords.patch new file mode 100644 index 0000000..0069973 --- /dev/null +++ b/SOURCES/passwd-0.79-no-length-limit-stdin-passwords.patch @@ -0,0 +1,48 @@ +From ca46cac76757082322d19f736a88cbf81bd70063 Mon Sep 17 00:00:00 2001 +From: Miloslav Trmač +Date: Nov 02 2015 18:20:24 +0000 +Subject: Support passwords up to PAM_MAX_RESP_SIZE - 1 with --stdin + + +--- + +diff --git a/passwd.c b/passwd.c +index b1dd114..45acf02 100644 +--- a/passwd.c ++++ b/passwd.c +@@ -479,17 +479,32 @@ main(int argc, const char **argv) + /* If we need to read the new password from stdin, read it and switch + * to the really-quiet stdin conversation function. */ + if (passwd_flags & PASSWD_STDIN) { +- char *ptr, newPassword[80]; ++ /* PAM's documentation says that PAM_MAX_RESP_SIZE is the ++ * maximum supported length of the password, but in practice ++ * the code (including examples in the OSF RFC) often truncates ++ * data at PAM_MAX_RESP_SIZE - 1. So, refuse to use anything ++ * longer than PAM_MAX_RESP_SIZE - 1, to prevent users from ++ * setting a password they won't be able to use to log in. */ ++ char *ptr, newPassword[PAM_MAX_RESP_SIZE]; + int i; + + i = read(STDIN_FILENO, newPassword, +- sizeof(newPassword) - 1); ++ sizeof(newPassword)); + if (i < 0) { + fprintf(stderr, + _("%s: error reading from stdin: %s\n"), progname, + strerror(errno)); + exit(1); + } ++ if (i == sizeof(newPassword)) { ++ if (newPassword[i - 1] != '\n') { ++ fprintf(stderr, ++ _("%s: password too long, maximum is %zu"), ++ progname, sizeof(newPassword) - 1); ++ exit(1); ++ } ++ i--; ++ } + + newPassword[i] = '\0'; + ptr = strchr(newPassword, '\n'); + diff --git a/SPECS/passwd.spec b/SPECS/passwd.spec index 0ece643..03c5ce4 100644 --- a/SPECS/passwd.spec +++ b/SPECS/passwd.spec @@ -7,12 +7,18 @@ Summary: An utility for setting or changing passwords using PAM Name: passwd Version: 0.79 -Release: 4%{?dist} +Release: 5%{?dist} License: BSD or GPL+ Group: System Environment/Base -URL: http://fedorahosted.org/passwd -Source: https://fedorahosted.org/releases/p/a/%{name}/%{name}-%{version}.tar.bz2 +URL: https://pagure.io/%{name} +Source: https://releases.pagure.org/%{name}/%{name}-%{version}.tar.bz2 Patch0: passwd-0.79-translation-updates.patch +# Backport ca46cac (rhbz#1276570) +Patch1: passwd-0.79-no-length-limit-stdin-passwords.patch +# Backport Steve Grubb's patches c461efa^..e2a9bdf (rhbz#1489086, rhbz#1638105) +Patch2: passwd-0.79-auditing.patch +# Backport 02d4478 (rhbz#1145256) +Patch3: passwd-0.79-document-S-option.patch Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) Requires: pam >= 1.0.90, /etc/pam.d/system-auth %if %{WITH_SELINUX} @@ -35,6 +41,9 @@ Modules) library. %setup -q -n %{name}-%{version} # Remove the (make -C po update-gmo) below when removing the patch. %patch0 -p2 -b .translation-updates +%patch1 -p1 -b .length-limit +%patch2 -p1 -b .auditing +%patch3 -p1 -b .doc-S-opt %build %configure \ @@ -77,6 +86,15 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man1/passwd.1* %changelog +* Fri Mar 22 2019 Jiri Kucera - 0.79-5 +- Backport ca46cac (allow passwords longer than 79 characters) + Backport Steve Grubb's patches + - stop double auditing, use appropriate record types, update op field in + audit events, don't audit status check, fix password aging logging + Backport 02d4478 (better document -S option) + Fix URL and Source tags + Resolves: #1276570, #1489086, #1638105, #1145256, #1472567 + * Thu Jan 30 2014 Miloslav Trmač - 0.79-4 - Include updated translations Resolves: #1044298