diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7b65955 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/shadow-4.9.tar.xz diff --git a/.shadow-utils.metadata b/.shadow-utils.metadata new file mode 100644 index 0000000..db7b7f1 --- /dev/null +++ b/.shadow-utils.metadata @@ -0,0 +1 @@ +fa2307ff6c85ab3863d9e24dba0935bbbb337f3f SOURCES/shadow-4.9.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/shadow-4.2.1-date-parsing.patch b/SOURCES/shadow-4.2.1-date-parsing.patch new file mode 100644 index 0000000..2a798d0 --- /dev/null +++ b/SOURCES/shadow-4.2.1-date-parsing.patch @@ -0,0 +1,69 @@ +Index: shadow-4.5/libmisc/getdate.y +=================================================================== +--- shadow-4.5.orig/libmisc/getdate.y ++++ shadow-4.5/libmisc/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.5-usermod-unlock.patch b/SOURCES/shadow-4.5-usermod-unlock.patch new file mode 100644 index 0000000..e2d70b5 --- /dev/null +++ b/SOURCES/shadow-4.5-usermod-unlock.patch @@ -0,0 +1,64 @@ +Index: shadow-4.5/src/usermod.c +=================================================================== +--- shadow-4.5.orig/src/usermod.c ++++ shadow-4.5/src/usermod.c +@@ -455,14 +455,17 @@ static char *new_pw_passwd (char *pw_pas + strcat (buf, pw_pass); + pw_pass = buf; + } else if (Uflg && pw_pass[0] == '!') { +- char *s; ++ char *s = pw_pass; + +- if (pw_pass[1] == '\0') { ++ while ('!' == *s) ++ ++s; ++ ++ if (*s == '\0') { + fprintf (stderr, + _("%s: unlocking the user's password would result in a passwordless account.\n" + "You should set a password with usermod -p to unlock this user's password.\n"), + Prog); +- return pw_pass; ++ return NULL; + } + + #ifdef WITH_AUDIT +@@ -471,12 +474,15 @@ static char *new_pw_passwd (char *pw_pas + user_newname, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); +- s = pw_pass; +- while ('\0' != *s) { +- *s = *(s + 1); +- s++; +- } ++ memmove (pw_pass, s, strlen (s) + 1); + } else if (pflg) { ++ if (strchr (user_pass, ':') != NULL) { ++ fprintf (stderr, ++ _("%s: The password field cannot contain a colon character.\n"), ++ Prog); ++ return NULL; ++ ++ } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, + "updating-password", +@@ -525,6 +531,8 @@ static void new_pwent (struct passwd *pw + if ( (!is_shadow_pwd) + || (strcmp (pwent->pw_passwd, SHADOW_PASSWD_STRING) != 0)) { + pwent->pw_passwd = new_pw_passwd (pwent->pw_passwd); ++ if (pwent->pw_passwd == NULL) ++ fail_exit (E_PW_UPDATE); + } + + if (uflg) { +@@ -639,6 +647,8 @@ static void new_spent (struct spwd *spen + * + aging has been requested + */ + spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp); ++ if (spent->sp_pwdp == NULL) ++ fail_exit(E_PW_UPDATE); + + if (pflg) { + spent->sp_lstchg = (long) gettime () / SCALE; diff --git a/SOURCES/shadow-4.6-move-home.patch b/SOURCES/shadow-4.6-move-home.patch new file mode 100644 index 0000000..cff9561 --- /dev/null +++ b/SOURCES/shadow-4.6-move-home.patch @@ -0,0 +1,15 @@ +diff -up shadow-4.6/src/usermod.c.move-home shadow-4.6/src/usermod.c +--- shadow-4.6/src/usermod.c.move-home 2018-05-28 14:59:05.594076665 +0200 ++++ shadow-4.6/src/usermod.c 2018-05-28 15:00:28.479837392 +0200 +@@ -1845,6 +1845,11 @@ static void move_home (void) + Prog, prefix_user_home, prefix_user_newhome); + fail_exit (E_HOMEDIR); + } ++ } else { ++ fprintf (stderr, ++ _("%s: The previous home directory (%s) does " ++ "not exist or is inaccessible. Move cannot be completed.\n"), ++ Prog, prefix_user_home); + } + } + diff --git a/SOURCES/shadow-4.6-sysugid-min-limit.patch b/SOURCES/shadow-4.6-sysugid-min-limit.patch new file mode 100644 index 0000000..4cea6ef --- /dev/null +++ b/SOURCES/shadow-4.6-sysugid-min-limit.patch @@ -0,0 +1,34 @@ +diff -up shadow-4.6/libmisc/find_new_gid.c.min-limit shadow-4.6/libmisc/find_new_gid.c +--- shadow-4.6/libmisc/find_new_gid.c.min-limit 2018-04-29 18:42:37.000000001 +0200 ++++ shadow-4.6/libmisc/find_new_gid.c 2018-11-06 10:51:20.554963292 +0100 +@@ -82,6 +82,13 @@ static int get_ranges (bool sys_group, g + (unsigned long) *max_id); + return EINVAL; + } ++ /* ++ * Zero is reserved for root and the allocation algorithm does not ++ * work right with it. ++ */ ++ if (*min_id == 0) { ++ *min_id = (gid_t) 1; ++ } + } else { + /* Non-system groups */ + +diff -up shadow-4.6/libmisc/find_new_uid.c.min-limit shadow-4.6/libmisc/find_new_uid.c +--- shadow-4.6/libmisc/find_new_uid.c.min-limit 2018-04-29 18:42:37.000000001 +0200 ++++ shadow-4.6/libmisc/find_new_uid.c 2018-11-06 10:51:39.341399569 +0100 +@@ -82,6 +82,13 @@ static int get_ranges (bool sys_user, ui + (unsigned long) *max_id); + return EINVAL; + } ++ /* ++ * Zero is reserved for root and the allocation algorithm does not ++ * work right with it. ++ */ ++ if (*min_id == 0) { ++ *min_id = (uid_t) 1; ++ } + } else { + /* Non-system users */ + diff --git a/SOURCES/shadow-4.8-goodname.patch b/SOURCES/shadow-4.8-goodname.patch new file mode 100644 index 0000000..f3c18d5 --- /dev/null +++ b/SOURCES/shadow-4.8-goodname.patch @@ -0,0 +1,100 @@ +diff -up shadow-4.8/libmisc/chkname.c.goodname shadow-4.8/libmisc/chkname.c +--- shadow-4.8/libmisc/chkname.c.goodname 2020-01-13 09:44:41.968507996 +0100 ++++ shadow-4.8/libmisc/chkname.c 2020-01-13 09:46:27.863727732 +0100 +@@ -55,26 +55,44 @@ static bool is_valid_name (const char *n + } + + /* +- * User/group names must match [a-z_][a-z0-9_-]*[$] +- */ ++ * User/group names must match gnu e-regex: ++ * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]? ++ * ++ * as a non-POSIX, extension, allow "$" as the last char for ++ * sake of Samba 3.x "add machine script" ++ * ++ * Also do not allow fully numeric names or just "." or "..". ++ */ ++ int numeric; + +- if (('\0' == *name) || +- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) { ++ if ('\0' == *name || ++ ('.' == *name && (('.' == name[1] && '\0' == name[2]) || ++ '\0' == name[1])) || ++ !((*name >= 'a' && *name <= 'z') || ++ (*name >= 'A' && *name <= 'Z') || ++ (*name >= '0' && *name <= '9') || ++ *name == '_' || ++ *name == '.')) { + return false; + } + ++ numeric = isdigit(*name); ++ + while ('\0' != *++name) { +- if (!(( ('a' <= *name) && ('z' >= *name) ) || +- ( ('0' <= *name) && ('9' >= *name) ) || +- ('_' == *name) || +- ('-' == *name) || +- ( ('$' == *name) && ('\0' == *(name + 1)) ) ++ if (!((*name >= 'a' && *name <= 'z') || ++ (*name >= 'A' && *name <= 'Z') || ++ (*name >= '0' && *name <= '9') || ++ *name == '_' || ++ *name == '.' || ++ *name == '-' || ++ (*name == '$' && name[1] == '\0') + )) { + return false; + } ++ numeric &= isdigit(*name); + } + +- return true; ++ return !numeric; + } + + bool is_valid_user_name (const char *name) +diff -up shadow-4.8/man/groupadd.8.xml.goodname shadow-4.8/man/groupadd.8.xml +--- shadow-4.8/man/groupadd.8.xml.goodname 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/man/groupadd.8.xml 2020-01-13 09:44:41.968507996 +0100 +@@ -273,10 +273,12 @@ + + CAVEATS + +- Groupnames must start with a lower case letter or an underscore, +- followed by lower case letters, digits, underscores, or dashes. +- They can end with a dollar sign. +- In regular expression terms: [a-z_][a-z0-9_-]*[$]? ++ Groupnames may contain only lower and upper case letters, digits, ++ underscores, or dashes. They can end with a dollar sign. ++ ++ Dashes are not allowed at the beginning of the groupname. ++ Fully numeric groupnames and groupnames . or .. are ++ also disallowed. + + + Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long. +diff -up shadow-4.8/man/useradd.8.xml.goodname shadow-4.8/man/useradd.8.xml +--- shadow-4.8/man/useradd.8.xml.goodname 2019-10-05 03:23:58.000000000 +0200 ++++ shadow-4.8/man/useradd.8.xml 2020-01-13 09:44:41.968507996 +0100 +@@ -661,10 +661,14 @@ + + + +- Usernames must start with a lower case letter or an underscore, +- followed by lower case letters, digits, underscores, or dashes. +- They can end with a dollar sign. +- In regular expression terms: [a-z_][a-z0-9_-]*[$]? ++ Usernames may contain only lower and upper case letters, digits, ++ underscores, or dashes. They can end with a dollar sign. ++ ++ Dashes are not allowed at the beginning of the username. ++ Fully numeric usernames and usernames . or .. are ++ also disallowed. It is not recommended to use usernames beginning ++ with . character as their home directories will be hidden in ++ the ls output. + + + Usernames may only be up to 32 characters long. diff --git a/SOURCES/shadow-4.8-ignore-login-prompt.patch b/SOURCES/shadow-4.8-ignore-login-prompt.patch new file mode 100644 index 0000000..c93aae7 --- /dev/null +++ b/SOURCES/shadow-4.8-ignore-login-prompt.patch @@ -0,0 +1,11 @@ +diff -up shadow-4.8/lib/getdef.c.login-prompt shadow-4.8/lib/getdef.c +--- shadow-4.8/lib/getdef.c.login-prompt 2020-01-13 10:38:44.852796681 +0100 ++++ shadow-4.8/lib/getdef.c 2020-01-13 10:39:54.472612511 +0100 +@@ -98,6 +98,7 @@ static struct itemdef def_table[] = { + {"LASTLOG_UID_MAX", NULL}, + {"LOGIN_RETRIES", NULL}, + {"LOGIN_TIMEOUT", NULL}, ++ {"LOGIN_PLAIN_PROMPT", NULL}, + {"LOG_OK_LOGINS", NULL}, + {"LOG_UNKFAIL_ENAB", NULL}, + {"MAIL_DIR", NULL}, diff --git a/SOURCES/shadow-4.8-long-entry.patch b/SOURCES/shadow-4.8-long-entry.patch new file mode 100644 index 0000000..64d9636 --- /dev/null +++ b/SOURCES/shadow-4.8-long-entry.patch @@ -0,0 +1,86 @@ +diff -up shadow-4.8/lib/defines.h.long-entry shadow-4.8/lib/defines.h +--- shadow-4.8/lib/defines.h.long-entry 2020-01-13 10:29:45.288957339 +0100 ++++ shadow-4.8/lib/defines.h 2020-01-13 10:30:47.482902954 +0100 +@@ -388,6 +388,9 @@ extern char *strerror (); + # endif + #endif + ++/* Maximum length of passwd entry */ ++#define PASSWD_ENTRY_MAX_LENGTH 32768 ++ + #ifdef HAVE_SECURE_GETENV + # define shadow_getenv(name) secure_getenv(name) + # else +diff -up shadow-4.8/lib/pwio.c.long-entry shadow-4.8/lib/pwio.c +--- shadow-4.8/lib/pwio.c.long-entry 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/pwio.c 2020-01-13 10:29:45.288957339 +0100 +@@ -79,7 +79,10 @@ static int passwd_put (const void *ent, + || (pw->pw_gid == (gid_t)-1) + || (valid_field (pw->pw_gecos, ":\n") == -1) + || (valid_field (pw->pw_dir, ":\n") == -1) +- || (valid_field (pw->pw_shell, ":\n") == -1)) { ++ || (valid_field (pw->pw_shell, ":\n") == -1) ++ || (strlen (pw->pw_name) + strlen (pw->pw_passwd) + ++ strlen (pw->pw_gecos) + strlen (pw->pw_dir) + ++ strlen (pw->pw_shell) + 100 > PASSWD_ENTRY_MAX_LENGTH)) { + return -1; + } + +diff -up shadow-4.8/lib/sgetpwent.c.long-entry shadow-4.8/lib/sgetpwent.c +--- shadow-4.8/lib/sgetpwent.c.long-entry 2019-10-05 03:23:58.000000000 +0200 ++++ shadow-4.8/lib/sgetpwent.c 2020-01-13 10:29:45.288957339 +0100 +@@ -57,7 +57,7 @@ + struct passwd *sgetpwent (const char *buf) + { + static struct passwd pwent; +- static char pwdbuf[1024]; ++ static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH]; + register int i; + register char *cp; + char *fields[NFIELDS]; +@@ -67,8 +67,10 @@ struct passwd *sgetpwent (const char *bu + * the password structure remain valid. + */ + +- if (strlen (buf) >= sizeof pwdbuf) ++ if (strlen (buf) >= sizeof pwdbuf) { ++ fprintf (stderr, "Too long passwd entry encountered, file corruption?\n"); + return 0; /* fail if too long */ ++ } + strcpy (pwdbuf, buf); + + /* +diff -up shadow-4.8/lib/sgetspent.c.long-entry shadow-4.8/lib/sgetspent.c +--- shadow-4.8/lib/sgetspent.c.long-entry 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/sgetspent.c 2020-01-13 10:29:45.289957322 +0100 +@@ -48,7 +48,7 @@ + */ + struct spwd *sgetspent (const char *string) + { +- static char spwbuf[1024]; ++ static char spwbuf[PASSWD_ENTRY_MAX_LENGTH]; + static struct spwd spwd; + char *fields[FIELDS]; + char *cp; +@@ -61,6 +61,7 @@ struct spwd *sgetspent (const char *stri + */ + + if (strlen (string) >= sizeof spwbuf) { ++ fprintf (stderr, "Too long shadow entry encountered, file corruption?\n"); + return 0; /* fail if too long */ + } + strcpy (spwbuf, string); +diff -up shadow-4.8/lib/shadowio.c.long-entry shadow-4.8/lib/shadowio.c +--- shadow-4.8/lib/shadowio.c.long-entry 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8/lib/shadowio.c 2020-01-13 10:29:45.289957322 +0100 +@@ -79,7 +79,9 @@ static int shadow_put (const void *ent, + + if ( (NULL == sp) + || (valid_field (sp->sp_namp, ":\n") == -1) +- || (valid_field (sp->sp_pwdp, ":\n") == -1)) { ++ || (valid_field (sp->sp_pwdp, ":\n") == -1) ++ || (strlen (sp->sp_namp) + strlen (sp->sp_pwdp) + ++ 1000 > PASSWD_ENTRY_MAX_LENGTH)) { + return -1; + } + diff --git a/SOURCES/shadow-4.8-selinux-perms.patch b/SOURCES/shadow-4.8-selinux-perms.patch new file mode 100644 index 0000000..dfb32ec --- /dev/null +++ b/SOURCES/shadow-4.8-selinux-perms.patch @@ -0,0 +1,240 @@ +diff -up shadow-4.8/src/chgpasswd.c.selinux-perms shadow-4.8/src/chgpasswd.c +--- shadow-4.8/src/chgpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8/src/chgpasswd.c 2020-01-13 10:21:44.558107260 +0100 +@@ -39,6 +39,13 @@ + #include + #include + #include ++#ifdef WITH_SELINUX ++#include ++#include ++#endif ++#ifdef WITH_LIBAUDIT ++#include ++#endif + #ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + #include "pam_defs.h" +@@ -80,6 +87,9 @@ static bool sgr_locked = false; + #endif + static bool gr_locked = false; + ++/* The name of the caller */ ++static char *myname = NULL; ++ + /* local function prototypes */ + static void fail_exit (int code); + static /*@noreturn@*/void usage (int status); +@@ -334,6 +344,63 @@ static void check_perms (void) + #endif /* ACCT_TOOLS_SETUID */ + } + ++#ifdef WITH_SELINUX ++static int ++log_callback (int type, const char *fmt, ...) ++{ ++ int audit_fd; ++ va_list ap; ++ ++ va_start(ap, fmt); ++#ifdef WITH_AUDIT ++ audit_fd = audit_open(); ++ ++ if (audit_fd >= 0) { ++ char *buf; ++ ++ if (vasprintf (&buf, fmt, ap) < 0) ++ goto ret; ++ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, ++ NULL, 0); ++ audit_close(audit_fd); ++ free(buf); ++ goto ret; ++ } ++ ++#endif ++ vsyslog (LOG_USER | LOG_INFO, fmt, ap); ++ret: ++ va_end(ap); ++ return 0; ++} ++ ++static void ++selinux_check_root (void) ++{ ++ int status = -1; ++ security_context_t user_context; ++ union selinux_callback old_callback; ++ ++ if (is_selinux_enabled() < 1) ++ return; ++ ++ old_callback = selinux_get_callback(SELINUX_CB_LOG); ++ /* setup callbacks */ ++ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback); ++ if ((status = getprevcon(&user_context)) < 0) { ++ selinux_set_callback(SELINUX_CB_LOG, old_callback); ++ exit(1); ++ } ++ ++ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL); ++ ++ selinux_set_callback(SELINUX_CB_LOG, old_callback); ++ freecon(user_context); ++ if (status != 0 && security_getenforce() != 0) ++ exit(1); ++} ++#endif ++ + /* + * open_files - lock and open the group databases + */ +@@ -427,6 +494,7 @@ int main (int argc, char **argv) + + const struct group *gr; + struct group newgr; ++ struct passwd *pw = NULL; + int errors = 0; + int line = 0; + +@@ -436,12 +504,37 @@ int main (int argc, char **argv) + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + process_root_flag ("-R", argc, argv); + + process_flags (argc, argv); + + OPENLOG ("chgpasswd"); + ++#ifdef WITH_AUDIT ++ audit_help_open (); ++#endif ++ ++ /* ++ * Determine the name of the user that invoked this command. This ++ * is really hit or miss because there are so many ways that command ++ * can be executed and so many ways to trip up the routines that ++ * report the user name. ++ */ ++ pw = get_my_pwent (); ++ if (NULL == pw) { ++ fprintf (stderr, _("%s: Cannot determine your user name.\n"), ++ Prog); ++ SYSLOG ((LOG_WARN, ++ "Cannot determine the user name of the caller (UID %lu)", ++ (unsigned long) getuid ())); ++ exit (E_NOPERM); ++ } ++ myname = xstrdup (pw->pw_name); ++ + check_perms (); + + #ifdef SHADOWGRP +diff -up shadow-4.8/src/chpasswd.c.selinux-perms shadow-4.8/src/chpasswd.c +--- shadow-4.8/src/chpasswd.c.selinux-perms 2019-12-01 18:02:43.000000000 +0100 ++++ shadow-4.8/src/chpasswd.c 2020-01-13 10:21:44.558107260 +0100 +@@ -39,6 +39,13 @@ + #include + #include + #include ++#ifdef WITH_SELINUX ++#include ++#include ++#endif ++#ifdef WITH_LIBAUDIT ++#include ++#endif + #ifdef USE_PAM + #include "pam_defs.h" + #endif /* USE_PAM */ +@@ -332,6 +339,63 @@ static void check_perms (void) + #endif /* USE_PAM */ + } + ++#ifdef WITH_SELINUX ++static int ++log_callback (int type, const char *fmt, ...) ++{ ++ int audit_fd; ++ va_list ap; ++ ++ va_start(ap, fmt); ++#ifdef WITH_AUDIT ++ audit_fd = audit_open(); ++ ++ if (audit_fd >= 0) { ++ char *buf; ++ ++ if (vasprintf (&buf, fmt, ap) < 0) ++ goto ret; ++ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL, ++ NULL, 0); ++ audit_close(audit_fd); ++ free(buf); ++ goto ret; ++ } ++ ++#endif ++ vsyslog (LOG_USER | LOG_INFO, fmt, ap); ++ret: ++ va_end(ap); ++ return 0; ++} ++ ++static void ++selinux_check_root (void) ++{ ++ int status = -1; ++ security_context_t user_context; ++ union selinux_callback old_callback; ++ ++ if (is_selinux_enabled() < 1) ++ return; ++ ++ old_callback = selinux_get_callback(SELINUX_CB_LOG); ++ /* setup callbacks */ ++ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback); ++ if ((status = getprevcon(&user_context)) < 0) { ++ selinux_set_callback(SELINUX_CB_LOG, old_callback); ++ exit(1); ++ } ++ ++ status = selinux_check_access(user_context, user_context, "passwd", "passwd", NULL); ++ ++ selinux_set_callback(SELINUX_CB_LOG, old_callback); ++ freecon(user_context); ++ if (status != 0 && security_getenforce() != 0) ++ exit(1); ++} ++#endif ++ + /* + * open_files - lock and open the password databases + */ +@@ -428,6 +492,10 @@ int main (int argc, char **argv) + (void) bindtextdomain (PACKAGE, LOCALEDIR); + (void) textdomain (PACKAGE); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + process_root_flag ("-R", argc, argv); + + process_flags (argc, argv); +@@ -440,6 +508,10 @@ int main (int argc, char **argv) + + OPENLOG ("chpasswd"); + ++#ifdef WITH_AUDIT ++ audit_help_open (); ++#endif ++ + check_perms (); + + #ifdef USE_PAM diff --git a/SOURCES/shadow-4.9-audit-update.patch b/SOURCES/shadow-4.9-audit-update.patch new file mode 100644 index 0000000..99513ef --- /dev/null +++ b/SOURCES/shadow-4.9-audit-update.patch @@ -0,0 +1,2347 @@ +diff -up shadow-4.8.1/libmisc/audit_help.c.audit-update shadow-4.8.1/libmisc/audit_help.c +--- shadow-4.8.1/libmisc/audit_help.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/audit_help.c 2020-03-17 16:53:44.371943299 +0100 +@@ -68,7 +68,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" +@@ -88,6 +88,39 @@ void audit_logger (int type, unused cons + } + } + ++/* ++ * 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, 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.8.1/libmisc/cleanup_group.c.audit-update shadow-4.8.1/libmisc/cleanup_group.c +--- shadow-4.8.1/libmisc/cleanup_group.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/cleanup_group.c 2020-03-17 16:53:44.371943299 +0100 +@@ -83,7 +83,7 @@ void cleanup_report_mod_group (void *cle + gr_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, Prog, + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -101,7 +101,7 @@ void cleanup_report_mod_gshadow (void *c + sgr_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, ++ audit_logger (AUDIT_GRP_MGMT, Prog, + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -122,7 +122,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, Prog, +- "adding group to /etc/group", ++ "adding-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -141,8 +141,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, Prog, +- "adding group to /etc/gshadow", ++ audit_logger (AUDIT_GRP_MGMT, Prog, ++ "adding-shadow-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -164,8 +164,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, Prog, +- "removing group from /etc/group", ++ audit_logger (AUDIT_DEL_GROUP, Prog, ++ "removing-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -187,8 +187,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, Prog, +- "removing group from /etc/gshadow", ++ audit_logger (AUDIT_GRP_MGMT, Prog, ++ "removing-shadow-group", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -208,7 +208,7 @@ void cleanup_unlock_group (unused void * + Prog, 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 + } +@@ -228,7 +228,7 @@ void cleanup_unlock_gshadow (unused void + Prog, 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.8.1/libmisc/cleanup_user.c.audit-update shadow-4.8.1/libmisc/cleanup_user.c +--- shadow-4.8.1/libmisc/cleanup_user.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/libmisc/cleanup_user.c 2020-03-17 16:53:44.371943299 +0100 +@@ -65,7 +65,7 @@ void cleanup_report_mod_passwd (void *cl + pw_dbname (), + info->action)); + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_ACCT, Prog, ++ audit_logger (AUDIT_USER_MGMT, Prog, + info->audit_msg, + info->name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); +@@ -86,7 +86,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, Prog, +- "adding user to /etc/passwd", ++ "adding-user", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -105,8 +105,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, Prog, +- "adding user to /etc/shadow", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "adding-shadow-user", + name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -125,7 +125,7 @@ void cleanup_unlock_passwd (unused void + Prog, 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 + } +@@ -144,7 +144,7 @@ void cleanup_unlock_shadow (unused void + Prog, 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.8.1/lib/prototypes.h.audit-update shadow-4.8.1/lib/prototypes.h +--- shadow-4.8.1/lib/prototypes.h.audit-update 2020-03-17 16:53:44.364943206 +0100 ++++ shadow-4.8.1/lib/prototypes.h 2020-03-17 16:53:44.371943299 +0100 +@@ -219,12 +219,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, 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.8.1/src/chage.c.audit-update shadow-4.8.1/src/chage.c +--- shadow-4.8.1/src/chage.c.audit-update 2019-11-12 01:18:25.000000000 +0100 ++++ shadow-4.8.1/src/chage.c 2020-03-17 16:53:44.371943299 +0100 +@@ -123,9 +123,10 @@ static /*@noreturn@*/void fail_exit (int + + #ifdef WITH_AUDIT + if (E_SUCCESS != code) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change age", +- user_name, (unsigned int) user_uid, 0); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-age", ++ user_name, (unsigned int) user_uid, ++ SHADOW_AUDIT_FAILURE); + } + #endif + +@@ -883,11 +884,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, (unsigned int) user_uid, 1); +-#endif ++ /* Displaying fields is not of interest to audit */ + list_fields (); + fail_exit (E_SUCCESS); + } +@@ -906,41 +903,43 @@ int main (int argc, char **argv) + } + #ifdef WITH_AUDIT + else { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change all aging information", +- user_name, (unsigned int) user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-all-aging-information", ++ user_name, (unsigned int) user_uid, ++ SHADOW_AUDIT_SUCCESS); + } + #endif + } else { + #ifdef WITH_AUDIT + if (Mflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change max age", +- user_name, (unsigned int) user_uid, 1); ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-max-age", ++ user_name, (unsigned int) user_uid, ++ SHADOW_AUDIT_SUCCESS); + } + if (mflg) { +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "change min age", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "change-min-age", + user_name, (unsigned int) 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, (unsigned int) 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, (unsigned int) 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, (unsigned int) 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, (unsigned int) user_uid, 1); + } + #endif +diff -up shadow-4.8.1/src/gpasswd.c.audit-update shadow-4.8.1/src/gpasswd.c +--- shadow-4.8.1/src/gpasswd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/gpasswd.c 2020-03-17 16:53:44.371943299 +0100 +@@ -138,7 +138,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 +@@ -397,21 +397,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, 1023, +- "%s failed to add user %s to group %s%s", +- myname, user, group, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -419,13 +412,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, 1023, +- "%s failed to remove user %s from group %s%s", +- myname, user, group, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -433,13 +422,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, 1023, +- "%s failed to remove password of group %s%s", +- myname, group, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -447,13 +432,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, 1023, +- "%s failed to restrict access to group %s%s", +- myname, group, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -463,13 +444,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, 1023, +- "%s failed to set the administrators of group %s to %s%s", +- myname, group, admins, suffix); +- buf[1023] = '\0'; +- 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 + } +@@ -479,13 +456,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, 1023, +- "%s failed to set the members of group %s to %s%s", +- myname, group, members, suffix); +- buf[1023] = '\0'; +- 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 + } +@@ -494,13 +467,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, 1023, +- "%s failed to change password of group %s%s", +- myname, group, suffix); +- buf[1023] = '\0'; +- 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 + } +@@ -531,21 +500,14 @@ static void log_gpasswd_failure_gshadow + + static void log_gpasswd_success (const char *suffix) + { +-#ifdef WITH_AUDIT +- char buf[1024]; +-#endif + if (aflg) { + SYSLOG ((LOG_INFO, + "user %s added by %s to group %s%s", + user, myname, group, suffix)); + #ifdef WITH_AUDIT +- snprintf (buf, 1023, +- "user %s added by %s to group %s%s", +- user, myname, group, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -553,13 +515,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, 1023, +- "user %s removed by %s from group %s%s", +- user, myname, group, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -567,13 +525,9 @@ static void log_gpasswd_success (const c + "password of group %s removed by %s%s", + group, myname, suffix)); + #ifdef WITH_AUDIT +- snprintf (buf, 1023, +- "password of group %s removed by %s%s", +- group, myname, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -581,13 +535,9 @@ static void log_gpasswd_success (const c + "access to group %s restricted by %s%s", + group, myname, suffix)); + #ifdef WITH_AUDIT +- snprintf (buf, 1023, +- "access to group %s restricted by %s%s", +- group, myname, suffix); +- buf[1023] = '\0'; +- 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) { +@@ -597,13 +547,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, 1023, +- "administrators of group %s set by %s to %s%s", +- group, myname, admins, suffix); +- buf[1023] = '\0'; +- 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 + } +@@ -613,13 +559,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, 1023, +- "members of group %s set by %s to %s%s", +- group, myname, members, suffix); +- buf[1023] = '\0'; +- 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 + } +@@ -628,13 +570,9 @@ static void log_gpasswd_success (const c + "password of group %s changed by %s%s", + group, myname, suffix)); + #ifdef WITH_AUDIT +- snprintf (buf, 1023, +- "password of group %s changed by %s%s", +- group, myname, suffix); +- buf[1023] = '\0'; +- 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.8.1/src/groupadd.c.audit-update shadow-4.8.1/src/groupadd.c +--- shadow-4.8.1/src/groupadd.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupadd.c 2020-03-17 16:53:44.372943312 +0100 +@@ -131,6 +131,15 @@ static /*@noreturn@*/void usage (int sta + 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 + * +@@ -214,7 +223,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 + /* +@@ -224,7 +233,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 */ + } +@@ -248,7 +257,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); + } + + /* +@@ -264,11 +273,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, (unsigned int) group_id, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -286,11 +295,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, (unsigned int) group_id, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -304,12 +313,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, (unsigned int) 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); +@@ -327,7 +330,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); + +@@ -337,7 +340,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); + } +@@ -353,7 +356,7 @@ static void open_files (void) + if (gr_open (O_CREAT | O_RDWR) == 0) { + fprintf (stderr, _("%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 +@@ -363,7 +366,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 */ +@@ -496,7 +499,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)) { +@@ -515,7 +518,7 @@ static void check_flags (void) + fprintf (stderr, + _("%s: GID '%lu' already exists\n"), + Prog, (unsigned long int) group_id); +- exit (E_GID_IN_USE); ++ fail_exit (E_GID_IN_USE); + } + } + } +@@ -543,7 +546,7 @@ static void check_perms (void) + fprintf (stderr, + _("%s: Cannot determine your user name.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); +@@ -563,7 +566,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 */ +@@ -596,7 +599,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Cannot setup cleanup service.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + /* +@@ -618,7 +621,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.8.1/src/groupdel.c.audit-update shadow-4.8.1/src/groupdel.c +--- shadow-4.8.1/src/groupdel.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupdel.c 2020-03-17 16:53:44.372943312 +0100 +@@ -106,6 +106,15 @@ static /*@noreturn@*/void usage (int sta + 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 + * +@@ -132,7 +141,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 +@@ -144,7 +153,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 */ +@@ -163,12 +172,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, (unsigned int) group_id, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -188,12 +197,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, (unsigned int) group_id, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -207,13 +216,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, (unsigned int) group_id, +- SHADOW_AUDIT_SUCCESS); +-#endif + SYSLOG ((LOG_INFO, "group '%s' removed\n", group_name)); + del_cleanup (cleanup_report_del_group); + } +@@ -230,7 +232,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 +@@ -239,7 +241,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); + } +@@ -257,7 +259,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) { +@@ -266,7 +268,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 */ +@@ -307,7 +309,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); + } + + /* +@@ -392,7 +394,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); +@@ -406,7 +408,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 ("groupdel", pampw->pw_name, &conv, &pamh); +@@ -427,7 +429,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 */ +@@ -447,7 +449,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; +@@ -471,7 +473,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.8.1/src/groupmod.c.audit-update shadow-4.8.1/src/groupmod.c +--- shadow-4.8.1/src/groupmod.c.audit-update 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/src/groupmod.c 2020-03-17 16:53:44.372943312 +0100 +@@ -450,7 +450,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); +@@ -473,7 +473,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); +@@ -496,7 +503,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); +@@ -511,8 +518,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 +@@ -524,6 +531,8 @@ static void close_files (void) + */ + static void prepare_failure_reports (void) + { ++ char *nv_pair, nv[64]; ++ + info_group.name = group_name; + #ifdef SHADOWGRP + info_gshadow.name = group_name; +@@ -536,76 +545,109 @@ static void prepare_failure_reports (voi + #endif + info_passwd.audit_msg = xmalloc (512); + +- (void) snprintf (info_group.audit_msg, 511, +- "changing %s; ", gr_dbname ()); ++ info_group.action = xmalloc (512); + #ifdef SHADOWGRP +- (void) snprintf (info_gshadow.audit_msg, 511, +- "changing %s; ", sgr_dbname ()); ++ info_gshadow.action = xmalloc (512); + #endif +- (void) snprintf (info_passwd.audit_msg, 511, +- "changing %s; ", pw_dbname ()); ++ info_passwd.action = xmalloc (512); + +- info_group.action = info_group.audit_msg +- + strlen (info_group.audit_msg); ++ (void) snprintf (info_group.audit_msg, 511, ++ "changing-group"); + #ifdef SHADOWGRP +- info_gshadow.action = info_gshadow.audit_msg +- + strlen (info_gshadow.audit_msg); ++ (void) snprintf (info_gshadow.audit_msg, 511, ++ "changing-shadow-group"); + #endif +- info_passwd.action = info_passwd.audit_msg +- + strlen (info_passwd.audit_msg); ++ (void) snprintf (info_passwd.audit_msg, 511, ++ "changing-group-passwd"); + ++ nv_pair = audit_encode_nv_string(" grp", group_name, ++ strlen(group_name)); ++ if(nv_pair) { ++ strncat(info_group.audit_msg, nv_pair, ++ 511 - strlen(info_group.audit_msg)); ++#ifdef SHADOWGRP ++ strncat(info_gshadow.audit_msg, nv_pair, ++ 511 - strlen(info_gshadow.audit_msg)); ++#endif ++ strncat(info_passwd.audit_msg, nv_pair, ++ 511 - strlen(info_passwd.audit_msg)); ++ free(nv_pair); ++ } ++ snprintf(nv, sizeof(nv), " gid=%lu", (unsigned long)group_id); ++ strncat(info_group.audit_msg, nv, 511 - strlen(info_group.audit_msg)); ++ strncat(info_passwd.audit_msg, nv, 511 - strlen(info_passwd.audit_msg)); ++ + (void) snprintf (info_group.action, +- 511 - strlen (info_group.audit_msg), ++ 511, + "group %s/%lu", + group_name, (unsigned long int) group_id); + #ifdef SHADOWGRP + (void) snprintf (info_gshadow.action, +- 511 - strlen (info_group.audit_msg), ++ 511, + "group %s", group_name); + #endif + (void) snprintf (info_passwd.action, +- 511 - strlen (info_group.audit_msg), ++ 511, + "group %s/%lu", + group_name, (unsigned long int) group_id); + + if (nflg) { ++ nv_pair = audit_encode_nv_string(" new_group", group_newname, ++ strlen(group_newname)); ++ strncat(info_group.audit_msg, nv_pair, ++ 511 - strlen(info_group.audit_msg)); + strncat (info_group.action, ", new name: ", +- 511 - strlen (info_group.audit_msg)); ++ 511 - strlen (info_group.action)); + strncat (info_group.action, group_newname, +- 511 - strlen (info_group.audit_msg)); ++ 511 - strlen (info_group.action)); + + #ifdef SHADOWGRP ++ strncat(info_gshadow.audit_msg, nv_pair, ++ 511 - strlen(info_gshadow.audit_msg)); + strncat (info_gshadow.action, ", new name: ", +- 511 - strlen (info_gshadow.audit_msg)); ++ 511 - strlen (info_gshadow.action)); + strncat (info_gshadow.action, group_newname, +- 511 - strlen (info_gshadow.audit_msg)); ++ 511 - strlen (info_gshadow.action)); + #endif + ++ strncat(info_passwd.audit_msg, nv_pair, ++ 511 - strlen(info_passwd.audit_msg)); + strncat (info_passwd.action, ", new name: ", +- 511 - strlen (info_passwd.audit_msg)); ++ 511 - strlen (info_passwd.action)); + strncat (info_passwd.action, group_newname, +- 511 - strlen (info_passwd.audit_msg)); ++ 511 - strlen (info_passwd.action)); ++ free(nv_pair); + } + if (pflg) { ++ strncat(info_passwd.audit_msg, "op=change-password", ++ 511 - strlen (info_passwd.action)); ++ ++ /* Note: audit doesn't want this value recorded */ + strncat (info_group.action, ", new password", +- 511 - strlen (info_group.audit_msg)); ++ 511 - strlen (info_group.action)); + + #ifdef SHADOWGRP + strncat (info_gshadow.action, ", new password", +- 511 - strlen (info_gshadow.audit_msg)); ++ 511 - strlen (info_gshadow.action)); + #endif + } + if (gflg) { ++ snprintf(nv, sizeof(nv), " new_gid=%lu", (unsigned long)group_newid); ++ strncat(info_group.audit_msg, nv, ++ 511 - strlen(info_group.audit_msg)); ++ strncat(info_passwd.audit_msg, nv, ++ 511 - strlen(info_passwd.audit_msg)); ++ + strncat (info_group.action, ", new gid: ", +- 511 - strlen (info_group.audit_msg)); ++ 511 - strlen (info_group.action)); + (void) snprintf (info_group.action+strlen (info_group.action), +- 511 - strlen (info_group.audit_msg), ++ 511 - strlen (info_group.action), + "%lu", (unsigned long int) group_newid); + + strncat (info_passwd.action, ", new gid: ", +- 511 - strlen (info_passwd.audit_msg)); ++ 511 - strlen (info_passwd.action)); + (void) snprintf (info_passwd.action+strlen (info_passwd.action), +- 511 - strlen (info_passwd.audit_msg), ++ 511 - strlen (info_passwd.action), + "%lu", (unsigned long int) group_newid); + } + info_group.audit_msg[511] = '\0'; +@@ -613,6 +655,11 @@ static void prepare_failure_reports (voi + info_gshadow.audit_msg[511] = '\0'; + #endif + info_passwd.audit_msg[511] = '\0'; ++ info_group.action[511] = '\0'; ++#ifdef SHADOWGRP ++ info_gshadow.action[511] = '\0'; ++#endif ++ info_passwd.action[511] = '\0'; + + // FIXME: add a system cleanup + add_cleanup (cleanup_report_mod_group, &info_group); +diff -up shadow-4.8.1/src/newgrp.c.audit-update shadow-4.8.1/src/newgrp.c +--- shadow-4.8.1/src/newgrp.c.audit-update 2020-01-12 15:19:28.000000000 +0100 ++++ shadow-4.8.1/src/newgrp.c 2020-03-17 16:53:44.372943312 +0100 +@@ -206,11 +206,12 @@ static void check_perms (const struct gr + strcmp (cpasswd, grp->gr_passwd) != 0) { + #ifdef WITH_AUDIT + snprintf (audit_buf, sizeof(audit_buf), +- "authentication new-gid=%lu", ++ "authentication new_gid=%lu", + (unsigned long) grp->gr_gid); + audit_logger (AUDIT_GRP_AUTH, Prog, + audit_buf, NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), ++ SHADOW_AUDIT_FAILURE); + #endif + SYSLOG ((LOG_INFO, + "Invalid password for group '%s' from '%s'", +@@ -221,11 +222,12 @@ static void check_perms (const struct gr + } + #ifdef WITH_AUDIT + snprintf (audit_buf, sizeof(audit_buf), +- "authentication new-gid=%lu", ++ "authentication new_gid=%lu", + (unsigned long) grp->gr_gid); + audit_logger (AUDIT_GRP_AUTH, Prog, + audit_buf, NULL, +- (unsigned int) getuid (), 1); ++ (unsigned int) getuid (), ++ SHADOW_AUDIT_SUCCESS); + #endif + } + +@@ -236,19 +238,6 @@ failure: + * harm. -- JWP + */ + closelog (); +-#ifdef WITH_AUDIT +- if (groupname) { +- snprintf (audit_buf, sizeof(audit_buf), +- "changing new-group=%s", groupname); +- audit_logger (AUDIT_CHGRP_ID, Prog, +- audit_buf, NULL, +- (unsigned int) getuid (), 0); +- } else { +- audit_logger (AUDIT_CHGRP_ID, Prog, +- "changing", NULL, +- (unsigned int) getuid (), 0); +- } +-#endif + exit (EXIT_FAILURE); + } + +@@ -320,15 +309,27 @@ static void syslog_sg (const char *name, + is_newgrp ? "newgrp" : "sg", strerror (errno)); + #ifdef WITH_AUDIT + if (group) { +- snprintf (audit_buf, sizeof(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, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), ++ SHADOW_AUDIT_FAILURE); + } else { + audit_logger (AUDIT_CHGRP_ID, Prog, + "changing", NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), ++ SHADOW_AUDIT_FAILURE); + } + #endif + exit (EXIT_FAILURE); +@@ -458,7 +459,7 @@ int main (int argc, char **argv) + #ifdef WITH_AUDIT + audit_logger (AUDIT_CHGRP_ID, Prog, + "changing", NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); + #endif + SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)", + (unsigned long) getuid ())); +@@ -574,15 +575,26 @@ int main (int argc, char **argv) + perror ("getgroups"); + #ifdef WITH_AUDIT + if (group) { +- snprintf (audit_buf, sizeof(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, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), ++ SHADOW_AUDIT_FAILURE); + } else { + audit_logger (AUDIT_CHGRP_ID, Prog, + "changing", NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), ++ SHADOW_AUDIT_FAILURE); + } + #endif + exit (EXIT_FAILURE); +@@ -739,10 +751,10 @@ int main (int argc, char **argv) + perror ("setgid"); + #ifdef WITH_AUDIT + snprintf (audit_buf, sizeof(audit_buf), +- "changing new-gid=%lu", (unsigned long) gid); ++ "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, + audit_buf, NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); + #endif + exit (EXIT_FAILURE); + } +@@ -751,10 +763,10 @@ int main (int argc, char **argv) + perror ("setuid"); + #ifdef WITH_AUDIT + snprintf (audit_buf, sizeof(audit_buf), +- "changing new-gid=%lu", (unsigned long) gid); ++ "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, + audit_buf, NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); + #endif + exit (EXIT_FAILURE); + } +@@ -768,10 +780,10 @@ int main (int argc, char **argv) + execl (SHELL, "sh", "-c", command, (char *) 0); + #ifdef WITH_AUDIT + snprintf (audit_buf, sizeof(audit_buf), +- "changing new-gid=%lu", (unsigned long) gid); ++ "changing new_gid=%lu", (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, + audit_buf, NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); + #endif + perror (SHELL); + exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); +@@ -835,11 +847,11 @@ int main (int argc, char **argv) + } + + #ifdef WITH_AUDIT +- snprintf (audit_buf, sizeof(audit_buf), "changing new-gid=%lu", ++ snprintf (audit_buf, sizeof(audit_buf), "changing new_gid=%lu", + (unsigned long) gid); + audit_logger (AUDIT_CHGRP_ID, Prog, + audit_buf, NULL, +- (unsigned int) getuid (), 1); ++ (unsigned int) getuid (), SHADOW_AUDIT_SUCCESS); + #endif + /* + * Exec the login shell and go away. We are trying to get back to +@@ -863,15 +875,24 @@ int main (int argc, char **argv) + closelog (); + #ifdef WITH_AUDIT + if (NULL != group) { +- snprintf (audit_buf, sizeof(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, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); + } else { + audit_logger (AUDIT_CHGRP_ID, Prog, + "changing", NULL, +- (unsigned int) getuid (), 0); ++ (unsigned int) getuid (), SHADOW_AUDIT_FAILURE); + } + #endif + exit (EXIT_FAILURE); +diff -up shadow-4.8.1/src/useradd.c.audit-update shadow-4.8.1/src/useradd.c +--- shadow-4.8.1/src/useradd.c.audit-update 2020-03-17 16:53:44.365943219 +0100 ++++ shadow-4.8.1/src/useradd.c 2020-03-17 17:03:11.614503929 +0100 +@@ -233,6 +233,8 @@ static void create_mail (void); + */ + static void fail_exit (int code) + { ++ int type; ++ + if (home_added) { + if (rmdir (prefix_user_home) != 0) { + fprintf (stderr, +@@ -246,12 +248,6 @@ static void fail_exit (int code) + if (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 */ + } + } +@@ -259,12 +255,6 @@ static void fail_exit (int code) + if (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 */ + } + } +@@ -272,12 +262,6 @@ static void fail_exit (int code) + if (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 */ + } + } +@@ -286,12 +270,6 @@ static void fail_exit (int code) + if (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 */ + } + } +@@ -301,12 +279,6 @@ static void fail_exit (int code) + if (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 */ + } + } +@@ -314,20 +286,19 @@ static void fail_exit (int code) + if (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 +@@ -692,7 +663,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 +@@ -974,12 +945,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 */ + } + +@@ -993,18 +958,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, +@@ -1049,12 +1008,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 */ + } + +@@ -1068,18 +1021,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, +@@ -1452,7 +1400,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 +@@ -1567,7 +1515,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 +@@ -1580,7 +1528,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 +@@ -1622,7 +1570,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 +@@ -1636,7 +1584,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 +@@ -1828,7 +1776,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 +@@ -1844,7 +1792,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 +@@ -1854,7 +1802,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 +@@ -2025,12 +1973,6 @@ static void usr_update (void) + 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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_PW_UPDATE); + } + #ifdef ENABLE_SUBIDS +@@ -2051,9 +1993,14 @@ static void usr_update (void) + #endif /* ENABLE_SUBIDS */ + + #ifdef WITH_AUDIT ++ /* ++ * Even though we have the ID of the user, we won't send it now ++ * because its not written to disk yet. After close_files it is ++ * and we can use the real ID thereafter. ++ */ + audit_logger (AUDIT_ADD_USER, Prog, +- "adding user", +- user_name, (unsigned int) user_id, ++ "add-user", ++ user_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); + #endif + /* +@@ -2140,12 +2087,6 @@ static void create_home (void) + fprintf (stderr, + _("%s: cannot create directory %s\n"), + Prog, path); +-#ifdef WITH_AUDIT +- audit_logger (AUDIT_ADD_USER, Prog, +- "adding home directory", +- user_name, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_HOMEDIR); + } + if (chown (path, 0, 0) < 0) { +@@ -2168,8 +2109,8 @@ 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, (unsigned int) user_id, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -2354,12 +2295,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); + } + +@@ -2375,12 +2310,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); + } + } +@@ -2410,12 +2339,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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif + fail_exit (E_UID_IN_USE); + } + } +@@ -2489,9 +2412,10 @@ 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, (unsigned int) user_id, 0); ++ audit_logger (AUDIT_ROLE_ASSIGN, Prog, ++ "add-selinux-user-mapping", ++ user_name, (unsigned int) user_id, ++ SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ + fail_exit (E_SE_UPDATE); + } +diff -up shadow-4.8.1/src/userdel.c.audit-update shadow-4.8.1/src/userdel.c +--- shadow-4.8.1/src/userdel.c.audit-update 2020-03-17 16:53:44.368943259 +0100 ++++ shadow-4.8.1/src/userdel.c 2020-03-17 16:53:44.373943325 +0100 +@@ -222,9 +222,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, (unsigned int) user_id, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "deleting-user-from-group", ++ user_name, (unsigned int) user_id, ngrp->gr_name, + SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, "delete '%s' from group '%s'\n", +@@ -284,9 +284,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, (unsigned int) user_id, ++ audit_logger_with_group (AUDIT_USER_MGMT, Prog, ++ "deleting-user-from-shadow-group", ++ user_name, (unsigned int) user_id, nsgrp->sg_name, + SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ + SYSLOG ((LOG_INFO, "delete '%s' from shadow group '%s'\n", +@@ -363,9 +363,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, +@@ -381,9 +381,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, +@@ -545,7 +545,7 @@ static void fail_exit (int code) + + #ifdef WITH_AUDIT + audit_logger (AUDIT_DEL_USER, Prog, +- "deleting user", ++ "delete-user", + user_name, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -565,24 +565,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, (unsigned int) 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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + if (is_shadow_pwd) { +@@ -590,12 +578,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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + spw_locked = true; +@@ -603,12 +585,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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_PW_UPDATE); + } + } +@@ -616,23 +592,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, (unsigned int) 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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_GRP_UPDATE); + } + #ifdef SHADOWGRP +@@ -641,24 +605,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, (unsigned int) 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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_GRP_UPDATE); + } + } +@@ -669,24 +621,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, (unsigned int) 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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_SUB_UID_UPDATE); + } + } +@@ -695,24 +635,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, (unsigned int) 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, (unsigned int) user_id, +- SHADOW_AUDIT_FAILURE); +-#endif /* WITH_AUDIT */ + fail_exit (E_SUB_GID_UPDATE); + } + } +@@ -757,7 +685,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, (unsigned int) user_id, + SHADOW_AUDIT_SUCCESS); + #endif /* WITH_AUDIT */ +@@ -865,7 +793,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -882,7 +810,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -892,8 +820,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, (unsigned int) user_id, + SHADOW_AUDIT_SUCCESS); + } +@@ -911,7 +839,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -928,7 +856,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -938,8 +866,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, (unsigned int) user_id, + SHADOW_AUDIT_SUCCESS); + } +@@ -1152,7 +1080,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 */ +@@ -1208,7 +1136,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 */ +@@ -1302,8 +1230,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, (unsigned int) user_id, + SHADOW_AUDIT_SUCCESS); + } +@@ -1312,7 +1240,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); + } +@@ -1325,8 +1253,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +diff -up shadow-4.8.1/src/usermod.c.audit-update shadow-4.8.1/src/usermod.c +--- shadow-4.8.1/src/usermod.c.audit-update 2020-03-17 16:53:44.370943285 +0100 ++++ shadow-4.8.1/src/usermod.c 2020-03-17 16:53:44.373943325 +0100 +@@ -457,8 +457,8 @@ static char *new_pw_passwd (char *pw_pas + + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "updating passwd", +- user_newname, (unsigned int) user_newid, 0); ++ "updating-password", ++ user_newname, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "lock user '%s' password", user_newname)); + strcpy (buf, "!"); +@@ -477,8 +477,8 @@ static char *new_pw_passwd (char *pw_pas + + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "updating password", +- user_newname, (unsigned int) user_newid, 0); ++ "updating-password", ++ user_newname, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "unlock user '%s' password", user_newname)); + s = pw_pass; +@@ -489,7 +489,7 @@ static char *new_pw_passwd (char *pw_pas + } else if (pflg) { + #ifdef WITH_AUDIT + audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing password", ++ "updating-password", + user_newname, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, "change user '%s' password", user_newname)); +@@ -518,8 +518,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", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-name", + user_newname, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -539,8 +539,8 @@ static void new_pwent (struct passwd *pw + + if (uflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing uid", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-uid", + user_newname, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -550,8 +550,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, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -561,8 +561,8 @@ static void new_pwent (struct passwd *pw + } + if (cflg) { + #ifdef WITH_AUDIT +- audit_logger (AUDIT_USER_CHAUTHTOK, Prog, +- "changing comment", ++ audit_logger (AUDIT_USER_MGMT, Prog, ++ "changing-comment", + user_newname, (unsigned int) user_newid, 1); + #endif + pwent->pw_gecos = user_newcomment; +@@ -570,8 +570,8 @@ static void new_pwent (struct passwd *pw + + 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, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -581,8 +581,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, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -612,8 +612,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, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -629,8 +629,8 @@ static void new_spent (struct spwd *spen + date_to_str (old_exp, sizeof(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, (unsigned int) user_newid, 1); + #endif + SYSLOG ((LOG_INFO, +@@ -713,9 +713,9 @@ static /*@noreturn@*/void fail_exit (int + #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); + } +@@ -769,9 +769,12 @@ static void update_group (void) + 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'", +@@ -785,9 +788,11 @@ static void update_group (void) + 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'", +@@ -800,9 +805,11 @@ static void update_group (void) + 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)); +@@ -877,9 +884,10 @@ static void update_gshadow (void) + 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'", +@@ -899,9 +907,10 @@ static void update_gshadow (void) + 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'", +@@ -915,9 +924,10 @@ static void update_gshadow (void) + 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'", +@@ -930,9 +940,10 @@ static void update_gshadow (void) + 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)); +@@ -1799,8 +1810,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, (unsigned int) user_newid, 1); + } + #endif +@@ -1818,8 +1829,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, (unsigned int) user_newid, + 1); + #endif +@@ -1847,9 +1858,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, + (unsigned int) user_newid, + 1); +@@ -2071,8 +2082,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, (unsigned int) user_newid, 1); + } + #endif +@@ -2098,8 +2109,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, (unsigned int) user_newid, 1); + } + #endif +@@ -2294,8 +2305,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -2307,8 +2318,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, (unsigned int) user_id, + SHADOW_AUDIT_FAILURE); + #endif /* WITH_AUDIT */ +@@ -2349,8 +2360,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, (unsigned int) user_newid, 1); + } + #endif diff --git a/SOURCES/shadow-4.9-default-range.patch b/SOURCES/shadow-4.9-default-range.patch new file mode 100644 index 0000000..f6e0427 --- /dev/null +++ b/SOURCES/shadow-4.9-default-range.patch @@ -0,0 +1,35 @@ +diff -up shadow-4.9/lib/semanage.c.default-range shadow-4.9/lib/semanage.c +--- shadow-4.9/lib/semanage.c.default-range 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/lib/semanage.c 2021-08-02 12:43:16.822817392 +0200 +@@ -143,6 +143,7 @@ static int semanage_user_mod (semanage_h + goto done; + } + ++#if 0 + ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); + if (ret != 0) { + fprintf (shadow_logfd, +@@ -150,6 +151,7 @@ static int semanage_user_mod (semanage_h + ret = 1; + goto done; + } ++#endif + + ret = semanage_seuser_set_sename (handle, seuser, seuser_name); + if (ret != 0) { +@@ -200,6 +202,7 @@ static int semanage_user_add (semanage_h + goto done; + } + ++#if 0 + ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE); + if (ret != 0) { + fprintf (shadow_logfd, +@@ -208,6 +211,7 @@ static int semanage_user_add (semanage_h + ret = 1; + goto done; + } ++#endif + + ret = semanage_seuser_set_sename (handle, seuser, seuser_name); + if (ret != 0) { diff --git a/SOURCES/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch b/SOURCES/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch new file mode 100644 index 0000000..5eaaec9 --- /dev/null +++ b/SOURCES/shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch @@ -0,0 +1,60 @@ +From 234e8fa7b134d1ebabfdad980a3ae5b63c046c62 Mon Sep 17 00:00:00 2001 +From: Mike Gilbert +Date: Sat, 14 Aug 2021 13:24:34 -0400 +Subject: [PATCH] libmisc: fix default value in SHA_get_salt_rounds() + +If SHA_CRYPT_MIN_ROUNDS and SHA_CRYPT_MAX_ROUNDS are both unspecified, +use SHA_ROUNDS_DEFAULT. + +Previously, the code fell through, calling shadow_random(-1, -1). This +ultimately set rounds = (unsigned long) -1, which ends up being a very +large number! This then got capped to SHA_ROUNDS_MAX later in the +function. + +The new behavior matches BCRYPT_get_salt_rounds(). + +Bug: https://bugs.gentoo.org/808195 +Fixes: https://github.com/shadow-maint/shadow/issues/393 +--- + libmisc/salt.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/libmisc/salt.c b/libmisc/salt.c +index 91d528fd..30eefb9c 100644 +--- a/libmisc/salt.c ++++ b/libmisc/salt.c +@@ -223,20 +223,21 @@ static /*@observer@*/const unsigned long SHA_get_salt_rounds (/*@null@*/int *pre + if ((-1 == min_rounds) && (-1 == max_rounds)) { + rounds = SHA_ROUNDS_DEFAULT; + } ++ else { ++ if (-1 == min_rounds) { ++ min_rounds = max_rounds; ++ } + +- if (-1 == min_rounds) { +- min_rounds = max_rounds; +- } ++ if (-1 == max_rounds) { ++ max_rounds = min_rounds; ++ } + +- if (-1 == max_rounds) { +- max_rounds = min_rounds; +- } ++ if (min_rounds > max_rounds) { ++ max_rounds = min_rounds; ++ } + +- if (min_rounds > max_rounds) { +- max_rounds = min_rounds; ++ rounds = (unsigned long) shadow_random (min_rounds, max_rounds); + } +- +- rounds = (unsigned long) shadow_random (min_rounds, max_rounds); + } else if (0 == *prefered_rounds) { + rounds = SHA_ROUNDS_DEFAULT; + } else { +-- +2.31.1 + diff --git a/SOURCES/shadow-4.9-manfix.patch b/SOURCES/shadow-4.9-manfix.patch new file mode 100644 index 0000000..46cba1a --- /dev/null +++ b/SOURCES/shadow-4.9-manfix.patch @@ -0,0 +1,180 @@ +diff -up shadow-4.8.1/man/groupmems.8.xml.manfix shadow-4.8.1/man/groupmems.8.xml +--- shadow-4.8.1/man/groupmems.8.xml.manfix 2020-03-17 15:34:48.750414984 +0100 ++++ shadow-4.8.1/man/groupmems.8.xml 2020-03-17 15:41:13.383588722 +0100 +@@ -179,20 +179,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.8.1/man/ja/man5/login.defs.5.manfix shadow-4.8.1/man/ja/man5/login.defs.5 +--- shadow-4.8.1/man/ja/man5/login.defs.5.manfix 2019-07-23 17:26:08.000000000 +0200 ++++ shadow-4.8.1/man/ja/man5/login.defs.5 2020-03-17 15:34:48.750414984 +0100 +@@ -147,10 +147,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.8.1/man/login.defs.5.xml.manfix shadow-4.8.1/man/login.defs.5.xml +--- shadow-4.8.1/man/login.defs.5.xml.manfix 2020-01-17 16:47:56.000000000 +0100 ++++ shadow-4.8.1/man/login.defs.5.xml 2020-03-17 15:34:48.750414984 +0100 +@@ -164,6 +164,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: + + +@@ -256,16 +267,6 @@ + + + +- chfn +- +- +- CHFN_AUTH +- CHFN_RESTRICT +- LOGIN_STRING +- +- +- +- + chgpasswd + + +@@ -286,14 +287,6 @@ + + + +- +- chsh +- +- +- CHSH_AUTH LOGIN_STRING +- +- +- + + + +@@ -359,34 +352,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 +@@ -415,17 +380,6 @@ + + + +- +- passwd +- +- +- ENCRYPT_METHOD MD5_CRYPT_ENAB OBSCURE_CHECKS_ENAB +- PASS_ALWAYS_WARN PASS_CHANGE_TRIES PASS_MAX_LEN PASS_MIN_LEN +- SHA_CRYPT_MAX_ROUNDS +- SHA_CRYPT_MIN_ROUNDS +- +- +- + + pwck + +@@ -452,32 +406,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.9-move-create-home.patch b/SOURCES/shadow-4.9-move-create-home.patch new file mode 100644 index 0000000..94bb84c --- /dev/null +++ b/SOURCES/shadow-4.9-move-create-home.patch @@ -0,0 +1,64 @@ +diff --git a/src/useradd.c b/src/useradd.c +index baeffb35..02e1402c 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -2644,27 +2644,12 @@ int main (int argc, char **argv) + + usr_update (); + +- if (mflg) { +- create_home (); +- if (home_added) { +- copy_tree (def_template, prefix_user_home, false, false, +- (uid_t)-1, user_id, (gid_t)-1, user_gid); +- } else { +- fprintf (stderr, +- _("%s: warning: the home directory %s already exists.\n" +- "%s: Not copying any file from skel directory into it.\n"), +- Prog, user_home, Prog); +- } +- +- } +- +- /* Do not create mail directory for system accounts */ +- if (!rflg) { +- create_mail (); +- } +- + close_files (); + ++ nscd_flush_cache ("passwd"); ++ nscd_flush_cache ("group"); ++ sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); ++ + /* + * tallylog_reset needs to be able to lookup + * a valid existing user name, +@@ -2695,9 +2680,24 @@ int main (int argc, char **argv) + exit(1); + } + +- nscd_flush_cache ("passwd"); +- nscd_flush_cache ("group"); +- sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); ++ if (mflg) { ++ create_home (); ++ if (home_added) { ++ copy_tree (def_template, prefix_user_home, false, true, ++ (uid_t)-1, user_id, (gid_t)-1, user_gid); ++ } else { ++ fprintf (stderr, ++ _("%s: warning: the home directory %s already exists.\n" ++ "%s: Not copying any file from skel directory into it.\n"), ++ Prog, user_home, Prog); ++ } ++ ++ } ++ ++ /* Do not create mail directory for system accounts */ ++ if (!rflg) { ++ create_mail (); ++ } + + return E_SUCCESS; + } diff --git a/SOURCES/shadow-4.9-newuidmap-libeconf-dependency.patch b/SOURCES/shadow-4.9-newuidmap-libeconf-dependency.patch new file mode 100644 index 0000000..a1907a6 --- /dev/null +++ b/SOURCES/shadow-4.9-newuidmap-libeconf-dependency.patch @@ -0,0 +1,15 @@ +diff --git a/src/Makefile.am b/src/Makefile.am +index 7c1a3491..6cc873be 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -96,8 +96,8 @@ LIBCRYPT_NOPAM = $(LIBCRYPT) + endif + + chage_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBECONF) +-newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl +-newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) -ldl ++newuidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl ++newgidmap_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCAP) $(LIBECONF) -ldl + chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) + chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) $(LIBECONF) + chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) $(LIBECONF) diff --git a/SOURCES/shadow-4.9-null-tm.patch b/SOURCES/shadow-4.9-null-tm.patch new file mode 100644 index 0000000..249b27b --- /dev/null +++ b/SOURCES/shadow-4.9-null-tm.patch @@ -0,0 +1,70 @@ +Index: shadow-4.5/src/chage.c +=================================================================== +--- shadow-4.5.orig/src/chage.c ++++ shadow-4.5/src/chage.c +@@ -168,6 +168,10 @@ static void date_to_str (char *buf, size + struct tm *tp; + + tp = gmtime (&date); ++ if (tp == NULL) { ++ (void) snprintf (buf, maxsize, "(unknown)"); ++ return; ++ } + #ifdef HAVE_STRFTIME + (void) strftime (buf, maxsize, "%Y-%m-%d", tp); + #else +Index: shadow-4.5/src/lastlog.c +=================================================================== +--- shadow-4.5.orig/src/lastlog.c ++++ shadow-4.5/src/lastlog.c +@@ -158,13 +158,17 @@ static void print_one (/*@null@*/const s + + ll_time = ll.ll_time; + tm = localtime (&ll_time); ++ if (tm == NULL) { ++ cp = "(unknown)"; ++ } else { + #ifdef HAVE_STRFTIME +- strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); +- cp = ptime; ++ strftime (ptime, sizeof (ptime), "%a %b %e %H:%M:%S %z %Y", tm); ++ cp = ptime; + #else +- cp = asctime (tm); +- cp[24] = '\0'; ++ cp = asctime (tm); ++ cp[24] = '\0'; + #endif ++ } + + if (ll.ll_time == (time_t) 0) { + cp = _("**Never logged in**\0"); +Index: shadow-4.5/src/passwd.c +=================================================================== +--- shadow-4.5.orig/src/passwd.c ++++ shadow-4.5/src/passwd.c +@@ -455,6 +455,9 @@ static /*@observer@*/const char *date_to + struct tm *tm; + + tm = gmtime (&t); ++ if (tm == NULL) { ++ return "(unknown)"; ++ } + #ifdef HAVE_STRFTIME + (void) strftime (buf, sizeof buf, "%m/%d/%Y", tm); + #else /* !HAVE_STRFTIME */ +Index: shadow-4.5/src/usermod.c +=================================================================== +--- shadow-4.5.orig/src/usermod.c ++++ shadow-4.5/src/usermod.c +@@ -210,6 +210,10 @@ static void date_to_str (/*@unique@*//*@ + } else { + time_t t = (time_t) date; + tp = gmtime (&t); ++ if (tp == NULL) { ++ strncpy (buf, "unknown", maxsize); ++ return; ++ } + #ifdef HAVE_STRFTIME + strftime (buf, maxsize, "%Y-%m-%d", tp); + #else diff --git a/SOURCES/shadow-4.9-redhat.patch b/SOURCES/shadow-4.9-redhat.patch new file mode 100644 index 0000000..9dfb3e8 --- /dev/null +++ b/SOURCES/shadow-4.9-redhat.patch @@ -0,0 +1,41 @@ +diff -up shadow-4.9/src/useradd.c.redhat shadow-4.9/src/useradd.c +--- shadow-4.9/src/useradd.c.redhat 2021-07-22 23:55:35.000000000 +0200 ++++ shadow-4.9/src/useradd.c 2021-08-02 11:45:11.942867250 +0200 +@@ -104,7 +104,7 @@ FILE *shadow_logfd = NULL; + static gid_t def_group = 1000; + static const char *def_gname = "other"; + static const char *def_home = "/home"; +-static const char *def_shell = "/bin/bash"; ++static const char *def_shell = "/sbin/nologin"; + static const char *def_template = SKEL_DIR; + static const char *def_create_mail_spool = "yes"; + +@@ -114,7 +114,7 @@ static const char *def_expire = ""; + #define VALID(s) (strcspn (s, ":\n") == strlen (s)) + + static const char *user_name = ""; +-static const char *user_pass = "!"; ++static const char *user_pass = "!!"; + static uid_t user_id; + static gid_t user_gid; + static const char *user_comment = ""; +@@ -1204,9 +1204,9 @@ static void process_flags (int argc, cha + }; + while ((c = getopt_long (argc, argv, + #ifdef WITH_SELINUX +- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:UZ:", ++ "b:c:d:De:f:g:G:hk:K:lmMnNop:rR:P:s:u:UZ:", + #else /* !WITH_SELINUX */ +- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:P:s:u:U", ++ "b:c:d:De:f:g:G:hk:K:lmMnNop:rR:P:s:u:U", + #endif /* !WITH_SELINUX */ + long_options, NULL)) != -1) { + switch (c) { +@@ -1363,6 +1363,7 @@ static void process_flags (int argc, cha + case 'M': + Mflg = true; + break; ++ case 'n': + case 'N': + Nflg = true; + break; diff --git a/SOURCES/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch b/SOURCES/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch new file mode 100644 index 0000000..b94fd60 --- /dev/null +++ b/SOURCES/shadow-4.9-useradd-avoid-generating-empty-subid-range.patch @@ -0,0 +1,79 @@ +diff --git a/src/useradd.c b/src/useradd.c +index baeffb35..9abeea6e 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -142,9 +142,7 @@ static bool is_sub_gid = false; + static bool sub_uid_locked = false; + static bool sub_gid_locked = false; + static uid_t sub_uid_start; /* New subordinate uid range */ +-static unsigned long sub_uid_count; + static gid_t sub_gid_start; /* New subordinate gid range */ +-static unsigned long sub_gid_count; + #endif /* ENABLE_SUBIDS */ + static bool pw_locked = false; + static bool gr_locked = false; +@@ -234,7 +232,7 @@ static void open_shadow (void); + static void faillog_reset (uid_t); + static void lastlog_reset (uid_t); + static void tallylog_reset (const char *); +-static void usr_update (void); ++static void usr_update (unsigned long subuid_count, unsigned long subgid_count); + static void create_home (void); + static void create_mail (void); + static void check_uid_range(int rflg, uid_t user_id); +@@ -2092,7 +2090,7 @@ static void tallylog_reset (const char *user_name) + * usr_update() creates the password file entries for this user + * and will update the group entries if required. + */ +-static void usr_update (void) ++static void usr_update (unsigned long subuid_count, unsigned long subgid_count) + { + struct passwd pwent; + struct spwd spent; +@@ -2155,14 +2153,14 @@ static void usr_update (void) + } + #ifdef ENABLE_SUBIDS + if (is_sub_uid && +- (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) { ++ (sub_uid_add(user_name, sub_uid_start, subuid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); + fail_exit (E_SUB_UID_UPDATE); + } + if (is_sub_gid && +- (sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) { ++ (sub_gid_add(user_name, sub_gid_start, subgid_count) == 0)) { + fprintf (stderr, + _("%s: failed to prepare the new %s entry\n"), + Prog, sub_uid_dbname ()); +@@ -2624,16 +2622,16 @@ int main (int argc, char **argv) + } + + #ifdef ENABLE_SUBIDS +- if (is_sub_uid && sub_uid_count != 0) { +- if (find_new_sub_uids(&sub_uid_start, &sub_uid_count) < 0) { ++ if (is_sub_uid && subuid_count != 0) { ++ if (find_new_sub_uids(&sub_uid_start, &subuid_count) < 0) { + fprintf (stderr, + _("%s: can't create subordinate user IDs\n"), + Prog); + fail_exit(E_SUB_UID_UPDATE); + } + } +- if (is_sub_gid && sub_gid_count != 0) { +- if (find_new_sub_gids(&sub_gid_start, &sub_gid_count) < 0) { ++ if (is_sub_gid && subgid_count != 0) { ++ if (find_new_sub_gids(&sub_gid_start, &subgid_count) < 0) { + fprintf (stderr, + _("%s: can't create subordinate group IDs\n"), + Prog); +@@ -2642,7 +2640,7 @@ int main (int argc, char **argv) + } + #endif /* ENABLE_SUBIDS */ + +- usr_update (); ++ usr_update (subuid_count, subgid_count); + + close_files (); + diff --git a/SOURCES/shadow-4.9-usermod-allow-all-group-types.patch b/SOURCES/shadow-4.9-usermod-allow-all-group-types.patch new file mode 100644 index 0000000..fada15e --- /dev/null +++ b/SOURCES/shadow-4.9-usermod-allow-all-group-types.patch @@ -0,0 +1,322 @@ +From e481437ab9ebe9a8bf8fbaabe986d42b2f765991 Mon Sep 17 00:00:00 2001 +From: Iker Pedrosa +Date: Tue, 3 Aug 2021 08:57:20 +0200 +Subject: [PATCH] usermod: allow all group types with -G option + +The only way of removing a group from the supplementary list is to use +-G option, and list all groups that the user is a member of except for +the one that wants to be removed. The problem lies when there's a user +that contains both local and remote groups, and the group to be removed +is a local one. As we need to include the remote group with -G option +the command will fail. + +This reverts commit 140510de9de4771feb3af1d859c09604043a4c9b. This way, +it would be possible to remove the remote groups from the supplementary +list. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1967641 +Resolves: https://github.com/shadow-maint/shadow/issues/338 + +Signed-off-by: Iker Pedrosa +--- + src/usermod.c | 220 ++++++++++++++++++-------------------------------- + 1 file changed, 77 insertions(+), 143 deletions(-) + +diff --git a/src/usermod.c b/src/usermod.c +index 03bb9b9d..a0c03afa 100644 +--- a/src/usermod.c ++++ b/src/usermod.c +@@ -187,7 +187,6 @@ static bool sub_gid_locked = false; + static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, + long int date); + static int get_groups (char *); +-static struct group * get_local_group (char * grp_name); + static /*@noreturn@*/void usage (int status); + static void new_pwent (struct passwd *); + static void new_spent (struct spwd *); +@@ -201,9 +200,7 @@ static void grp_update (void); + + static void process_flags (int, char **); + static void close_files (void); +-static void close_group_files (void); + static void open_files (void); +-static void open_group_files (void); + static void usr_update (void); + static void move_home (void); + static void update_lastlog (void); +@@ -260,11 +257,6 @@ static int get_groups (char *list) + return 0; + } + +- /* +- * Open the group files +- */ +- open_group_files (); +- + /* + * So long as there is some data to be converted, strip off each + * name and look it up. A mix of numerical and string values for +@@ -284,7 +276,7 @@ static int get_groups (char *list) + * Names starting with digits are treated as numerical GID + * values, otherwise the string is looked up as is. + */ +- grp = get_local_group (list); ++ grp = prefix_getgr_nam_gid (list); + + /* + * There must be a match, either by GID value or by +@@ -334,8 +326,6 @@ static int get_groups (char *list) + gr_free ((struct group *)grp); + } while (NULL != list); + +- close_group_files (); +- + user_groups[ngroups] = (char *) 0; + + /* +@@ -348,44 +338,6 @@ static int get_groups (char *list) + return 0; + } + +-/* +- * get_local_group - checks if a given group name exists locally +- * +- * get_local_group() checks if a given group name exists locally. +- * If the name exists the group information is returned, otherwise NULL is +- * returned. +- */ +-static struct group * get_local_group(char * grp_name) +-{ +- const struct group *grp; +- struct group *result_grp = NULL; +- long long int gid; +- char *endptr; +- +- gid = strtoll (grp_name, &endptr, 10); +- if ( ('\0' != *grp_name) +- && ('\0' == *endptr) +- && (ERANGE != errno) +- && (gid == (gid_t)gid)) { +- grp = gr_locate_gid ((gid_t) gid); +- } +- else { +- grp = gr_locate(grp_name); +- } +- +- if (grp != NULL) { +- result_grp = __gr_dup (grp); +- if (NULL == result_grp) { +- fprintf (stderr, +- _("%s: Out of memory. Cannot find group '%s'.\n"), +- Prog, grp_name); +- fail_exit (E_GRP_UPDATE); +- } +- } +- +- return result_grp; +-} +- + #ifdef ENABLE_SUBIDS + struct ulong_range + { +@@ -1523,7 +1475,50 @@ static void close_files (void) + } + + if (Gflg || lflg) { +- close_group_files (); ++ if (gr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failure while writing changes to %s", ++ gr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_close () == 0) { ++ fprintf (stderr, ++ _("%s: failure while writing changes to %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failure while writing changes to %s", ++ sgr_dbname ())); ++ fail_exit (E_GRP_UPDATE); ++ } ++ } ++#endif ++#ifdef SHADOWGRP ++ if (is_shadow_grp) { ++ if (sgr_unlock () == 0) { ++ fprintf (stderr, ++ _("%s: failed to unlock %s\n"), ++ Prog, sgr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failed to unlock %s", ++ sgr_dbname ())); ++ /* continue */ ++ } ++ } ++#endif ++ if (gr_unlock () == 0) { ++ fprintf (stderr, ++ _("%s: failed to unlock %s\n"), ++ Prog, gr_dbname ()); ++ SYSLOG ((LOG_ERR, ++ "failed to unlock %s", ++ gr_dbname ())); ++ /* continue */ ++ } + } + + if (is_shadow_pwd) { +@@ -1592,60 +1587,6 @@ static void close_files (void) + #endif + } + +-/* +- * close_group_files - close all of the files that were opened +- * +- * close_group_files() closes all of the files that were opened related +- * with groups. This causes any modified entries to be written out. +- */ +-static void close_group_files (void) +-{ +- if (gr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failure while writing changes to %s", +- gr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_close () == 0) { +- fprintf (stderr, +- _("%s: failure while writing changes to %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failure while writing changes to %s", +- sgr_dbname ())); +- fail_exit (E_GRP_UPDATE); +- } +- } +-#endif +-#ifdef SHADOWGRP +- if (is_shadow_grp) { +- if (sgr_unlock () == 0) { +- fprintf (stderr, +- _("%s: failed to unlock %s\n"), +- Prog, sgr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failed to unlock %s", +- sgr_dbname ())); +- /* continue */ +- } +- } +-#endif +- if (gr_unlock () == 0) { +- fprintf (stderr, +- _("%s: failed to unlock %s\n"), +- Prog, gr_dbname ()); +- SYSLOG ((LOG_ERR, +- "failed to unlock %s", +- gr_dbname ())); +- /* continue */ +- } +-} +- + /* + * open_files - lock and open the password files + * +@@ -1681,7 +1622,38 @@ static void open_files (void) + } + + if (Gflg || lflg) { +- open_group_files (); ++ /* ++ * Lock and open the group file. This will load all of the ++ * group entries. ++ */ ++ if (gr_lock () == 0) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, gr_dbname ()); ++ 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 ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++#ifdef SHADOWGRP ++ if (is_shadow_grp && (sgr_lock () == 0)) { ++ fprintf (stderr, ++ _("%s: cannot lock %s; try again later.\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++ sgr_locked = true; ++ if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { ++ fprintf (stderr, ++ _("%s: cannot open %s\n"), ++ Prog, sgr_dbname ()); ++ fail_exit (E_GRP_UPDATE); ++ } ++#endif + } + #ifdef ENABLE_SUBIDS + if (vflg || Vflg) { +@@ -1717,44 +1689,6 @@ static void open_files (void) + #endif /* ENABLE_SUBIDS */ + } + +-/* +- * open_group_files - lock and open the group files +- * +- * open_group_files() loads all of the group entries. +- */ +-static void open_group_files (void) +-{ +- if (gr_lock () == 0) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, gr_dbname ()); +- 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 ()); +- fail_exit (E_GRP_UPDATE); +- } +- +-#ifdef SHADOWGRP +- if (is_shadow_grp && (sgr_lock () == 0)) { +- fprintf (stderr, +- _("%s: cannot lock %s; try again later.\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +- sgr_locked = true; +- if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) { +- fprintf (stderr, +- _("%s: cannot open %s\n"), +- Prog, sgr_dbname ()); +- fail_exit (E_GRP_UPDATE); +- } +-#endif +-} +- + /* + * usr_update - create the user entries + * +-- +2.31.1 + diff --git a/SOURCES/shadow-4.9.tar.xz.asc b/SOURCES/shadow-4.9.tar.xz.asc new file mode 100644 index 0000000..01906ef --- /dev/null +++ b/SOURCES/shadow-4.9.tar.xz.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- + +iQEzBAABCgAdFiEE8dCNt3gYW/eEAC3/6f7qBqheP50FAmD5+dkACgkQ6f7qBqhe +P53Qywf/ShkcKvecTDRIrKUNJUTIlP8iywZ1NXypfdDKG/J63awMAGrKMZwOkLUS +AnImsvyoW3+XDIhdkeJd1Kv+8JDEt3oJ0ifHjfpXl4FzOervb1ZKtRPUcoJzzpnJ +Szt/7f3Sd0VfbItgf5F6jgMi7iDA/ZIqJTXeI0kEfVVL7DT681jVRjpnoURlrEq1 +6SmIyAul50VmZjLXq1xJ35uktr7VclnaRu17acax95e+oekP4sdNMaV5E5DSeq2N +db7kKCu80+lPvtQpj22vOO2w15ActH6f5Ec3P7OG8jL125q3yZNebVoh8FKxmFsh +PssfXu0TL50qH/p7qNEeihDLpwoI7g== +=6MLu +-----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..d117aec --- /dev/null +++ b/SOURCES/shadow-utils.login.defs @@ -0,0 +1,278 @@ +# +# 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_WARN_AGE 7 + +# Currently PASS_MIN_LEN is not supported + +# 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 100000 +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 100000 +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 + +# Currently PASS_CHANGE_TRIES is not supported + +# Currently PASS_ALWAYS_WARN is not supported + +# Currently PASS_MAX_LEN is not supported + +# 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 BLOWFISH, BLOWFISH-based algorithm will be used for encrypting password +# If set to DES, DES-based algorithm will be used for encrypting password (default) +# +ENCRYPT_METHOD SHA512 + +# +# 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 + +# Currently BCRYPT_MIN_ROUNDS and BCRYPT_MAX_ROUNDS are not supported + +# 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..e9cb766 --- /dev/null +++ b/SPECS/shadow-utils.spec @@ -0,0 +1,1326 @@ +Summary: Utilities for managing accounts and shadow password files +Name: shadow-utils +Version: 4.9 +Release: 2%{?dist} +Epoch: 2 +URL: https://github.com/shadow-maint/shadow +Source0: https://github.com/shadow-maint/shadow/releases/download/%{version}/shadow-%{version}.tar.xz +Source1: https://github.com/shadow-maint/shadow/releases/download/%{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 + +### Globals ### +%global includesubiddir %{_includedir}/shadow + +### Patches ### +# Misc small changes - most probably non-upstreamable +Patch0: shadow-4.9-redhat.patch +# Be more lenient with acceptable user/group names - non upstreamable +Patch1: shadow-4.8-goodname.patch +# Move create home to the end of main - upstreamability unknown +Patch2: shadow-4.9-move-create-home.patch +# SElinux related - upstreamability unknown +Patch3: shadow-4.9-default-range.patch +# Misc manual page changes - non-upstreamable +Patch4: shadow-4.9-manfix.patch +# Date parsing improvement - could be upstreamed +Patch5: shadow-4.2.1-date-parsing.patch +# Additional error message - could be upstreamed +Patch6: shadow-4.6-move-home.patch +# Audit message changes - upstreamability unknown +Patch7: shadow-4.9-audit-update.patch +# Changes related to password unlocking - could be upstreamed +Patch8: shadow-4.5-usermod-unlock.patch +# Additional SElinux related changes - upstreamability unknown +Patch9: shadow-4.8-selinux-perms.patch +# Handle NULL return from *time funcs - could be upstreamed +Patch10: shadow-4.9-null-tm.patch +# Handle /etc/passwd corruption - could be upstreamed +Patch11: shadow-4.8-long-entry.patch +# Limit uid/gid allocation to non-zero - could be upstreamed +Patch12: shadow-4.6-sysugid-min-limit.patch +# Ignore LOGIN_PLAIN_PROMPT in login.defs - upstreamability unknown +Patch13: shadow-4.8-ignore-login-prompt.patch +# https://github.com/shadow-maint/shadow/commit/c6847011e8b656adacd9a0d2a78418cad0de34cb +Patch14: shadow-4.9-newuidmap-libeconf-dependency.patch +# https://github.com/shadow-maint/shadow/commit/e481437ab9ebe9a8bf8fbaabe986d42b2f765991 +Patch15: shadow-4.9-usermod-allow-all-group-types.patch +# https://github.com/shadow-maint/shadow/commit/9dd720a28578eef5be8171697aae0906e4c53249 +Patch16: shadow-4.9-useradd-avoid-generating-empty-subid-range.patch +# https://github.com/shadow-maint/shadow/commit/234e8fa7b134d1ebabfdad980a3ae5b63c046c62 +Patch17: shadow-4.9-libmisc-fix-default-value-in-SHA_get_salt_rounds.patch + +License: BSD and GPLv2+ +BuildRequires: make +BuildRequires: gcc +BuildRequires: libselinux-devel >= 1.25.2-1 +BuildRequires: audit-libs-devel >= 1.6.5 +BuildRequires: libsemanage-devel +BuildRequires: libacl-devel, libattr-devel +BuildRequires: bison, flex, docbook-style-xsl, docbook-dtds +BuildRequires: autoconf, automake, libtool, gettext-devel +BuildRequires: /usr/bin/xsltproc, /usr/bin/itstool +Requires: libselinux >= 1.25.2-1 +Requires: audit-libs >= 1.6.5 +Requires: setup +Provides: shadow = %{epoch}:%{version}-%{release} + +%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+ + +%description subid-devel +Development files for shadow-utils-subid. + +%prep +%setup -q -n shadow-%{version} +%patch0 -p1 -b .redhat +%patch1 -p1 -b .goodname +%patch2 -p1 -b .move-create-home +%patch3 -p1 -b .default-range +%patch4 -p1 -b .manfix +%patch5 -p1 -b .date-parsing +%patch6 -p1 -b .move-home +%patch7 -p1 -b .audit-update +%patch8 -p1 -b .unlock +%patch9 -p1 -b .selinux-perms +%patch10 -p1 -b .null-tm +%patch11 -p1 -b .long-entry +%patch12 -p1 -b .sysugid-min-limit +%patch13 -p1 -b .login-prompt +%patch14 -p1 -b .newuidmap-libeconf-dependency +%patch15 -p1 -b .usermod-allow-all-group-types +%patch16 -p1 -b .useradd-avoid-generating-empty-subid-range +%patch17 -p1 -b .libmisc-fix-default-value-in-SHA_get_salt_rounds + +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 libmisc/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-sha-crypt \ + --with-selinux \ + --without-libcrack \ + --without-libpam \ + --enable-shared \ + --with-group-name-max-length=32 +%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 + + +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}/passwd +rm $RPM_BUILD_ROOT%{_bindir}/su +rm $RPM_BUILD_ROOT%{_bindir}/faillog +rm $RPM_BUILD_ROOT%{_sysconfdir}/login.access +rm $RPM_BUILD_ROOT%{_sysconfdir}/limits +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/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/man1/su.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man1/su.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/limits.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/limits.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/login.access.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/login.access.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/passwd.* +rm $RPM_BUILD_ROOT%{_mandir}/man5/porttime.* +rm $RPM_BUILD_ROOT%{_mandir}/*/man5/porttime.* +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.* + +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 files created by libsubid +rm -f $RPM_BUILD_ROOT/%{_libdir}/libsubid.la + +%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 +%{_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 +%{_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}/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.* + +%files subid-devel +%{includesubiddir}/subid.h +%{_libdir}/libsubid.so + +%changelog +* Tue Aug 17 2021 Iker Pedrosa - 2:4.9-2 +- libmisc: fix default value in SHA_get_salt_rounds(). Resolves: #1993919 + +* Thu Aug 12 2021 Iker Pedrosa - 2:4.9-1 +- Rebase to version 4.9. Resolves: #1989556 +- usermod: allow all group types with -G option. Resolves: #1975329 +- useradd: avoid generating an empty subid range +- Clean spec file + +* Tue Aug 10 2021 Mohan Boddu - 2:4.8.1-12 +- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags + Related: rhbz#1991688 + +* Wed Jul 14 2021 Iker Pedrosa - 2:4.8.1-11 +- Fix regression issues detected in rhbz#667593 and rhbz#672510. Resolves: #1938871 + +* Tue Jul 13 2021 Iker Pedrosa - 2:4.8.1-10 +- Covscan fixes. Resolves: #1938871 + +* Fri Jun 25 2021 Iker Pedrosa - 2:4.8.1-9 +- libsubid: creation and nsswitch support. Resolves: #1859252 +- Creation of subid and subid-devel subpackages +- man: mention NSS in new[ug]idmap manpages +- libsubid: move development header to shadow folder +- 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 +- login.defs: include HMAC_CRYPTO_ALGO key + +* Fri Apr 16 2021 Mohan Boddu - 2:4.8.1-8 +- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 + +* 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