diff --git a/Fix-some-issues-found-in-Coverity-scan.patch b/Fix-some-issues-found-in-Coverity-scan.patch new file mode 100644 index 0000000..116c362 --- /dev/null +++ b/Fix-some-issues-found-in-Coverity-scan.patch @@ -0,0 +1,67 @@ +From fb97da1ce1606f7a2f7c897f5441d1d04020f402 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Wed, 10 Oct 2018 12:22:04 +0200 +Subject: [PATCH 10/19] Fix some issues found in Coverity scan. + +--- + lib/commonio.c | 4 +--- + lib/spawn.c | 2 +- + libmisc/console.c | 5 +++-- + 3 files changed, 5 insertions(+), 6 deletions(-) + +--- shadow-4.6/lib/commonio.c 2019-02-12 00:00:00.000000000 +0000 ++++ shadow-4.6-new/lib/commonio.c 2019-02-12 00:00:00.000000000 +0000 +@@ -384,7 +384,7 @@ + char* lock = NULL; + size_t lock_file_len; + size_t file_len; +- int err; ++ int err = 0; + + if (db->locked) { + return 1; +@@ -393,12 +393,10 @@ + lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */ + file = (char*)malloc(file_len); + if(file == NULL) { +- err = ENOMEM; + goto cleanup_ENOMEM; + } + lock = (char*)malloc(lock_file_len); + if(lock == NULL) { +- err = ENOMEM; + goto cleanup_ENOMEM; + } + snprintf (file, file_len, "%s%s.%lu", +--- shadow-4.6/lib/spawn.c 2019-02-12 00:00:00.000000000 +0000 ++++ shadow-4.6-new/lib/spawn.c 2019-02-12 00:00:00.000000000 +0000 +@@ -69,7 +69,7 @@ + do { + wpid = waitpid (pid, status, 0); + } while ( ((pid_t)-1 == wpid && errno == EINTR) +- || (wpid != pid)); ++ || ((pid_t)-1 != wpid && wpid != pid)); + + if ((pid_t)-1 == wpid) { + fprintf (stderr, "%s: waitpid (status: %d): %s\n", +--- shadow-4.6/libmisc/console.c 2019-02-12 00:00:00.000000000 +0000 ++++ shadow-4.6-new/libmisc/console.c 2019-02-12 00:00:00.000000000 +0000 +@@ -50,7 +50,7 @@ + static bool is_listed (const char *cfgin, const char *tty, bool def) + { + FILE *fp; +- char buf[200], *s; ++ char buf[1024], *s; + const char *cons; + + /* +@@ -70,7 +70,8 @@ + + if (*cons != '/') { + char *pbuf; +- strcpy (buf, cons); ++ strncpy (buf, cons, sizeof (buf)); ++ buf[sizeof (buf) - 1] = '\0'; + pbuf = &buf[0]; + while ((s = strtok (pbuf, ":")) != NULL) { + if (strcmp (s, tty) == 0) { diff --git a/Fix-the-default-mentioned-in-man-page-for-SUB_UID-GI.patch b/Fix-the-default-mentioned-in-man-page-for-SUB_UID-GI.patch new file mode 100644 index 0000000..64a8a27 --- /dev/null +++ b/Fix-the-default-mentioned-in-man-page-for-SUB_UID-GI.patch @@ -0,0 +1,40 @@ +From ebad423023b753b970f491afc7a0df179d151a81 Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Thu, 31 Jan 2019 13:30:59 +0100 +Subject: [PATCH 18/19] Fix the default mentioned in man page for + SUB_UID/GID_COUNT variables. + +--- + man/login.defs.d/SUB_GID_COUNT.xml | 2 +- + man/login.defs.d/SUB_UID_COUNT.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/man/login.defs.d/SUB_GID_COUNT.xml b/man/login.defs.d/SUB_GID_COUNT.xml +index 01ace007..93fe7421 100644 +--- a/man/login.defs.d/SUB_GID_COUNT.xml ++++ b/man/login.defs.d/SUB_GID_COUNT.xml +@@ -42,7 +42,7 @@ + + The default values for , + , +- are respectively 100000, 600100000 and 10000. ++ are respectively 100000, 600100000 and 65536. + + + +diff --git a/man/login.defs.d/SUB_UID_COUNT.xml b/man/login.defs.d/SUB_UID_COUNT.xml +index 5ad812f7..516417b7 100644 +--- a/man/login.defs.d/SUB_UID_COUNT.xml ++++ b/man/login.defs.d/SUB_UID_COUNT.xml +@@ -42,7 +42,7 @@ + + The default values for , + , +- are respectively 100000, 600100000 and 10000. ++ are respectively 100000, 600100000 and 65536. + + + +-- +2.19.1 + diff --git a/Log-UID-in-nologin.patch b/Log-UID-in-nologin.patch new file mode 100644 index 0000000..9d01647 --- /dev/null +++ b/Log-UID-in-nologin.patch @@ -0,0 +1,46 @@ +From 4be18d32991e73c460ca59c43384f75419602a35 Mon Sep 17 00:00:00 2001 +From: Vladimir Ivanov +Date: Fri, 3 Aug 2018 09:44:16 +0800 +Subject: [PATCH 08/19] Log UID in nologin + +Sometimes getlogin() may fail, e.g., in a chroot() environment or due to NSS +misconfiguration. Loggin UID allows for investigation and troubleshooting in +such situation. +--- + src/nologin.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/nologin.c b/src/nologin.c +index 7fe8a6a2..98989d26 100644 +--- a/src/nologin.c ++++ b/src/nologin.c +@@ -24,7 +24,6 @@ + * SUCH DAMAGE. + */ + +-#include + + #ident "$Id$" + +@@ -36,6 +35,7 @@ + int main (void) + { + const char *user, *tty; ++ uid_t uid; + + tty = ttyname (0); + if (NULL == tty) { +@@ -45,8 +45,9 @@ int main (void) + if (NULL == user) { + user = "UNKNOWN"; + } ++ uid = getuid (); /* getuid() is always successful */ + openlog ("nologin", LOG_CONS, LOG_AUTH); +- syslog (LOG_CRIT, "Attempted login by %s on %s", user, tty); ++ syslog (LOG_CRIT, "Attempted login by %s (UID: %d) on %s", user, uid, tty); + closelog (); + + printf ("%s", "This account is currently not available.\n"); +-- +2.19.1 + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 853a96b..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# shadow - -#### Description -{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index 3ae433c..0000000 --- a/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# shadow - -#### 介绍 -{**以下是码云平台说明,您可以替换此简介** -码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 -无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 码云特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 -5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/gpl-2.0.txt b/gpl-2.0.txt new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/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/shadow-4.1.5.1-default-range.patch b/shadow-4.1.5.1-default-range.patch new file mode 100644 index 0000000..2a9d640 --- /dev/null +++ b/shadow-4.1.5.1-default-range.patch @@ -0,0 +1,36 @@ +Index: shadow-4.5/lib/semanage.c +=================================================================== +--- shadow-4.5.orig/lib/semanage.c ++++ shadow-4.5/lib/semanage.c +@@ -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 (stderr, +@@ -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 (stderr, +@@ -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/shadow-4.1.5.1-info-parent-dir.patch b/shadow-4.1.5.1-info-parent-dir.patch new file mode 100644 index 0000000..b3a525b --- /dev/null +++ b/shadow-4.1.5.1-info-parent-dir.patch @@ -0,0 +1,21 @@ +Index: shadow-4.5/man/newusers.8.xml +=================================================================== +--- shadow-4.5.orig/man/newusers.8.xml ++++ shadow-4.5/man/newusers.8.xml +@@ -218,7 +218,15 @@ + + If this field does not specify an existing directory, the + specified directory is created, with ownership set to the +- user being created or updated and its primary group. ++ user being created or updated and its primary group. Note ++ that newusers does not create parent directories of the new ++ user's home directory. The newusers command will fail to ++ create the home directory if the parent directories do not ++ exist, and will send a message to stderr informing the user ++ of the failure. The newusers command will not halt or return ++ a failure to the calling shell if it fails to create the home ++ directory, it will continue to process the batch of new users ++ specified. + + + If the home directory of an existing user is changed, diff --git a/shadow-4.1.5.1-logmsg.patch b/shadow-4.1.5.1-logmsg.patch new file mode 100644 index 0000000..ca7e57b --- /dev/null +++ b/shadow-4.1.5.1-logmsg.patch @@ -0,0 +1,13 @@ +Index: shadow-4.5/src/useradd.c +=================================================================== +--- shadow-4.5.orig/src/useradd.c ++++ shadow-4.5/src/useradd.c +@@ -323,7 +323,7 @@ static void fail_exit (int code) + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +- SYSLOG ((LOG_INFO, "failed adding user '%s', data deleted", user_name)); ++ SYSLOG ((LOG_INFO, "failed adding user '%s', exit code: %d", user_name, code)); + exit (code); + } + diff --git a/shadow-4.1.5.1-userdel-helpfix.patch b/shadow-4.1.5.1-userdel-helpfix.patch new file mode 100644 index 0000000..075f482 --- /dev/null +++ b/shadow-4.1.5.1-userdel-helpfix.patch @@ -0,0 +1,16 @@ +Index: shadow-4.5/src/userdel.c +=================================================================== +--- shadow-4.5.orig/src/userdel.c ++++ shadow-4.5/src/userdel.c +@@ -143,8 +143,9 @@ static void usage (int status) + "\n" + "Options:\n"), + Prog); +- (void) fputs (_(" -f, --force force removal of files,\n" +- " even if not owned by user\n"), ++ (void) fputs (_(" -f, --force force some actions that would fail otherwise\n" ++ " e.g. removal of user still logged in\n" ++ " or files, even if not owned by the user\n"), + usageout); + (void) fputs (_(" -h, --help display this help message and exit\n"), usageout); + (void) fputs (_(" -r, --remove remove home directory and mail spool\n"), usageout); diff --git a/shadow-4.1.5.1-var-lock.patch b/shadow-4.1.5.1-var-lock.patch new file mode 100644 index 0000000..46f75cb --- /dev/null +++ b/shadow-4.1.5.1-var-lock.patch @@ -0,0 +1,47 @@ +From 19efe574cd394a769672dac951e650c14a730e77 Mon Sep 17 00:00:00 2001 +From: hanzhijun +Date: Wed, 6 Mar 2019 10:15:19 +0800 +Subject: [PATCH] change VAR_DIR + +reason: change VAR_DIR + +Signed-off-by: hanzhijun +--- + lib/commonio.c | 11 +++++++---- + 1 file changed, 7 insertion(+), 4 deletion(-) + +diff -Nur shadow-4.6.old/lib/commonio.c shadow-4.6/lib/commonio.c +--- shadow-4.6.old/lib/commonio.c 2019-03-05 06:42:27.620509161 -0500 ++++ shadow-4.6/lib/commonio.c 2019-03-05 06:48:05.048509161 -0500 +@@ -51,6 +51,8 @@ + #include "prototypes.h" + #include "commonio.h" + ++#define VAR_DIR "/var/run/" ++ + /* local function prototypes */ + static int lrename (const char *, const char *); + static int check_link_count (const char *file); +@@ -399,9 +401,10 @@ + if(lock == NULL) { + goto cleanup_ENOMEM; + } +- snprintf (file, file_len, "%s.%lu", +- db->filename, (unsigned long) getpid ()); +- snprintf (lock, lock_file_len, "%s.lock", db->filename); ++ snprintf (file, file_len, "%s%s.%lu", ++ VAR_DIR, basename(db->filename), (unsigned long) getpid ()); ++ snprintf (lock, lock_file_len, "%s%s.lock", VAR_DIR, basename(db->filename)); ++ + if (do_lock_file (file, lock, log) != 0) { + db->locked = true; + lock_count++; +@@ -517,7 +520,7 @@ + * then call ulckpwdf() (if used) on last unlock. + */ + db->locked = false; +- snprintf (lock, sizeof lock, "%s.lock", db->filename); ++ snprintf (lock, sizeof lock, "%s%s.lock", VAR_DIR, basename(db->filename)); + unlink (lock); + dec_lock_count (); + return 1; diff --git a/shadow-4.2.1-date-parsing.patch b/shadow-4.2.1-date-parsing.patch new file mode 100644 index 0000000..2a798d0 --- /dev/null +++ b/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/shadow-4.2.1-no-lock-dos.patch b/shadow-4.2.1-no-lock-dos.patch new file mode 100644 index 0000000..c6873e9 --- /dev/null +++ b/shadow-4.2.1-no-lock-dos.patch @@ -0,0 +1,16 @@ +Index: shadow-4.5/lib/commonio.c +=================================================================== +--- shadow-4.5.orig/lib/commonio.c ++++ shadow-4.5/lib/commonio.c +@@ -140,7 +140,10 @@ static int do_lock_file (const char *fil + int retval; + char buf[32]; + +- fd = open (file, O_CREAT | O_EXCL | O_WRONLY, 0600); ++ /* We depend here on the fact, that the file name is pid-specific. ++ * So no O_EXCL here and no DoS. ++ */ ++ fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600); + if (-1 == fd) { + if (log) { + (void) fprintf (stderr, diff --git a/shadow-4.2.1-null-tm.patch b/shadow-4.2.1-null-tm.patch new file mode 100644 index 0000000..b1dd1c4 --- /dev/null +++ b/shadow-4.2.1-null-tm.patch @@ -0,0 +1,91 @@ +Index: shadow-4.5/src/faillog.c +=================================================================== +--- shadow-4.5.orig/src/faillog.c ++++ shadow-4.5/src/faillog.c +@@ -163,10 +163,14 @@ static void print_one (/*@null@*/const s + } + + tm = localtime (&fl.fail_time); ++ if (tm == NULL) { ++ cp = "(unknown)"; ++ } else { + #ifdef HAVE_STRFTIME +- strftime (ptime, sizeof (ptime), "%D %H:%M:%S %z", tm); +- cp = ptime; ++ strftime (ptime, sizeof (ptime), "%D %H:%M:%S %z", tm); ++ cp = ptime; + #endif ++ } + printf ("%-9s %5d %5d ", + pw->pw_name, fl.fail_cnt, fl.fail_max); + /* FIXME: cp is not defined ifndef HAVE_STRFTIME */ +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/shadow-4.3.1-manfix.patch b/shadow-4.3.1-manfix.patch new file mode 100644 index 0000000..a56d2ed --- /dev/null +++ b/shadow-4.3.1-manfix.patch @@ -0,0 +1,266 @@ +Index: shadow-4.5/man/groupmems.8.xml +=================================================================== +--- shadow-4.5.orig/man/groupmems.8.xml ++++ shadow-4.5/man/groupmems.8.xml +@@ -179,20 +179,10 @@ + + SETUP + +- The groupmems executable should be in mode +- 2770 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 2770 groupmems +- $ chown root.groups groupmems +- $ groupmems -g groups -a gk4 +- + + + +Index: shadow-4.5/man/chage.1.xml +=================================================================== +--- shadow-4.5.orig/man/chage.1.xml ++++ shadow-4.5/man/chage.1.xml +@@ -102,6 +102,9 @@ + Set the number of days since January 1st, 1970 when the password + was last changed. The date may also be expressed in the format + YYYY-MM-DD (or the format more commonly used in your area). ++ If the LAST_DAY is set to ++ 0 the user is forced to change his password ++ on the next log on. + + + +@@ -119,6 +122,13 @@ + system again. + + ++ For example the following can be used to set an account to expire ++ in 180 days: ++ ++ ++ chage -E $(date -d +180days +%Y-%m-%d) ++ ++ + Passing the number -1 as the + EXPIRE_DATE will remove an account + expiration date. +Index: shadow-4.5/man/ja/man5/login.defs.5 +=================================================================== +--- shadow-4.5.orig/man/ja/man5/login.defs.5 ++++ shadow-4.5/man/ja/man5/login.defs.5 +@@ -147,10 +147,6 @@ PASS_MAX_DAYS, PASS_MIN_DAYS, PASS_WARN_ + shadow パスワード機能のどのプログラムが + どのパラメータを使用するかを示したものである。 + .na +-.IP chfn 12 +-CHFN_AUTH CHFN_RESTRICT +-.IP chsh 12 +-CHFN_AUTH + .IP groupadd 12 + GID_MAX GID_MIN + .IP newusers 12 +Index: shadow-4.5/man/login.defs.5.xml +=================================================================== +--- shadow-4.5.orig/man/login.defs.5.xml ++++ shadow-4.5/man/login.defs.5.xml +@@ -162,6 +162,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: + + +@@ -252,16 +263,6 @@ + + + +- chfn +- +- +- CHFN_AUTH +- CHFN_RESTRICT +- LOGIN_STRING +- +- +- +- + chgpasswd + + +@@ -282,14 +283,6 @@ + + + +- +- chsh +- +- +- CHSH_AUTH LOGIN_STRING +- +- +- + + + +@@ -350,34 +343,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 +@@ -405,17 +370,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 + +@@ -442,32 +396,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 + +Index: shadow-4.5/man/shadow.5.xml +=================================================================== +--- shadow-4.5.orig/man/shadow.5.xml ++++ shadow-4.5/man/shadow.5.xml +@@ -208,8 +208,8 @@ + + + After expiration of the password and this expiration period is +- elapsed, no login is possible using the current user's +- password. The user should contact her administrator. ++ elapsed, no login is possible for the user. ++ The user should contact her administrator. + + + An empty field means that there are no enforcement of an +Index: shadow-4.5/man/useradd.8.xml +=================================================================== +--- shadow-4.5.orig/man/useradd.8.xml ++++ shadow-4.5/man/useradd.8.xml +@@ -347,6 +347,11 @@ + is not enabled, no home + directories are created. + ++ ++ The directory where the user's home directory is created must ++ exist and have proper SELinux context and permissions. Otherwise ++ the user's home directory cannot be created or accessed. ++ + + + +Index: shadow-4.5/man/usermod.8.xml +=================================================================== +--- shadow-4.5.orig/man/usermod.8.xml ++++ shadow-4.5/man/usermod.8.xml +@@ -132,7 +132,8 @@ + If the + option is given, the contents of the current home directory will + be moved to the new home directory, which is created if it does +- not already exist. ++ not already exist. If the current home directory does not exist ++ the new home directory will not be created. + + + +@@ -256,7 +257,8 @@ + + + Move the content of the user's home directory to the new +- location. ++ location. If the current home directory does not exist ++ the new home directory will not be created. + + + This option is only valid in combination with the diff --git a/shadow-4.3.1-selinux-perms.patch b/shadow-4.3.1-selinux-perms.patch new file mode 100644 index 0000000..78c2c02 --- /dev/null +++ b/shadow-4.3.1-selinux-perms.patch @@ -0,0 +1,277 @@ +Index: shadow-4.5/src/chgpasswd.c +=================================================================== +--- shadow-4.5.orig/src/chgpasswd.c ++++ shadow-4.5/src/chgpasswd.c +@@ -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" +@@ -76,6 +83,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); +@@ -300,6 +310,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 + */ +@@ -393,6 +460,7 @@ int main (int argc, char **argv) + + const struct group *gr; + struct group newgr; ++ struct passwd *pw = NULL; + int errors = 0; + int line = 0; + +@@ -408,8 +476,33 @@ int main (int argc, char **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 WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + #ifdef SHADOWGRP + is_shadow_grp = sgr_file_present (); + #endif +@@ -536,6 +629,15 @@ int main (int argc, char **argv) + newgr.gr_passwd = cp; + } + ++#ifdef WITH_AUDIT ++ { ++ ++ audit_logger_with_group (AUDIT_GRP_CHAUTHTOK, Prog, ++ "change-password", ++ myname, AUDIT_NO_ID, gr->gr_name, ++ SHADOW_AUDIT_SUCCESS); ++ } ++#endif + /* + * The updated group file entry is then put back and will + * be written to the group file later, after all the +Index: shadow-4.5/src/chpasswd.c +=================================================================== +--- shadow-4.5.orig/src/chpasswd.c ++++ shadow-4.5/src/chpasswd.c +@@ -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 */ +@@ -297,6 +304,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 + */ +@@ -405,8 +469,16 @@ int main (int argc, char **argv) + + OPENLOG ("chpasswd"); + ++#ifdef WITH_AUDIT ++ audit_help_open (); ++#endif ++ + check_perms (); + ++#ifdef WITH_SELINUX ++ selinux_check_root (); ++#endif ++ + #ifdef USE_PAM + if (!use_pam) + #endif /* USE_PAM */ +@@ -566,6 +638,11 @@ int main (int argc, char **argv) + newpw.pw_passwd = cp; + } + ++#ifdef WITH_AUDIT ++ audit_logger (AUDIT_USER_CHAUTHTOK, Prog, ++ "updating-password", ++ pw->pw_name, (unsigned int) pw->pw_uid, 1); ++#endif + /* + * The updated password file entry is then put back and will + * be written to the password file later, after all the +Index: shadow-4.5/src/Makefile.am +=================================================================== +--- shadow-4.5.orig/src/Makefile.am ++++ shadow-4.5/src/Makefile.am +@@ -91,9 +91,9 @@ chage_LDADD = $(LDADD) $(LIBPAM_SUID) + newuidmap_LDADD = $(LDADD) $(LIBSELINUX) $(LIBCAP) + newgidmap_LDADD = $(LDADD) $(LIBSELINUX) $(LIBCAP) + chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) +-chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT) ++chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT) + chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD) +-chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT) ++chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBAUDIT) $(LIBCRYPT) + gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT) + groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) + groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) diff --git a/shadow-4.5-crypt_h.patch b/shadow-4.5-crypt_h.patch new file mode 100644 index 0000000..1b493d4 --- /dev/null +++ b/shadow-4.5-crypt_h.patch @@ -0,0 +1,37 @@ +Index: shadow-4.5/configure.ac +=================================================================== +--- shadow-4.5.orig/configure.ac ++++ shadow-4.5/configure.ac +@@ -36,7 +36,7 @@ AC_HEADER_STDC + utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \ + utime.h ulimit.h sys/capability.h sys/resource.h gshadow.h lastlog.h \ + locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \ +- attr/error_context.h) ++ attr/error_context.h crypt.h) + + dnl shadow now uses the libc's shadow implementation + AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])]) +Index: shadow-4.5/lib/defines.h +=================================================================== +--- shadow-4.5.orig/lib/defines.h ++++ shadow-4.5/lib/defines.h +@@ -4,6 +4,8 @@ + #ifndef _DEFINES_H_ + #define _DEFINES_H_ + ++#include "config.h" ++ + #if HAVE_STDBOOL_H + # include + #else +@@ -94,6 +96,10 @@ char *strchr (), *strrchr (), *strtok () + # include + #endif + ++#if HAVE_CRYPT_H ++# include /* crypt(3) may be defined in here */ ++#endif ++ + #if TIME_WITH_SYS_TIME + # include + # include diff --git a/shadow-4.5-goodname.patch b/shadow-4.5-goodname.patch new file mode 100644 index 0000000..215f658 --- /dev/null +++ b/shadow-4.5-goodname.patch @@ -0,0 +1,96 @@ +Index: shadow-4.5/libmisc/chkname.c +=================================================================== +--- shadow-4.5.orig/libmisc/chkname.c ++++ shadow-4.5/libmisc/chkname.c +@@ -47,27 +47,46 @@ + #include "chkname.h" + + static bool is_valid_name (const char *name) +-{ ++{ + /* +- * User/group names must match [a-z_][a-z0-9_-]*[$] +- */ +- if (('\0' == *name) || +- !((('a' <= *name) && ('z' >= *name)) || ('_' == *name))) { ++ * 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 || ++ ('.' == *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) +Index: shadow-4.5/man/groupadd.8.xml +=================================================================== +--- shadow-4.5.orig/man/groupadd.8.xml ++++ shadow-4.5/man/groupadd.8.xml +@@ -256,12 +256,6 @@ + + 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 only be up to &GROUP_NAME_MAX_LENGTH; characters long. + + +Index: shadow-4.5/man/useradd.8.xml +=================================================================== +--- shadow-4.5.orig/man/useradd.8.xml ++++ shadow-4.5/man/useradd.8.xml +@@ -633,12 +633,6 @@ + + + +- 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 only be up to 32 characters long. + + diff --git a/shadow-4.5-long-entry.patch b/shadow-4.5-long-entry.patch new file mode 100644 index 0000000..dc0be93 --- /dev/null +++ b/shadow-4.5-long-entry.patch @@ -0,0 +1,84 @@ +diff -up shadow-4.5/lib/defines.h.long-entry shadow-4.5/lib/defines.h +--- shadow-4.5/lib/defines.h.long-entry 2014-09-01 16:36:40.000000000 +0200 ++++ shadow-4.5/lib/defines.h 2018-04-20 11:53:07.419308212 +0200 +@@ -382,4 +382,7 @@ extern char *strerror (); + # define shadow_getenv(name) getenv(name) + #endif + ++/* Maximum length of passwd entry */ ++#define PASSWD_ENTRY_MAX_LENGTH 32768 ++ + #endif /* _DEFINES_H_ */ +diff -up shadow-4.5/lib/pwio.c.long-entry shadow-4.5/lib/pwio.c +--- shadow-4.5/lib/pwio.c.long-entry 2015-11-17 17:45:15.000000000 +0100 ++++ shadow-4.5/lib/pwio.c 2018-04-20 12:10:24.400837235 +0200 +@@ -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.5/lib/sgetpwent.c.long-entry shadow-4.5/lib/sgetpwent.c +--- shadow-4.5/lib/sgetpwent.c.long-entry 2014-09-01 16:36:40.000000000 +0200 ++++ shadow-4.5/lib/sgetpwent.c 2018-04-20 12:16:31.911513808 +0200 +@@ -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.5/lib/sgetspent.c.long-entry shadow-4.5/lib/sgetspent.c +--- shadow-4.5/lib/sgetspent.c.long-entry 2014-09-01 16:36:40.000000000 +0200 ++++ shadow-4.5/lib/sgetspent.c 2018-04-20 12:16:54.505056257 +0200 +@@ -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.5/lib/shadowio.c.long-entry shadow-4.5/lib/shadowio.c +--- shadow-4.5/lib/shadowio.c.long-entry 2016-12-07 06:30:41.000000001 +0100 ++++ shadow-4.5/lib/shadowio.c 2018-04-20 12:12:03.292171667 +0200 +@@ -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/shadow-4.5-usermod-unlock.patch b/shadow-4.5-usermod-unlock.patch new file mode 100644 index 0000000..e2d70b5 --- /dev/null +++ b/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/shadow-4.6-audit-update.patch b/shadow-4.6-audit-update.patch new file mode 100644 index 0000000..7fdbe53 --- /dev/null +++ b/shadow-4.6-audit-update.patch @@ -0,0 +1,2347 @@ +diff -up shadow-4.6/libmisc/audit_help.c.audit-update shadow-4.6/libmisc/audit_help.c +--- shadow-4.6/libmisc/audit_help.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/libmisc/audit_help.c 2018-05-28 15:01:09.913717564 +0200 +@@ -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.6/libmisc/cleanup_group.c.audit-update shadow-4.6/libmisc/cleanup_group.c +--- shadow-4.6/libmisc/cleanup_group.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/libmisc/cleanup_group.c 2018-05-28 15:01:09.913717564 +0200 +@@ -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.6/libmisc/cleanup_user.c.audit-update shadow-4.6/libmisc/cleanup_user.c +--- shadow-4.6/libmisc/cleanup_user.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/libmisc/cleanup_user.c 2018-05-28 15:01:09.913717564 +0200 +@@ -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.6/lib/prototypes.h.audit-update shadow-4.6/lib/prototypes.h +--- shadow-4.6/lib/prototypes.h.audit-update 2018-05-28 15:01:09.901717309 +0200 ++++ shadow-4.6/lib/prototypes.h 2018-05-28 15:01:09.913717564 +0200 +@@ -211,12 +211,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.6/src/gpasswd.c.audit-update shadow-4.6/src/gpasswd.c +--- shadow-4.6/src/gpasswd.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/gpasswd.c 2018-05-28 15:01:09.914717585 +0200 +@@ -137,7 +137,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 +@@ -396,21 +396,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) { +@@ -418,13 +411,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) { +@@ -432,13 +421,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) { +@@ -446,13 +431,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) { +@@ -462,13 +443,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 + } +@@ -478,13 +455,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 + } +@@ -493,13 +466,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 + } +@@ -530,21 +499,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) { +@@ -552,13 +514,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) { +@@ -566,13 +524,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) { +@@ -580,13 +534,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) { +@@ -596,13 +546,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 + } +@@ -612,13 +558,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 + } +@@ -627,13 +569,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.6/src/groupadd.c.audit-update shadow-4.6/src/groupadd.c +--- shadow-4.6/src/groupadd.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/groupadd.c 2018-05-28 15:02:53.137910337 +0200 +@@ -130,6 +130,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 + * +@@ -213,7 +222,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 + /* +@@ -223,7 +232,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 */ + } +@@ -247,7 +256,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); + } + + /* +@@ -263,11 +272,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 +@@ -285,11 +294,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 +@@ -303,12 +312,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); +@@ -326,7 +329,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); + +@@ -336,7 +339,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); + } +@@ -352,7 +355,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 +@@ -362,7 +365,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 */ +@@ -495,7 +498,7 @@ static void check_flags (void) + fprintf (stderr, + _("%s: group '%s' already exists\n"), + Prog, group_name); +- exit (E_NAME_IN_USE); ++ fail_exit (E_NAME_IN_USE); + } + + if (gflg && (prefix_getgrgid (group_id) != NULL)) { +@@ -514,7 +517,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); + } + } + } +@@ -542,7 +545,7 @@ static void check_perms (void) + fprintf (stderr, + _("%s: Cannot determine your user name.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + retval = pam_start ("groupadd", pampw->pw_name, &conv, &pamh); +@@ -562,7 +565,7 @@ static void check_perms (void) + if (NULL != pamh) { + (void) pam_end (pamh, retval); + } +- exit (1); ++ fail_exit (1); + } + (void) pam_end (pamh, retval); + #endif /* USE_PAM */ +@@ -595,7 +598,7 @@ int main (int argc, char **argv) + fprintf (stderr, + _("%s: Cannot setup cleanup service.\n"), + Prog); +- exit (1); ++ fail_exit (1); + } + + /* +@@ -617,7 +620,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.6/src/groupdel.c.audit-update shadow-4.6/src/groupdel.c +--- shadow-4.6/src/groupdel.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/groupdel.c 2018-05-28 15:01:09.914717585 +0200 +@@ -105,6 +105,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 + * +@@ -131,7 +140,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 +@@ -143,7 +152,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 */ +@@ -162,12 +171,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 +@@ -187,12 +196,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 +@@ -206,13 +215,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); + } +@@ -229,7 +231,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 +@@ -238,7 +240,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); + } +@@ -256,7 +258,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) { +@@ -265,7 +267,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 */ +@@ -306,7 +308,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); + } + + /* +@@ -391,7 +393,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); +@@ -405,7 +407,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); +@@ -426,7 +428,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 */ +@@ -446,7 +448,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; +@@ -470,7 +472,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.6/src/groupmod.c.audit-update shadow-4.6/src/groupmod.c +--- shadow-4.6/src/groupmod.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/groupmod.c 2018-05-28 15:01:09.915717607 +0200 +@@ -449,7 +449,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); +@@ -472,7 +472,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_gshadow.audit_msg, + group_name, AUDIT_NO_ID, + SHADOW_AUDIT_SUCCESS); +@@ -495,7 +495,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); +@@ -510,8 +510,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 +@@ -523,6 +523,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; +@@ -535,76 +537,106 @@ 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) { ++ /* 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'; +@@ -612,6 +644,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.6/src/chage.c.audit-update shadow-4.6/src/chage.c +--- shadow-4.6/src/chage.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/chage.c 2018-05-28 15:01:09.915717607 +0200 +@@ -126,9 +126,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 + +@@ -873,11 +874,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); + } +@@ -896,41 +893,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.6/src/newgrp.c.audit-update shadow-4.6/src/newgrp.c +--- shadow-4.6/src/newgrp.c.audit-update 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/newgrp.c 2018-05-28 15:01:09.915717607 +0200 +@@ -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); +@@ -457,7 +458,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 ())); +@@ -573,15 +574,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); +@@ -738,10 +750,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); + } +@@ -750,10 +762,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); + } +@@ -767,10 +779,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); +@@ -834,11 +846,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 +@@ -862,15 +874,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.6/src/useradd.c.audit-update shadow-4.6/src/useradd.c +--- shadow-4.6/src/useradd.c.audit-update 2018-05-28 15:01:09.903717352 +0200 ++++ shadow-4.6/src/useradd.c 2018-05-28 15:06:36.824662074 +0200 +@@ -229,6 +229,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, +@@ -242,12 +244,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 */ + } + } +@@ -255,12 +251,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 */ + } + } +@@ -268,12 +258,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 */ + } + } +@@ -282,12 +266,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 */ + } + } +@@ -297,12 +275,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 */ + } + } +@@ -310,20 +282,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 +@@ -673,7 +644,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 +@@ -950,12 +921,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 */ + } + +@@ -969,18 +934,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, +@@ -1025,12 +984,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 */ + } + +@@ -1044,18 +997,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, +@@ -1407,7 +1355,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 +@@ -1522,7 +1470,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 +@@ -1535,7 +1483,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 +@@ -1547,7 +1495,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking group file", ++ "unlocking-group-file", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1561,7 +1509,7 @@ static void close_files (void) + SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "unlocking gshadow file", ++ "unlocking-gshadow-file", + user_name, AUDIT_NO_ID, + SHADOW_AUDIT_FAILURE); + #endif +@@ -1577,7 +1525,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 +@@ -1591,7 +1539,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 +@@ -1783,7 +1731,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 +@@ -1799,7 +1747,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 +@@ -1809,7 +1757,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 +@@ -1970,12 +1918,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 +@@ -1997,7 +1939,7 @@ static void usr_update (void) + + #ifdef WITH_AUDIT + audit_logger (AUDIT_ADD_USER, Prog, +- "adding user", ++ "add-user", + user_name, (unsigned int) user_id, + SHADOW_AUDIT_SUCCESS); + #endif +@@ -2032,12 +1974,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) { +@@ -2045,8 +1981,8 @@ static void create_home (void) + 0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK)); + 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 +@@ -2231,12 +2167,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); + } + +@@ -2252,12 +2182,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); + } + } +@@ -2287,12 +2211,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); + } + } +@@ -2365,9 +2283,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 */ + rv = E_SE_UPDATE; + } +diff -up shadow-4.6/src/userdel.c.audit-update shadow-4.6/src/userdel.c +--- shadow-4.6/src/userdel.c.audit-update 2018-05-28 15:01:09.909717479 +0200 ++++ shadow-4.6/src/userdel.c 2018-05-28 15:01:09.916717628 +0200 +@@ -219,9 +219,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", +@@ -281,9 +281,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", +@@ -360,9 +360,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, +@@ -378,9 +378,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, +@@ -542,7 +542,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 */ +@@ -562,24 +562,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) { +@@ -587,12 +575,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; +@@ -600,12 +582,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); + } + } +@@ -613,23 +589,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 +@@ -638,24 +602,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); + } + } +@@ -666,24 +618,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); + } + } +@@ -692,24 +632,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); + } + } +@@ -754,7 +682,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 */ +@@ -862,7 +790,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 */ +@@ -879,7 +807,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 */ +@@ -889,8 +817,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); + } +@@ -908,7 +836,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 */ +@@ -925,7 +853,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 */ +@@ -935,8 +863,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); + } +@@ -1149,7 +1077,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 */ +@@ -1205,7 +1133,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 */ +@@ -1282,8 +1210,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); + } +@@ -1292,7 +1220,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); + } +@@ -1305,8 +1233,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.6/src/usermod.c.audit-update shadow-4.6/src/usermod.c +--- shadow-4.6/src/usermod.c.audit-update 2018-05-28 15:01:09.912717543 +0200 ++++ shadow-4.6/src/usermod.c 2018-05-28 15:08:25.424969050 +0200 +@@ -453,8 +453,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, "!"); +@@ -473,8 +473,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; +@@ -485,7 +485,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)); +@@ -514,8 +514,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, +@@ -535,8 +535,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, +@@ -546,8 +546,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, +@@ -557,8 +557,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; +@@ -566,8 +566,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, +@@ -577,8 +577,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, +@@ -608,8 +608,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, +@@ -625,8 +625,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, +@@ -709,9 +709,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); + } +@@ -765,9 +765,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'", +@@ -781,9 +784,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'", +@@ -796,9 +801,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)); +@@ -873,9 +880,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'", +@@ -895,9 +903,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'", +@@ -911,9 +920,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'", +@@ -926,9 +936,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)); +@@ -1789,8 +1800,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 +@@ -1808,8 +1819,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 +@@ -1828,9 +1839,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); +@@ -2045,8 +2056,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 +@@ -2072,8 +2083,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 +@@ -2267,8 +2278,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 */ +@@ -2280,8 +2291,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 */ +@@ -2319,8 +2330,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/shadow-4.6-getenforce.patch b/shadow-4.6-getenforce.patch new file mode 100644 index 0000000..8a55bf5 --- /dev/null +++ b/shadow-4.6-getenforce.patch @@ -0,0 +1,21 @@ +diff -up shadow-4.6/lib/selinux.c.getenforce shadow-4.6/lib/selinux.c +--- shadow-4.6/lib/selinux.c.getenforce 2018-05-28 15:10:15.870315221 +0200 ++++ shadow-4.6/lib/selinux.c 2018-05-28 15:10:15.894315731 +0200 +@@ -75,7 +75,7 @@ int set_selinux_file_context (const char + } + return 0; + error: +- if (security_getenforce () != 0) { ++ if (security_getenforce () > 0) { + return 1; + } + return 0; +@@ -95,7 +95,7 @@ int reset_selinux_file_context (void) + selinux_checked = true; + } + if (selinux_enabled) { +- if (setfscreatecon (NULL) != 0) { ++ if (setfscreatecon (NULL) != 0 && security_getenforce () > 0) { + return 1; + } + } diff --git a/shadow-4.6-move-home.patch b/shadow-4.6-move-home.patch new file mode 100644 index 0000000..cff9561 --- /dev/null +++ b/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/shadow-4.6-orig-context.patch b/shadow-4.6-orig-context.patch new file mode 100644 index 0000000..1f2470b --- /dev/null +++ b/shadow-4.6-orig-context.patch @@ -0,0 +1,128 @@ +diff -up shadow-4.6/lib/commonio.c.orig-context shadow-4.6/lib/commonio.c +--- shadow-4.6/lib/commonio.c.orig-context 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/lib/commonio.c 2018-05-28 14:56:37.287929667 +0200 +@@ -961,7 +961,7 @@ int commonio_close (struct commonio_db * + snprintf (buf, sizeof buf, "%s-", db->filename); + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (buf) != 0) { ++ if (set_selinux_file_context (buf, db->filename) != 0) { + errors++; + } + #endif +@@ -994,7 +994,7 @@ int commonio_close (struct commonio_db * + snprintf (buf, sizeof buf, "%s+", db->filename); + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (buf) != 0) { ++ if (set_selinux_file_context (buf, db->filename) != 0) { + errors++; + } + #endif +diff -up shadow-4.6/libmisc/copydir.c.orig-context shadow-4.6/libmisc/copydir.c +--- shadow-4.6/libmisc/copydir.c.orig-context 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/libmisc/copydir.c 2018-05-28 14:56:37.287929667 +0200 +@@ -484,7 +484,7 @@ static int copy_dir (const char *src, co + */ + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + return -1; + } + #endif /* WITH_SELINUX */ +@@ -605,7 +605,7 @@ static int copy_symlink (const char *src + } + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + free (oldlink); + return -1; + } +@@ -684,7 +684,7 @@ static int copy_special (const char *src + int err = 0; + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + return -1; + } + #endif /* WITH_SELINUX */ +@@ -744,7 +744,7 @@ static int copy_file (const char *src, c + return -1; + } + #ifdef WITH_SELINUX +- if (set_selinux_file_context (dst) != 0) { ++ if (set_selinux_file_context (dst, NULL) != 0) { + return -1; + } + #endif /* WITH_SELINUX */ +diff -up shadow-4.6/lib/prototypes.h.orig-context shadow-4.6/lib/prototypes.h +--- shadow-4.6/lib/prototypes.h.orig-context 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/lib/prototypes.h 2018-05-28 14:56:37.287929667 +0200 +@@ -326,7 +326,7 @@ extern /*@observer@*/const char *crypt_m + + /* selinux.c */ + #ifdef WITH_SELINUX +-extern int set_selinux_file_context (const char *dst_name); ++extern int set_selinux_file_context (const char *dst_name, const char *orig_name); + extern int reset_selinux_file_context (void); + #endif + +diff -up shadow-4.6/lib/selinux.c.orig-context shadow-4.6/lib/selinux.c +--- shadow-4.6/lib/selinux.c.orig-context 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/lib/selinux.c 2018-05-28 14:56:37.287929667 +0200 +@@ -50,7 +50,7 @@ static bool selinux_enabled; + * Callers may have to Reset SELinux to create files with default + * contexts with reset_selinux_file_context + */ +-int set_selinux_file_context (const char *dst_name) ++int set_selinux_file_context (const char *dst_name, const char *orig_name) + { + /*@null@*/security_context_t scontext = NULL; + +@@ -62,19 +62,23 @@ int set_selinux_file_context (const char + if (selinux_enabled) { + /* Get the default security context for this file */ + if (matchpathcon (dst_name, 0, &scontext) < 0) { +- if (security_getenforce () != 0) { +- return 1; +- } ++ /* We could not get the default, copy the original */ ++ if (orig_name == NULL) ++ goto error; ++ if (getfilecon (orig_name, &scontext) < 0) ++ goto error; + } + /* Set the security context for the next created file */ +- if (setfscreatecon (scontext) < 0) { +- if (security_getenforce () != 0) { +- return 1; +- } +- } ++ if (setfscreatecon (scontext) < 0) ++ goto error; + freecon (scontext); + } + return 0; ++ error: ++ if (security_getenforce () != 0) { ++ return 1; ++ } ++ return 0; + } + + /* +diff -up shadow-4.6/src/useradd.c.orig-context shadow-4.6/src/useradd.c +--- shadow-4.6/src/useradd.c.orig-context 2018-05-28 14:56:37.288929688 +0200 ++++ shadow-4.6/src/useradd.c 2018-05-28 14:58:02.242730903 +0200 +@@ -2020,7 +2020,7 @@ static void create_home (void) + ++bhome; + + #ifdef WITH_SELINUX +- if (set_selinux_file_context (prefix_user_home) != 0) { ++ if (set_selinux_file_context (prefix_user_home, NULL) != 0) { + fprintf (stderr, + _("%s: cannot set SELinux context for home directory %s\n"), + Prog, user_home); diff --git a/shadow-4.6-redhat.patch b/shadow-4.6-redhat.patch new file mode 100644 index 0000000..7a8be2e --- /dev/null +++ b/shadow-4.6-redhat.patch @@ -0,0 +1,41 @@ +diff -up shadow-4.6/src/useradd.c.redhat shadow-4.6/src/useradd.c +--- shadow-4.6/src/useradd.c.redhat 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/src/useradd.c 2018-05-28 13:37:16.695651258 +0200 +@@ -98,7 +98,7 @@ const char *Prog; + static gid_t def_group = 100; + static const char *def_gname = "other"; + static const char *def_home = "/home"; +-static const char *def_shell = ""; ++static const char *def_shell = "/sbin/nologin"; + static const char *def_template = SKEL_DIR; + static const char *def_create_mail_spool = "no"; + +@@ -108,7 +108,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 = ""; +@@ -1114,9 +1114,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) { +@@ -1267,6 +1267,7 @@ static void process_flags (int argc, cha + case 'M': + Mflg = true; + break; ++ case 'n': + case 'N': + Nflg = true; + break; diff --git a/shadow-4.6-selinux.patch b/shadow-4.6-selinux.patch new file mode 100644 index 0000000..3c4fde7 --- /dev/null +++ b/shadow-4.6-selinux.patch @@ -0,0 +1,117 @@ +diff -up shadow-4.6/lib/semanage.c.selinux shadow-4.6/lib/semanage.c +--- shadow-4.6/lib/semanage.c.selinux 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/lib/semanage.c 2018-05-28 13:38:20.551008911 +0200 +@@ -294,6 +294,9 @@ int set_seuser (const char *login_name, + + ret = 0; + ++ /* drop obsolete matchpathcon cache */ ++ matchpathcon_fini(); ++ + done: + semanage_seuser_key_free (key); + semanage_handle_destroy (handle); +@@ -369,6 +372,10 @@ int del_seuser (const char *login_name) + } + + ret = 0; ++ ++ /* drop obsolete matchpathcon cache */ ++ matchpathcon_fini(); ++ + done: + semanage_handle_destroy (handle); + return ret; +diff -up shadow-4.6/src/useradd.c.selinux shadow-4.6/src/useradd.c +--- shadow-4.6/src/useradd.c.selinux 2018-05-28 13:43:30.996748997 +0200 ++++ shadow-4.6/src/useradd.c 2018-05-28 13:44:04.645486199 +0200 +@@ -2120,6 +2120,7 @@ static void create_mail (void) + */ + int main (int argc, char **argv) + { ++ int rv = E_SUCCESS; + #ifdef ACCT_TOOLS_SETUID + #ifdef USE_PAM + pam_handle_t *pamh = NULL; +@@ -2342,27 +2343,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 already exists.\n" +- "Not copying any file from skel directory into it.\n"), +- 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, +@@ -2373,8 +2358,9 @@ int main (int argc, char **argv) + } + + #ifdef WITH_SELINUX +- if (Zflg) { +- if (set_seuser (user_name, user_selinux) != 0) { ++ if (Zflg && *user_selinux) { ++ if (is_selinux_enabled () > 0) { ++ if (set_seuser (user_name, user_selinux) != 0) { + fprintf (stderr, + _("%s: warning: the user name %s to %s SELinux user mapping failed.\n"), + Prog, user_name, user_selinux); +@@ -2383,15 +2369,31 @@ int main (int argc, char **argv) + "adding SELinux user mapping", + user_name, (unsigned int) user_id, 0); + #endif /* WITH_AUDIT */ +- fail_exit (E_SE_UPDATE); ++ rv = E_SE_UPDATE; ++ } + } + } +-#endif /* WITH_SELINUX */ ++#endif + +- 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 already exists.\n" ++ "Not copying any file from skel directory into it.\n"), ++ Prog); ++ } ++ ++ } ++ ++ /* Do not create mail directory for system accounts */ ++ if (!rflg) { ++ create_mail (); ++ } + +- return E_SUCCESS; ++ return rv; + } + diff --git a/shadow-4.6-usermod-crash.patch b/shadow-4.6-usermod-crash.patch new file mode 100644 index 0000000..d2861b3 --- /dev/null +++ b/shadow-4.6-usermod-crash.patch @@ -0,0 +1,42 @@ +diff -up shadow-4.6/libmisc/prefix_flag.c.usermod-crash shadow-4.6/libmisc/prefix_flag.c +--- shadow-4.6/libmisc/prefix_flag.c.usermod-crash 2018-04-29 18:42:37.000000000 +0200 ++++ shadow-4.6/libmisc/prefix_flag.c 2018-05-28 15:14:10.642302440 +0200 +@@ -319,6 +319,7 @@ extern struct group *prefix_getgr_nam_gi + { + long long int gid; + char *endptr; ++ struct group *g; + + if (NULL == grname) { + return NULL; +@@ -333,7 +334,8 @@ extern struct group *prefix_getgr_nam_gi + && (gid == (gid_t)gid)) { + return prefix_getgrgid ((gid_t) gid); + } +- return prefix_getgrnam (grname); ++ g = prefix_getgrnam (grname); ++ return g ? __gr_dup(g) : NULL; + } + else + return getgr_nam_gid(grname); +diff -up shadow-4.6/src/usermod.c.usermod-crash shadow-4.6/src/usermod.c +--- shadow-4.6/src/usermod.c.usermod-crash 2018-05-28 15:12:37.920332763 +0200 ++++ shadow-4.6/src/usermod.c 2018-05-28 15:15:50.337422470 +0200 +@@ -1276,11 +1276,13 @@ static void process_flags (int argc, cha + prefix_user_home = xmalloc(len); + wlen = snprintf(prefix_user_home, len, "%s/%s", prefix, user_home); + assert (wlen == (int) len -1); ++ if (user_newhome) { ++ len = strlen(prefix) + strlen(user_newhome) + 2; ++ prefix_user_newhome = xmalloc(len); ++ wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome); ++ assert (wlen == (int) len -1); ++ } + +- len = strlen(prefix) + strlen(user_newhome) + 2; +- prefix_user_newhome = xmalloc(len); +- wlen = snprintf(prefix_user_newhome, len, "%s/%s", prefix, user_newhome); +- assert (wlen == (int) len -1); + } + else { + prefix_user_home = user_home; diff --git a/shadow-4.6.tar.xz.asc b/shadow-4.6.tar.xz.asc new file mode 100644 index 0000000..e36c97f --- /dev/null +++ b/shadow-4.6.tar.xz.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- + +iQEzBAABCgAdFiEE8dCNt3gYW/eEAC3/6f7qBqheP50FAlrncOkACgkQ6f7qBqhe +P52UGAf/eOnoIYIZ52y72iMxeNfQMTMjYTZd1YrtjlK0RQKquK7FrCOg91MvOF2B +hLVKu2OU7mzuPTMSAraAxjXLkrM0E3vFjMtu1fHBGlGTMspAfik/9Gu9qoevAKXy +BRqgN5m5HMfoGPeEjzILzaGq8bnPKIOfJ0iAYVkjjIa73Vn20uTmNgNZIRqHqwfw +5GUFHn6cjQXFcQ3ngywgwQD7/h/65w8dBbGysF551sAqzPJRbneQL9Wtklcqi1ub +55NyF0ifT67RqMh+EyxhuhXP1Hi57PTEAeqaFMFxnPlQPb+8pQ8nszWBmI+vUN8D +FmhwCtSTnmKlj0jeAqevmkijJhGPQQ== +=fk/F +-----END PGP SIGNATURE----- diff --git a/shadow-4.7.tar.xz b/shadow-4.7.tar.xz new file mode 100644 index 0000000..c4e121d Binary files /dev/null and b/shadow-4.7.tar.xz differ diff --git a/shadow-4.7.tar.xz.asc b/shadow-4.7.tar.xz.asc new file mode 100644 index 0000000..a3fe96d --- /dev/null +++ b/shadow-4.7.tar.xz.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- + +iQEzBAABCgAdFiEE8dCNt3gYW/eEAC3/6f7qBqheP50FAl0CfrYACgkQ6f7qBqhe +P50xqQgAgmeu46zmQ7A+8nzcna8aaKQ5aftc9QVCQuPg94DvkXNuUjz384os1PBa +9DM5ukiDiDWhkmoKDCro9d/JVfKg0v0W2Ee29JvaZRhpUFlk3xWZAM55Na22ywbv +JYIF94wLfH0+AZQvjTpJmlJgeCK5K0L2LvAsPoEsHNuAKjpz7tFGJgqBKgK2+xAv +csmBhPRShZypXH3tQ/jcMT8itPSRBGt4W55zuNUT2OKc5ioXxc1TJ5jn0YX8AsOQ +5ZkBbGHL416QRonhiKfWsntB3RnmJQMcL8R72MpemKjVw+q+QYnnKIE/Fta7J0+N +EkUBRYdbbiAsUNW3syN/Q2o+DF00aw== +=dbPQ +-----END PGP SIGNATURE----- diff --git a/shadow-bsd.txt b/shadow-bsd.txt new file mode 100644 index 0000000..a2c1609 --- /dev/null +++ b/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/shadow-utils-fix-invalid-path.patch b/shadow-utils-fix-invalid-path.patch new file mode 100644 index 0000000..f98fb3a --- /dev/null +++ b/shadow-utils-fix-invalid-path.patch @@ -0,0 +1,39 @@ +From d268644440170ea52e124061e2d848278c693c90 Mon Sep 17 00:00:00 2001 +From: guoxiaoqi +Date: Mon, 16 Dec 2019 10:31:44 -0500 +Subject: [PATCH] fix invalid path + +Signed-off-by: guoxiaoqi +--- + src/useradd.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/src/useradd.c b/src/useradd.c +index cafbe90..930b4ea 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -1276,6 +1276,21 @@ static void process_flags (int argc, char **argv) + exit (E_BAD_ARG); + } + user_shell = optarg; ++ struct stat st; ++ if (stat (optarg, &st) != 0) { ++ if ((ENOENT == errno) || (ENOTDIR == errno)) { ++ /* The file or directory does not exist */ ++ fprintf (stderr, ++ _("%s: warning :The file %s is not exist\n"), ++ Prog, optarg); ++ exit (E_BAD_ARG); ++ } ++ } else if ((st.st_mode & S_IXUSR) == 0) { ++ fprintf (stderr, ++ _("%s: warning :The file %s is not executable\n"), ++ Prog, optarg); ++ exit (E_BAD_ARG); ++ } + def_shell = optarg; + sflg = true; + break; +-- +1.8.3.1 + diff --git a/shadow-utils-fix-lock-file-residue.patch b/shadow-utils-fix-lock-file-residue.patch new file mode 100644 index 0000000..f04e4b9 --- /dev/null +++ b/shadow-utils-fix-lock-file-residue.patch @@ -0,0 +1,31 @@ +From f0c78e7ba1e2721398ff811b709cc1d46ae31386 Mon Sep 17 00:00:00 2001 +From: lubing +Date: Fri, 3 May 2019 16:46:45 +0800 +Subject: [PATCH] shadow-utils: fix lock file residue + +reason: fix lock file residue + +Signed-off-by: lubing +--- + lib/commonio.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/commonio.c b/lib/commonio.c +index 2c223e4..a110ca9 100644 +--- a/lib/commonio.c ++++ b/lib/commonio.c +@@ -389,8 +389,9 @@ int commonio_lock_nowait (struct commonio_db *db, bool log) + if (db->locked) { + return 1; + } +- file_len = strlen(db->filename) + 11;/* %lu max size */ +- lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */ ++ /* files moved from /etc/ to /var/run/, change malloc size */ ++ file_len = strlen(db->filename) + 15;/* %lu max size */ ++ lock_file_len = strlen(db->filename) + 15; /* sizeof ".lock" */ + file = (char*)malloc(file_len); + if(file == NULL) { + goto cleanup_ENOMEM; +-- +1.8.3.1 + diff --git a/shadow-utils.login.defs b/shadow-utils.login.defs new file mode 100644 index 0000000..3f27f88 --- /dev/null +++ b/shadow-utils.login.defs @@ -0,0 +1,72 @@ +# +# 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. +# + +# *REQUIRED* +# Directory where mailboxes reside, _or_ name of file, relative to the +# home directory. If you _do_ define both, MAIL_DIR takes precedence. +# QMAIL_DIR is for Qmail +# +#QMAIL_DIR Maildir +MAIL_DIR /var/spool/mail +#MAIL_FILE .mail + +# Password aging controls: +# +# PASS_MAX_DAYS Maximum number of days a password may be used. +# PASS_MIN_DAYS Minimum number of days allowed between password changes. +# PASS_MIN_LEN Minimum acceptable password length. +# PASS_WARN_AGE Number of days warning given before a password expires. +# +PASS_MAX_DAYS 99999 +PASS_MIN_DAYS 0 +PASS_MIN_LEN 5 +PASS_WARN_AGE 7 + +# +# Min/max values for automatic uid selection in useradd +# +UID_MIN 1000 +UID_MAX 60000 +# System accounts +SYS_UID_MIN 201 +SYS_UID_MAX 999 + +# +# Min/max values for automatic gid selection in groupadd +# +GID_MIN 1000 +GID_MAX 60000 +# System accounts +SYS_GID_MIN 201 +SYS_GID_MAX 999 + +# +# 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 + +# +# If useradd should create home directories for users by default +# On RH systems, we do. This option is overridden with the -m flag on +# useradd command line. +# +CREATE_HOME yes + +# The permission mask is initialized to this value. If not specified, +# the permission mask will be initialized to 022. +UMASK 077 + +# This enables userdel to remove user groups if no members exist. +# +USERGROUPS_ENAB yes + +# Use SHA512 to encrypt password. +ENCRYPT_METHOD SHA512 + diff --git a/shadow-utils.useradd b/shadow-utils.useradd new file mode 100644 index 0000000..4e81146 --- /dev/null +++ b/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/shadow.spec b/shadow.spec new file mode 100644 index 0000000..115cc2b --- /dev/null +++ b/shadow.spec @@ -0,0 +1,254 @@ +Name: shadow +Version: 4.7 +Release: 3 +Epoch: 2 +License: BSD and GPLv2+ +Summary: Tools for managing accounts and shadow password files +URL: http://pkg-shadow.alioth.debian.org/ +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 +#follow patches 0-33 come from fedora +Patch0: shadow-4.6-redhat.patch +Patch1: shadow-4.5-goodname.patch +Patch2: shadow-4.1.5.1-info-parent-dir.patch +Patch6: shadow-4.6-selinux.patch +Patch10: shadow-4.6-orig-context.patch +Patch11: shadow-4.1.5.1-logmsg.patch +Patch14: shadow-4.1.5.1-default-range.patch +Patch15: shadow-4.3.1-manfix.patch +Patch17: shadow-4.1.5.1-userdel-helpfix.patch +Patch19: shadow-4.2.1-date-parsing.patch +Patch21: shadow-4.6-move-home.patch +Patch22: shadow-4.6-audit-update.patch +Patch23: shadow-4.5-usermod-unlock.patch +Patch28: shadow-4.3.1-selinux-perms.patch +Patch29: shadow-4.2.1-null-tm.patch +Patch31: shadow-4.6-getenforce.patch +Patch32: shadow-4.5-crypt_h.patch +Patch33: shadow-4.5-long-entry.patch +Patch9000: shadow-4.1.5.1-var-lock.patch +Patch9001: shadow-utils-fix-lock-file-residue.patch +Patch9002: shadow-utils-fix-invalid-path.patch + +BuildRequires: gcc, libselinux-devel, audit-libs-devel, libsemanage-devel +BuildRequires: libacl-devel, libattr-devel +BuildRequires: bison, flex, gnome-doc-utils, docbook-style-xsl, docbook-dtds +BuildRequires: autoconf, automake, libtool, gettext-devel +Requires: libselinux +Requires: audit +Requires: setup +Requires(pre): coreutils +Requires(post): coreutils +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +Provides: shadow-utils +Obsoletes: shadow-utils + +%description +This package includes the necessary programs for converting plain +password files to the shadow password format and to manage user and +group accounts. + +%package_help + +%prep +%autosetup -n shadow-%{version} -p1 + +iconv -f ISO88591 -t utf-8 doc/HOWTO > doc/HOWTO.utf8 +cp -f doc/HOWTO.utf8 doc/HOWTO + +cp -a %{SOURCE4} %{SOURCE5} . + +%build +export CFLAGS="$RPM_OPT_FLAGS -fpie" +export LDFLAGS="-pie -Wl,-z,relro -Wl,-z,now" + +autoreconf -fiv +%configure \ + --enable-shadowgrp \ + --enable-man \ + --with-audit \ + --with-sha-crypt \ + --with-selinux \ + --without-libcrack \ + --without-libpam \ + --disable-shared \ + --with-group-name-max-length=32 +%make_build + +%install +rm -rf $RPM_BUILD_ROOT +%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 + +%files -f shadow.lang +%doc NEWS doc/HOWTO README +%{!?_licensedir:%global license %%doc} +%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(4755,root,root) %{_bindir}/newgidmap +%attr(4755,root,root) %{_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 + +%files help +%{_mandir}/*/* + +%changelog +* Thu Dec 19 2019 openEuler Buildteam - 2:4.7-3 +- Delete unused infomation + +* Mon Dec 16 2019 openEuler Buildteam - 2:4.7-2 +- fix invaild path + +* Thu Aug 29 2019 hexiaowen - 2:4.7-1 +- update to 4.7 + +* Tue Aug 20 2019 guoxiaoqi - 2:4.6-2.h9 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:rename patches + +* Thu Aug 8 2019 guoxiaoqi - 2:4.6-2.h8 +- Type:NA +- ID:NA +- SUG:NA +- DESC: format patches + +* Thu Aug 1 2019 Jiangchuangang - 2:4.6-2.h7 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:openEuler Debranding + +* Fri May 3 2019 lubing - 2:4.6-2.h6 +- Type:bugfix +- ID:NA +- SUG:restart +- DESC:fix lock file residue + +* Tue Mar 12 2019 yangzhuangzhuang - 2:4.6-2.h5 +- Type:bugfix +- ID:NA +- SUG:restart +- DESC:su.c: run pam_getenvlist() after setup_env + Log UID in nologin + Fix some issues found in Coverity scan. + useradd: fix segfault trying to overwrite const data with mkstemp + Fix the default mentioned in man page for SUB_UID/GID_COUNT variables. + +* Wed Mar 6 2019 hanzhijun - 2:4.6-2.h4 +- Type:bugfix +- ID:NA +- SUG:NA + DESC:shadow 4.1.5.1 var lock + +* Thu Jan 31 2019 liuqianya - 2:4.6-2.h3 +- Type:bugfix +- ID:NA +- SUG:NA + DESC:Revert"shadow 4.1.5.1 var lock" + +* Mon Jan 28 2019 liuqianya - 2:4.6-2.h2 +- Type:bugfix +- ID:NA +- SUG:NA + DESC:Revert "shadow-utils: sync patches" + +* Fri Jan 25 2019 liuqianya - 2:4.6-2.h1 +- Type:bugfix +- ID:NA +- SUG:NA + DESC:add ruserok to avoid compilation failure + hulk shadow remove passwd param for useradd + shadow 4.1.5.1 var lock + +* Sat Jul 14 2018 Jiangchuangang - 2:4.6-2 +- Package Initialization diff --git a/su.c-run-pam_getenvlist-after-setup_env.patch b/su.c-run-pam_getenvlist-after-setup_env.patch new file mode 100644 index 0000000..71958ba --- /dev/null +++ b/su.c-run-pam_getenvlist-after-setup_env.patch @@ -0,0 +1,79 @@ +From 89b96cb85cbd86a3f07a47e5e6826f7c5a69e3d5 Mon Sep 17 00:00:00 2001 +From: Michael Vogt +Date: Mon, 25 Jun 2018 16:00:17 +0200 +Subject: [PATCH 07/19] su.c: run pam_getenvlist() after setup_env + +When "su -l" is used the behaviour is described as similar to +a direct login. However login.c is doing a setup_env(pw) and then a +pam_getenvlist() in this scenario. But su.c is doing it the other +way around. Which means that the value of PATH from /etc/environment +is overriden. I think this is a bug because: + +The man-page claims that "-l": "provides an environment similar +to what the user would expect had the user logged in directly." + +And login.c is using the PATH from /etc/environment. + +This will fix: +https://bugs.launchpad.net/ubuntu/+source/shadow/+bug/984390 +--- + src/su.c | 35 +++++++++++++++-------------------- + 1 file changed, 15 insertions(+), 20 deletions(-) + +diff --git a/src/su.c b/src/su.c +index 685f7bb0..fc0e826f 100644 +--- a/src/su.c ++++ b/src/su.c +@@ -913,27 +913,7 @@ static void set_environment (struct passwd *pw) + addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */ + } + +-#ifdef USE_PAM +- /* we need to setup the environment *after* pam_open_session(), +- * else the UID is changed before stuff like pam_xauth could +- * run, and we cannot access /etc/shadow and co +- */ +- environ = newenvp; /* make new environment active */ +- +- if (change_environment) { +- /* update environment with all pam set variables */ +- char **envcp = pam_getenvlist (pamh); +- if (NULL != envcp) { +- while (NULL != *envcp) { +- addenv (*envcp, NULL); +- envcp++; +- } +- } +- } +- +-#else /* !USE_PAM */ + environ = newenvp; /* make new environment active */ +-#endif /* !USE_PAM */ + + if (change_environment) { + if (fakelogin) { +@@ -948,6 +928,21 @@ static void set_environment (struct passwd *pw) + addenv ("LOGNAME", pw->pw_name); + addenv ("SHELL", shellstr); + } ++ ++#ifdef USE_PAM ++ /* we need to setup the environment *after* pam_open_session(), ++ * else the UID is changed before stuff like pam_xauth could ++ * run, and we cannot access /etc/shadow and co ++ */ ++ /* update environment with all pam set variables */ ++ char **envcp = pam_getenvlist (pamh); ++ if (NULL != envcp) { ++ while (NULL != *envcp) { ++ addenv (*envcp, NULL); ++ envcp++; ++ } ++ } ++#endif /* !USE_PAM */ + } + + } +-- +2.19.1 + diff --git a/useradd-fix-segfault-trying-to-overwrite-const-data-.patch b/useradd-fix-segfault-trying-to-overwrite-const-data-.patch new file mode 100644 index 0000000..6626656 --- /dev/null +++ b/useradd-fix-segfault-trying-to-overwrite-const-data-.patch @@ -0,0 +1,174 @@ +From 10e388efc2c786d1ec4ed007891bfefa8826b6fd Mon Sep 17 00:00:00 2001 +From: Tomas Mraz +Date: Fri, 12 Oct 2018 10:14:02 +0200 +Subject: [PATCH 11/19] useradd: fix segfault trying to overwrite const data + with mkstemp + +Also fix memory leaks in error paths. +--- + src/useradd.c | 56 +++++++++++++++++++++++++++++++++------------------ + 1 file changed, 36 insertions(+), 20 deletions(-) + +diff --git a/src/useradd.c b/src/useradd.c +index ca90f076..85fe0ddf 100644 +--- a/src/useradd.c ++++ b/src/useradd.c +@@ -343,7 +343,7 @@ static void fail_exit (int code) + static void get_defaults (void) + { + FILE *fp; +- char* default_file = USER_DEFAULTS_FILE; ++ char *default_file = USER_DEFAULTS_FILE; + char buf[1024]; + char *cp; + +@@ -353,6 +353,8 @@ static void get_defaults (void) + + len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2; + default_file = malloc(len); ++ if (default_file == NULL) ++ return; + wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE); + assert (wlen == (int) len -1); + } +@@ -363,7 +365,7 @@ static void get_defaults (void) + + fp = fopen (default_file, "r"); + if (NULL == fp) { +- return; ++ goto getdef_err; + } + + /* +@@ -474,7 +476,7 @@ static void get_defaults (void) + } + } + (void) fclose (fp); +- ++ getdef_err: + if(prefix[0]) { + free(default_file); + } +@@ -509,8 +511,8 @@ static int set_defaults (void) + FILE *ifp; + FILE *ofp; + char buf[1024]; +- char* new_file = NEW_USER_FILE; +- char* default_file = USER_DEFAULTS_FILE; ++ char *new_file = NULL; ++ char *default_file = USER_DEFAULTS_FILE; + char *cp; + int ofd; + int wlen; +@@ -521,17 +523,30 @@ static int set_defaults (void) + bool out_shell = false; + bool out_skel = false; + bool out_create_mail_spool = false; ++ size_t len; ++ int ret = -1; + +- if(prefix[0]) { +- size_t len; + +- len = strlen(prefix) + strlen(NEW_USER_FILE) + 2; +- new_file = malloc(len); +- wlen = snprintf(new_file, len, "%s/%s", prefix, NEW_USER_FILE); +- assert (wlen == (int) len -1); ++ len = strlen(prefix) + strlen(NEW_USER_FILE) + 2; ++ new_file = malloc(len); ++ if (new_file == NULL) { ++ fprintf (stderr, ++ _("%s: cannot create new defaults file: %s\n"), ++ Prog, strerror(errno)); ++ return -1; ++ } ++ wlen = snprintf(new_file, len, "%s%s%s", prefix, prefix[0]?"/":"", NEW_USER_FILE); ++ assert (wlen <= (int) len -1); + ++ if(prefix[0]) { + len = strlen(prefix) + strlen(USER_DEFAULTS_FILE) + 2; + default_file = malloc(len); ++ if (default_file == NULL) { ++ fprintf (stderr, ++ _("%s: cannot create new defaults file: %s\n"), ++ Prog, strerror(errno)); ++ goto setdef_err; ++ } + wlen = snprintf(default_file, len, "%s/%s", prefix, USER_DEFAULTS_FILE); + assert (wlen == (int) len -1); + } +@@ -544,7 +559,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot create new defaults file\n"), + Prog); +- return -1; ++ goto setdef_err; + } + + ofp = fdopen (ofd, "w"); +@@ -552,7 +567,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: cannot open new defaults file\n"), + Prog); +- return -1; ++ goto setdef_err; + } + + /* +@@ -579,7 +594,7 @@ static int set_defaults (void) + _("%s: line too long in %s: %s..."), + Prog, default_file, buf); + (void) fclose (ifp); +- return -1; ++ goto setdef_err; + } + } + +@@ -643,7 +658,7 @@ static int set_defaults (void) + || (fsync (fileno (ofp)) != 0) + || (fclose (ofp) != 0)) { + unlink (new_file); +- return -1; ++ goto setdef_err; + } + + /* +@@ -658,7 +673,7 @@ static int set_defaults (void) + _("%s: Cannot create backup file (%s): %s\n"), + Prog, buf, strerror (err)); + unlink (new_file); +- return -1; ++ goto setdef_err; + } + + /* +@@ -669,7 +684,7 @@ static int set_defaults (void) + fprintf (stderr, + _("%s: rename: %s: %s\n"), + Prog, new_file, strerror (err)); +- return -1; ++ goto setdef_err; + } + #ifdef WITH_AUDIT + audit_logger (AUDIT_USYS_CONFIG, Prog, +@@ -683,13 +698,14 @@ static int set_defaults (void) + (unsigned int) def_group, def_home, def_shell, + def_inactive, def_expire, def_template, + def_create_mail_spool)); +- ++ ret = 0; ++ setdef_err: ++ free(new_file); + if(prefix[0]) { +- free(new_file); + free(default_file); + } + +- return 0; ++ return ret; + } + + /* +-- +2.19.1 +