From cd433ed05519e2585e4aa41adb9f1c461483f7c6 Mon Sep 17 00:00:00 2001 From: MSVSphere Packaging Team Date: Tue, 26 Nov 2024 19:18:13 +0300 Subject: [PATCH] import shadow-utils-4.15.0-3.el10 --- .gitignore | 1 + .shadow-utils.metadata | 1 + SOURCES/gpl-2.0.txt | 339 +++ SOURCES/passwd.pamd | 5 + .../shadow-4.15.0-account-tools-setuid.patch | 380 +++ SOURCES/shadow-4.15.0-audit-update.patch | 2062 +++++++++++++++++ SOURCES/shadow-4.15.0-date-parsing.patch | 69 + .../shadow-4.15.0-getdef-spurious-error.patch | 137 ++ SOURCES/shadow-4.15.0-manfix.patch | 162 ++ SOURCES/shadow-4.15.0-sast-fixes.patch | 1413 +++++++++++ SOURCES/shadow-4.15.0.tar.xz.asc | 16 + SOURCES/shadow-bsd.txt | 32 + SOURCES/shadow-utils.HOME_MODE.xml | 43 + SOURCES/shadow-utils.login.defs | 315 +++ SOURCES/shadow-utils.useradd | 9 + SPECS/shadow-utils.spec | 1457 ++++++++++++ 16 files changed, 6441 insertions(+) create mode 100644 .gitignore create mode 100644 .shadow-utils.metadata create mode 100644 SOURCES/gpl-2.0.txt create mode 100644 SOURCES/passwd.pamd create mode 100644 SOURCES/shadow-4.15.0-account-tools-setuid.patch create mode 100644 SOURCES/shadow-4.15.0-audit-update.patch create mode 100644 SOURCES/shadow-4.15.0-date-parsing.patch create mode 100644 SOURCES/shadow-4.15.0-getdef-spurious-error.patch create mode 100644 SOURCES/shadow-4.15.0-manfix.patch create mode 100644 SOURCES/shadow-4.15.0-sast-fixes.patch create mode 100644 SOURCES/shadow-4.15.0.tar.xz.asc create mode 100644 SOURCES/shadow-bsd.txt create mode 100644 SOURCES/shadow-utils.HOME_MODE.xml create mode 100644 SOURCES/shadow-utils.login.defs create mode 100644 SOURCES/shadow-utils.useradd create mode 100644 SPECS/shadow-utils.spec diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7e77bce --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/shadow-4.15.0.tar.xz diff --git a/.shadow-utils.metadata b/.shadow-utils.metadata new file mode 100644 index 0000000..8cffb01 --- /dev/null +++ b/.shadow-utils.metadata @@ -0,0 +1 @@ +cb918a7412f5b57d268e3b1964111c9cdb84bb56 SOURCES/shadow-4.15.0.tar.xz diff --git a/SOURCES/gpl-2.0.txt b/SOURCES/gpl-2.0.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/SOURCES/gpl-2.0.txt @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/SOURCES/passwd.pamd b/SOURCES/passwd.pamd new file mode 100644 index 0000000..fd03d03 --- /dev/null +++ b/SOURCES/passwd.pamd @@ -0,0 +1,5 @@ +#%PAM-1.0 +# This tool only uses the password stack. +password substack system-auth +-password optional pam_gnome_keyring.so use_authtok +password substack postlogin diff --git a/SOURCES/shadow-4.15.0-account-tools-setuid.patch b/SOURCES/shadow-4.15.0-account-tools-setuid.patch new file mode 100644 index 0000000..d162487 --- /dev/null +++ b/SOURCES/shadow-4.15.0-account-tools-setuid.patch @@ -0,0 +1,380 @@ +diff -up shadow-4.15.0/src/chpasswd.c.account-tools-setuid shadow-4.15.0/src/chpasswd.c +--- shadow-4.15.0/src/chpasswd.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/chpasswd.c 2024-03-11 11:21:57.561150382 +0100 +@@ -443,9 +443,11 @@ int main (int argc, char **argv) + char *cp; + const char *salt; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + bool use_pam = true; + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + int errors = 0; + int line = 0; +@@ -469,19 +471,23 @@ int main (int argc, char **argv) + process_root_flag ("-R", argc, argv); + prefix = process_prefix_flag ("-P", argc, argv); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (md5flg || eflg || cflg || prefix[0]) { + use_pam = false; + } + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + OPENLOG (Prog); + + check_perms (); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + is_shadow_pwd = spw_file_present (); + +@@ -543,6 +549,7 @@ int main (int argc, char **argv) + } + newpwd = cp; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (use_pam) { + if (do_pam_passwd_non_interactive (Prog, name, newpwd) != 0) { +@@ -553,6 +560,7 @@ int main (int argc, char **argv) + } + } else + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + const struct spwd *sp; + struct spwd newsp; +@@ -672,9 +680,11 @@ int main (int argc, char **argv) + * password database. + */ + if (0 != errors) { ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + fprintf (stderr, + _("%s: error detected, changes ignored\n"), +@@ -683,9 +693,11 @@ int main (int argc, char **argv) + fail_exit (1); + } + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + { + /* Save the changes */ + close_files (); +diff -up shadow-4.15.0/src/groupmems.c.account-tools-setuid shadow-4.15.0/src/groupmems.c +--- shadow-4.15.0/src/groupmems.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/groupmems.c 2024-03-11 11:16:18.365408572 +0100 +@@ -14,9 +14,11 @@ + #include + #include + #include ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + #include "pam_defs.h" + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + #include + + #include "alloc.h" +@@ -430,6 +432,7 @@ static void process_flags (int argc, cha + static void check_perms (void) + { + if (!list) { ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + pam_handle_t *pamh = NULL; + int retval; +@@ -463,7 +466,8 @@ static void check_perms (void) + fail_exit (1); + } + (void) pam_end (pamh, retval); +-#endif ++#endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + } + } + +diff -up shadow-4.15.0/src/newusers.c.account-tools-setuid shadow-4.15.0/src/newusers.c +--- shadow-4.15.0/src/newusers.c.account-tools-setuid 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.0/src/newusers.c 2024-03-11 11:20:07.198909046 +0100 +@@ -59,6 +59,7 @@ + static const char Prog[] = "newusers"; + + static bool rflg = false; /* create a system account */ ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + static /*@null@*//*@observer@*/char *crypt_method = NULL; + #define cflg (NULL != crypt_method) +@@ -75,6 +76,7 @@ static long bcrypt_rounds = 13; + static long yescrypt_cost = 5; + #endif /* USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + + static bool is_shadow; + #ifdef SHADOWGRP +@@ -97,9 +99,11 @@ NORETURN static void fail_exit (int); + static int add_group (const char *, const char *, gid_t *, gid_t); + static int get_user_id (const char *, uid_t *); + static int add_user (const char *, uid_t, gid_t); ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + static int update_passwd (struct passwd *, const char *); + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + static int add_passwd (struct passwd *, const char *); + static void process_flags (int argc, char **argv); + static void check_flags (void); +@@ -121,6 +125,7 @@ static void usage (int status) + "Options:\n"), + Prog); + (void) fputs (_(" -b, --badname allow bad names\n"), usageout); ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + (void) fprintf (usageout, + _(" -c, --crypt-method METHOD the crypt method (one of %s)\n"), +@@ -136,9 +141,11 @@ static void usage (int status) + #endif + ); + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); + (void) fputs (_(" -r, --system create system accounts\n"), usageout); + (void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout); ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + (void) fputs (_(" -s, --sha-rounds number of rounds for the SHA, BCRYPT\n" +@@ -146,6 +153,7 @@ static void usage (int status) + usageout); + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + (void) fputs ("\n", usageout); + + exit (status); +@@ -405,6 +413,7 @@ static int add_user (const char *name, u + return (pw_update (&pwent) == 0) ? -1 : 0; + } + ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + /* + * update_passwd - update the password in the passwd entry +@@ -457,6 +466,7 @@ static int update_passwd (struct passwd + return 0; + } + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + + /* + * add_passwd - add or update the encrypted password +@@ -465,10 +475,13 @@ static int add_passwd (struct passwd *pw + { + const struct spwd *sp; + struct spwd spent; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + char *cp; + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + void *crypt_arg = NULL; + if (NULL != crypt_method) { +@@ -505,13 +518,14 @@ static int add_passwd (struct passwd *pw + return update_passwd (pwd, password); + } + #endif /* USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + + /* + * Do the first and easiest shadow file case. The user already + * exists in the shadow password file. + */ + sp = spw_locate (pwd->pw_name); +-#ifndef USE_PAM ++#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) + if (NULL != sp) { + spent = *sp; + if ( (NULL != crypt_method) +@@ -547,7 +561,7 @@ static int add_passwd (struct passwd *pw + if (strcmp (pwd->pw_passwd, "x") != 0) { + return update_passwd (pwd, password); + } +-#else /* USE_PAM */ ++#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ + /* + * If there is already a shadow entry, do not touch it. + * If there is already a passwd entry with a password, do not +@@ -558,14 +572,14 @@ static int add_passwd (struct passwd *pw + || (strcmp (pwd->pw_passwd, "x") != 0)) { + return 0; + } +-#endif /* USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID && !USE_PAM */ + + /* + * Now the really hard case - I need to create an entirely new + * shadow password file entry. + */ + spent.sp_namp = pwd->pw_name; +-#ifndef USE_PAM ++#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) + if ((crypt_method != NULL) && (0 == strcmp(crypt_method, "NONE"))) { + spent.sp_pwdp = (char *)password; + } else { +@@ -610,35 +624,41 @@ static int add_passwd (struct passwd *pw + static void process_flags (int argc, char **argv) + { + int c; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + int bad_s; + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + static struct option long_options[] = { + {"badname", no_argument, NULL, 'b'}, ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + {"crypt-method", required_argument, NULL, 'c'}, + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + {"help", no_argument, NULL, 'h'}, + {"system", no_argument, NULL, 'r'}, + {"root", required_argument, NULL, 'R'}, ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + {"sha-rounds", required_argument, NULL, 's'}, + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + {NULL, 0, NULL, '\0'} + }; + + while ((c = getopt_long (argc, argv, +-#ifndef USE_PAM ++#if !defined(ACCT_TOOLS_SETUID) && !defined(USE_PAM) + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + "c:bhrs:", + #else /* !USE_SHA_CRYPT && !USE_BCRYPT && !USE_YESCRYPT */ + "c:bhr", + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ +-#else /* USE_PAM */ ++#else /* !ACCT_TOOLS_SETUID && !USE_PAM */ + "bhr", + #endif + long_options, NULL)) != -1) { +@@ -646,11 +666,13 @@ static void process_flags (int argc, cha + case 'b': + allow_bad_names = true; + break; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + case 'c': + crypt_method = optarg; + break; + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + case 'h': + usage (EXIT_SUCCESS); + break; +@@ -659,6 +681,7 @@ static void process_flags (int argc, cha + break; + case 'R': /* no-op, handled in process_root_flag () */ + break; ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + case 's': +@@ -698,6 +721,7 @@ static void process_flags (int argc, cha + break; + #endif /* USE_SHA_CRYPT || USE_BCRYPT || USE_YESCRYPT */ + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + default: + usage (EXIT_FAILURE); + break; +@@ -730,6 +754,7 @@ static void process_flags (int argc, cha + */ + static void check_flags (void) + { ++#ifndef ACCT_TOOLS_SETUID + #ifndef USE_PAM + #if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) || defined(USE_YESCRYPT) + if (sflg && !cflg) { +@@ -762,6 +787,7 @@ static void check_flags (void) + } + } + #endif /* !USE_PAM */ ++#endif /* !ACCT_TOOLS_SETUID */ + } + + /* +@@ -1052,12 +1078,14 @@ int main (int argc, char **argv) + int line = 0; + uid_t uid; + gid_t gid; ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + int *lines = NULL; + char **usernames = NULL; + char **passwords = NULL; + unsigned int nusers = 0; + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + log_set_progname(Prog); + log_set_logfd(stderr); +@@ -1195,6 +1223,7 @@ int main (int argc, char **argv) + } + newpw = *pw; + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + /* keep the list of user/password for later update by PAM */ + nusers++; +@@ -1211,6 +1240,7 @@ int main (int argc, char **argv) + usernames[nusers-1] = strdup (fields[0]); + passwords[nusers-1] = strdup (fields[1]); + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + if (add_passwd (&newpw, fields[1]) != 0) { + fprintf (stderr, + _("%s: line %d: can't update password\n"), +@@ -1327,6 +1357,7 @@ int main (int argc, char **argv) + nscd_flush_cache ("group"); + sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); + ++#ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + unsigned int i; + /* Now update the passwords using PAM */ +@@ -1339,6 +1370,7 @@ int main (int argc, char **argv) + } + } + #endif /* USE_PAM */ ++#endif /* ACCT_TOOLS_SETUID */ + + exit (EXIT_SUCCESS); + } diff --git a/SOURCES/shadow-4.15.0-audit-update.patch b/SOURCES/shadow-4.15.0-audit-update.patch new file mode 100644 index 0000000..a738d60 --- /dev/null +++ b/SOURCES/shadow-4.15.0-audit-update.patch @@ -0,0 +1,2062 @@ +diff -up shadow-4.15.1/lib/audit_help.c.audit-update shadow-4.15.1/lib/audit_help.c +--- shadow-4.15.1/lib/audit_help.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/audit_help.c 2024-05-20 11:52:05.639758532 +0200 +@@ -48,7 +48,7 @@ void audit_help_open (void) + * This function will log a message to the audit system using a predefined + * message format. Parameter usage is as follows: + * +- * type - type of message: AUDIT_USER_CHAUTHTOK for changing any account ++ * type - type of message: AUDIT_USER_MGMT for changing any account + * attributes. + * pgname - program's name + * op - operation. "adding user", "changing finger info", "deleting group" +@@ -68,6 +68,39 @@ void audit_logger (int type, MAYBE_UNUSE + } + } + ++/* ++ * This function will log a message to the audit system using a predefined ++ * message format. Parameter usage is as follows: ++ * ++ * type - type of message: AUDIT_USER_MGMT for changing any account ++ * attributes. ++ * pgname - program's name ++ * op - operation. "adding user", "changing finger info", "deleting group" ++ * name - user's account or group name. If not available use NULL. ++ * id - uid or gid that the operation is being performed on. This is used ++ * only when user is NULL. ++ * grp - group name associated with event ++ */ ++void audit_logger_with_group (int type, MAYBE_UNUSED const char *pgname, ++ const char *op, const char *name, unsigned int id, ++ const char *grp, shadow_audit_result result) ++{ ++ int len; ++ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1], buf[1024]; ++ if (audit_fd < 0) { ++ return; ++ } ++ len = strnlen(grp, sizeof(enc_group)/2); ++ if (audit_value_needs_encoding(grp, len)) { ++ snprintf(buf, sizeof(buf), "%s grp=%s", op, ++ audit_encode_value(enc_group, grp, len)); ++ } else { ++ snprintf(buf, sizeof(buf), "%s grp=\"%s\"", op, grp); ++ } ++ audit_log_acct_message (audit_fd, type, NULL, buf, name, id, ++ NULL, NULL, NULL, (int) result); ++} ++ + void audit_logger_message (const char *message, shadow_audit_result result) + { + if (audit_fd < 0) { +diff -up shadow-4.15.1/lib/cleanup_group.c.audit-update shadow-4.15.1/lib/cleanup_group.c +--- shadow-4.15.1/lib/cleanup_group.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/cleanup_group.c 2024-05-20 11:52:05.639758532 +0200 +@@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cle + gr_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, log_get_progname(), ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -80,7 +80,7 @@ void cleanup_report_mod_gshadow (void *c + sgr_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, log_get_progname(), ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -101,7 +101,7 @@ void cleanup_report_add_group_group (voi + SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_GROUP, log_get_progname(), +- "adding group to /etc/group", ++ "adding-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -120,8 +120,8 @@ void cleanup_report_add_group_gshadow (v + + SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), +- "adding group to /etc/gshadow", ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), ++ "adding-shadow-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -143,8 +143,8 @@ void cleanup_report_del_group_group (voi + "failed to remove group %s from %s", + name, gr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), +- "removing group from /etc/group", ++ audit_logger (AUDIT_DEL_GROUP, log_get_progname(), ++ "removing-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -166,8 +166,8 @@ void cleanup_report_del_group_gshadow (v + "failed to remove group %s from %s", + name, sgr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, log_get_progname(), +- "removing group from /etc/gshadow", ++ audit_logger (AUDIT_GRP_MGMT, log_get_progname(), ++ "removing-shadow-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -187,7 +187,7 @@ void cleanup_unlock_group (MAYBE_UNUSED + log_get_progname(), gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger_message ("unlocking group file", ++ audit_logger_message ("unlocking-group", + SHADOW_AUDIT_FAILURE); + #endif + } +@@ -207,7 +207,7 @@ void cleanup_unlock_gshadow (MAYBE_UNUSE + log_get_progname(), sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + #ifdef WITH_AUDIT +- audit_logger_message ("unlocking gshadow file", ++ audit_logger_message ("unlocking-gshadow", + SHADOW_AUDIT_FAILURE); + #endif + } +diff -up shadow-4.15.1/lib/cleanup_user.c.audit-update shadow-4.15.1/lib/cleanup_user.c +--- shadow-4.15.1/lib/cleanup_user.c.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/cleanup_user.c 2024-05-20 11:52:05.639758532 +0200 +@@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cl + pw_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, log_get_progname(), ++ audit_logger (AUDIT_USER_MGMT, log_get_progname(), + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -65,7 +65,7 @@ void cleanup_report_add_user_passwd (voi + SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, log_get_progname(), +- "adding user to /etc/passwd", ++ "adding-user", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -84,8 +84,8 @@ void cleanup_report_add_user_shadow (voi + + SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ())); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, log_get_progname(), +- "adding user to /etc/shadow", ++ audit_logger (AUDIT_USER_MGMT, log_get_progname(), ++ "adding-shadow-user", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -104,7 +104,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED + log_get_progname(), pw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + #ifdef WITH_AUDIT +- audit_logger_message ("unlocking passwd file", ++ audit_logger_message ("unlocking-passwd", + SHADOW_AUDIT_FAILURE); + #endif + } +@@ -123,7 +123,7 @@ void cleanup_unlock_shadow (MAYBE_UNUSED + log_get_progname(), spw_dbname ()); + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + #ifdef WITH_AUDIT +- audit_logger_message ("unlocking shadow file", ++ audit_logger_message ("unlocking-shadow", + SHADOW_AUDIT_FAILURE); + #endif + } +diff -up shadow-4.15.1/lib/prototypes.h.audit-update shadow-4.15.1/lib/prototypes.h +--- shadow-4.15.1/lib/prototypes.h.audit-update 2024-03-01 02:50:52.000000000 +0100 ++++ shadow-4.15.1/lib/prototypes.h 2024-05-20 11:52:05.639758532 +0200 +@@ -198,12 +198,21 @@ extern int audit_fd; + extern void audit_help_open (void); + /* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */ + #define AUDIT_NO_ID ((unsigned int) -1) ++#ifndef AUDIT_GRP_MGMT ++#define AUDIT_GRP_MGMT 1132 /* Group account was modified */ ++#endif ++#ifndef AUDIT_GRP_CHAUTHTOK ++#define AUDIT_GRP_CHAUTHTOK 1133 /* Group account password was changed */ ++#endif + typedef enum { + SHADOW_AUDIT_FAILURE = 0, + SHADOW_AUDIT_SUCCESS = 1} shadow_audit_result; + extern void audit_logger (int type, const char *pgname, const char *op, + const char *name, unsigned int id, + shadow_audit_result result); ++void audit_logger_with_group (int type, MAYBE_UNUSED const char *pgname, ++ const char *op, const char *name, unsigned int id, ++ const char *grp, shadow_audit_result result); + void audit_logger_message (const char *message, shadow_audit_result result); + #endif + +diff -up shadow-4.15.1/src/chage.c.audit-update shadow-4.15.1/src/chage.c +--- shadow-4.15.1/src/chage.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/chage.c 2024-05-20 11:52:05.639758532 +0200 +@@ -110,8 +110,8 @@ fail_exit (int code) + + #ifdef WITH_AUDIT + if (E_SUCCESS != code) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change age", user_name, user_uid, 0); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-age", user_name, user_uid, SHADOW_AUDIT_FAILURE); + } + #endif + +@@ -846,10 +846,7 @@ int main (int argc, char **argv) + fprintf (stderr, _("%s: Permission denied.\n"), Prog); + fail_exit (E_NOPERM); + } +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "display aging info", user_name, user_uid, 1); +-#endif ++ /* Displaying fields is not of interest to audit */ + list_fields (); + fail_exit (E_SUCCESS); + } +@@ -868,39 +865,39 @@ int main (int argc, char **argv) + } + #ifdef WITH_AUDIT + else { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change all aging information", +- user_name, user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-all-aging-information", ++ user_name, user_uid, SHADOW_AUDIT_SUCCESS); + } + #endif + } else { + #ifdef WITH_AUDIT + if (Mflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change max age", user_name, user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-max-age", user_name, user_uid, SHADOW_AUDIT_SUCCESS); + } + if (mflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change min age", user_name, user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-min-age", user_name, user_uid, 1); + } + if (dflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change last change date", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-last-change-date", + user_name, user_uid, 1); + } + if (Wflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change passwd warning", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-passwd-warning", + user_name, user_uid, 1); + } + if (Iflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change inactive days", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-inactive-days", + user_name, user_uid, 1); + } + if (Eflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change passwd expiration", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-passwd-expiration", + user_name, user_uid, 1); + } + #endif +diff -up shadow-4.15.1/src/gpasswd.c.audit-update shadow-4.15.1/src/gpasswd.c +--- shadow-4.15.1/src/gpasswd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/gpasswd.c 2024-05-20 11:52:05.640758536 +0200 +@@ -125,7 +125,7 @@ static void usage (int status) + (void) fputs (_(" -d, --delete USER remove USER from GROUP\n"), usageout); + (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); + (void) fputs (_(" -Q, --root CHROOT_DIR directory to chroot into\n"), usageout); +- (void) fputs (_(" -r, --remove-password remove the GROUP's password\n"), usageout); ++ (void) fputs (_(" -r, --delete-password remove the GROUP's password\n"), usageout); + (void) fputs (_(" -R, --restrict restrict access to GROUP to its members\n"), usageout); + (void) fputs (_(" -M, --members USER,... set the list of members of GROUP\n"), usageout); + #ifdef SHADOWGRP +@@ -384,20 +384,14 @@ static void open_files (void) + + static void log_gpasswd_failure (const char *suffix) + { +-#ifdef WITH_AUDIT +- char buf[1024]; +-#endif +- + if (aflg) { + SYSLOG ((LOG_ERR, + "%s failed to add user %s to group %s%s", + myname, user, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to add user %s to group %s%s", +- myname, user, group, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-group", ++ user, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } else if (dflg) { +@@ -405,11 +399,9 @@ static void log_gpasswd_failure (const c + "%s failed to remove user %s from group %s%s", + myname, user, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to remove user %s from group %s%s", +- myname, user, group, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "delete-user-from-group", ++ user, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } else if (rflg) { +@@ -417,11 +409,9 @@ static void log_gpasswd_failure (const c + "%s failed to remove password of group %s%s", + myname, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to remove password of group %s%s", +- myname, group, suffix); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, ++ "delete-group-password", ++ myname, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } else if (Rflg) { +@@ -429,11 +419,9 @@ static void log_gpasswd_failure (const c + "%s failed to restrict access to group %s%s", + myname, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to restrict access to group %s%s", +- myname, group, suffix); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "restrict-group", ++ myname, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } else if (Aflg || Mflg) { +@@ -443,11 +431,9 @@ static void log_gpasswd_failure (const c + "%s failed to set the administrators of group %s to %s%s", + myname, group, admins, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to set the administrators of group %s to %s%s", +- myname, group, admins, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "set-admins-of-group", ++ admins, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } +@@ -457,11 +443,9 @@ static void log_gpasswd_failure (const c + "%s failed to set the members of group %s to %s%s", + myname, group, members, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to set the members of group %s to %s%s", +- myname, group, members, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-users-to-group", ++ members, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } +@@ -470,11 +454,9 @@ static void log_gpasswd_failure (const c + "%s failed to change password of group %s%s", + myname, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "%s failed to change password of group %s%s", +- myname, group, suffix); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, ++ "change-password", ++ myname, AUDIT_NO_ID, group, + SHADOW_AUDIT_FAILURE); + #endif + } +@@ -514,11 +496,9 @@ static void log_gpasswd_success (const c + "user %s added by %s to group %s%s", + user, myname, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "user %s added by %s to group %s%s", +- user, myname, group, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-group", ++ user, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } else if (dflg) { +@@ -526,11 +506,9 @@ static void log_gpasswd_success (const c + "user %s removed by %s from group %s%s", + user, myname, group, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "user %s removed by %s from group %s%s", +- user, myname, group, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "delete-user-from-group", ++ user, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } else if (rflg) { +@@ -540,9 +518,9 @@ static void log_gpasswd_success (const c + #ifdef WITH_AUDIT + SNPRINTF(buf, "password of group %s removed by %s%s", + group, myname, suffix); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, ++ "delete-group-password", ++ myname, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } else if (Rflg) { +@@ -552,9 +530,9 @@ static void log_gpasswd_success (const c + #ifdef WITH_AUDIT + SNPRINTF(buf, "access to group %s restricted by %s%s", + group, myname, suffix); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "restrict-group", ++ myname, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } else if (Aflg || Mflg) { +@@ -564,11 +542,9 @@ static void log_gpasswd_success (const c + "administrators of group %s set by %s to %s%s", + group, myname, admins, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "administrators of group %s set by %s to %s%s", +- group, myname, admins, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "set-admins-of-group", ++ admins, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } +@@ -578,11 +554,9 @@ static void log_gpasswd_success (const c + "members of group %s set by %s to %s%s", + group, myname, members, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "members of group %s set by %s to %s%s", +- group, myname, members, suffix); +- audit_logger (AUDIT_USER_ACCT, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-users-to-group", ++ members, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } +@@ -591,11 +565,9 @@ static void log_gpasswd_success (const c + "password of group %s changed by %s%s", + group, myname, suffix)); + #ifdef WITH_AUDIT +- SNPRINTF(buf, "password of group %s changed by %s%s", +- group, myname, suffix); +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- buf, +- group, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, ++ "change-password", ++ myname, AUDIT_NO_ID, group, + SHADOW_AUDIT_SUCCESS); + #endif + } +diff -up shadow-4.15.1/src/groupadd.c.audit-update shadow-4.15.1/src/groupadd.c +--- shadow-4.15.1/src/groupadd.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/groupadd.c 2024-05-20 11:52:05.640758536 +0200 +@@ -115,6 +115,15 @@ usage (int status) + exit (status); + } + ++static void fail_exit(int status) ++{ ++#ifdef WITH_AUDIT ++ audit_logger(AUDIT_ADD_GROUP, Prog, "add-group", group_name, ++ AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); ++#endif ++ exit (status); ++} ++ + /* + * new_grent - initialize the values in a group file entry + * +@@ -211,7 +220,7 @@ static void grp_update (void) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), grp.gr_name); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + #ifdef SHADOWGRP + /* +@@ -221,7 +230,7 @@ static void grp_update (void) + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), sgrp.sg_name); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + #endif /* SHADOWGRP */ + } +@@ -245,7 +254,7 @@ static void check_new_name (void) + fprintf (stderr, _("%s: '%s' is not a valid group name\n"), + Prog, group_name); + +- exit (E_BAD_ARG); ++ fail_exit (E_BAD_ARG); + } + + /* +@@ -261,11 +270,11 @@ static void close_files (void) + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_GROUP, Prog, +- "adding group to /etc/group", ++ "add-group", + group_name, group_id, SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, "group added to %s: name=%s, GID=%u", +@@ -282,11 +291,11 @@ static void close_files (void) + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, Prog, +- "adding group to /etc/gshadow", ++ audit_logger (AUDIT_GRP_MGMT, Prog, ++ "add-shadow-group", + group_name, group_id, SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, "group added to %s: name=%s", +@@ -299,10 +308,6 @@ static void close_files (void) + #endif /* SHADOWGRP */ + + /* Report success at the system level */ +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_GROUP, Prog, +- "", group_name, group_id, SHADOW_AUDIT_SUCCESS); +-#endif + SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", + group_name, (unsigned int) group_id)); + del_cleanup (cleanup_report_add_group); +@@ -320,7 +325,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + add_cleanup (cleanup_unlock_group, NULL); + +@@ -330,7 +335,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + add_cleanup (cleanup_unlock_gshadow, NULL); + } +@@ -346,7 +351,7 @@ static void open_files (void) + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s: %s\n"), Prog, gr_dbname (), strerror(errno)); + SYSLOG ((LOG_WARN, "cannot open %s: %s", gr_dbname (), strerror(errno))); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + + #ifdef SHADOWGRP +@@ -356,7 +361,7 @@ static void open_files (void) + _("%s: cannot open %s: %s\n"), + Prog, sgr_dbname (), strerror(errno)); + SYSLOG ((LOG_WARN, "cannot open %s: %s", sgr_dbname (), strerror(errno))); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + } + #endif /* SHADOWGRP */ +@@ -493,7 +498,7 @@ static void check_flags (void) + fprintf (stderr, + _("%s: group '%s' already exists\n"), + Prog, group_name); +- exit (E_NAME_IN_USE); ++ fail_exit (E_NAME_IN_USE); + } + + if (gflg && (prefix_getgrgid (group_id) != NULL)) { +@@ -512,7 +517,7 @@ static void check_flags (void) + fprintf (stderr, + _("%s: GID '%lu' already exists\n"), + Prog, (unsigned long) group_id); +- exit (E_GID_IN_USE); ++ fail_exit (E_GID_IN_USE); + } + } + } +@@ -540,7 +545,7 @@ static void check_perms (void) + fprintf (stderr, + _("%s: Cannot determine your user name.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); +@@ -560,7 +565,7 @@ static void check_perms (void) + if (NULL != pamh) { + (void) pam_end (pamh, retval); + } +- exit (1); ++ fail_exit (1); + } + (void) pam_end (pamh, retval); + #endif /* USE_PAM */ +@@ -591,7 +596,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Cannot setup cleanup service.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + /* +@@ -618,7 +623,7 @@ int main (int argc, char **argv) + + if (!gflg) { + if (find_new_gid (rflg, &group_id, NULL) < 0) { +- exit (E_GID_IN_USE); ++ fail_exit (E_GID_IN_USE); + } + } + +diff -up shadow-4.15.1/src/groupdel.c.audit-update shadow-4.15.1/src/groupdel.c +--- shadow-4.15.1/src/groupdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/groupdel.c 2024-05-20 11:52:05.640758536 +0200 +@@ -87,6 +87,15 @@ usage (int status) + exit (status); + } + ++static void fail_exit(int status) ++{ ++#ifdef WITH_AUDIT ++ audit_logger(AUDIT_GRP_MGMT, Prog, "delete-group", group_name, ++ AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); ++#endif ++ exit (status); ++} ++ + /* + * grp_update - update group file entries + * +@@ -113,7 +122,7 @@ static void grp_update (void) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, group_name, gr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + + #ifdef SHADOWGRP +@@ -125,7 +134,7 @@ static void grp_update (void) + fprintf (stderr, + _("%s: cannot remove entry '%s' from %s\n"), + Prog, group_name, sgr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + } + #endif /* SHADOWGRP */ +@@ -144,12 +153,12 @@ static void close_files (void) + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, gr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_GROUP, Prog, +- "removing group from /etc/group", ++ "delete-group", + group_name, group_id, SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, +@@ -168,12 +177,12 @@ static void close_files (void) + fprintf (stderr, + _("%s: failure while writing changes to %s\n"), + Prog, sgr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_GROUP, Prog, +- "removing group from /etc/gshadow", ++ audit_logger (AUDIT_GRP_MGMT, Prog, ++ "delete-shadow-group", + group_name, group_id, SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, +@@ -186,11 +195,6 @@ static void close_files (void) + } + #endif /* SHADOWGRP */ + +- /* Report success at the system level */ +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_GROUP, Prog, +- "", group_name, group_id, SHADOW_AUDIT_SUCCESS); +-#endif + SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name)); + del_cleanup (cleanup_report_del_group); + } +@@ -207,7 +211,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + add_cleanup (cleanup_unlock_group, NULL); + #ifdef SHADOWGRP +@@ -216,7 +220,7 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + add_cleanup (cleanup_unlock_gshadow, NULL); + } +@@ -234,7 +238,7 @@ static void open_files (void) + _("%s: cannot open %s\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", gr_dbname ())); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + #ifdef SHADOWGRP + if (is_shadow_grp) { +@@ -243,7 +247,7 @@ static void open_files (void) + _("%s: cannot open %s\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_WARN, "cannot open %s", sgr_dbname ())); +- exit (E_GRP_UPDATE); ++ fail_exit (E_GRP_UPDATE); + } + } + #endif /* SHADOWGRP */ +@@ -284,7 +288,7 @@ static void group_busy (gid_t gid) + fprintf (stderr, + _("%s: cannot remove the primary group of user '%s'\n"), + Prog, pwd->pw_name); +- exit (E_GROUP_BUSY); ++ fail_exit (E_GROUP_BUSY); + } + + /* +@@ -368,7 +372,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Cannot setup cleanup service.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + process_flags (argc, argv); +@@ -382,7 +386,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Cannot determine your user name.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + retval = pam_start (Prog, pampw->pw_name, &conv, &pamh); +@@ -403,7 +407,7 @@ int main (int argc, char **argv) + if (NULL != pamh) { + (void) pam_end (pamh, retval); + } +- exit (1); ++ fail_exit (1); + } + (void) pam_end (pamh, retval); + #endif /* USE_PAM */ +@@ -423,7 +427,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: group '%s' does not exist\n"), + Prog, group_name); +- exit (E_NOTFOUND); ++ fail_exit (E_NOTFOUND); + } + + group_id = grp->gr_gid; +@@ -447,7 +451,7 @@ int main (int argc, char **argv) + _("%s: %s is the NIS master\n"), + Prog, nis_master); + } +- exit (E_NOTFOUND); ++ fail_exit (E_NOTFOUND); + } + #endif + +diff -up shadow-4.15.1/src/groupmod.c.audit-update shadow-4.15.1/src/groupmod.c +--- shadow-4.15.1/src/groupmod.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/groupmod.c 2024-05-20 11:52:05.640758536 +0200 +@@ -474,7 +474,7 @@ static void close_files (void) + exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, Prog, + info_group.audit_msg, + group_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); +@@ -497,7 +497,14 @@ static void close_files (void) + exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, ++ /* If both happened, log password change as its more important */ ++ if (pflg) ++ audit_logger (AUDIT_GRP_CHAUTHTOK, Prog, ++ info_gshadow.audit_msg, ++ group_name, AUDIT_NO_ID, ++ SHADOW_AUDIT_SUCCESS); ++ else ++ audit_logger (AUDIT_GRP_MGMT, Prog, + info_gshadow.audit_msg, + group_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); +@@ -520,7 +527,7 @@ static void close_files (void) + exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, Prog, + info_passwd.audit_msg, + group_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); +@@ -535,8 +542,8 @@ static void close_files (void) + } + + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, +- "modifying group", ++ audit_logger (AUDIT_GRP_MGMT, Prog, ++ "modify-group", + group_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); + #endif +diff -up shadow-4.15.1/src/newgrp.c.audit-update shadow-4.15.1/src/newgrp.c +--- shadow-4.15.1/src/newgrp.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/newgrp.c 2024-05-20 11:52:05.640758536 +0200 +@@ -188,10 +188,10 @@ static void check_perms (const struct gr + if (grp->gr_passwd[0] == '\0' || + strcmp (cpasswd, grp->gr_passwd) != 0) { + #ifdef WITH_AUDIT +- SNPRINTF(audit_buf, "authentication new-gid=%lu", ++ SNPRINTF(audit_buf, "authentication new_gid=%lu", + (unsigned long) grp->gr_gid); + audit_logger (AUDIT_GRP_AUTH, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + #endif + SYSLOG ((LOG_INFO, + "Invalid password for group '%s' from '%s'", +@@ -201,10 +201,10 @@ static void check_perms (const struct gr + goto failure; + } + #ifdef WITH_AUDIT +- SNPRINTF(audit_buf, "authentication new-gid=%lu", ++ SNPRINTF(audit_buf, "authentication new_gid=%lu", + (unsigned long) grp->gr_gid); + audit_logger (AUDIT_GRP_AUTH, Prog, +- audit_buf, NULL, getuid (), 1); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); + #endif + } + +@@ -215,16 +215,6 @@ failure: + * harm. -- JWP + */ + closelog (); +-#ifdef WITH_AUDIT +- if (groupname) { +- SNPRINTF(audit_buf, "changing new-group=%s", groupname); +- audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); +- } else { +- audit_logger (AUDIT_CHGRP_ID, Prog, +- "changing", NULL, getuid (), 0); +- } +-#endif + exit (EXIT_FAILURE); + } + +@@ -298,13 +288,23 @@ static void syslog_sg (const char *name, + is_newgrp ? "newgrp" : "sg", strerror (errno)); + #ifdef WITH_AUDIT + if (group) { +- SNPRINTF(audit_buf, +- "changing new-group=%s", group); ++ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; ++ int len = strnlen(group, sizeof(enc_group)/2); ++ if (audit_value_needs_encoding(group, len)) { ++ snprintf (audit_buf, sizeof(audit_buf), ++ "changing new_group=%s", ++ audit_encode_value(enc_group, ++ group, len)); ++ } else { ++ snprintf (audit_buf, sizeof(audit_buf), ++ "changing new_group=\"%s\"", ++ group); ++ } + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + } else { + audit_logger (AUDIT_CHGRP_ID, Prog, +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); + } + #endif + exit (EXIT_FAILURE); +@@ -440,7 +440,7 @@ int main (int argc, char **argv) + Prog); + #ifdef WITH_AUDIT + audit_logger (AUDIT_CHGRP_ID, Prog, +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); + #endif + SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", + (unsigned long) getuid ())); +@@ -556,12 +556,22 @@ int main (int argc, char **argv) + perror ("getgroups"); + #ifdef WITH_AUDIT + if (group) { +- SNPRINTF(audit_buf, "changing new-group=%s", group); ++ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; ++ int len = strnlen(group, sizeof(enc_group)/2); ++ if (audit_value_needs_encoding(group, len)) { ++ snprintf (audit_buf, sizeof(audit_buf), ++ "changing new_group=%s", ++ audit_encode_value(enc_group, ++ group, len)); ++ } else { ++ snprintf (audit_buf, sizeof(audit_buf), ++ "changing new_group=\"%s\"", group); ++ } + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + } else { + audit_logger (AUDIT_CHGRP_ID, Prog, +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); + } + #endif + exit (EXIT_FAILURE); +@@ -715,9 +725,9 @@ int main (int argc, char **argv) + if (setgid (gid) != 0) { + perror ("setgid"); + #ifdef WITH_AUDIT +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + #endif + exit (EXIT_FAILURE); + } +@@ -725,9 +735,9 @@ int main (int argc, char **argv) + if (setuid (getuid ()) != 0) { + perror ("setuid"); + #ifdef WITH_AUDIT +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + #endif + exit (EXIT_FAILURE); + } +@@ -740,9 +750,9 @@ int main (int argc, char **argv) + closelog (); + execl (SHELL, "sh", "-c", command, (char *) NULL); + #ifdef WITH_AUDIT +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + #endif + perror (SHELL); + exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); +@@ -806,9 +816,9 @@ int main (int argc, char **argv) + } + + #ifdef WITH_AUDIT +- SNPRINTF(audit_buf, "changing new-gid=%lu", (unsigned long) gid); ++ SNPRINTF(audit_buf, "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 1); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_SUCCESS); + #endif + /* + * Exec the login shell and go away. We are trying to get back to +@@ -832,12 +842,22 @@ int main (int argc, char **argv) + closelog (); + #ifdef WITH_AUDIT + if (NULL != group) { +- SNPRINTF(audit_buf, "changing new-group=%s", group); ++ char enc_group[(GROUP_NAME_MAX_LENGTH*2)+1]; ++ int len = strnlen(group, sizeof(enc_group)/2); ++ if (audit_value_needs_encoding(group, len)) { ++ snprintf (audit_buf, sizeof(audit_buf), ++ "changing new_group=%s", ++ audit_encode_value(enc_group, ++ group, len)); ++ } else { ++ snprintf (audit_buf, sizeof(audit_buf), ++ "changing new_group=\"%s\"", group); ++ } + audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, getuid (), 0); ++ audit_buf, NULL, getuid (), SHADOW_AUDIT_FAILURE); + } else { + audit_logger (AUDIT_CHGRP_ID, Prog, +- "changing", NULL, getuid (), 0); ++ "changing", NULL, getuid (), SHADOW_AUDIT_FAILURE); + } + #endif + exit (EXIT_FAILURE); +diff -up shadow-4.15.1/src/useradd.c.audit-update shadow-4.15.1/src/useradd.c +--- shadow-4.15.1/src/useradd.c.audit-update 2024-05-20 11:52:05.635758519 +0200 ++++ shadow-4.15.1/src/useradd.c 2024-05-20 11:52:05.640758536 +0200 +@@ -245,6 +245,8 @@ static FILE *fmkstemp(char *template); + */ + static void fail_exit (int code) + { ++ int type; ++ + if (home_added && rmdir(prefix_user_home) != 0) { + fprintf(stderr, + _("%s: %s was created, but could not be removed\n"), +@@ -255,38 +257,22 @@ static void fail_exit (int code) + if (spw_locked && spw_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", spw_dbname())); +-#ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking shadow file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-#endif + /* continue */ + } + if (pw_locked && pw_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, pw_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", pw_dbname())); +-#ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking passwd file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-#endif + /* continue */ + } + if (gr_locked && gr_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, gr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", gr_dbname())); +-#ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking group file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-#endif + /* continue */ + } + #ifdef SHADOWGRP + if (sgr_locked && sgr_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sgr_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sgr_dbname())); +-# ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "unlocking gshadow file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-# endif + /* continue */ + } + #endif +@@ -294,27 +280,23 @@ static void fail_exit (int code) + if (sub_uid_locked && sub_uid_unlock() == 0) { + fprintf(stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname()); + SYSLOG((LOG_ERR, "failed to unlock %s", sub_uid_dbname())); +-# ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, +- "unlocking subordinate user file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-# endif + /* continue */ + } + if (sub_gid_locked && sub_gid_unlock() == 0) { + fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname()); + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname())); +-# ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, +- "unlocking subordinate group file", +- user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); +-# endif + /* continue */ + } + #endif /* ENABLE_SUBIDS */ + + #ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "adding user", ++ if (code == E_PW_UPDATE || code >= E_GRP_UPDATE) ++ type = AUDIT_USER_MGMT; ++ else ++ type = AUDIT_ADD_USER; ++ ++ audit_logger (type, Prog, ++ "add-user", + user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); + #endif + SYSLOG((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); +@@ -727,7 +709,7 @@ static int set_defaults (void) + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USYS_CONFIG, Prog, +- "changing useradd defaults", ++ "changing-useradd-defaults", + NULL, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -1056,12 +1038,6 @@ static void grp_update (void) + _("%s: Out of memory. Cannot update %s.\n"), + Prog, gr_dbname ()); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_GRP_UPDATE); /* XXX */ + } + +@@ -1075,18 +1051,12 @@ static void grp_update (void) + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, gr_dbname (), ngrp->gr_name); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", gr_dbname (), user_name)); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-group", ++ user_name, AUDIT_NO_ID, ngrp->gr_name, + SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, +@@ -1131,12 +1101,6 @@ static void grp_update (void) + _("%s: Out of memory. Cannot update %s.\n"), + Prog, sgr_dbname ()); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user to shadow group", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_GRP_UPDATE); /* XXX */ + } + +@@ -1150,18 +1114,13 @@ static void grp_update (void) + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, sgr_dbname (), nsgrp->sg_name); + SYSLOG ((LOG_ERR, "failed to prepare the new %s entry '%s'", sgr_dbname (), user_name)); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user to shadow group", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif ++ + fail_exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user to shadow group", +- user_name, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-to-shadow-group", ++ user_name, AUDIT_NO_ID, nsgrp->sg_name, + SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, +@@ -1556,7 +1515,7 @@ static void process_flags (int argc, cha + Prog, user_name); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "adding user", ++ "add-user", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1656,7 +1615,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking shadow file", ++ "unlocking-shadow-file", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1669,7 +1628,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking passwd file", ++ "unlocking-passwd-file", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1686,7 +1645,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking subordinate user file", ++ "unlocking-subordinate-user-file", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1700,7 +1659,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking subordinate group file", ++ "unlocking-subordinate-group-file", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1963,7 +1922,7 @@ static void grp_add (void) + Prog, gr_dbname (), grp.gr_name); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_GROUP, Prog, +- "adding group", ++ "add-group", + grp.gr_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1979,7 +1938,7 @@ static void grp_add (void) + Prog, sgr_dbname (), sgrp.sg_name); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_GROUP, Prog, +- "adding group", ++ "add-group", + grp.gr_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1989,7 +1948,7 @@ static void grp_add (void) + SYSLOG ((LOG_INFO, "new group: name=%s, GID=%u", user_name, user_gid)); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_GROUP, Prog, +- "adding group", ++ "add-group", + grp.gr_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -2191,11 +2150,6 @@ static void usr_update (unsigned long su + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), + Prog, spw_dbname (), spent.sp_namp); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding shadow password", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_PW_UPDATE); + } + #ifdef ENABLE_SUBIDS +@@ -2222,7 +2176,7 @@ static void usr_update (unsigned long su + * and we can use the real ID thereafter. + */ + audit_logger (AUDIT_ADD_USER, Prog, +- "adding user", ++ "add-user", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -2317,10 +2271,6 @@ static void create_home (void) + if (mkdir(path, 0) != 0) { + fprintf(stderr, _("%s: cannot create directory %s\n"), + Prog, path); +-#ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "adding home directory", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif + fail_exit(E_HOMEDIR); + } + if (chown(path, 0, 0) < 0) { +@@ -2345,7 +2295,7 @@ static void create_home (void) + } + home_added = true; + #ifdef WITH_AUDIT +- audit_logger(AUDIT_ADD_USER, Prog, "adding home directory", ++ audit_logger(AUDIT_USER_MGMT, Prog, "add-home-dir", + user_name, user_id, SHADOW_AUDIT_SUCCESS); + #endif + #ifdef WITH_SELINUX +@@ -2586,12 +2536,6 @@ int main (int argc, char **argv) + */ + if (prefix_getpwnam (user_name) != NULL) { /* local, no need for xgetpwnam */ + fprintf (stderr, _("%s: user '%s' already exists\n"), Prog, user_name); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_NAME_IN_USE); + } + +@@ -2607,12 +2551,6 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: group %s exists - if you want to add this user to that group, use -g.\n"), + Prog, user_name); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding group", +- user_name, AUDIT_NO_ID, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_NAME_IN_USE); + } + } +@@ -2642,12 +2580,6 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: UID %lu is not unique\n"), + Prog, (unsigned long) user_id); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding user", +- user_name, user_id, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_UID_IN_USE); + } + } +@@ -2722,9 +2654,9 @@ int main (int argc, char **argv) + _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), + Prog, user_name, user_selinux); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding SELinux user mapping", +- user_name, user_id, 0); ++ audit_logger (AUDIT_ROLE_ASSIGN, Prog, ++ "add-selinux-user-mapping", ++ user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + fail_exit (E_SE_UPDATE); + } +diff -up shadow-4.15.1/src/userdel.c.audit-update shadow-4.15.1/src/userdel.c +--- shadow-4.15.1/src/userdel.c.audit-update 2024-03-08 22:27:04.000000000 +0100 ++++ shadow-4.15.1/src/userdel.c 2024-05-20 11:52:05.641758539 +0200 +@@ -206,9 +206,9 @@ static void update_groups (void) + * Update the DBM group file with the new entry as well. + */ + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user from group", +- user_name, user_id, SHADOW_AUDIT_SUCCESS); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "deleting-user-from-group", ++ user_name, user_id, ngrp->gr_name, SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", + user_name, ngrp->gr_name)); +@@ -267,9 +267,9 @@ static void update_groups (void) + exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user from shadow group", +- user_name, user_id, SHADOW_AUDIT_SUCCESS); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "deleting-user-from-shadow-group", ++ user_name, user_id, nsgrp->sg_name, SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", + user_name, nsgrp->sg_name)); +@@ -345,9 +345,9 @@ static void remove_usergroup (void) + } + + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_GROUP, Prog, +- "deleting group", +- user_name, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_DEL_GROUP, Prog, ++ "delete-group", ++ user_name, AUDIT_NO_ID, user_name, + SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, +@@ -363,9 +363,9 @@ static void remove_usergroup (void) + fail_exit (E_GRP_UPDATE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_GROUP, Prog, +- "deleting shadow group", +- user_name, AUDIT_NO_ID, ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "delete-shadow-group", ++ user_name, AUDIT_NO_ID, user_name, + SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, +@@ -527,7 +527,7 @@ static void fail_exit (int code) + + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user", ++ "delete-user", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + +@@ -546,22 +546,12 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, pw_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "locking password file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + pw_locked = true; + if (pw_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, pw_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "opening password file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + if (is_shadow_pwd) { +@@ -569,11 +559,6 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, spw_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "locking shadow password file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + spw_locked = true; +@@ -581,11 +566,6 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot open %s\n"), + Prog, spw_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "opening shadow password file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + } +@@ -593,21 +573,11 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, gr_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "locking group file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_GRP_UPDATE); + } + gr_locked = true; + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), Prog, gr_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "opening group file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_GRP_UPDATE); + } + #ifdef SHADOWGRP +@@ -616,22 +586,12 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sgr_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "locking shadow group file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_GRP_UPDATE); + } + sgr_locked= true; + if (sgr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%s: cannot open %s\n"), + Prog, sgr_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "opening shadow group file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_GRP_UPDATE); + } + } +@@ -642,22 +602,12 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_uid_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "locking subordinate user file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_SUB_UID_UPDATE); + } + sub_uid_locked = true; + if (sub_uid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, sub_uid_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "opening subordinate user file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_SUB_UID_UPDATE); + } + } +@@ -666,22 +616,12 @@ static void open_files (void) + fprintf (stderr, + _("%s: cannot lock %s; try again later.\n"), + Prog, sub_gid_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "locking subordinate group file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_SUB_GID_UPDATE); + } + sub_gid_locked = true; + if (sub_gid_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, + _("%s: cannot open %s\n"), Prog, sub_gid_dbname ()); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_DEL_USER, Prog, +- "opening subordinate group file", +- user_name, user_id, SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_SUB_GID_UPDATE); + } + } +@@ -726,7 +666,7 @@ static void update_user (void) + #endif /* ENABLE_SUBIDS */ + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user entries", ++ "delete-user", + user_name, user_id, SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, "delete user '%s'\n", user_name)); +@@ -824,7 +764,7 @@ static int remove_mailbox (void) + SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting mail file", ++ "delete-mail-file", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + free(mailfile); +@@ -840,7 +780,7 @@ static int remove_mailbox (void) + SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting mail file", ++ "delete-mail-file", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + errors = 1; +@@ -849,8 +789,8 @@ static int remove_mailbox (void) + #ifdef WITH_AUDIT + else + { +- audit_logger (AUDIT_DEL_USER, Prog, +- "deleting mail file", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "delete-mail-file", + user_name, user_id, SHADOW_AUDIT_SUCCESS); + } + #endif /* WITH_AUDIT */ +@@ -867,7 +807,7 @@ static int remove_mailbox (void) + mailfile, strerror (errno))); + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting mail file", ++ "delete-mail-file", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + free(mailfile); +@@ -883,7 +823,7 @@ static int remove_mailbox (void) + SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno))); + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting mail file", ++ "delete-mail-file", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + errors = 1; +@@ -892,8 +832,8 @@ static int remove_mailbox (void) + #ifdef WITH_AUDIT + else + { +- audit_logger (AUDIT_DEL_USER, Prog, +- "deleting mail file", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "delete-mail-file", + user_name, user_id, SHADOW_AUDIT_SUCCESS); + } + #endif /* WITH_AUDIT */ +@@ -1104,7 +1044,7 @@ int main (int argc, char **argv) + Prog, user_name); + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user not found", ++ "deleting-user-not-found", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -1154,7 +1094,7 @@ int main (int argc, char **argv) + if (!fflg) { + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user logged in", ++ "deleting-user-logged-in", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -1248,8 +1188,8 @@ int main (int argc, char **argv) + #ifdef WITH_AUDIT + else + { +- audit_logger (AUDIT_DEL_USER, Prog, +- "deleting home directory", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "deleting-home-directory", + user_name, user_id, SHADOW_AUDIT_SUCCESS); + } + #endif /* WITH_AUDIT */ +@@ -1257,7 +1197,7 @@ int main (int argc, char **argv) + #ifdef WITH_AUDIT + if (0 != errors) { + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting home directory", ++ "deleting-home-directory", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + } +@@ -1270,8 +1210,8 @@ int main (int argc, char **argv) + _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), + Prog, user_name); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "removing SELinux user mapping", ++ audit_logger (AUDIT_ROLE_REMOVE, Prog, ++ "delete-selinux-user-mapping", + user_name, user_id, SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + fail_exit (E_SE_UPDATE); +diff -up shadow-4.15.1/src/usermod.c.audit-update shadow-4.15.1/src/usermod.c +--- shadow-4.15.1/src/usermod.c.audit-update 2024-05-20 11:52:05.638758529 +0200 ++++ shadow-4.15.1/src/usermod.c 2024-05-20 11:56:51.962509443 +0200 +@@ -440,7 +440,7 @@ static char *new_pw_passwd (char *pw_pas + + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "updating passwd", user_newname, user_newid, 0); ++ "updating-passwd", user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); + strcpy (buf, "!"); +@@ -457,14 +457,14 @@ static char *new_pw_passwd (char *pw_pas + + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "updating password", user_newname, user_newid, 0); ++ "updating-password", user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); + memmove(pw_pass, pw_pass + 1, strlen(pw_pass)); + } else if (pflg) { + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing password", user_newname, user_newid, 1); ++ "updating-password", user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); + pw_pass = xstrdup (user_pass); +@@ -492,8 +492,8 @@ static void new_pwent (struct passwd *pw + fail_exit (E_NAME_IN_USE); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing name", user_newname, user_newid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-name", user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, + "change user name '%s' to '%s'", +@@ -512,8 +512,8 @@ static void new_pwent (struct passwd *pw + + if (uflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing uid", user_newname, user_newid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-uid", user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, + "change user '%s' UID from '%d' to '%d'", +@@ -522,8 +522,8 @@ static void new_pwent (struct passwd *pw + } + if (gflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing primary group", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-primary-group", + user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -533,16 +533,16 @@ static void new_pwent (struct passwd *pw + } + if (cflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing comment", user_newname, user_newid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-comment", user_newname, user_newid, 1); + #endif + pwent->pw_gecos = user_newcomment; + } + + if (dflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing home directory", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-home-dir", + user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -558,8 +558,8 @@ static void new_pwent (struct passwd *pw + } + if (sflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing user shell", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-shell", + user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -589,8 +589,8 @@ static void new_spent (struct spwd *spen + + if (fflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing inactive days", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-inactive-days", + user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -604,8 +604,8 @@ static void new_spent (struct spwd *spen + date_to_str (sizeof(new_exp), new_exp, user_newexpire * DAY); + date_to_str (sizeof(old_exp), old_exp, user_expire * DAY); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing expiration date", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-expiration-date", + user_newname, user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -690,9 +690,9 @@ fail_exit (int code) + #endif /* ENABLE_SUBIDS */ + + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "modifying account", +- user_name, AUDIT_NO_ID, 0); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "modify-account", ++ user_name, AUDIT_NO_ID, SHADOW_AUDIT_FAILURE); + #endif + exit (code); + } +@@ -762,9 +762,12 @@ update_group(const struct group *grp) + user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing group member", +- user_newname, AUDIT_NO_ID, 1); ++ audit_logger_with_group ( ++ AUDIT_USER_MGMT, Prog, ++ "update-member-in-group", ++ user_newname, AUDIT_NO_ID, ++ ngrp->gr_name, ++ SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, + "change '%s' to '%s' in group '%s'", +@@ -778,9 +781,11 @@ update_group(const struct group *grp) + ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "removing group member", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "delete-user-from-group", ++ user_name, AUDIT_NO_ID, ++ ngrp->gr_name, ++ SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, + "delete '%s' from group '%s'", +@@ -793,9 +798,11 @@ update_group(const struct group *grp) + ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-group", ++ user_name, AUDIT_NO_ID, ++ ngrp->gr_name, ++ SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, "add '%s' to group '%s'", + user_newname, ngrp->gr_name)); +@@ -888,9 +895,10 @@ update_gshadow(const struct sgrp *sgrp) + nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing admin name in shadow group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_GRP_MGMT, Prog, ++ "update-admin-name-in-shadow-group", ++ user_name, AUDIT_NO_ID, nsgrp->sg_name, ++ SHADOW_AUDIT_SUCCESS); + #endif + SYSLOG ((LOG_INFO, + "change admin '%s' to '%s' in shadow group '%s'", +@@ -910,9 +918,10 @@ update_gshadow(const struct sgrp *sgrp) + user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing member in shadow group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "update-member-in-shadow-group", ++ user_name, AUDIT_NO_ID, ++ nsgrp->sg_name, 1); + #endif + SYSLOG ((LOG_INFO, + "change '%s' to '%s' in shadow group '%s'", +@@ -926,9 +935,10 @@ update_gshadow(const struct sgrp *sgrp) + nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "removing user from shadow group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "delete-user-from-shadow-group", ++ user_name, AUDIT_NO_ID, ++ nsgrp->sg_name, 1); + #endif + SYSLOG ((LOG_INFO, + "delete '%s' from shadow group '%s'", +@@ -941,9 +951,10 @@ update_gshadow(const struct sgrp *sgrp) + nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); + changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to shadow group", +- user_newname, AUDIT_NO_ID, 1); ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "add-user-to-shadow-group", ++ user_newname, AUDIT_NO_ID, ++ nsgrp->sg_name, 1); + #endif + SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", + user_newname, nsgrp->sg_name)); +@@ -1852,8 +1863,8 @@ static void move_home (void) + + #ifdef WITH_AUDIT + if (uflg || gflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing home directory owner", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "updating-home-dir-owner", + user_newname, user_newid, 1); + } + #endif +@@ -1871,8 +1882,8 @@ static void move_home (void) + fail_exit (E_HOMEDIR); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "moving home directory", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "moving-home-dir", + user_newname, user_newid, 1); + #endif + return; +@@ -1899,9 +1910,9 @@ static void move_home (void) + Prog, prefix_user_home); + } + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, ++ audit_logger (AUDIT_USER_MGMT, + Prog, +- "moving home directory", ++ "moving-home-dir", + user_newname, + user_newid, + 1); +@@ -2125,8 +2136,8 @@ static void move_mailbox (void) + } + #ifdef WITH_AUDIT + else { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing mail file owner", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "updating-mail-file-owner", + user_newname, user_newid, 1); + } + #endif +@@ -2149,8 +2160,8 @@ static void move_mailbox (void) + } + #ifdef WITH_AUDIT + else { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing mail file name", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "updating-mail-file-name", + user_newname, user_newid, 1); + } + +@@ -2347,8 +2358,8 @@ int main (int argc, char **argv) + _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), + Prog, user_name, user_selinux); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "modifying User mapping ", ++ audit_logger (AUDIT_ROLE_ASSIGN, Prog, ++ "changing-selinux-user-mapping ", + user_name, user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -2360,8 +2371,8 @@ int main (int argc, char **argv) + _("%s: warning: the user name %s to SELinux user mapping removal failed.\n"), + Prog, user_name); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "removing SELinux user mapping", ++ audit_logger (AUDIT_ROLE_REMOVE, Prog, ++ "delete-selinux-user-mapping", + user_name, user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -2404,8 +2415,8 @@ int main (int argc, char **argv) + */ + #ifdef WITH_AUDIT + if (uflg || gflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing home directory owner", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "updating-home-dir-owner", + user_newname, user_newid, 1); + } + #endif diff --git a/SOURCES/shadow-4.15.0-date-parsing.patch b/SOURCES/shadow-4.15.0-date-parsing.patch new file mode 100644 index 0000000..272d2df --- /dev/null +++ b/SOURCES/shadow-4.15.0-date-parsing.patch @@ -0,0 +1,69 @@ +Index: shadow-4.5/lib/getdate.y +=================================================================== +--- shadow-4.5.orig/lib/getdate.y ++++ shadow-4.5/lib/getdate.y +@@ -152,6 +152,7 @@ static int yyHaveDay; + static int yyHaveRel; + static int yyHaveTime; + static int yyHaveZone; ++static int yyHaveYear; + static int yyTimezone; + static int yyDay; + static int yyHour; +@@ -293,18 +294,21 @@ date : tUNUMBER '/' tUNUMBER { + yyDay = $3; + yyYear = $5; + } ++ yyHaveYear++; + } + | tUNUMBER tSNUMBER tSNUMBER { + /* ISO 8601 format. yyyy-mm-dd. */ + yyYear = $1; + yyMonth = -$2; + yyDay = -$3; ++ yyHaveYear++; + } + | tUNUMBER tMONTH tSNUMBER { + /* e.g. 17-JUN-1992. */ + yyDay = $1; + yyMonth = $2; + yyYear = -$3; ++ yyHaveYear++; + } + | tMONTH tUNUMBER { + yyMonth = $1; +@@ -314,6 +318,7 @@ date : tUNUMBER '/' tUNUMBER { + yyMonth = $1; + yyDay = $2; + yyYear = $4; ++ yyHaveYear++; + } + | tUNUMBER tMONTH { + yyMonth = $2; +@@ -323,6 +328,7 @@ date : tUNUMBER '/' tUNUMBER { + yyMonth = $2; + yyDay = $1; + yyYear = $3; ++ yyHaveYear++; + } + ; + +@@ -395,7 +401,8 @@ relunit : tUNUMBER tYEAR_UNIT { + + number : tUNUMBER + { +- if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0)) ++ if ((yyHaveTime != 0 || $1 >= 100) && !yyHaveYear ++ && (yyHaveDate != 0) && (yyHaveRel == 0)) + yyYear = $1; + else + { +@@ -802,7 +809,7 @@ yylex (void) + return LookupWord (buff); + } + if (c != '(') +- return *yyInput++; ++ return (unsigned char)*yyInput++; + Count = 0; + do + { diff --git a/SOURCES/shadow-4.15.0-getdef-spurious-error.patch b/SOURCES/shadow-4.15.0-getdef-spurious-error.patch new file mode 100644 index 0000000..9cec295 --- /dev/null +++ b/SOURCES/shadow-4.15.0-getdef-spurious-error.patch @@ -0,0 +1,137 @@ +From ead55e9ba8958504e23e29545f90c4dd925c7462 Mon Sep 17 00:00:00 2001 +From: Serge Hallyn +Date: Wed, 20 Mar 2024 17:39:46 -0500 +Subject: [PATCH] getdef: avoid spurious error messages about unknown + configuration options + +def_find can return NULL for unset, not just unknown, config options. So +move the decision of whether to log an error message about an unknown config +option back into def_find, which knows the difference. Only putdef_str() +will pass a char* srcfile to def_find, so only calls from putdef_str will +cause the message, which was the original intent of fa68441bc4be8. + +closes #967 + +fixes: fa68441bc4be8 ("Improve the login.defs unknown item error message") +Signed-off-by: Serge Hallyn +--- + lib/getdef.c | 30 ++++++++++++++++-------------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +diff --git a/lib/getdef.c b/lib/getdef.c +index 4d4d4e19..ef2ae1f0 100644 +--- a/lib/getdef.c ++++ b/lib/getdef.c +@@ -176,7 +176,7 @@ static const char* def_fname = LOGINDEFS; /* login config defs file */ + static bool def_loaded = false; /* are defs already loaded? */ + + /* local function prototypes */ +-static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *); ++static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *, const char *); + static void def_load (void); + + +@@ -195,7 +195,7 @@ static void def_load (void); + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + return (NULL == d) ? NULL : d->value; + } + +@@ -214,7 +214,7 @@ bool getdef_bool (const char *item) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return false; + } +@@ -240,7 +240,7 @@ int getdef_num (const char *item, int dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -275,7 +275,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -310,7 +310,7 @@ long getdef_long (const char *item, long dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -342,7 +342,7 @@ unsigned long getdef_ulong (const char *item, unsigned long dflt) + def_load (); + } + +- d = def_find (item); ++ d = def_find (item, NULL); + if ((NULL == d) || (NULL == d->value)) { + return dflt; + } +@@ -375,12 +375,9 @@ int putdef_str (const char *name, const char *value, const char *srcfile) + * Locate the slot to save the value. If this parameter + * is unknown then "def_find" will print an err message. + */ +- d = def_find (name); +- if (NULL == d) { +- if (NULL != srcfile) +- SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile)); ++ d = def_find (name, srcfile); ++ if (NULL == d) + return -1; +- } + + /* + * Save off the value. +@@ -404,9 +401,12 @@ int putdef_str (const char *name, const char *value, const char *srcfile) + * + * Search through a table of configurable items to locate the + * specified configuration option. ++ * ++ * If srcfile is not NULL, and the item is not found, then report an error saying ++ * the unknown item was used in this file. + */ + +-static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name) ++static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name, const char *srcfile) + { + struct itemdef *ptr; + +@@ -432,6 +432,8 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name) + fprintf (shadow_logfd, + _("configuration error - unknown item '%s' (notify administrator)\n"), + name); ++ if (srcfile != NULL) ++ SYSLOG ((LOG_CRIT, "shadow: unknown configuration item '%s' in '%s'", name, srcfile)); + + out: + return NULL; +@@ -610,7 +612,7 @@ int main (int argc, char **argv) + def_load (); + + for (i = 0; i < NUMDEFS; ++i) { +- d = def_find (def_table[i].name); ++ d = def_find (def_table[i].name, NULL); + if (NULL == d) { + printf ("error - lookup '%s' failed\n", + def_table[i].name); +-- +2.44.0 + diff --git a/SOURCES/shadow-4.15.0-manfix.patch b/SOURCES/shadow-4.15.0-manfix.patch new file mode 100644 index 0000000..34e62f9 --- /dev/null +++ b/SOURCES/shadow-4.15.0-manfix.patch @@ -0,0 +1,162 @@ +diff -up shadow-4.15.0/man/groupmems.8.xml.manfix shadow-4.15.0/man/groupmems.8.xml +--- shadow-4.15.0/man/groupmems.8.xml.manfix 2023-05-26 04:56:11.000000000 +0200 ++++ shadow-4.15.0/man/groupmems.8.xml 2024-02-09 10:42:20.337036378 +0100 +@@ -156,20 +156,10 @@ + + SETUP + +- The groupmems executable should be in mode +- 2710 as user root and in group +- groups. The system administrator can add users to +- group groups to allow or disallow them using the +- groupmems utility to manage their own group +- membership list. ++ In this operating system the groupmems executable ++ is not setuid and regular users cannot use it to manipulate ++ the membership of their own group. + +- +- +- $ groupadd -r groups +- $ chmod 2710 groupmems +- $ chown root:groups groupmems +- $ groupmems -g groups -a gk4 +- + + + +diff -up shadow-4.15.0/man/ja/man5/login.defs.5.manfix shadow-4.15.0/man/ja/man5/login.defs.5 +--- shadow-4.15.0/man/ja/man5/login.defs.5.manfix 2023-03-13 21:58:56.000000000 +0100 ++++ shadow-4.15.0/man/ja/man5/login.defs.5 2024-02-09 10:42:20.337036378 +0100 +@@ -123,10 +123,6 @@ 以下の参照表は、 + shadow パスワード機能のどのプログラムが + どのパラメータを使用するかを示したものである。 + .na +-.IP chfn 12 +-CHFN_AUTH CHFN_RESTRICT +-.IP chsh 12 +-CHFN_AUTH + .IP groupadd 12 + GID_MAX GID_MIN + .IP newusers 12 +diff -up shadow-4.15.0/man/login.defs.5.xml.manfix shadow-4.15.0/man/login.defs.5.xml +--- shadow-4.15.0/man/login.defs.5.xml.manfix 2024-01-22 22:36:43.000000000 +0100 ++++ shadow-4.15.0/man/login.defs.5.xml 2024-02-09 10:45:49.014407259 +0100 +@@ -144,6 +144,17 @@ + long numeric parameters is machine-dependent. + + ++ ++ Please note that the parameters in this configuration file control the ++ behavior of the tools from the shadow-utils component. None of these ++ tools uses the PAM mechanism, and the utilities that use PAM (such as the ++ passwd command) should be configured elsewhere. The only values that ++ affect PAM modules are ENCRYPT_METHOD and SHA_CRYPT_MAX_ROUNDS ++ for pam_unix module, FAIL_DELAY for pam_faildelay module, ++ and UMASK for pam_umask module. Refer to ++ pam(8) for more information. ++ ++ + The following configuration items are provided: + + +@@ -240,16 +251,6 @@ + + + +- chfn +- +- +- CHFN_AUTH +- CHFN_RESTRICT +- LOGIN_STRING +- +- +- +- + chgpasswd + + +@@ -276,14 +277,6 @@ + + + +- +- chsh +- +- +- CHSH_AUTH LOGIN_STRING +- +- +- + + + +@@ -352,34 +345,6 @@ + LASTLOG_UID_MAX + + +- +- login +- +- +- CONSOLE +- CONSOLE_GROUPS DEFAULT_HOME +- ENV_HZ ENV_PATH ENV_SUPATH +- ENV_TZ ENVIRON_FILE +- ERASECHAR FAIL_DELAY +- FAILLOG_ENAB +- FAKE_SHELL +- FTMP_FILE +- HUSHLOGIN_FILE +- ISSUE_FILE +- KILLCHAR +- LASTLOG_ENAB LASTLOG_UID_MAX +- LOGIN_RETRIES +- LOGIN_STRING +- LOGIN_TIMEOUT LOG_OK_LOGINS LOG_UNKFAIL_ENAB +- MAIL_CHECK_ENAB MAIL_DIR MAIL_FILE +- MOTD_FILE NOLOGINS_FILE PORTTIME_CHECKS_ENAB +- QUOTAS_ENAB +- TTYGROUP TTYPERM TTYTYPE_FILE +- ULIMIT UMASK +- USERGROUPS_ENAB +- +- +- + + + newgrp / sg +@@ -451,32 +416,6 @@ + + + +- +- su +- +- +- CONSOLE +- CONSOLE_GROUPS DEFAULT_HOME +- ENV_HZ ENVIRON_FILE +- ENV_PATH ENV_SUPATH +- ENV_TZ LOGIN_STRING MAIL_CHECK_ENAB +- MAIL_DIR MAIL_FILE QUOTAS_ENAB +- SULOG_FILE SU_NAME +- SU_WHEEL_ONLY +- SYSLOG_SU_ENAB +- USERGROUPS_ENAB +- +- +- +- +- sulogin +- +- +- ENV_HZ +- ENV_TZ +- +- +- + + useradd + diff --git a/SOURCES/shadow-4.15.0-sast-fixes.patch b/SOURCES/shadow-4.15.0-sast-fixes.patch new file mode 100644 index 0000000..e674ebf --- /dev/null +++ b/SOURCES/shadow-4.15.0-sast-fixes.patch @@ -0,0 +1,1413 @@ +From 4c16416ebc5f0958d58a1ea1e7890eafd9f8bb75 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Wed, 15 May 2024 12:25:51 +0200 +Subject: [PATCH 01/16] port: fix OVERRUN (CWE-119) + +``` +shadow-4.15.0/lib/port.c:154:2: alias: Assigning: "port.pt_names" = "ttys". "port.pt_names" now points to element 0 of "ttys" (which consists of 65 8-byte elements). +shadow-4.15.0/lib/port.c:155:2: cond_const: Checking "j < 64" implies that "j" is 64 on the false branch. +shadow-4.15.0/lib/port.c:175:2: overrun-local: Overrunning array of 65 8-byte elements at element index 65 (byte offset 527) by dereferencing pointer "port.pt_names + (j + 1)". +173| *cp = '\0'; +174| cp++; +175|-> port.pt_names[j + 1] = NULL; +176| +177| /* +``` + +Resolves: https://issues.redhat.com/browse/RHEL-35383 + +Signed-off-by: Iker Pedrosa +Reviewed-by: Alejandro Colomar +--- + lib/port.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/port.c b/lib/port.c +index 05b95651..60ff8989 100644 +--- a/lib/port.c ++++ b/lib/port.c +@@ -168,7 +168,7 @@ again: + } + *cp = '\0'; + cp++; +- port.pt_names[j + 1] = NULL; ++ port.pt_names[j] = NULL; + + /* + * Get the list of user names. It is the second colon +-- +2.45.1 + + +From f8fc6371f69930bbd5801284256e182ba35ced2a Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 14:05:31 +0200 +Subject: [PATCH 02/16] src/useradd.c: set_defaults(): Fix order of clean-ups + +Resources should be freed in the inverse order of the allocation. +This refactor prepares for the following commits, which fix some leaks. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 88d8ab7f..56a74559 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -745,10 +745,9 @@ static int set_defaults (void) + def_create_mail_spool, def_log_init)); + ret = 0; + setdef_err: +- free(new_file); +- if (prefix[0]) { ++ if (prefix[0]) + free(default_file); +- } ++ free(new_file); + + return ret; + } +-- +2.45.1 + + +From 37ae8827a0869ee4a723954c3c9e7c48165d9b50 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 14:28:50 +0200 +Subject: [PATCH 03/16] src/useradd.c: set_defaults(): Rename goto label + +This will help add other labels in the following commits. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 24 +++++++++++++----------- + 1 file changed, 13 insertions(+), 11 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 56a74559..bc72e6bc 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -558,7 +558,7 @@ static int set_defaults (void) + fprintf(stderr, + _("%s: cannot create new defaults file: %s\n"), + Prog, strerror(errno)); +- goto setdef_err; ++ goto err_free_def; + } + } + +@@ -567,7 +567,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot create directory for defaults file\n"), + Prog); +- goto setdef_err; ++ goto err_free_def; + } + + ret = mkdir(dirname(new_file_dup), 0755); +@@ -576,7 +576,7 @@ static int set_defaults (void) + _("%s: cannot create directory for defaults file\n"), + Prog); + free(new_file_dup); +- goto setdef_err; ++ goto err_free_def; + } + free(new_file_dup); + +@@ -588,7 +588,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot create new defaults file\n"), + Prog); +- goto setdef_err; ++ goto err_free_def; + } + + ofp = fdopen (ofd, "w"); +@@ -596,7 +596,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot open new defaults file\n"), + Prog); +- goto setdef_err; ++ goto err_free_def; + } + + /* +@@ -623,7 +623,7 @@ static int set_defaults (void) + _("%s: line too long in %s: %s..."), + Prog, default_file, buf); + (void) fclose (ifp); +- goto setdef_err; ++ goto err_free_def; + } + } + +@@ -702,9 +702,10 @@ static int set_defaults (void) + (void) fflush (ofp); + if ( (ferror (ofp) != 0) + || (fsync (fileno (ofp)) != 0) +- || (fclose (ofp) != 0)) { ++ || (fclose (ofp) != 0)) ++ { + unlink (new_file); +- goto setdef_err; ++ goto err_free_def; + } + + /* +@@ -718,7 +719,7 @@ static int set_defaults (void) + _("%s: Cannot create backup file (%s): %s\n"), + Prog, buf, strerror (err)); + unlink (new_file); +- goto setdef_err; ++ goto err_free_def; + } + + /* +@@ -729,7 +730,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: rename: %s: %s\n"), + Prog, new_file, strerror (err)); +- goto setdef_err; ++ goto err_free_def; + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USYS_CONFIG, Prog, +@@ -744,7 +745,8 @@ static int set_defaults (void) + def_inactive, def_expire, def_template, + def_create_mail_spool, def_log_init)); + ret = 0; +- setdef_err: ++ ++err_free_def: + if (prefix[0]) + free(default_file); + free(new_file); +-- +2.45.1 + + +From 701fe4cf1aeac9e66fa949369c91d135dbf375d2 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:10:46 +0200 +Subject: [PATCH 04/16] src/useradd.c: set_defaults(): Do not free(3) the + result of asprintf(3) if it failed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +See asprintf(3): + +RETURN VALUE + When successful, these functions return the number of bytes + printed, just like sprintf(3). If memory allocation wasn’t possi‐ + ble, or some other error occurs, these functions will return -1, + and the contents of strp are undefined. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index bc72e6bc..6a3edfe3 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -558,7 +558,7 @@ static int set_defaults (void) + fprintf(stderr, + _("%s: cannot create new defaults file: %s\n"), + Prog, strerror(errno)); +- goto err_free_def; ++ goto err_free_new; + } + } + +@@ -749,6 +749,7 @@ static int set_defaults (void) + err_free_def: + if (prefix[0]) + free(default_file); ++err_free_new: + free(new_file); + + return ret; +-- +2.45.1 + + +From a74c4b6ae124a55cd272e574e0d056102f331e17 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:14:31 +0200 +Subject: [PATCH 05/16] src/useradd.c: De-duplicate code + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index 6a3edfe3..ad2676c1 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -571,14 +571,13 @@ static int set_defaults (void) + } + + ret = mkdir(dirname(new_file_dup), 0755); ++ free(new_file_dup); + if (-1 == ret && EEXIST != errno) { + fprintf (stderr, + _("%s: cannot create directory for defaults file\n"), + Prog); +- free(new_file_dup); + goto err_free_def; + } +- free(new_file_dup); + + /* + * Create a temporary file to copy the new output to. +-- +2.45.1 + + +From e7d1508e076bbf4053faacc0370c6fe43d9c8f04 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:40:58 +0200 +Subject: [PATCH 06/16] src/useradd.c: Add fmkstemp() to fix file-descriptor + leak + +This function creates a temporary file, and returns a FILE pointer to +it. This avoids dealing with both a file descriptor and a FILE pointer, +and correctly deallocating the resources on error. + +The code before this patch was leaking the file descriptor if fdopen(3) +failed. + +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 34 ++++++++++++++++++++++++---------- + 1 file changed, 24 insertions(+), 10 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index ad2676c1..e0238457 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -238,6 +238,9 @@ static void create_home (void); + static void create_mail (void); + static void check_uid_range(int rflg, uid_t user_id); + ++static FILE *fmkstemp(char *template); ++ ++ + /* + * fail_exit - undo as much as possible + */ +@@ -524,7 +527,6 @@ static void show_defaults (void) + */ + static int set_defaults (void) + { +- int ofd; + int ret = -1; + bool out_group = false; + bool out_groups = false; +@@ -582,15 +584,7 @@ static int set_defaults (void) + /* + * Create a temporary file to copy the new output to. + */ +- ofd = mkstemp (new_file); +- if (-1 == ofd) { +- fprintf (stderr, +- _("%s: cannot create new defaults file\n"), +- Prog); +- goto err_free_def; +- } +- +- ofp = fdopen (ofd, "w"); ++ ofp = fmkstemp(new_file); + if (NULL == ofp) { + fprintf (stderr, + _("%s: cannot open new defaults file\n"), +@@ -2752,3 +2746,23 @@ int main (int argc, char **argv) + return E_SUCCESS; + } + ++ ++static FILE * ++fmkstemp(char *template) ++{ ++ int fd; ++ FILE *fp; ++ ++ fd = mkstemp(template); ++ if (fd == -1) ++ return NULL; ++ ++ fp = fdopen(fd, "w"); ++ if (fp == NULL) { ++ close(fd); ++ unlink(template); ++ return NULL; ++ } ++ ++ return fp; ++} +-- +2.45.1 + + +From 1ee066ae1e5b39ac42120ad0f6f8af0f102db952 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 13:52:07 +0200 +Subject: [PATCH 07/16] src/useradd.c: set_defaults(): Fix FILE* leak + +Report: +> shadow-4.15.0/src/useradd.c:575:2: alloc_fn: Storage is returned from allocation function "fdopen". +> shadow-4.15.0/src/useradd.c:575:2: var_assign: Assigning: "ofp" = storage returned from "fdopen(ofd, "w")". +> shadow-4.15.0/src/useradd.c:734:2: leaked_storage: Variable "ofp" going out of scope leaks the storage it points to. +> 732| } +> 733| +> 734|-> return ret; +> 735| } +> 736| + +Link: +Reported-by: Iker Pedrosa +Reviewed-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/useradd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/useradd.c b/src/useradd.c +index e0238457..347334a6 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -615,7 +615,8 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: line too long in %s: %s..."), + Prog, default_file, buf); +- (void) fclose (ifp); ++ fclose(ifp); ++ fclose(ofp); + goto err_free_def; + } + } +-- +2.45.1 + + +From 151f14ad69de8100d25c1974947d53ae40d1448a Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 13:52:15 +0200 +Subject: [PATCH 08/16] src/usermod.c: Reduce scope of local variables + +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 0fcf0325..57b58f5b 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -687,11 +687,8 @@ fail_exit (int code) + + static void update_group (void) + { +- bool is_member; +- bool was_member; +- bool changed; +- const struct group *grp; +- struct group *ngrp; ++ bool changed; ++ const struct group *grp; + + changed = false; + +@@ -700,6 +697,9 @@ static void update_group (void) + * the user is a member of. + */ + while ((grp = gr_next ()) != NULL) { ++ bool is_member; ++ bool was_member; ++ struct group *ngrp; + /* + * See if the user specified this group as one of their + * concurrent groups. +@@ -799,12 +799,8 @@ static void update_group (void) + #ifdef SHADOWGRP + static void update_gshadow (void) + { +- bool is_member; +- bool was_member; +- bool was_admin; +- bool changed; +- const struct sgrp *sgrp; +- struct sgrp *nsgrp; ++ bool changed; ++ const struct sgrp *sgrp; + + changed = false; + +@@ -813,6 +809,10 @@ static void update_gshadow (void) + * that the user is a member of. + */ + while ((sgrp = sgr_next ()) != NULL) { ++ bool is_member; ++ bool was_member; ++ bool was_admin; ++ struct sgrp *nsgrp; + + /* + * See if the user was a member of this group +-- +2.45.1 + + +From b089a63ab38f69c32d099320fe8181802f7f4092 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 13:49:34 +0200 +Subject: [PATCH 09/16] src/usermod.c: Rename update_group() => + update_group_file() + +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 57b58f5b..aaa83d7d 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -178,7 +178,7 @@ NORETURN static void usage (int status); + static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); + NORETURN static void fail_exit (int); +-static void update_group (void); ++static void update_group_file(void); + + #ifdef SHADOWGRP + static void update_gshadow (void); +@@ -685,7 +685,8 @@ fail_exit (int code) + } + + +-static void update_group (void) ++static void ++update_group_file(void) + { + bool changed; + const struct group *grp; +@@ -950,7 +951,7 @@ static void update_gshadow (void) + */ + static void grp_update (void) + { +- update_group (); ++ update_group_file(); + #ifdef SHADOWGRP + if (is_shadow_grp) { + update_gshadow (); +-- +2.45.1 + + +From 81bc78ec5cdd59790bc7c591c9d1f66bd4d7b78e Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:11:22 +0200 +Subject: [PATCH 10/16] src/usermod.c: Rename update_gshadow() => + update_gshadow_file() + +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index aaa83d7d..3048f801 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -181,7 +181,7 @@ NORETURN static void fail_exit (int); + static void update_group_file(void); + + #ifdef SHADOWGRP +-static void update_gshadow (void); ++static void update_gshadow_file(void); + #endif + static void grp_update (void); + +@@ -798,7 +798,8 @@ update_group_file(void) + } + + #ifdef SHADOWGRP +-static void update_gshadow (void) ++static void ++update_gshadow_file(void) + { + bool changed; + const struct sgrp *sgrp; +@@ -954,7 +955,7 @@ static void grp_update (void) + update_group_file(); + #ifdef SHADOWGRP + if (is_shadow_grp) { +- update_gshadow (); ++ update_gshadow_file(); + } + #endif + } +-- +2.45.1 + + +From 61964aa06b9e6e0643a6519f64290f18ac04867f Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 13:54:06 +0200 +Subject: [PATCH 11/16] src/usermod.c: update_group_file(): Fix RESOURCE_LEAK + (CWE-772) + +Report: +> shadow-4.15.0/src/usermod.c:734:3: alloc_fn: Storage is returned from allocation function "__gr_dup". +> shadow-4.15.0/src/usermod.c:734:3: var_assign: Assigning: "ngrp" = storage returned from "__gr_dup(grp)". +> shadow-4.15.0/src/usermod.c:815:1: leaked_storage: Variable "ngrp" going out of scope leaks the storage it points to. +> 813| gr_free(ngrp); +> 814| } +> 815|-> } +> 816| +> 817| #ifdef SHADOWGRP + +Link: https://issues.redhat.com/browse/RHEL-35383 +Reported-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 3048f801..e0cfdd83 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -780,9 +780,8 @@ update_group_file(void) + SYSLOG ((LOG_INFO, "add '%s' to group '%s'", + user_newname, ngrp->gr_name)); + } +- if (!changed) { +- continue; +- } ++ if (!changed) ++ goto free_ngrp; + + changed = false; + if (gr_update (ngrp) == 0) { +@@ -793,6 +792,7 @@ update_group_file(void) + fail_exit (E_GRP_UPDATE); + } + ++free_ngrp: + gr_free(ngrp); + } + } +-- +2.45.1 + + +From 71a3238b7996285fc3c8dec841244ba95d663fa5 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:15:15 +0200 +Subject: [PATCH 12/16] src/usermod.c: update_gshadow_file(): Fix RESOURCE_LEAK + (CWE-772) + +Report: +> shadow-4.15.0/src/usermod.c:864:3: alloc_fn: Storage is returned from allocation function "__sgr_dup". +> shadow-4.15.0/src/usermod.c:864:3: var_assign: Assigning: "nsgrp" = storage returned from "__sgr_dup(sgrp)". +> shadow-4.15.0/src/usermod.c:964:1: leaked_storage: Variable "nsgrp" going out of scope leaks the storage it points to. +> 962| free (nsgrp); +> 963| } +> 964|-> } +> 965| #endif /* SHADOWGRP */ +> 966| + +Link: https://issues.redhat.com/browse/RHEL-35383 +Reported-by: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index e0cfdd83..bb5d3535 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -921,9 +921,8 @@ update_gshadow_file(void) + SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", + user_newname, nsgrp->sg_name)); + } +- if (!changed) { +- continue; +- } ++ if (!changed) ++ goto free_nsgrp; + + changed = false; + +@@ -939,6 +938,7 @@ update_gshadow_file(void) + fail_exit (E_GRP_UPDATE); + } + ++free_nsgrp: + free (nsgrp); + } + } +-- +2.45.1 + + +From 68d42a8fbe42b89cf13d3f672ad8502dbaf05835 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 14:02:54 +0200 +Subject: [PATCH 13/16] src/usermod.c: update_group_file(): Reduce scope of + local variable + +After _every_ iteration, 'changed' is always 'false'. We don't need to +have it outside of the loop. + +See: + +$ grepc update_group_file . \ +| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + bool changed; + changed = false; + while ((grp = gr_next ()) != NULL) { + if (!was_member && !is_member) { + continue; + } + if (was_member) { + if ((!Gflg) || is_member) { + if (lflg) { + changed = true; + } + } else { + changed = true; + } + } else if (is_member) { + changed = true; + } + if (!changed) + goto free_ngrp; + changed = false; +free_ngrp: + } +} + +This was already true in the commit that introduced the code: + +$ git show 45c6603cc:src/usermod.c \ +| grepc update_group \ +| grep -e changed -e goto -e break -e continue -e '\' -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + int changed; + changed = 0; + while ((grp = gr_next())) { + * See if the user specified this group as one of their + if (!was_member && !is_member) + continue; + if (was_member && (!Gflg || is_member)) { + if (lflg) { + changed = 1; + } + } else if (was_member && Gflg && !is_member) { + changed = 1; + } else if (!was_member && Gflg && is_member) { + changed = 1; + } + if (!changed) + continue; + changed = 0; + } +} + +Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index bb5d3535..30f47b8a 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -688,19 +688,20 @@ fail_exit (int code) + static void + update_group_file(void) + { +- bool changed; + const struct group *grp; + +- changed = false; +- + /* + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ + while ((grp = gr_next ()) != NULL) { ++ bool changed; + bool is_member; + bool was_member; + struct group *ngrp; ++ ++ changed = false; ++ + /* + * See if the user specified this group as one of their + * concurrent groups. +@@ -783,7 +784,6 @@ update_group_file(void) + if (!changed) + goto free_ngrp; + +- changed = false; + if (gr_update (ngrp) == 0) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry '%s'\n"), +-- +2.45.1 + + +From da77a82ecbc90e89808f143e7fa2abb7650f50d7 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:19:46 +0200 +Subject: [PATCH 14/16] src/usermod.c: update_gshadow_file(): Reduce scope of + local variable + +After _every_ iteration, 'changed' is always 'false'. We don't need to +have it outside of the loop. + +See: + +$ grepc update_gshadow_file . \ +| grep -e changed -e goto -e continue -e break -e free_ngrp -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + bool changed; + changed = false; + while ((sgrp = sgr_next ()) != NULL) { + if (!was_member && !was_admin && !is_member) { + continue; + } + if (was_admin && lflg) { + changed = true; + } + if (was_member) { + if ((!Gflg) || is_member) { + if (lflg) { + changed = true; + } + } else { + changed = true; + } + } else if (is_member) { + changed = true; + } + if (!changed) + goto free_nsgrp; + changed = false; + } +} + +This was already true in the commit that introduced the code: + +$ git show 45c6603cc:src/usermod.c \ +| grepc update_gshadow \ +| grep -e changed -e goto -e break -e continue -e '\' -e '{' -e '}' \ +| pcre2grep -v -M '{\n\t*}'; +{ + int changed; + changed = 0; + while ((sgrp = sgr_next())) { + * See if the user was a member of this group + * See if the user was an administrator of this group + * See if the user specified this group as one of their + if (!was_member && !was_admin && !is_member) + continue; + if (was_admin && lflg) { + changed = 1; + } + if (was_member && (!Gflg || is_member)) { + if (lflg) { + changed = 1; + } + } else if (was_member && Gflg && !is_member) { + changed = 1; + } else if (!was_member && Gflg && is_member) { + changed = 1; + } + if (!changed) + continue; + changed = 0; + } +} + +Fixes: 45c6603cc86c ("[svn-upgrade] Integrating new upstream version, shadow (19990709)") +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 30f47b8a..7b1e0581 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -801,21 +801,21 @@ free_ngrp: + static void + update_gshadow_file(void) + { +- bool changed; + const struct sgrp *sgrp; + +- changed = false; +- + /* + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. + */ + while ((sgrp = sgr_next ()) != NULL) { ++ bool changed; + bool is_member; + bool was_member; + bool was_admin; + struct sgrp *nsgrp; + ++ changed = false; ++ + /* + * See if the user was a member of this group + */ +@@ -924,8 +924,6 @@ update_gshadow_file(void) + if (!changed) + goto free_nsgrp; + +- changed = false; +- + /* + * Update the group entry to reflect the changes. + */ +-- +2.45.1 + + +From adf37cccd0fa4ce7d05644514b0af57fe71905c3 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Thu, 16 May 2024 14:12:09 +0200 +Subject: [PATCH 15/16] src/usermod.c: update_group(): Add helper function + +Keep the while loop in the outer function, and move the iteration code +to this new helper. This makes it a bit more readable. + +Cc: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 167 ++++++++++++++++++++++++++------------------------ + 1 file changed, 87 insertions(+), 80 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 7b1e0581..4ea11376 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -179,6 +179,7 @@ static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); + NORETURN static void fail_exit (int); + static void update_group_file(void); ++static void update_group(const struct group *grp); + + #ifdef SHADOWGRP + static void update_gshadow_file(void); +@@ -694,109 +695,115 @@ update_group_file(void) + * Scan through the entire group file looking for the groups that + * the user is a member of. + */ +- while ((grp = gr_next ()) != NULL) { +- bool changed; +- bool is_member; +- bool was_member; +- struct group *ngrp; ++ while ((grp = gr_next()) != NULL) ++ update_group(grp); ++} + +- changed = false; + +- /* +- * See if the user specified this group as one of their +- * concurrent groups. +- */ +- was_member = is_on_list (grp->gr_mem, user_name); +- is_member = Gflg && ( (was_member && aflg) +- || is_on_list (user_groups, grp->gr_name)); ++static void ++update_group(const struct group *grp) ++{ ++ bool changed; ++ bool is_member; ++ bool was_member; ++ struct group *ngrp; + +- if (!was_member && !is_member) { +- continue; +- } ++ changed = false; + +- /* +- * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes +- * mentioned groups while leaving the others. +- */ +- if (Gflg && rflg) { +- is_member = !is_member; +- } ++ /* ++ * See if the user specified this group as one of their ++ * concurrent groups. ++ */ ++ was_member = is_on_list (grp->gr_mem, user_name); ++ is_member = Gflg && ( (was_member && aflg) ++ || is_on_list (user_groups, grp->gr_name)); + +- ngrp = __gr_dup (grp); +- if (NULL == ngrp) { +- fprintf (stderr, +- _("%s: Out of memory. Cannot update %s.\n"), +- Prog, gr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } ++ if (!was_member && !is_member) ++ return; + +- if (was_member) { +- if ((!Gflg) || is_member) { +- /* User was a member and is still a member +- * of this group. +- * But the user might have been renamed. +- */ +- if (lflg) { +- ngrp->gr_mem = del_list (ngrp->gr_mem, +- user_name); +- ngrp->gr_mem = add_list (ngrp->gr_mem, +- user_newname); +- changed = true; +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing group member", +- user_newname, AUDIT_NO_ID, 1); +-#endif +- SYSLOG ((LOG_INFO, +- "change '%s' to '%s' in group '%s'", +- user_name, user_newname, +- ngrp->gr_name)); +- } +- } else { +- /* User was a member but is no more a +- * member of this group. +- */ +- ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); ++ /* ++ * If rflg+Gflg is passed in AKA -rG invert is_member flag, which removes ++ * mentioned groups while leaving the others. ++ */ ++ if (Gflg && rflg) { ++ is_member = !is_member; ++ } ++ ++ ngrp = __gr_dup (grp); ++ if (NULL == ngrp) { ++ fprintf (stderr, ++ _("%s: Out of memory. Cannot update %s.\n"), ++ Prog, gr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ ++ if (was_member) { ++ if ((!Gflg) || is_member) { ++ /* User was a member and is still a member ++ * of this group. ++ * But the user might have been renamed. ++ */ ++ if (lflg) { ++ ngrp->gr_mem = del_list (ngrp->gr_mem, ++ user_name); ++ ngrp->gr_mem = add_list (ngrp->gr_mem, ++ user_newname); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "removing group member", +- user_name, AUDIT_NO_ID, 1); ++ "changing group member", ++ user_newname, AUDIT_NO_ID, 1); + #endif + SYSLOG ((LOG_INFO, +- "delete '%s' from group '%s'", +- user_name, ngrp->gr_name)); ++ "change '%s' to '%s' in group '%s'", ++ user_name, user_newname, ++ ngrp->gr_name)); + } +- } else if (is_member) { +- /* User was not a member but is now a member this +- * group. ++ } else { ++ /* User was a member but is no more a ++ * member of this group. + */ +- ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); ++ ngrp->gr_mem = del_list (ngrp->gr_mem, user_name); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to group", +- user_name, AUDIT_NO_ID, 1); ++ "removing group member", ++ user_name, AUDIT_NO_ID, 1); + #endif +- SYSLOG ((LOG_INFO, "add '%s' to group '%s'", +- user_newname, ngrp->gr_name)); ++ SYSLOG ((LOG_INFO, ++ "delete '%s' from group '%s'", ++ user_name, ngrp->gr_name)); + } +- if (!changed) +- goto free_ngrp; ++ } else if (is_member) { ++ /* User was not a member but is now a member this ++ * group. ++ */ ++ ngrp->gr_mem = add_list (ngrp->gr_mem, user_newname); ++ changed = true; ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "adding user to group", ++ user_name, AUDIT_NO_ID, 1); ++#endif ++ SYSLOG ((LOG_INFO, "add '%s' to group '%s'", ++ user_newname, ngrp->gr_name)); ++ } ++ if (!changed) ++ goto free_ngrp; + +- if (gr_update (ngrp) == 0) { +- fprintf (stderr, +- _("%s: failed to prepare the new %s entry '%s'\n"), +- Prog, gr_dbname (), ngrp->gr_name); +- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); +- fail_exit (E_GRP_UPDATE); +- } ++ if (gr_update (ngrp) == 0) { ++ fprintf (stderr, ++ _("%s: failed to prepare the new %s entry '%s'\n"), ++ Prog, gr_dbname (), ngrp->gr_name); ++ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", gr_dbname (), ngrp->gr_name)); ++ fail_exit (E_GRP_UPDATE); ++ } + + free_ngrp: +- gr_free(ngrp); +- } ++ gr_free(ngrp); + } + ++ + #ifdef SHADOWGRP + static void + update_gshadow_file(void) +-- +2.45.1 + + +From d8e6a8b99b4d844328d875287babf6e13860d464 Mon Sep 17 00:00:00 2001 +From: Alejandro Colomar +Date: Fri, 17 May 2024 02:29:46 +0200 +Subject: [PATCH 16/16] src/usermod.c: update_gshadow(): Add helper function + +Keep the while loop in the outer function, and move the iteration code +to this new helper. This makes it a bit more readable. + +Cc: Iker Pedrosa +Signed-off-by: Alejandro Colomar +--- + src/usermod.c | 223 ++++++++++++++++++++++++++------------------------ + 1 file changed, 116 insertions(+), 107 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 4ea11376..f8896984 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -183,6 +183,7 @@ static void update_group(const struct group *grp); + + #ifdef SHADOWGRP + static void update_gshadow_file(void); ++static void update_gshadow(const struct sgrp *sgrp); + #endif + static void grp_update (void); + +@@ -814,141 +815,149 @@ update_gshadow_file(void) + * Scan through the entire shadow group file looking for the groups + * that the user is a member of. + */ +- while ((sgrp = sgr_next ()) != NULL) { +- bool changed; +- bool is_member; +- bool was_member; +- bool was_admin; +- struct sgrp *nsgrp; ++ while ((sgrp = sgr_next()) != NULL) ++ update_gshadow(sgrp); ++} ++#endif /* SHADOWGRP */ + +- changed = false; + +- /* +- * See if the user was a member of this group +- */ +- was_member = is_on_list (sgrp->sg_mem, user_name); ++#ifdef SHADOWGRP ++static void ++update_gshadow(const struct sgrp *sgrp) ++{ ++ bool changed; ++ bool is_member; ++ bool was_member; ++ bool was_admin; ++ struct sgrp *nsgrp; + +- /* +- * See if the user was an administrator of this group +- */ +- was_admin = is_on_list (sgrp->sg_adm, user_name); ++ changed = false; + +- /* +- * See if the user specified this group as one of their +- * concurrent groups. +- */ +- is_member = Gflg && ( (was_member && aflg) +- || is_on_list (user_groups, sgrp->sg_name)); ++ /* ++ * See if the user was a member of this group ++ */ ++ was_member = is_on_list (sgrp->sg_mem, user_name); + +- if (!was_member && !was_admin && !is_member) { +- continue; +- } ++ /* ++ * See if the user was an administrator of this group ++ */ ++ was_admin = is_on_list (sgrp->sg_adm, user_name); + +- /* +- * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted +- * groups while leaving the user apart of groups not mentioned +- */ +- if (Gflg && rflg) { +- is_member = !is_member; +- } ++ /* ++ * See if the user specified this group as one of their ++ * concurrent groups. ++ */ ++ is_member = Gflg && ( (was_member && aflg) ++ || is_on_list (user_groups, sgrp->sg_name)); + +- nsgrp = __sgr_dup (sgrp); +- if (NULL == nsgrp) { +- fprintf (stderr, +- _("%s: Out of memory. Cannot update %s.\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } ++ if (!was_member && !was_admin && !is_member) ++ return; + +- if (was_admin && lflg) { +- /* User was an admin of this group but the user +- * has been renamed. +- */ +- nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); +- nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); +- changed = true; +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing admin name in shadow group", +- user_name, AUDIT_NO_ID, 1); +-#endif +- SYSLOG ((LOG_INFO, +- "change admin '%s' to '%s' in shadow group '%s'", +- user_name, user_newname, nsgrp->sg_name)); +- } +- +- if (was_member) { +- if ((!Gflg) || is_member) { +- /* User was a member and is still a member +- * of this group. +- * But the user might have been renamed. +- */ +- if (lflg) { +- nsgrp->sg_mem = del_list (nsgrp->sg_mem, +- user_name); +- nsgrp->sg_mem = add_list (nsgrp->sg_mem, +- user_newname); +- changed = true; ++ /* ++ * If rflg+Gflg is passed in AKA -rG invert is_member, to remove targeted ++ * groups while leaving the user apart of groups not mentioned ++ */ ++ if (Gflg && rflg) { ++ is_member = !is_member; ++ } ++ ++ nsgrp = __sgr_dup (sgrp); ++ if (NULL == nsgrp) { ++ fprintf (stderr, ++ _("%s: Out of memory. Cannot update %s.\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ ++ if (was_admin && lflg) { ++ /* User was an admin of this group but the user ++ * has been renamed. ++ */ ++ nsgrp->sg_adm = del_list (nsgrp->sg_adm, user_name); ++ nsgrp->sg_adm = add_list (nsgrp->sg_adm, user_newname); ++ changed = true; + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing member in shadow group", +- user_name, AUDIT_NO_ID, 1); ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "changing admin name in shadow group", ++ user_name, AUDIT_NO_ID, 1); + #endif +- SYSLOG ((LOG_INFO, +- "change '%s' to '%s' in shadow group '%s'", +- user_name, user_newname, +- nsgrp->sg_name)); +- } +- } else { +- /* User was a member but is no more a +- * member of this group. +- */ +- nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); ++ SYSLOG ((LOG_INFO, ++ "change admin '%s' to '%s' in shadow group '%s'", ++ user_name, user_newname, nsgrp->sg_name)); ++ } ++ ++ if (was_member) { ++ if ((!Gflg) || is_member) { ++ /* User was a member and is still a member ++ * of this group. ++ * But the user might have been renamed. ++ */ ++ if (lflg) { ++ nsgrp->sg_mem = del_list (nsgrp->sg_mem, ++ user_name); ++ nsgrp->sg_mem = add_list (nsgrp->sg_mem, ++ user_newname); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "removing user from shadow group", +- user_name, AUDIT_NO_ID, 1); ++ "changing member in shadow group", ++ user_name, AUDIT_NO_ID, 1); + #endif + SYSLOG ((LOG_INFO, +- "delete '%s' from shadow group '%s'", +- user_name, nsgrp->sg_name)); ++ "change '%s' to '%s' in shadow group '%s'", ++ user_name, user_newname, ++ nsgrp->sg_name)); + } +- } else if (is_member) { +- /* User was not a member but is now a member this +- * group. ++ } else { ++ /* User was a member but is no more a ++ * member of this group. + */ +- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); ++ nsgrp->sg_mem = del_list (nsgrp->sg_mem, user_name); + changed = true; + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "adding user to shadow group", +- user_newname, AUDIT_NO_ID, 1); ++ "removing user from shadow group", ++ user_name, AUDIT_NO_ID, 1); + #endif +- SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", +- user_newname, nsgrp->sg_name)); ++ SYSLOG ((LOG_INFO, ++ "delete '%s' from shadow group '%s'", ++ user_name, nsgrp->sg_name)); + } +- if (!changed) +- goto free_nsgrp; +- +- /* +- * Update the group entry to reflect the changes. ++ } else if (is_member) { ++ /* User was not a member but is now a member this ++ * group. + */ +- if (sgr_update (nsgrp) == 0) { +- fprintf (stderr, +- _("%s: failed to prepare the new %s entry '%s'\n"), +- Prog, sgr_dbname (), nsgrp->sg_name); +- SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", +- sgr_dbname (), nsgrp->sg_name)); +- fail_exit (E_GRP_UPDATE); +- } ++ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_newname); ++ changed = true; ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "adding user to shadow group", ++ user_newname, AUDIT_NO_ID, 1); ++#endif ++ SYSLOG ((LOG_INFO, "add '%s' to shadow group '%s'", ++ user_newname, nsgrp->sg_name)); ++ } ++ if (!changed) ++ goto free_nsgrp; + +-free_nsgrp: +- free (nsgrp); ++ /* ++ * Update the group entry to reflect the changes. ++ */ ++ if (sgr_update (nsgrp) == 0) { ++ fprintf (stderr, ++ _("%s: failed to prepare the new %s entry '%s'\n"), ++ Prog, sgr_dbname (), nsgrp->sg_name); ++ SYSLOG ((LOG_WARN, "failed to prepare the new %s entry '%s'", ++ sgr_dbname (), nsgrp->sg_name)); ++ fail_exit (E_GRP_UPDATE); + } ++ ++free_nsgrp: ++ free (nsgrp); + } + #endif /* SHADOWGRP */ + ++ + /* + * grp_update - add user to secondary group set + * +-- +2.45.1 + diff --git a/SOURCES/shadow-4.15.0.tar.xz.asc b/SOURCES/shadow-4.15.0.tar.xz.asc new file mode 100644 index 0000000..bc7a410 --- /dev/null +++ b/SOURCES/shadow-4.15.0.tar.xz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCgAdFiEEflbiwT+nfOMVWa3JfcJMNsM0HSAFAmXrjOcACgkQfcJMNsM0 +HSC+Xg/8DIzBlPlkuvgmKSQbTV2AsRDrGxRSSks36hAsi/uBNhpIi5RI5OftN9S2 +PuuY+nfja8K1zbOt8IyUx8dLmBFbN5U3u53mb0W0hI2RQFn3G18Pg4CurzBktA6P +tQ23wr2YnWfjbq6k7ed8keAKh0CTxe+hy7IYpYww+RImxAuYOYgSoRn7qBbcFMkI +WUbg5dku4ijy+2N1llxjOX7hIKaYN+BlKBIxAiku4IBmxdRyVrKi5njmiFEQh8PG +53ZLW6lIy8Q2GJxZA+A/xEm+sZnaMuVTIKlQJouHTEYwhQ882PPm1lnFBFvoMPsk +mAXoUj4otJcXWnJbMgkFYv0BFWKKUpMdhT61miwGywOY8d60D9V85AnUjwRk8EOD +7pSGiVECZGEQsSaFXWDboYhNZZ7VlvpTUkMEphNfj7xENnGbr7BlgQEEPNpFwkUL +zNwIV30bP1qLwZD/MowjKfB5uc9MYt8Q7dP5IZNwqJv+WIRBQjr9LA3iGLxc3YfH +DlYLP8pLjmd0+4HuHdtlc2b8QSY5kLQKYy12MnvGL77EGUq76bjGVtgrE9AWy9V4 +PRlS91lAdRqCCqAvWQ5wQx5lJwAED5uxAl64GEdyvHzGTkbFaH5DqTJBLd6v7Jyj +UTP+RxIAVrV+lCYy5TWwemeSlZkO/F0T/Lkk2wU/9S4rSltOkT4= +=fkei +-----END PGP SIGNATURE----- diff --git a/SOURCES/shadow-bsd.txt b/SOURCES/shadow-bsd.txt new file mode 100644 index 0000000..a2c1609 --- /dev/null +++ b/SOURCES/shadow-bsd.txt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1990 - 1994, Julianne Frances Haugh + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2000 - 2006, Tomasz Kłoczko + * Copyright (c) 2007 - 2011, Nicolas François + * All rights reserved. + * + * 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, this list of conditions and the following disclaimer. + * 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 copyright holders or contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 COPYRIGHT + * HOLDERS OR CONTRIBUTORS 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. + */ + diff --git a/SOURCES/shadow-utils.HOME_MODE.xml b/SOURCES/shadow-utils.HOME_MODE.xml new file mode 100644 index 0000000..21aa55f --- /dev/null +++ b/SOURCES/shadow-utils.HOME_MODE.xml @@ -0,0 +1,43 @@ + + + (number) + + + The mode for new home directories. If not specified, + the is used to create the mode. + + + useradd and newusers use this + to set the mode of the home directory they create. + + + diff --git a/SOURCES/shadow-utils.login.defs b/SOURCES/shadow-utils.login.defs new file mode 100644 index 0000000..e84c7ab --- /dev/null +++ b/SOURCES/shadow-utils.login.defs @@ -0,0 +1,315 @@ +# +# Please note that the parameters in this configuration file control the +# behavior of the tools from the shadow-utils component. None of these +# tools uses the PAM mechanism, and the utilities that use PAM (such as the +# passwd command) should therefore be configured elsewhere. Refer to +# /etc/pam.d/system-auth for more information. +# + +# +# Delay in seconds before being allowed another attempt after a login failure +# Note: When PAM is used, some modules may enforce a minimum delay (e.g. +# pam_unix(8) enforces a 2s delay) +# +#FAIL_DELAY 3 + +# Currently FAILLOG_ENAB is not supported + +# +# Enable display of unknown usernames when login(1) failures are recorded. +# +#LOG_UNKFAIL_ENAB no + +# Currently LOG_OK_LOGINS is not supported + +# Currently LASTLOG_ENAB is not supported + +# +# Limit the highest user ID number for which the lastlog entries should +# be updated. +# +# No LASTLOG_UID_MAX means that there is no user ID limit for writing +# lastlog entries. +# +#LASTLOG_UID_MAX + +# Currently MAIL_CHECK_ENAB is not supported + +# Currently OBSCURE_CHECKS_ENAB is not supported + +# Currently PORTTIME_CHECKS_ENAB is not supported + +# Currently QUOTAS_ENAB is not supported + +# Currently SYSLOG_SU_ENAB is not supported + +# +# Enable "syslog" logging of newgrp(1) and sg(1) activity. +# +#SYSLOG_SG_ENAB yes + +# Currently CONSOLE is not supported + +# Currently SULOG_FILE is not supported + +# Currently MOTD_FILE is not supported + +# Currently ISSUE_FILE is not supported + +# Currently TTYTYPE_FILE is not supported + +# Currently FTMP_FILE is not supported + +# Currently NOLOGINS_FILE is not supported + +# Currently SU_NAME is not supported + +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# +MAIL_DIR /var/spool/mail +#MAIL_FILE .mail + +# +# If defined, file which inhibits all the usual chatter during the login +# sequence. If a full pathname, then hushed mode will be enabled if the +# user's name or shell are found in the file. If not a full pathname, then +# hushed mode will be enabled if the file exists in the user's home directory. +# +#HUSHLOGIN_FILE .hushlogin +#HUSHLOGIN_FILE /etc/hushlogins + +# Currently ENV_TZ is not supported + +# Currently ENV_HZ is not supported + +# +# The default PATH settings, for superuser and normal users. +# +# (they are minimal, add the rest in the shell startup files) +#ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin +#ENV_PATH PATH=/bin:/usr/bin + +# +# Terminal permissions +# +# TTYGROUP Login tty will be assigned this group ownership. +# TTYPERM Login tty will be set to this permission. +# +# If you have a write(1) program which is "setgid" to a special group +# which owns the terminals, define TTYGROUP as the number of such group +# and TTYPERM as 0620. Otherwise leave TTYGROUP commented out and +# set TTYPERM to either 622 or 600. +# +#TTYGROUP tty +#TTYPERM 0600 + +# Currently ERASECHAR, KILLCHAR and ULIMIT are not supported + +# Default initial "umask" value used by login(1) on non-PAM enabled systems. +# Default "umask" value for pam_umask(8) on PAM enabled systems. +# UMASK is also used by useradd(8) and newusers(8) to set the mode for new +# home directories if HOME_MODE is not set. +# 022 is the default value, but 027, or even 077, could be considered +# for increased privacy. There is no One True Answer here: each sysadmin +# must make up their mind. +UMASK 022 + +# HOME_MODE is used by useradd(8) and newusers(8) to set the mode for new +# home directories. +# If HOME_MODE is not set, the value of UMASK is used to create the mode. +HOME_MODE 0700 + +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_MIN_LEN Minimum acceptable password length. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_MIN_LEN 8 +PASS_WARN_AGE 7 + +# Currently SU_WHEEL_ONLY is not supported + +# Currently CRACKLIB_DICTPATH is not supported + +# +# Min/max values for automatic uid selection in useradd(8) +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +SYS_UID_MIN 201 +SYS_UID_MAX 999 +# Extra per user uids +SUB_UID_MIN 524288 +SUB_UID_MAX 600100000 +SUB_UID_COUNT 65536 + +# +# Min/max values for automatic gid selection in groupadd(8) +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +SYS_GID_MIN 201 +SYS_GID_MAX 999 +# Extra per user group ids +SUB_GID_MIN 524288 +SUB_GID_MAX 600100000 +SUB_GID_COUNT 65536 + +# +# Max number of login(1) retries if password is bad +# +#LOGIN_RETRIES 3 + +# +# Max time in seconds for login(1) +# +#LOGIN_TIMEOUT 60 + +# +# Maximum number of attempts to change password if rejected (too easy) +# +PASS_CHANGE_TRIES 5 + +# +# Warn about weak passwords (but still allow them) if you are root. +# +PASS_ALWAYS_WARN yes + +# +# Number of significant characters in the password for crypt(). +# Default is 8, don't change unless your crypt() is better. +# Ignored if MD5_CRYPT_ENAB set to "yes". +# +#PASS_MAX_LEN 8 + +# Currently CHFN_AUTH is not supported + +# +# Which fields may be changed by regular users using chfn(1) - use +# any combination of letters "frwh" (full name, room number, work +# phone, home phone). If not defined, no changes are allowed. +# For backward compatibility, "yes" = "rwh" and "no" = "frwh". +# +#CHFN_RESTRICT rwh + +# Currently LOGIN_STRING is not supported + +# Currently MD5_CRYPT_ENAB is not supported + +# +# If set to MD5, MD5-based algorithm will be used for encrypting password +# If set to SHA256, SHA256-based algorithm will be used for encrypting password +# If set to SHA512, SHA512-based algorithm will be used for encrypting password +# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password +# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# +ENCRYPT_METHOD YESCRYPT + +# +# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512. +# +# Define the number of SHA rounds. +# With a lot of rounds, it is more difficult to brute-force the password. +# However, more CPU resources will be needed to authenticate users if +# this value is increased. +# +# If not specified, the libc will choose the default number of rounds (5000). +# The values must be within the 1000-999999999 range. +# +#SHA_CRYPT_MAX_ROUNDS 5000 + +# Currently SHA_CRYPT_MIN_ROUNDS is not supported + +# +# Only works if ENCRYPT_METHOD is set to BCRYPT. +# +# Define the number of BCRYPT rounds. +# With a lot of rounds, it is more difficult to brute-force the password. +# However, more CPU resources will be needed to authenticate users if +# this value is increased. +# +# If not specified, 13 rounds will be attempted. +# If only one of the MIN or MAX values is set, then this value will be used. +# If MIN > MAX, the highest value will be used. +# +#BCRYPT_MIN_ROUNDS 13 +#BCRYPT_MAX_ROUNDS 31 + +# +# Only works if ENCRYPT_METHOD is set to YESCRYPT. +# +# Define the YESCRYPT cost factor. +# With a higher cost factor, it is more difficult to brute-force the password. +# However, more CPU time and more memory will be needed to authenticate users +# if this value is increased. +# +# If not specified, a cost factor of 5 will be used. +# The value must be within the 1-11 range. +# +#YESCRYPT_COST_FACTOR 5 + +# Currently CONSOLE_GROUPS is not supported + +# +# Should login be allowed if we can't cd to the home directory? +# Default is yes. +# +#DEFAULT_HOME yes + +# Currently ENVIRON_FILE is not supported + +# +# If defined, this command is run when removing a user. +# It should remove any at/cron/print jobs etc. owned by +# the user to be removed (passed as the first argument). +# +#USERDEL_CMD /usr/sbin/userdel_local + +# +# Enables userdel(8) to remove user groups if no members exist. +# +USERGROUPS_ENAB yes + +# +# If set to a non-zero number, the shadow utilities will make sure that +# groups never have more than this number of users on one line. +# This permits to support split groups (groups split into multiple lines, +# with the same group ID, to avoid limitation of the line length in the +# group file). +# +# 0 is the default value and disables this feature. +# +#MAX_MEMBERS_PER_GROUP 0 + +# +# If useradd(8) should create home directories for users by default (non +# system users only). +# This option is overridden with the -M or -m flags on the useradd(8) +# command-line. +# +CREATE_HOME yes + +# +# Force use shadow, even if shadow passwd & shadow group files are +# missing. +# +#FORCE_SHADOW yes + +# +# Select the HMAC cryptography algorithm. +# Used in pam_timestamp module to calculate the keyed-hash message +# authentication code. +# +# Note: It is recommended to check hmac(3) to see the possible algorithms +# that are available in your system. +# +HMAC_CRYPTO_ALGO SHA512 diff --git a/SOURCES/shadow-utils.useradd b/SOURCES/shadow-utils.useradd new file mode 100644 index 0000000..4e81146 --- /dev/null +++ b/SOURCES/shadow-utils.useradd @@ -0,0 +1,9 @@ +# useradd defaults file +GROUP=100 +HOME=/home +INACTIVE=-1 +EXPIRE= +SHELL=/bin/bash +SKEL=/etc/skel +CREATE_MAIL_SPOOL=yes + diff --git a/SPECS/shadow-utils.spec b/SPECS/shadow-utils.spec new file mode 100644 index 0000000..53c5357 --- /dev/null +++ b/SPECS/shadow-utils.spec @@ -0,0 +1,1457 @@ +Summary: Utilities for managing accounts and shadow password files +Name: shadow-utils +Version: 4.15.0 +Release: 3%{?dist} +Epoch: 2 +License: BSD-3-Clause AND GPL-2.0-or-later +URL: https://github.com/shadow-maint/shadow +Source0: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/v%{version}/shadow-%{version}.tar.xz.asc +Source2: shadow-utils.useradd +Source3: shadow-utils.login.defs +Source4: shadow-bsd.txt +Source5: https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +Source6: shadow-utils.HOME_MODE.xml +Source7: passwd.pamd + +### Globals ### +%global includesubiddir %{_includedir}/shadow + +### Patches ### +# Misc manual page changes - non-upstreamable +Patch0: shadow-4.15.0-manfix.patch +# Date parsing improvement - could be upstreamed +Patch1: shadow-4.15.0-date-parsing.patch +# https://github.com/shadow-maint/shadow/commit/d8e6a8b99b4d844328d875287babf6e13860d464 +Patch2: shadow-4.15.0-sast-fixes.patch +# Audit message changes - partially upstreamed +Patch3: shadow-4.15.0-audit-update.patch +# Probably non-upstreamable +Patch4: shadow-4.15.0-account-tools-setuid.patch +# https://github.com/shadow-maint/shadow/commit/ead55e9ba8958504e23e29545f90c4dd925c7462 +Patch5: shadow-4.15.0-getdef-spurious-error.patch + +### Dependencies ### +Requires: audit-libs >= 1.6.5 +Requires: libselinux >= 1.25.2-1 +Requires: pam-libs +Requires: setup + +### Build Dependencies ### +BuildRequires: audit-libs-devel >= 1.6.5 +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: bison +BuildRequires: docbook-dtds +BuildRequires: docbook-style-xsl +BuildRequires: flex +BuildRequires: gcc +BuildRequires: gettext-devel +BuildRequires: git +BuildRequires: itstool +BuildRequires: libacl-devel +BuildRequires: libattr-devel +BuildRequires: libeconf-devel +BuildRequires: libselinux-devel >= 1.25.2-1 +BuildRequires: libsemanage-devel +BuildRequires: libtool +BuildRequires: libxslt +BuildRequires: make +BuildRequires: pam-devel + +### Provides ### +Provides: shadow = %{epoch}:%{version}-%{release} +Provides: passwd = 0.80-18 +Obsoletes: passwd <= 0.80-19 + +%description +The shadow-utils package includes the necessary programs for +converting UNIX password files to the shadow password format, plus +programs for managing user and group accounts. The pwconv command +converts passwords to the shadow password format. The pwunconv command +unconverts shadow passwords and generates a passwd file (a standard +UNIX password file). The pwck command checks the integrity of password +and shadow files. The lastlog command prints out the last login times +for all users. The useradd, userdel, and usermod commands are used for +managing user accounts. The groupadd, groupdel, and groupmod commands +are used for managing group accounts. + + +### Subpackages ### +%package subid +Summary: A library to manage subordinate uid and gid ranges +License: BSD and GPLv2+ + +%description subid +Utility library that provides a way to manage subid ranges. + + +%package subid-devel +Summary: Development package for shadow-utils-subid +License: BSD and GPLv2+ +Requires: shadow-utils-subid = %{epoch}:%{version}-%{release} + +%description subid-devel +Development files for shadow-utils-subid. + +%prep +%autosetup -p 1 -S git -n shadow-%{version} + +iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 +cp -f doc/HOWTO.utf8 doc/HOWTO + +cp -a %{SOURCE4} %{SOURCE5} . +cp -a %{SOURCE6} man/login.defs.d/HOME_MODE.xml + +# Force regeneration of getdate.c +rm lib/getdate.c + +%build +%ifarch sparc64 +#sparc64 need big PIE +export CFLAGS="$RPM_OPT_FLAGS -fPIE" +export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" +%else +export CFLAGS="$RPM_OPT_FLAGS -fpie" +export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" +%endif + +autoreconf +%configure \ + --enable-shadowgrp \ + --enable-man \ + --with-audit \ + --with-libpam \ + --with-sha-crypt \ + --with-bcrypt \ + --with-yescrypt \ + --with-selinux \ + --without-libbsd \ + --without-libcrack \ + --without-sssd \ + --enable-shared \ + --with-group-name-max-length=32 \ + --enable-lastlog \ + --enable-logind=no \ + --disable-account-tools-setuid +%make_build + +%install +%make_install gnulocaledir=$RPM_BUILD_ROOT%{_datadir}/locale MKINSTALLDIRS=`pwd`/mkinstalldirs +install -d -m 755 $RPM_BUILD_ROOT%{_sysconfdir}/default +install -p -c -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_sysconfdir}/login.defs +install -p -c -m 0600 %{SOURCE2} $RPM_BUILD_ROOT%{_sysconfdir}/default/useradd +install -d -m 755 $RPM_BUILD_ROOT%{_pam_confdir} +install -m 644 %{SOURCE7} $RPM_BUILD_ROOT%{_pam_confdir}/passwd + + +ln -s useradd $RPM_BUILD_ROOT%{_sbindir}/adduser +ln -s useradd.8 $RPM_BUILD_ROOT%{_mandir}/man8/adduser.8 +for subdir in $RPM_BUILD_ROOT%{_mandir}/{??,??_??,??_??.*}/man* ; do + test -d $subdir && test -e $subdir/useradd.8 && echo ".so man8/useradd.8" > $subdir/adduser.8 +done + +# Remove binaries we don't use. +rm $RPM_BUILD_ROOT%{_bindir}/chfn +rm $RPM_BUILD_ROOT%{_bindir}/chsh +rm $RPM_BUILD_ROOT%{_bindir}/expiry +rm $RPM_BUILD_ROOT%{_bindir}/groups +rm $RPM_BUILD_ROOT%{_bindir}/login +rm $RPM_BUILD_ROOT%{_bindir}/su +rm $RPM_BUILD_ROOT%{_bindir}/faillog +rm $RPM_BUILD_ROOT%{_sbindir}/logoutd +rm $RPM_BUILD_ROOT%{_sbindir}/nologin +rm $RPM_BUILD_ROOT%{_mandir}/man1/chfn.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chfn.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/chsh.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/chsh.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/expiry.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/expiry.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/groups.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/groups.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/login.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/login.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/suauth.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/suauth.* +rm $RPM_BUILD_ROOT%{_mandir}/man8/logoutd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man8/logoutd.* +rm $RPM_BUILD_ROOT%{_mandir}/man8/nologin.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man8/nologin.* +rm $RPM_BUILD_ROOT%{_mandir}/man3/getspnam.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man3/getspnam.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/faillog.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/faillog.* +rm $RPM_BUILD_ROOT%{_mandir}/man8/faillog.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man8/faillog.* + +# Remove PAM service files we don't use. +rm $RPM_BUILD_ROOT%{_pam_confdir}/chfn +rm $RPM_BUILD_ROOT%{_pam_confdir}/chpasswd +rm $RPM_BUILD_ROOT%{_pam_confdir}/chsh +rm $RPM_BUILD_ROOT%{_pam_confdir}/groupmems +rm $RPM_BUILD_ROOT%{_pam_confdir}/login +rm $RPM_BUILD_ROOT%{_pam_confdir}/newusers +rm $RPM_BUILD_ROOT%{_pam_confdir}/su + +find $RPM_BUILD_ROOT%{_mandir} -depth -type d -empty -delete +%find_lang shadow +for dir in $(ls -1d $RPM_BUILD_ROOT%{_mandir}/{??,??_??}) ; do + dir=$(echo $dir | sed -e "s|^$RPM_BUILD_ROOT||") + lang=$(basename $dir) +# echo "%%lang($lang) $dir" >> shadow.lang +# echo "%%lang($lang) $dir/man*" >> shadow.lang + echo "%%lang($lang) $dir/man*/*" >> shadow.lang +done + +# Move header files to its own folder +echo $(ls) +mkdir -p $RPM_BUILD_ROOT/%{includesubiddir} +install -m 644 libsubid/subid.h $RPM_BUILD_ROOT/%{includesubiddir}/ + +# Remove .la and .a files created by libsubid +rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la +rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.a + +%files -f shadow.lang +%doc NEWS doc/HOWTO README +%license gpl-2.0.txt shadow-bsd.txt +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/login.defs +%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/default/useradd +%config(noreplace) %{_pam_confdir}/passwd +%{_bindir}/sg +%attr(4755,root,root) %{_bindir}/chage +%attr(4755,root,root) %{_bindir}/gpasswd +%{_bindir}/lastlog +%attr(4755,root,root) %{_bindir}/newgrp +%attr(0755,root,root) %caps(cap_setgid=ep) %{_bindir}/newgidmap +%attr(0755,root,root) %caps(cap_setuid=ep) %{_bindir}/newuidmap +%attr(4755,root,root) %{_bindir}/passwd +%{_sbindir}/adduser +%attr(0755,root,root) %{_sbindir}/user* +%attr(0755,root,root) %{_sbindir}/group* +%{_sbindir}/grpck +%{_sbindir}/pwck +%{_sbindir}/*conv +%{_sbindir}/chpasswd +%{_sbindir}/chgpasswd +%{_sbindir}/newusers +%{_sbindir}/vipw +%{_sbindir}/vigr +%{_mandir}/man1/chage.1* +%{_mandir}/man1/gpasswd.1* +%{_mandir}/man1/sg.1* +%{_mandir}/man1/newgrp.1* +%{_mandir}/man1/newgidmap.1* +%{_mandir}/man1/newuidmap.1* +%{_mandir}/man1/passwd.* +%{_mandir}/man3/shadow.3* +%{_mandir}/man5/shadow.5* +%{_mandir}/man5/login.defs.5* +%{_mandir}/man5/gshadow.5* +%{_mandir}/man5/subuid.5* +%{_mandir}/man5/subgid.5* +%{_mandir}/man8/adduser.8* +%{_mandir}/man8/group*.8* +%{_mandir}/man8/user*.8* +%{_mandir}/man8/pwck.8* +%{_mandir}/man8/grpck.8* +%{_mandir}/man8/chpasswd.8* +%{_mandir}/man8/chgpasswd.8* +%{_mandir}/man8/newusers.8* +%{_mandir}/man8/*conv.8* +%{_mandir}/man8/lastlog.8* +%{_mandir}/man8/vipw.8* +%{_mandir}/man8/vigr.8* + +%files subid +%{_libdir}/libsubid.so.* +%{_bindir}/getsubids +%{_mandir}/man1/getsubids.1* + +%files subid-devel +%{includesubiddir}/subid.h +%{_libdir}/libsubid.so + +%changelog +* Mon Jun 24 2024 Troy Dawson - 2:4.15.0-3 +- Bump release for June 2024 mass rebuild + +* Tue Jun 18 2024 Iker Pedrosa - 2:4.15.0-2 +- Fix static analyzer detected issues. Resolves: RHEL-35383 + +* Wed Apr 3 2024 Iker Pedrosa - 2:4.15.0-1 +- Rebase to version 4.15.0 +- getdef: avoid spurious error messages about unknown configuration options + +* Mon Feb 12 2024 Iker Pedrosa - 2:4.14.0-6 +- Build linking `libpam` + +* Thu Feb 1 2024 Iker Pedrosa - 2:4.14.0-5 +- passwd: Provide binary from this package. Enable libpam and + disable account-tools-setuid. Provide passwd PAM service file. + Resolves: #2233275 +- passwd: provide --stdin option + +* Mon Jan 29 2024 Iker Pedrosa - 2:4.14.0-4 +- Disable SSSD support. Resolves: #2253182 + +* Sat Jan 27 2024 Fedora Release Engineering - 2:4.14.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Tue Oct 3 2023 Iker Pedrosa - 2:4.14.0-2 +- useradd: Set proper SELinux labels for def_usrtemplate + +* Wed Aug 16 2023 Iker Pedrosa - 2:4.14.0-1 +- Rebase to version 4.14.0. Resolves: #2229000 + +* Sat Jul 22 2023 Fedora Release Engineering - 2:4.13-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Tue Jun 06 2023 Yaakov Selkowitz - 2:4.13-7 +- Remove unused libbsd-devel dependency + +* Mon Mar 6 2023 Iker Pedrosa - 2:4.13-6 +- Add libbsd-devel and libeconf-devel as build dependencies + +* Thu Mar 2 2023 Iker Pedrosa - 2:4.13-5 +- newuidmap and newgidmap: support passing pid as fd. Resolves: #2174752 + +* Sat Jan 21 2023 Fedora Release Engineering - 2:4.13-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Wed Nov 23 2022 Iker Pedrosa - 2:4.13-3 +- Change SUB_UID_MIN and SUB_GID_MIN to 524288. Resolves: #2144558 + +* Mon Nov 21 2022 Florian Weimer - 2:4.13-2 +- Fix gshadow configure check (switching to glibc implementation) + +* Wed Nov 9 2022 Iker Pedrosa - 2:4.13-1 +- Rebase to version 4.13 +- SPDX license migration + +* Wed Oct 5 2022 Iker Pedrosa - 2:4.12.3-3 +- chage: Fix regression in print_date. Resolves: #2129336 + +* Fri Sep 9 2022 Iker Pedrosa - 2:4.12.3-2 +- useradd: Do not reset non-existent data in {last,fail}log + +* Mon Aug 22 2022 Iker Pedrosa - 2:4.12.3-1 +- Rebase to version 4.12.3. Resolves: #2117809 + +* Mon Aug 1 2022 Iker Pedrosa - 2:4.11.1-4 +- useradd: modify check ID range for system users. Resolves: #2093692 + +* Sat Jul 23 2022 Fedora Release Engineering - 2:4.11.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Thu Feb 10 2022 Iker Pedrosa - 2:4.11.1-2 +- Fix explicit subid requirement for subid-devel + +* Tue Jan 25 2022 Iker Pedrosa - 2:4.11.1-1 +- Rebase to version 4.11.1 (#2034038) +- Fix release sources +- Add explicit subid requirement for subid-devel + +* Sat Jan 22 2022 Fedora Release Engineering - 2:4.9-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Mon Jan 17 2022 Iker Pedrosa - 2:4.9-9 +- nss: get shadow_logfd with log_get_logfd() (#2038811) +- lib: make shadow_logfd and Prog not extern +- lib: rename Prog to shadow_progname +- lib: provide default values for shadow_progname +- libsubid: use log_set_progname in subid_init + +* Fri Nov 19 2021 Iker Pedrosa - 2:4.9-8 +- getsubids: provide system binary and man page (#1980780) +- pwck: fix segfault when calling fprintf() (#2021339) +- newgrp: fix segmentation fault (#2019553) +- groupdel: fix SIGSEGV when passwd does not exist (#1986111) + +* Fri Nov 12 2021 Iker Pedrosa - 2:4.9-7 +- useradd: change SELinux labels for home files (#2022658) + +* Thu Nov 4 2021 Iker Pedrosa - 2:4.9-6 +- useradd: revert fix memleak of grp (#2018697) + +* Wed Oct 27 2021 Iker Pedrosa - 2:4.9-5 +- useradd: generate home and mail directories with selinux user attribute + +* Thu Sep 23 2021 Iker Pedrosa - 2:4.9-4 +- login.defs: include HMAC_CRYPTO_ALGO key +- Clean spec file: organize dependencies and move License location + +* Tue Aug 17 2021 Iker Pedrosa - 2:4.9-3 +- libmisc: fix default value in SHA_get_salt_rounds() + +* Mon Aug 9 2021 Iker Pedrosa - 2:4.9-2 +- useradd: avoid generating an empty subid range (#1990653) + +* Wed Aug 4 2021 Iker Pedrosa - 2:4.9-1 +- Rebase to version 4.9 +- usermod: allow all group types with -G option (#1975327) +- Clean spec file + +* Fri Jul 23 2021 Fedora Release Engineering - 2:4.8.1-20 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Wed Jul 14 2021 Björn Esser - 2:4.8.1-19 +- Add patch to fix 'fread returns element count, not element size' + +* Wed Jul 14 2021 Iker Pedrosa - 2:4.8.1-18 +- Fix regression issues detected in rhbz#667593 and rhbz#672510 + +* Mon Jul 12 2021 Björn Esser - 2:4.8.1-17 +- Enable bcrypt support, as libxcrypt supports it well + +* Sun Jul 04 2021 Björn Esser - 2:4.8.1-16 +- Add a patch to obtain random bytes using getentropy() +- Update shadow-4.8-crypt_h.patch with the upstreamed version +- Add a patch to make use of crypt_gensalt() from libxcrypt + +* Tue Jun 29 2021 Iker Pedrosa - 2:4.8.1-15 +- useradd: free correct pointer (#1976809) + +* Mon Jun 28 2021 Björn Esser - 2:4.8.1-14 +- Add a patch to fix the used prefix for the bcrypt hash method +- Add a patch to cleanup the code in libmisc/salt.c +- Add a patch adding some clarifying comments in libmisc/salt.c +- Add a patch to obtain random bytes from /dev/urandom + +* Mon Jun 28 2021 Iker Pedrosa - 2:4.8.1-13 +- Covscan fixes + +* Mon Jun 21 2021 Björn Esser - 2:4.8.1-12 +- Backport support for yescrypt hash method +- Add a patch to fix the parameter type of YESCRYPT_salt_cost() + +* Mon Jun 21 2021 Iker Pedrosa - 2:4.8.1-11 +- libsubid: don't print error messages on stderr by default +- libsubid: libsubid_init return false if out of memory +- useradd: fix SUB_UID_COUNT=0 +- libsubid: don't return owner in list_owner_ranges API call +- libsubid: libsubid_init don't print messages on error +- libsubid: fix newusers when nss provides subids +- man: clarify subid delegation +- libsubid: make shadow_logfd not extern + +* Thu May 6 2021 Iker Pedrosa - 2:4.8.1-10 +- man: mention NSS in new[ug]idmap manpages +- libsubid: move development header to shadow folder + +* Fri Apr 16 2021 Iker Pedrosa - 2:4.8.1-9 +- libsubid: creation and nsswitch support +- Creation of subid and subid-devel subpackages + +* Mon Mar 29 2021 Iker Pedrosa - 2:4.8.1-8 +- man: include lastlog file caveat (#951564) +- Upstream links to several patches +- Spec file cleanup by Robert Scheck +- Add BuildRequires: make by Tom Stellard + +* Wed Jan 27 2021 Fedora Release Engineering - 2:4.8.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Mon Nov 9 2020 Iker Pedrosa - 2:4.8.1-6 +- commonio: force lock file sync (#1862056) + +* Tue Nov 3 2020 Petr Lautrbach - 2:4.8.1-5 +- Rebuild with libsemanage.so.2 + +* Wed Jul 29 2020 Fedora Release Engineering - 2:4.8.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Thu May 14 2020 Iker Pedrosa - 2:4.8.1-3 +- check only local groups when adding new supplementary groups to a user (#1727236) + +* Tue Mar 24 2020 Iker Pedrosa - 2:4.8.1-2 +- useradd: clarify the useradd -d parameter behavior in man page + +* Tue Mar 17 2020 Iker Pedrosa - 2:4.8.1-1 +- updated upstream to 4.8.1 + +* Tue Mar 17 2020 Iker Pedrosa - 2:4.8-5 +- synchronized login.defs with upstream file (#1261099 and #1807957) + +* Mon Feb 24 2020 Iker Pedrosa - 2:4.8-4 +- fix useradd: doesn't generate spool mail with the proper SELinux user identity + (#1690527) + +* Thu Jan 30 2020 Fedora Release Engineering - 2:4.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jan 16 2020 Tomáš Mráz - 2:4.8-2 +- make the invalid shell check into warning + +* Mon Jan 13 2020 Tomáš Mráz - 2:4.8-1 +- update to current upstream release 4.8 + +* Mon Sep 2 2019 Tomáš Mráz - 2:4.6-16 +- fix SELinux related problem in chpasswd/chgpasswd when run with -R + (patch by Petr Lautrbach) (#1747215) + +* Fri Jul 26 2019 Fedora Release Engineering - 2:4.6-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Jun 7 2019 Tomáš Mráz - 2:4.6-14 +- minor auditing fixes + +* Fri May 3 2019 Tomáš Mráz - 2:4.6-13 +- use lckpwdf() again to disable concurrent edits of databases by + other applications + +* Tue Apr 2 2019 Tomáš Mráz - 2:4.6-12 +- force regeneration of getdate.c otherwise the date parsing fix + is not applied + +* Fri Mar 22 2019 Tomáš Mráz - 2:4.6-11 +- clarify chage manual page in regards to shadow and passwd + inconsistency (#1686440) + +* Thu Mar 21 2019 Tomáš Mráz - 2:4.6-10 +- Ignore LOGIN_PLAIN_PROMPT variable in login.defs + +* Thu Mar 7 2019 Tim Landscheidt - 2:4.6-9 +- Remove obsolete requirements for post/pre scriptlets + +* Sat Feb 02 2019 Fedora Release Engineering - 2:4.6-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Jan 14 2019 Björn Esser - 2:4.6-7 +- Rebuilt for libcrypt.so.2 (#1666033) + +* Tue Dec 18 2018 Tomáš Mráz - 2:4.6-6 +- usermod: guard against unsafe change of ownership of + special home directories + +* Mon Nov 19 2018 Tomáš Mráz - 2:4.6-5 +- use itstool instead of xml2po + +* Tue Nov 6 2018 Tomáš Mráz - 2:4.6-4 +- use cap_setxid file capabilities for newxidmap instead of making them setuid +- limit the SYS_U/GID_MIN value to 1 as the algorithm does not work with 0 + and the 0 is always used by root anyway +- manual page improvements + +* Wed Oct 10 2018 Tomáš Mráz - 2:4.6-3 +- fix some issues from Coverity scan +- flush sssd caches - patch by Jakub Hrozek + +* Sat Jul 14 2018 Fedora Release Engineering - 2:4.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon May 28 2018 Tomáš Mráz - 2:4.6-1 +- update to current upstream release 4.6 + +* Fri Apr 20 2018 Tomáš Mráz - 2:4.5-10 +- Raise limit for passwd and shadow entry length but also prevent + writing longer entries (#1422497) + +* Tue Feb 06 2018 Björn Esser - 2:4.5-9 +- Add patch to include crypt.h, if present +- Use %%make_{build,install} macros +- Refresh other patches for proper alignment + +* Sat Jan 20 2018 Björn Esser - 2:4.5-8 +- Rebuilt for switch to libxcrypt + +* Mon Nov 6 2017 Tomáš Mráz - 2:4.5-7 +- fix regression caused by the userdel-chroot patch (#1509978) + +* Thu Nov 2 2017 Tomáš Mráz - 2:4.5-6 +- fix userdel in chroot (#1316168) +- add useful chage -E example to chage manpage + +* Fri Sep 15 2017 Tomáš Mráz - 2:4.5-5 +- do not allow "." and ".." user names + +* Mon Aug 14 2017 Tomáš Mráz - 2:4.5-4 +- allow switching to secondary group without checking the membership + explicitly (patch from upstream) + +* Thu Aug 03 2017 Fedora Release Engineering - 2:4.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 2:4.5-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Jul 21 2017 Tomáš Mráz - 2:4.5-1 +- update to current upstream release 4.5 + +* Sat Feb 11 2017 Fedora Release Engineering - 2:4.3.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Aug 25 2016 Tomáš Mráz - 2:4.3.1-2 +- fix regression in useradd - not processing defaults properly (#1369979) + +* Tue Aug 23 2016 Tomáš Mráz - 2:4.3.1-1 +- new upstream release fixing low impact security issue + +* Tue Jun 14 2016 Tomáš Mráz - 2:4.2.1-11 +- guard for localtime() and gmtime() failure + +* Mon May 30 2016 Tomáš Mráz - 2:4.2.1-10 +- chpasswd, chgpasswd: open audit when starting + +* Thu May 26 2016 Tomáš Mráz - 2:4.2.1-9 +- chgpasswd: do not remove it +- chpasswd, chgpasswd: add selinux_check_access call (#1336902) + +* Thu Mar 17 2016 Tomáš Mráz - 2:4.2.1-8 +- userdel: fix userdel -f with /etc/subuid present (#1316168) + +* Tue Feb 9 2016 Tomáš Mráz - 2:4.2.1-7 +- usermod: properly return error during password manipulation + +* Wed Feb 3 2016 Tomáš Mráz - 2:4.2.1-6 +- add possibility to clear or set lastlog record for user via lastlog + +* Fri Jan 8 2016 Tomáš Mráz - 2:4.2.1-5 +- do not use obscure permissions for binaries +- remove unused commands from login.defs(5) cross-reference + +* Fri Nov 6 2015 Tomáš Mráz - 2:4.2.1-4 +- document that groupmems is not setuid root +- document that expiration of the password after inactivity period + locks the user account completely + +* Thu Aug 27 2015 Tomáš Mráz - 2:4.2.1-3 +- unlock also passwords locked with passwd -l +- prevent breaking user entry by entering a password containing colon +- fix possible DoS when locking the database files for update +- properly use login.defs from the chroot in useradd + +* Fri Jun 19 2015 Fedora Release Engineering - 2:4.2.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Wed Nov 26 2014 Tomáš Mráz - 2:4.2.1-1 +- new upstream release with support for subordinate uids and gids + +* Tue Nov 25 2014 Tomáš Mráz - 2:4.1.5.1-22 +- small adjustments to the audit patch + +* Fri Oct 17 2014 Tomáš Mráz - 2:4.1.5.1-21 +- update auditing to cover more events and fix some incorrect audit + records - patch by Steve Grubb (#1151580) +- apply the same new allocation algorithm to uids as for gids + +* Wed Sep 10 2014 Tomas Mraz - 2:4.1.5.1-20 +- discard obsolete matchpathcon cache after semanage_commit() + +* Tue Sep 9 2014 Tomas Mraz - 2:4.1.5.1-19 +- disallow all-numeric user and group names (#1139318) + +* Fri Aug 29 2014 Tomas Mraz - 2:4.1.5.1-18 +- label the newly created home dir correctly (#1077809) +- mention that chage -d 0 forces password change (#1135010) +- improve date parsing and error detecting in chage +- avoid full group database scanning in newgrp in most common case +- report error if usermod asked for moving homedir and it does not exist + +* Mon Aug 18 2014 Fedora Release Engineering - 2:4.1.5.1-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Tue Aug 5 2014 Tom Callaway - 2:4.1.5.1-16 +- fix license handling + +* Mon Jul 14 2014 Tomas Mraz - 2:4.1.5.1-15 +- revert the last change as it is not really needed + +* Thu Jul 10 2014 Tomas Mraz - 2:4.1.5.1-14 +- put system users and groups into /usr/lib/{passwd,group} if + the files exist and SHADOW_USE_USRLIB environment variable is set + Patch by Colin Walters + +* Mon Jun 30 2014 Tomas Mraz - 2:4.1.5.1-13 +- ignore getgrgid() errors for now + +* Mon Jun 30 2014 Tomas Mraz - 2:4.1.5.1-12 +- improve group allocation algorithm - patch by Stephen Gallager (#1089738) + +* Sun Jun 08 2014 Fedora Release Engineering - 2:4.1.5.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Feb 12 2014 Tomas Mraz - 2:4.1.5.1-10 +- clean up login.defs manpage +- properly document userdel -f behavior + +* Fri Oct 18 2013 Tomas Mraz - 2:4.1.5.1-9 +- document that the directory where user's home is created must exist + +* Thu Jul 25 2013 Tomas Mraz - 2:4.1.5.1-8 +- slightly more meaningful error messages if crypt() returns NULL (#988184) +- explicit suid permissions + +* Fri Jul 19 2013 Tomas Mraz - 2:4.1.5.1-7 +- fix useradd man page bugs + +* Fri Jun 14 2013 Tomas Mraz - 2:4.1.5.1-6 +- report error to stdout when SELinux context for home directory + cannot be determined (#973647) +- audit the changing home directory owner (#885797) +- do not set the default SELinux MLS range (#852676) + +* Tue Mar 19 2013 Tomas Mraz - 2:4.1.5.1-5 +- improve the failure syslog message in useradd (#830617) + +* Wed Feb 20 2013 Tomas Mraz - 2:4.1.5.1-4 +- keep the original context if matchpathcon() fails (#912399) + +* Tue Jan 29 2013 Tomas Mraz - 2:4.1.5.1-3 +- fix bugs in merge_group_entries() + +* Fri Jan 11 2013 Tomas Mraz - 2:4.1.5.1-2 +- /etc/default is owned by glibc-common now (#894194) + +* Wed Sep 19 2012 Tomas Mraz - 2:4.1.5.1-1 +- new upstream version +- use the original file permissions when creating backup (#853102) + +* Wed Jul 25 2012 Peter Vrabec - 2:4.1.5-5 +- make /etc/default/useradd world-readable (#835137) + +* Sat Jul 21 2012 Fedora Release Engineering - 2:4.1.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jun 18 2012 Peter Vrabec - 2:4.1.5-3 +- pwconv/grpconv skipped 2nd of consecutive failures (#832995) + +* Thu Mar 22 2012 Peter Vrabec - 2:4.1.5-2 +- fix selinux context handling +- reset selinux context on files copied from skel + +* Mon Mar 19 2012 Peter Vrabec - 2:4.1.5-1 +- upgrade + +* Tue Feb 07 2012 Peter Vrabec - 2:4.1.4.3-14 +- compile with PIE and RELRO flags (#784349) + +* Sat Jan 14 2012 Fedora Release Engineering - 2:4.1.4.3-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Tue Dec 20 2011 Peter Vrabec - 2:4.1.4.3-12 +- fix leaks in .IDs patch (#734340) + +* Wed Nov 16 2011 Peter Vrabec - 2:4.1.4.3-11 +- free memory associated with SELinux security contexts + +* Wed Nov 09 2011 Peter Vrabec - 2:4.1.4.3-10 +- replace semanage call by library call +- useradd man page (#739147) + +* Tue Aug 02 2011 Peter Vrabec - 2:4.1.4.3-9 +- man page adjustment (userdel -Z) + +* Tue Aug 02 2011 Peter Vrabec - 2:4.1.4.3-8 +- fixing semanage issue (#701355) + +* Fri Jul 22 2011 Miloslav Trmač - 2:4.1.4.3-7 +- Make sure /etc/login.defs is not changed on upgrades from Fedora 1[345]. + +* Wed Jun 29 2011 Peter Vrabec - 2:4.1.4.3-6 +- man page fixes (#696213 #674878) + +* Tue Jun 28 2011 Peter Vrabec - 2:4.1.4.3-5 +- userdel option to remove Linux login <-> SELinux login mapping (#639900) +- useradd special exit value if SELinux user mapping is invalid (#639975) +- usermod special exit value if SELinux user mapping is invalid (#639976) + +* Mon Jun 27 2011 Peter Vrabec - 2:4.1.4.3-4 +- refer to PAM in /etc/login.defs (#629277) + +* Mon Jun 06 2011 Peter Vrabec - 2:4.1.4.3-3 +- fix shadow-4.1.4.2-underflow.patch + +* Tue May 31 2011 Peter Vrabec - 2:4.1.4.3-2 +- fix integer underflow in laslog (#706321) + +* Fri May 20 2011 Peter Vrabec - 2:4.1.4.3-1 +- upgrade +- change UID/GID_MIN to #1000 +- fix find_new_uid/gid for big UID/GID_MAX + +* Wed Feb 09 2011 Peter Vrabec - 2:4.1.4.2-11 +- useradd man page (-m option) +- create home directory on fs with noacl +- remove faillog app (pam_tally.so is no longer shipped) + Resolves: #523265, #622320 + +* Tue Feb 01 2011 Peter Vrabec - 2:4.1.4.2-10 +- do not use gshadow functions from glibc, there is a bug + in glibc sgetsgent(#674361) + Resolves: #674234 + +* Wed Jan 05 2011 Peter Vrabec - 2:4.1.4.2-9 +- fix gshadow functions from shadow utils +- make shadow utils use gshadow functions from glibc + Resolves: #665780 + +* Tue Jul 20 2010 Peter Vrabec - 2:4.1.4.2-8 +- fix pwck/grpck hang + Resolves: #586322 + +* Mon Jun 14 2010 Peter Vrabec - 2:4.1.4.2-7 +- fix integer underflow in faillog (#603683) +- use preferred GID for reserved static IDs + +* Thu Apr 29 2010 Peter Vrabec - 2:4.1.4.2-6 +- preserve ACL's on files in /etc/skel + Resolves: #513055 + +* Wed Apr 28 2010 Peter Vrabec - 2:4.1.4.2-5 +- newusers man page more informative +- userdel should not need to run semanage + Resolves: #586330 #586408 + +* Thu Apr 01 2010 Peter Vrabec - 2:4.1.4.2-4 +- fix man directories ownership (#569418) + +* Fri Mar 26 2010 Peter Vrabec - 2:4.1.4.2-3 +- max group name length set to 32 characters + +* Wed Nov 18 2009 Peter Vrabec - 2:4.1.4.2-2 +- apply patches{1,2,3} +- enable SHA512 in /etc/login.defs + +* Mon Sep 07 2009 Peter Vrabec - 2:4.1.4.2-1 +- upgrade + +* Fri Aug 21 2009 Tomas Mraz - 2:4.1.4.1-7 +- rebuilt with new audit + +* Wed Aug 05 2009 Peter Vrabec 2:4.1.4.1-6 +- increase threshold for uid/gid reservations to 200 (#515667) + +* Sun Jul 26 2009 Fedora Release Engineering - 2:4.1.4.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Thu Jul 16 2009 Peter Vrabec 2:4.1.4.1-4 +- fix a list of owned directories (#510366) + +* Thu Jul 16 2009 Peter Vrabec 2:4.1.4.1-3 +- reduce the reuse of system IDs + +* Wed Jul 15 2009 Peter Vrabec 2:4.1.4.1-2 +- speed up sys users look up on LDAP boxes (#511813) + +* Tue Jun 16 2009 Peter Vrabec 2:4.1.4.1-1 +- upgrade + +* Fri May 15 2009 Peter Vrabec 2:4.1.4-1 +- upgrade + +* Wed Apr 22 2009 Peter Vrabec 2:4.1.3.1-2 +- lastlog fix + +* Fri Apr 17 2009 Peter Vrabec 2:4.1.3.1-1 +- upgrade + +* Tue Apr 14 2009 Peter Vrabec 2:4.1.3-2 +- get "-n" option back +- fix selinux issues + +* Tue Apr 14 2009 Peter Vrabec 2:4.1.3-1 +- upgrade + +* Tue Mar 24 2009 Peter Vrabec 2:4.1.2-12 +- don not allow UID/GID = 4294967295 (#484040) + +* Mon Jan 19 2009 Peter Vrabec 2:4.1.2-11 +- fix license tag (#226416) +- get rid of tabs in spec file (#226416) +- convert HOWTO to UTF8 (#226416) + +* Mon Jan 05 2009 Peter Vrabec 2:4.1.2-10 +- Add policycoreutils as Requires, because of restorecon (#478494) + +* Sun Dec 21 2008 Jesse Keating - 2:4.1.2-9 +- Add setup as a Requires. Perhaps this should be a files requires. (#477529) + +* Wed Sep 24 2008 Peter Vrabec 2:4.1.2-8 +- groupmems: check username for valid character (#455603) +- groupmems: don't segfault on nonexistent group (#456088) + +* Thu Sep 11 2008 Peter Vrabec 2:4.1.2-7 +- fix usermod SELinux user mappings change (#458766) + +* Tue Sep 02 2008 Peter Vrabec 2:4.1.2-6 +- audit improvements, thnx. to sgrubb@redhat.com + +* Tue Sep 02 2008 Peter Vrabec 2:4.1.2-5 +- fix groupmems issues (#459825) + +* Mon Jul 28 2008 Peter Vrabec 2:4.1.2-4 +- fix configure options (#456748) + +* Thu Jul 24 2008 Peter Vrabec 2:4.1.2-3 +- recreate selinux patch + +* Tue Jul 22 2008 Peter Vrabec 2:4.1.2-2 +- provide getspnam by man-pages + +* Mon May 26 2008 Peter Vrabec 2:4.1.2-1 +- upgrade + +* Tue May 20 2008 Peter Vrabec 2:4.1.1-2 +- fix salt size problem (#447136) + +* Mon Apr 07 2008 Peter Vrabec 2:4.1.1-1 +- upgrade + +* Fri Mar 07 2008 Peter Vrabec 2:4.1.0-5 +- improve newgrp audit patch + +* Mon Mar 03 2008 Peter Vrabec 2:4.1.0-4 +- fix selinux labeling (#433757) + +* Tue Feb 19 2008 Peter Vrabec 2:4.1.0-3 +- fix groupmems segmentation fault (#430813) + +* Wed Feb 13 2008 Peter Vrabec 2:4.1.0-2 +- fix newgrp audit event + +* Wed Dec 12 2007 Peter Vrabec 2:4.1.0-1 +- new upgrade release from new upstream +- provide vipw and vigr + +* Thu Nov 29 2007 Peter Vrabec 2:4.0.18.1-20 +- do not create mail spool entries for system accounts (#402351) + +* Thu Oct 18 2007 Peter Vrabec 2:4.0.18.1-19 +- fix timestamps when moving home dirs to another file system (#278571) + +* Mon Oct 08 2007 Peter Vrabec 2:4.0.18.1-18 +- mark localized man pages with %%lang + +* Wed Aug 22 2007 Peter Vrabec 2:4.0.18.1-17 +- rebuild + +* Tue Jun 26 2007 Peter Vrabec 2:4.0.18.1-16 +- fix "CAVEATS" section of groupadd man page (#245590) + +* Wed Jun 06 2007 Peter Vrabec 2:4.0.18.1-15 +- fix infinitive loop if there are duplicate entries + in /etc/group (#240915) + +* Wed Jun 06 2007 Peter Vrabec 2:4.0.18.1-14 +- do not run find_new_uid() twice and use getpwuid() to check + UID uniqueness (#236871) + +* Tue Apr 10 2007 Peter Vrabec 2:4.0.18.1-13 +- fix useradd dump core when build without WITH_SELINUX (#235641) + +* Mon Mar 26 2007 Peter Vrabec 2:4.0.18.1-12 +- create user's mailbox file by default (#231311) + +* Fri Mar 16 2007 Peter Vrabec 2:4.0.18.1-11 +- assign system dynamic UID/GID from the top of available UID/GID (#190523) + +* Wed Feb 28 2007 Peter Vrabec 2:4.0.18.1-10 +- spec file fixes to meet fedora standarts. +- fix useless call of restorecon(). (#222159) + +* Sun Jan 14 2007 Peter Vrabec 2:4.0.18.1-9 +- fix append option in usermod (#222540). + +* Thu Dec 21 2006 Dan Walsh 2:4.0.18.1-8 +- Fix execution and creation of Home Directories under SELinux +- Resolves: rhbz#217441 + +* Thu Dec 14 2006 Peter Vrabec 2:4.0.18.1-7 +- fix rpmlint issues + +* Wed Dec 06 2006 Peter Vrabec 2:4.0.18.1-6 +- use MD5 encryption by default (#218629). + +* Thu Nov 30 2006 Steve Grubb 2:4.0.18.1-5 +- Fix SELinux context on home directories created with useradd (#217441) + +* Tue Nov 14 2006 Peter Vrabec 2:4.0.18.1-4 +- fix chpasswd and chgpasswd stack overflow (#213052) + +* Sat Nov 04 2006 Peter Vrabec 2:4.0.18.1-3 +- fix "-g" and "-G" option. + +* Fri Nov 03 2006 Peter Vrabec 2:4.0.18.1-2 +- improve audit logging (#211659) +- improve "-l" option. Do not reset faillog if it's used (#213450). + +* Wed Nov 01 2006 Peter Vrabec 2:4.0.18.1-1 +- upgrade + +* Wed Oct 25 2006 Peter Vrabec 2:4.0.17-7 +- add dist-tag + +* Wed Oct 04 2006 Peter Vrabec 2:4.0.17-6 +- fix regression. Permissions on user* group* binaries + should be 0750, because of CAPP/LSPP certification +- fix groupdel man page + +* Fri Aug 11 2006 Peter Vrabec 2:4.0.17-5 +- fix bug introduced with UIG_GID.patch (#201991) + +* Sat Aug 05 2006 Peter Vrabec 2:4.0.17-4 +- fix userdel, it didn't delete user's group (#201379) + +* Fri Aug 04 2006 Peter Vrabec 2:4.0.17-3 +- fix UID/GID overflow in user* group* (#198920) + +* Fri Aug 04 2006 Peter Vrabec 2:4.0.17-2 +- do not inherit file desc. in execve(nscd) + +* Mon Jul 17 2006 Peter Vrabec 2:4.0.17-1 +- upgrade + +* Wed Jul 12 2006 Jesse Keating - 2:4.0.16-3.1 +- rebuild + +* Tue Jun 13 2006 Peter Vrabec 2:4.0.16-3 +- call "nscd -i" to flush nscd cache (#191464) + +* Sat Jun 10 2006 Peter Vrabec 2:4.0.16-2 +- "useradd -r" must create a system group (#194728) + +* Tue Jun 06 2006 Peter Vrabec 2:4.0.16-1 +- upgrade +- do not replace login.defs file (#190014) + +* Sat Apr 08 2006 Peter Vrabec 2:4.0.15-3 +- fix typo in shadow-4.0.15-login.defs (#188263) + +* Tue Apr 04 2006 Peter Vrabec 2:4.0.15-2 +- properly notify nscd to flush its cache(#186803) + +* Mon Apr 03 2006 Peter Vrabec 2:4.0.15-1 +- upgrade + +* Fri Mar 10 2006 Peter Vrabec 2:4.0.14-4 +- fix lrename() function to handle relative symlinks too + +* Tue Mar 07 2006 Peter Vrabec 2:4.0.14-3 +- set default umask to 077 in login.defs + +* Mon Mar 06 2006 Peter Vrabec 2:4.0.14-2 +- use lrename() function, which follow a destination symbolic link(#181977) + +* Fri Feb 10 2006 Jesse Keating - 2:4.0.14-1.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 2:4.0.14-1.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Jan 06 2006 Peter Vrabec 2:4.0.14-1 +- upgrade + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Tue Nov 29 2005 Peter Vrabec 2:4.0.13-4 +- fix incorrect audit record in userdel (#174392) + +* Wed Nov 16 2005 Peter Vrabec 2:4.0.13-3 +- fix useradd segfaults (#173241) + +* Sat Nov 5 2005 Steve Grubb 2:4.0.13-2 +- Update audit communication to standard format messages + +* Fri Oct 21 2005 Peter Vrabec 2:4.0.13-1 +- upgrade + +* Fri Sep 23 2005 Peter Vrabec 2:4.0.12-4 +- add useradd -l option back, it was removed by mistake + +* Tue Sep 20 2005 Peter Vrabec 2:4.0.12-3 +- provide login.defs man page +- adjust audit patch + +* Tue Aug 30 2005 Peter Vrabec 2:4.0.12-2 +- audit support + +* Sat Aug 27 2005 Peter Vrabec 2:4.0.12-1 +- upgrade + +* Sat Aug 13 2005 Dan Walsh 2:4.0.11.1-5 +- Change to use new selinux api for selinux_check_passwd_access + +* Tue Aug 09 2005 Peter Vrabec 2:4.0.11.1-4 +- change the password last changed field in the shadow file + when "usermod -p" is used (#164943) + +* Mon Aug 08 2005 Peter Vrabec 2:4.0.11.1-3 +- provide getspnam.3 man page(#162476) +- fix useradd man page(#97131) + +* Mon Aug 08 2005 Peter Vrabec 2:4.0.11.1-2 +- do not copy files from skel directory if home directory + already exist (#89591,#80242) + +* Fri Aug 05 2005 Peter Vrabec 2:4.0.11.1-1 +- upgrade + +* Mon May 23 2005 Peter Vrabec 2:4.0.7-9 +- remove vigr binary + +* Mon May 23 2005 Peter Vrabec 2:4.0.7-8 +- fix nscd socket path + +* Fri Apr 29 2005 Jeremy Katz - 2:4.0.7-7 +- don't assume selinux is enabled if is_selinux_enabled() returns -1 + +* Mon Apr 18 2005 Peter Vrabec 2:4.0.7-6 +- fix chage -l option (#109499, #137498) + +* Mon Apr 04 2005 Peter Vrabec 2:4.0.7-5 +- fix memory leak, and CPU spinning when grp_update() and + duplicate group entries in /etc/group (#151484) + +* Tue Mar 29 2005 Peter Vrabec 2:4.0.7-4 +- use newgrp binary +- newgrp don't ask for password if user's default GID = group ID, + ask for password if there is some in /etc/gshadow + and in /etc/group is 'x' (#149997) + +* Mon Mar 14 2005 Peter Vrabec +- gcc4 fix (#150994) 2:4.0.7-3 + +* Mon Mar 07 2005 Peter Vrabec +- man pages cs,es,ko,ru,zh_CN,zh_TW to UTF-8 + +* Wed Mar 02 2005 Peter Vrabec +- upgrade 2:4.0.7-1 + +* Fri Feb 25 2005 Peter Vrabec 2:4.0.3-59 +- static limit on group count to dynamic (#125510, #148994, #147742) + +* Mon Feb 21 2005 Peter Vrabec 2:4.0.3-58 +- add "-l" option #146214 + +* Mon Feb 14 2005 Adrian Havill +- rebuilt + +* Wed Feb 9 2005 Dan Walsh 2:4.0.3-39 +- Change useradd to use matchpathcon + +* Thu Oct 21 2004 Dan Walsh 2:4.0.3-37 +- Add matchpathcon to create the files correctly when they do not exist. + +* Mon Oct 18 2004 Miloslav Trmac - 2:4.0.3-36 +- Change symlink ownership when copying from /etc/skel (#66819, patch by + Michael Weiser) + +* Fri Oct 15 2004 Adrian Havill 2:4.0.3-35 +- make the limit for the group name the same as the username (determined + by the header files, rather than a constant) (#56850) + +* Wed Oct 13 2004 Adrian Havill 2:4.0.3-33 +- allow for mixed case and dots in usernames (#135401) +- all man pages to UTF-8, not just Japanese (#133883) +- add Polish blurb for useradd -n man page option (#82177) + +* Tue Oct 12 2004 Adrian Havill 2:4.0.3-31 +- check for non-standard legacy place for ncsd HUP (/var/run/nscd.pid) and + then the std FHS place (/var/run/nscd.pid) (#125421) + +* Fri Oct 1 2004 Dan Walsh 2:4.0.3-30 +- Add checkPasswdAccess for chage in SELinux + +* Sun Sep 26 2004 Adrian Havill 2:4.0.3-29 +- always unlock all files on any exit (#126709) + +* Tue Aug 24 2004 Warren Togami 2:4.0.3-26 +- #126596 fix Req and BuildReqs + +* Sun Aug 1 2004 Alan Cox 4.0.3-25 +- Fix build deps etc, move to current auto* (Steve Grubb) + +* Sat Jul 10 2004 Alan Cox 4.0.3-24 +- Fix nscd path. This fixes various stale data caching bugs (#125421) + +* Thu Jun 17 2004 Dan Walsh 4.0.3-23 +- Add get_enforce checks +- Clean up patch for potential upstream submission +- Add removemalloc patch to get it to build on 3.4 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Tue Mar 30 2004 Nalin Dahyabhai 4.0.3-21 +- rebuild + +* Tue Mar 30 2004 Nalin Dahyabhai 4.0.3-20 +- make /etc/default world-readable, needed for #118338 + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Wed Jan 21 2004 Dan Walsh 4.0.3-18 +- Fix selinux relabel of /etc/passwd file + +* Wed Jan 7 2004 Nalin Dahyabhai 4.0.3-17 +- fix use of uninitialized memory in useradd (#89145) + +* Tue Dec 16 2003 Nalin Dahyabhai 4.0.3-16 +- back to UTF-8 again +- remove getspnam(3) man page, now conflicts with man-pages 1.64 + +* Thu Nov 13 2003 Nalin Dahyabhai 4.0.3-15 +- don't convert man pages to UTF-8 for RHEL 3, conditionalized using macro +- fixup dangling man page references + +* Mon Nov 10 2003 Nalin Dahyabhai 4.0.3-14 +- lastlog: don't pass a possibly-smaller field to localtime (#109648) +- configure: call AC_SYS_LARGEFILE to get large file support + +* Fri Nov 7 2003 Dan Walsh 4.0.3-13.sel +- turn on SELinux support + +* Wed Oct 22 2003 Nalin Dahyabhai 4.0.3-12 +- convert ja man pages to UTF-8 (#106051) +- override MKINSTALLDIRS at install-time (#107476) + +* Mon Sep 8 2003 Dan Walsh +- turn off SELinux support + +* Thu Sep 4 2003 Dan Walsh 4.0.3-11.sel +- build with SELinux support + +* Mon Jul 28 2003 Dan Walsh 4.0.3-10 +- Add SELinux support + +* Wed Jun 04 2003 Elliot Lee +- rebuilt + +* Wed Jun 4 2003 Nalin Dahyabhai 4.0.3-8 +- rebuild + +* Tue Jun 3 2003 Nalin Dahyabhai 4.0.3-7 +- run autoconf to generate updated configure at compile-time + +* Wed Feb 12 2003 Nalin Dahyabhai 4.0.3-6 +- adjust mailspool patch to complain if no group named "mail" exists, even + though that should never happen + +* Tue Feb 11 2003 Nalin Dahyabhai 4.0.3-5 +- fix perms on mailspools created by useradd to be owned by the "mail" + group (#59810) + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Mon Dec 9 2002 Nalin Dahyabhai 4.0.3-3 +- install the shadow.3 man page + +* Mon Nov 25 2002 Nalin Dahyabhai 4.0.3-2 +- disable use of cracklib at build-time +- fixup reserved-account changes for useradd + +* Thu Nov 21 2002 Nalin Dahyabhai 4.0.3-1 +- update to 4.0.3, bumping epoch + +* Mon Nov 18 2002 Nalin Dahyabhai 20000902-14 +- remove man pages which conflict with the man-pages package(s) + +* Fri Nov 15 2002 Nalin Dahyabhai 20000902-13 +- prevent libshadow from being built more than once, to keep automake happy +- change how md5 and md5crypt are enabled, to keep autoconf happy +- remove unpackaged files after %%install + +* Thu Aug 29 2002 Nalin Dahyabhai 20000902-12 +- force .mo files to be regenerated with current gettext to flush out possible + problems +- fixup non-portable encodings in translations +- make sv translation header non-fuzzy so that it will be included (#71281) + +* Fri Aug 23 2002 Nalin Dahyabhai 20000902-11 +- don't apply aging parameters when creating system accounts (#67408) + +* Fri Jun 21 2002 Tim Powers +- automated rebuild + +* Sun May 26 2002 Tim Powers +- automated rebuild + +* Fri May 17 2002 Nalin Dahyabhai 20000902-8 +- rebuild in new environment + +* Wed Mar 27 2002 Nalin Dahyabhai 20000902-7 +- rebuild with proper defines to get support for large lastlog files (#61983) + +* Fri Feb 22 2002 Nalin Dahyabhai 20000902-6 +- rebuild + +* Fri Jan 25 2002 Nalin Dahyabhai 20000902-5 +- fix autoheader breakage and random other things autotools complain about + +* Mon Aug 27 2001 Nalin Dahyabhai 20000902-4 +- use -O0 instead of -O on ia64 +- build in source directory +- don't leave lock files on the filesystem when useradd creates a group for + the user (#50269) +- fix the -o option to check for duplicate UIDs instead of login names (#52187) + +* Thu Jul 26 2001 Bill Nottingham 20000902-3 +- build with -O on ia64 + +* Fri Jun 08 2001 Than Ngo 20000902-2 +- fixup broken specfile + +* Tue May 22 2001 Bernhard Rosenkraenzer 20000902-1 +- Create an empty mailspool when creating a user so non-setuid/non-setgid + MDAs (postfix+procmail) can deliver mail (#41811) +- 20000902 +- adapt patches + +* Fri Mar 9 2001 Nalin Dahyabhai +- don't overwrite user dot files in useradd (#19982) +- truncate new files when moving overwriting files with the contents of other + files while moving directories (keeps files from looking weird later on) +- configure using %%{_prefix} as the prefix + +* Fri Feb 23 2001 Trond Eivind Glomsrxd +- langify + +* Wed Aug 30 2000 Bernhard Rosenkraenzer +- Fix up chage behavior (Bug #15883) + +* Wed Aug 30 2000 Bernhard Rosenkraenzer +- 20000826 +- Fix up useradd man page (Bug #17036) + +* Tue Aug 8 2000 Bernhard Rosenkraenzer +- check for vipw lock before adding or deleting users (Bug #6489) + +* Mon Aug 7 2000 Nalin Dahyabhai +- take LOG_CONS out of the openlog() call so that we don't litter the + screen during text-mode upgrades + +* Tue Jul 18 2000 Bernhard Rosenkraenzer +- Remove a fixed-size buffer that caused problems when adding a huge number + of users to a group (>8192 bytes) (Bugs #3809, #11930) + +* Tue Jul 18 2000 Bernhard Rosenkraenzer +- remove dependency on util-linux because it causes prereq loops + +* Tue Jul 18 2000 Nalin Dahyabhai +- change symlinked man pages to includers +- require /usr/bin/newgrp (util-linux) so that /usr/bin/sg isn't left dangling + +* Wed Jul 12 2000 Prospector +- automatic rebuild + +* Sun Jun 18 2000 Matt Wilson +- use mandir for FHS +- added patches in src/ and po/ to honor DESTDIR +- use make install DESTDIR=$RPM_BUILD_ROOT + +* Wed Feb 16 2000 Bernhard Rosenkraenzer +- Fix up usermod's symlink behavior (Bug #5458) + +* Fri Feb 11 2000 Cristian Gafton +- get rid of mkpasswd + +* Mon Feb 7 2000 Nalin Dahyabhai +- fix usermod patch to check for shadow before doing any shadow-specific stuff + and merge it into the pwlock patch + +* Sat Feb 5 2000 Bernhard Rosenkraenzer +- fix man symlinks + +* Wed Feb 2 2000 Nalin Dahyabhai +- make -p only change shadow password (bug #8923) + +* Mon Jan 31 2000 Cristian Gafton +- rebuild to fix dependeencies +- man pages are compressed + +* Wed Jan 19 2000 Bernhard Rosenkraenzer +- Fix a security bug (adduser could overwrite previously existing + groups, Bug #8609) + +* Sun Jan 9 2000 Bernhard Rosenkraenzer +- unset LINGUAS before building +- Fix typo in newusers manpage (Bug #8258) +- libtoolize + +* Wed Sep 22 1999 Cristian Gafton +- fix segfault for userdel when the primary group for the user is not + defined + +* Tue Sep 21 1999 Cristian Gafton +- Serial: 1 because now we are using 19990827 (why the heck can't they have + a normal version just like everybody else?!) +- ported all patches to the new code base + +* Thu Apr 15 1999 Bill Nottingham +- SIGHUP nscd from usermod, too + +* Fri Apr 09 1999 Michael K. Johnson +- added usermod password locking from Chris Adams + +* Thu Apr 08 1999 Bill Nottingham +- have things that modify users/groups SIGHUP nscd on exit + +* Wed Mar 31 1999 Michael K. Johnson +- have userdel remove user private groups when it is safe to do so +- allow -f to force user removal even when user appears busy in utmp + +* Tue Mar 23 1999 Preston Brown +- edit out unused CHFN fields from login.defs. + +* Sun Mar 21 1999 Cristian Gafton +- auto rebuild in the new build environment (release 7) + +* Wed Jan 13 1999 Bill Nottingham +- configure fix for arm + +* Wed Dec 30 1998 Cristian Gafton +- build against glibc 2.1 + +* Fri Aug 21 1998 Jeff Johnson +- Note that /usr/sbin/mkpasswd conflicts with /usr/bin/mkpasswd; + one of these (I think /usr/sbin/mkpasswd but other opinions are valid) + should probably be renamed. In any case, mkpasswd.8 from this package + needs to be installed. (problem #823) + +* Fri May 08 1998 Prospector System +- translations modified for de, fr, tr + +* Tue Apr 21 1998 Cristian Gafton +- updated to 980403 +- redid the patches + +* Tue Dec 30 1997 Cristian Gafton +- updated the spec file +- updated the patch so that new accounts created on shadowed system won't + confuse pam_pwdb anymore ('!!' default password instead on '!') +- fixed a bug that made useradd -G segfault +- the check for the ut_user is now patched into configure + +* Thu Nov 13 1997 Erik Troan +- added patch for XOPEN oddities in glibc headers +- check for ut_user before checking for ut_name -- this works around some + confusion on glibc 2.1 due to the utmpx header not defining the ut_name + compatibility stuff. I used a gross sed hack here because I couldn't make + automake work properly on the sparc (this could be a glibc 2.0.99 problem + though). The utuser patch works fine, but I don't apply it. +- sleep after running autoconf + +* Thu Nov 06 1997 Cristian Gafton +- added forgot lastlog command to the spec file + +* Mon Oct 27 1997 Cristian Gafton +- obsoletes adduser + +* Thu Oct 23 1997 Cristian Gafton +- modified groupadd; updated the patch + +* Fri Sep 12 1997 Cristian Gafton +- updated to 970616 +- changed useradd to meet RH specs +- fixed some bugs + +* Tue Jun 17 1997 Erik Troan +- built against glibc