Compare commits

...

8 Commits

Author SHA1 Message Date
Chris Hofstaedtler
e8b8d7a84b New upstream version 4.16.0 2024-06-25 20:09:23 +02:00
Chris Hofstaedtler
0fda4df4f1 New upstream version 4.15.2 2024-06-22 17:34:25 +02:00
Chris Hofstaedtler
f7f4fd7c05 New upstream version 4.15.1 2024-06-13 03:08:44 +02:00
Balint Reczey
3987cc7880 New upstream version 4.13+dfsg1 2022-11-10 16:24:06 +01:00
Balint Reczey
8ead740677 New upstream version 4.12.3+dfsg1 2022-08-24 00:06:41 +02:00
Balint Reczey
675b462b64 New upstream version 4.12.2+dfsg1 2022-08-20 18:17:16 +02:00
Balint Reczey
0c04b92a9a New upstream version 4.11.1+dfsg1 2022-01-21 23:41:15 +01:00
Balint Reczey
749c178062 New upstream version 4.9 2021-11-07 15:18:49 +01:00
11134 changed files with 604467 additions and 154908 deletions

2025
ABOUT-NLS

File diff suppressed because it is too large Load Diff

98
AUTHORS.md Normal file
View File

@@ -0,0 +1,98 @@
Thanks to at least the following people for sending patches, bug
reports and various comments. This list may be incomplete, I received
a lot of mail...
# Maintainers
* Marek Michałkiewicz <marekm72@gmail.com> (1995-2000)
* Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
* Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
* Serge E. Hallyn <serge@hallyn.com> (2014-now)
* Christian Brauner <christian@brauner.io> (2019-now)
* Iker Pedrosa <ipedrosa@redhat.com> (2022-now)
* Alejandro Colomar <alx@kernel.org> (2023-now) (4.14 stable)
To verify signatures on releases, use the following keys under keys/ :
* Serge Hallyn: keys/66D0387DB85D320F8408166DB175CFA98F192AF2.asc
* Christian Brauner: keys/4880B8C9BD0E5106FC070F4F7B3C391EFEA93624.asc
* Iker Pedrosa: keys/4E80EF49C7987B6DE2F81F5005079C6C3A653E57.asc
* Alejandro Colomar: keys/A9348594CE31283A826FBDD8D57633D441E25BB5.asc
# Authors and contributors
* Adam Rudnicki <adam@v-lo.krakow.pl>
* Alan Curry <pacman@tardis.mars.net>
* Aleksa Sarai <cyphar@cyphar.com>
* Alexander O. Yuriev <alex@bach.cis.temple.edu>
* Algis Rudys <arudys@rice.edu>
* Andreas Jaeger <aj@arthur.rhein-neckar.de>
* Andy Zaugg <andy.zaugg@gmail.com>
* Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
* Anton Gluck <gluc@midway.uchicago.edu>
* Arkadiusz Miskiewicz <misiek@pld.org.pl>
* Ben Collins <bcollins@debian.org>
* Brian R. Gaeke <brg@dgate.org>
* Calle Karlsson <ckn@kash.se>
* Chip Rosenthal <chip@unicom.com>
* Chris Evans <lady0110@sable.ox.ac.uk>
* Chris Lamb <chris@chris-lamb.co.uk>
* Cristian Gafton <gafton@sorosis.ro>
* Dan Walsh <dwalsh@redhat.com>
* Darcy Boese <possum@chardonnay.niagara.com>
* Dave Hagewood <admin@arrowweb.com>
* David A. Holland <dholland@hcs.harvard.edu>
* David Frey <David.Frey@lugs.ch>
* Ed Carp <ecarp@netcom.com>
* Ed Neville <ed@s5h.net>
* Eric W. Biederman" <ebiederm@xmission.com>
* Floody <flood@evcom.net>
* Frank Denis <j@4u.net>
* George Kraft IV <gk4@us.ibm.com>
* Greg Mortensen <loki@world.std.com>
* Guido van Rooij
* Guy Maor <maor@debian.org>
* Hrvoje Dogan <hdogan@bjesomar.srce.hr>
* Jakub Hrozek <jhrozek@redhat.com>
* Janos Farkas <chexum@bankinf.banki.hu>
* Jason Franklin <jason.franklin@quoininc.com>
* Jay Soffian <jay@lw.net>
* Jesse Thilo <Jesse.Thilo@pobox.com>
* Joey Hess <joey@kite.ml.org>
* John Adelsberger <jja@umr.edu>
* Jonathan Hankins <jhankins@mailserv.homewood.k12.al.us>
* Jon Lewis <jlewis@lewis.org>
* Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
* Judd Bourgeois <shagboy@bluesky.net>
* Juergen Heinzl <unicorn@noris.net>
* Juha Virtanen <jiivee@iki.fi>
* Julian Pidancet <julian.pidancet@gmail.com>
* Julianne Frances Haugh <julie78787@gmail.com>
* Leonard N. Zubkoff <lnz@dandelion.com>
* Luca Berra <bluca@www.polimi.it>
* Lukáš Kuklínek <lkukline@redhat.com>
* Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
* Marc Ewing <marc@redhat.com>
* Martin Bene <mb@sime.com>
* Martin Mares <mj@gts.cz>
* Michael Meskes <meskes@topsystem.de>
* Michael Talbot-Wilson <mike@calypso.bns.com.au>
* Michael Vetter <jubalh@iodoru.org>
* Mike Frysinger <vapier@gentoo.org>
* Mike Pakovic <mpakovic@users.southeast.net>
* Nicolas François <nicolas.francois@centraliens.net>
* Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
* Pavel Machek <pavel@bug.ucw.cz>
* Peter Vrabec <pvrabec@redhat.com>
* Phillip Street
* Rafał Maszkowski <rzm@icm.edu.pl>
* Rani Chouha <ranibey@smartec.com>
* Sami Kerola <kerolasa@rocketmail.com>
* Scott Garman <scott.a.garman@intel.com>
* Sebastian Rick Rijkers <srrijkers@gmail.com>
* Seraphim Mellos <mellos@ceid.upatras.gr>
* Shane Watts <shane@nexus.mlckew.edu.au>
* Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
* Thorsten Kukuk <kukuk@suse.de>
* Tim Hockin <thockin@eagle.ais.net>
* Timo Karjalainen <timok@iki.fi>
* Ulisses Alonso Camaro <ulisses@pusa.eleinf.uv.es>
* Werner Fink <werner@suse.de>

143
COPYING
View File

@@ -1,118 +1,41 @@
NOTE:
This license has been obsoleted by the change to the BSD-style copyright.
You may continue to use this license if you wish, but you are under no
obligation to do so.
SPDX-License-Identifier: BSD-3-Clause
(*
This document is freely plagiarised from the 'Artistic Licence',
distributed as part of the Perl v4.0 kit by Larry Wall, which is
available from most major archive sites. I stole it from CrackLib.
All files under this project either
$Id$
*)
1. fall under the BSD 3 clause license (by default).
This documents purpose is to state the conditions under which this
Package (See definition below) viz: "Shadow", the Shadow Password Suite
which is held by Julianne Frances Haugh, may be copied, such that the
copyright holder maintains some semblance of artistic control over the
development of the package, while giving the users of the package the
right to use and distribute the Package in a more-or-less customary
fashion, plus the right to make reasonable modifications.
2. carry an SPDX header declaring what license applies.
So there.
or
***************************************************************************
3. list a full custom license
Definitions:
This software is originally
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
A "Package" refers to the collection of files distributed by the
Copyright Holder, and derivatives of that collection of files created
through textual modification, or segments thereof.
"Standard Version" refers to such a Package if it has not been modified,
or has been modified in accordance with the wishes of the Copyright
Holder.
"Copyright Holder" is whoever is named in the copyright or copyrights
for the package.
"You" is you, if you're thinking about copying or distributing this
Package.
"Reasonable copying fee" is whatever you can justify on the basis of
media cost, duplication charges, time of people involved, and so on.
(You will not be required to justify it to the Copyright Holder, but
only to the computing community at large as a market that must bear the
fee.)
"Freely Available" means that no fee is charged for the item itself,
though there may be fees involved in handling the item. It also means
that recipients of the item may redistribute it under the same
conditions they received it.
1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated
disclaimers.
2. You may apply bug fixes, portability fixes and other modifications
derived from the Public Domain or from the Copyright Holder. A Package
modified in such a way shall still be considered the Standard Version.
3. You may otherwise modify your copy of this Package in any way,
provided that you insert a prominent notice in each changed file stating
how and when AND WHY you changed that file, and provided that you do at
least ONE of the following:
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet or an
equivalent medium, or placing the modifications on a major archive site
such as uunet.uu.net, or by allowing the Copyright Holder to include
your modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation or organization.
c) rename any non-standard executables so the names do not conflict with
standard executables, which must also be provided, and provide separate
documentation for each non-standard executable that clearly documents
how it differs from the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and library files,
together with instructions (in the manual page or equivalent) on where
to get the Standard Version.
b) accompany the distribution with the machine-readable source of the
Package with your modifications.
c) accompany any non-standard executables with their corresponding
Standard Version executables, giving the non-standard executables
non-standard names, and clearly documenting the differences in manual
pages (or equivalent), together with instructions on where to get the
Standard Version.
d) make other distribution arrangements with the Copyright Holder.
5. You may charge a reasonable copying fee for any distribution of this
Package. You may charge any fee you choose for support of this Package.
YOU MAY NOT CHARGE A FEE FOR THIS PACKAGE ITSELF. However, you may
distribute this Package in aggregate with other (possibly commercial)
programs as part of a larger (possibly commercial) software distribution
provided that YOU DO NOT ADVERTISE this package as a product of your
own.
6. The name of the Copyright Holder may not be used to endorse or
promote products derived from this software without specific prior
written permission.
7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
* 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.

225
ChangeLog
View File

@@ -1,3 +1,184 @@
2022-11-08 Serge Hallyn <serge@hallyn.com>
* useradd.8: fix default group ID (Tim Biermann)
* Revert drop of subid_init() (Serge Hallyn)
* Georgian translation (NorwayFun)
* useradd: Avoid taking unneeded space: do not reset non-existent data
in lastlog (David Kalnischkies)
* relax username restrictions (Alexander Kanavin)
* selinux: check MLS enabled before setting serange (genBTC)
* copy_tree: use fchmodat instead of chmod (Samanta Navarro)
* copy_tree: don't block on FIFOs (Samanta Navarro)
* add shell linter (Jan Macku)
* copy_tree: carefully treat permissions (Samanta Navarro)
* lib/commonio: make lock failures more detailed (Luca BRUNO)
* lib: use strzero and memzero where applicable (Christian Göttsche)
* Update Dutch translation (Frans Spiesschaert)
* Don't test for NULL before calling free (Alex Colomar)
* Use libc MAX() and MIN() (Alejandro Colomar)
* chage: Fix regression in print_date (Xiami)
* usermod: report error if homedir does not exist (Iker Pedrosa)
* libmisc: minimum id check for system accounts (Iker Pedrosa)
* fix usermod -rG x y wrongly adding a group (xyz)
* man: add missing space in useradd.8.xml (Iker Pedrosa)
* lastlog: check for localtime() return value (Iker Pedrosa)
* Raise limit for passwd and shadow entry length (Iker Pedrosa)
* Remove adduser-old.c (Alejandro Colomar)
* useradd: Fix buffer overflow when using a prefix (David Michael)
* Don't warn when failed to open /etc/nsswitch.conf (Serge Hallyn)
2022-08-15 Serge Hallyn <serge@hallyn.com>
* Address CVE-2013-4235 (TOCTTOU when copying directories)
(Christian Göttsche)
2022-08-15 Serge Hallyn <serge@hallyn.com>
* Fix uk manpages
2022-08-08 Serge Hallyn <serge@hallyn.com>
* Add absolute path hint to --root (Celeste Liu)
* Various cleanups (Christian Göttsche)
* Fix Ubuntu release used in CI tests (Jeremy Whiting)
* add -F options to useradd (and tests) (Masatake YAMATO)
* useradd manpage updates (Masatake YAMATO and Alexander Zhang))
* Check for ownerid (not just username) in subid ranges (Iker Pedrosa)
2022-07-04 Serge Hallyn <serge@hallyn.com>
* Declare file local functions static (Christian Göttsche)
* Use strict prototypes (Christian Göttsche)
* Do not drop const qualifier for Basename (Christian Göttsche)
* Constify various pointers (Christian Göttsche)
* Don't return uninitialized memory (Christian Göttsche)
* Don't let compiler optimize away memory cleaning (Christian Göttsche)
* Remove many obsolete compatibility checks and defines (Alejandro Colomar)
* Modify ID range check in useradd (Iker Pedrosa)
* Use "extern "C"" to make libsubid easier to use from C++ (Alois Wohlschlager)
* French translation updates (bubu)
* Fix s/with-pam/with-libpam/ (serge)
* Spanish translation updates (Fernando)
* French translation fixes (Balint Reczey)
* Default max group name length to 32 (Jami Kettunen)
* Fix PAM service files without-selinux (Ali Riza KESKIN)
* Improve manpages (Markus Hiereth)
- groupadd, useradd, usermod
- groups and id
- pwck
* Add fedora to CI builds (Iker Pedrosa)
* Fix condition under which pw_dir check happens (Ed Neville)
* logoutd: switch to strncat (Steve Grubb)
* AUTHORS: improve markdown output (Iker Pedrosa)
* Handle ERANGE errors correctly (Niko)
* Check for fopen NULL return (juyin)
* Split get_salt() into its own fn juyin)
* Get salt before chroot to ensure /dev/urandom. (juyin)
* Chpasswd code cleanup (juyin)
* Work around git safe.directory enforcement (serge)
* Alphabetize order in usermod help (Matheus Marques)
* Erase password copy on error branches (Christian Göttsche)
* Suggest using --badname if needed (Iker Pedrosa)
* Update translation files (Iker Pedrosa)
* Correct badnames option to badname (Iker Pedrosa)
* configure: replace obsolete autoconf macros (Christian Göttsche)
* tests: replace egrep with grep -E (Sam James)
* Update Ukrainian translations (Yuri Chornoivan)
* Cleanups (Iker Pedrosa)
- Remove redeclared variable
- Remove commented out code and FIXMEs
- Add header guards
- Initialize local variables
* CI updates (Iker Pedrosa)
- Create github workflow to install dependencies
- Enable CodeQL
- Update actions version
* libmisc: use /dev/urandom as fallback if other methods fail (Xi Ruoyao)
2022-01-02 Serge Hallyn <serge@hallyn.com>
* build: include lib/shadowlog_internal.h in dist tarballs (Sam James)
2022-01-02 Serge Hallyn <serge@hallyn.com>
* Handle possible TOCTTOU issues in usermod/userdel (edneville)
* (CVE-2013-4235)
* Use O_NOFOLLOW when copying file
* Kill all user tasks in userdel
* Fix useradd -D segfault (Xi Ruoyao)
* Clean up obsolete libc feature-check ifdefs (Alejandro Colomar)
* Fix -fno-common build breaks due to duplicate Prog declarations
(Adam Sampson)
* Have single date_to_str definition (Alejandro Colomar)
* Fix libsubid SONAME version (Sam James)
2021-12-19 Serge Hallyn <serge@hallyn.com>
Note: From this release forward, su from this package should be
considered deprecated. Please replace any users of it with su from
util-linux. Please open an issue if there is a problem with that.
We intend to remove it in an upcoming release.
* libsubid fixes (Xi Ruoyao, Serge Hallyn, Iker Pedrosa, Mike Gilbert,
GalaxyMaster, and Luís Ferreira)
* Rename the test program list_subid_ranges to getsubids, write
a manpage, so distros can ship it. (Iker Pedrosa)
* Add libeconf dep for new*idmap (Iker Pedrosa)
* Allow all group types with usermod -G (Iker Pedrosa)
* Avoid useradd generating empty subid range (Iker Pedrosa)
* Handle NULL pw_passwd (Jaroslav Jindrak)
* Fix default value SHA_get_salt_rounds (Mike Gilbert)
* Use https where possible in README (Paul Menzel)
* Update content and format of README (Iker Pedrosa)
* Translation updates (Balint Reczey, Frans Spiesschaert)
* Switch from xml2po to itstool in 'make dist' (Serge Hallyn)
* Fix double frees (Michael Vetter)
* Add LOG_INIT configurable to useradd (Andy Zaugg)
* Add CREATE_MAIL_SPOOL documentation (Andy Zaugg)
* Create a security.md
* Fix su never being SIGKILLd when trapping TERM (Ruihan li)
* Fix wrong SELinux labels in several possible cases (Iker Pedrosa)
* Fix missing chmod in chadowtb_move (GalaxyMaster)
* Handle malformed hushlogins entries (Tobias Stoeckmann)
* Fix groupdel segv when passwd does not exist (François Rigault)
* Fix covscan-found newgrp segfault (Iker Pedrosa)
* Remove trailing slash on hoedir (Ed Neville)
* Fix passwd -l message - it does not change expirey (Ed Neville)
* Fix SIGCHLD handling bugs in su and vipw (Tobias Stoeckmann)
* Remove special case for "" in usermod (Alejandro Colomar)
* Implement usermod -rG to remove a specific group
(Andy Zaugg)
* call pam_end() after fork in child path for su and login
(Björn Fischer)
* useradd: In absence of /etc/passwd, assume 0 == root
(Ludwig Nussel)
* lib: check NULL before freeing data (Iker Pedrosa)
* Fix pwck segfault (Iker Pedrosa)
2021-07-22 Serge Hallyn <serge@hallyn.com>
* Updated translations (Björn Esser, Juergen Hoetzel)
* Major salt updates (Björn Esser)
* Various coverity and cleanup fixes (Iker Pedrosa)
* Consistently use 0 to disable PASS_MIN_DAYS in man (tzccinct)
* Implement NSS support for subids and a libsubid (Serge Hallyn)
* setfcap: retain setfcap when mapping uid 0 (Christian Brauner)
* login.defs: include HMAC_CRYPTO_ALGO key (Iker Pedrosa)
* selinux fixes (Christian Göttsche)
* Fix path prefix path handling (Lucas Servén Marín)
* Manpage updates (tzccinct, Sevan Janiyan, Iker Pedrosa, Geert Ijewski,
谭九鼎, Jamin W. Collins, towerpark, andydna, Frans Spiesschaert)
* Treat an empty passwd field as invalid (Haelwenn Monnier)
* newxidmap: allow running under alternative gid (Martijn de Gouw)
* usermod: check that shell is executable (Geert Ijewski)
* Add yescript support (Rodolphe Bréard)
* useradd memleak fixes (whzhe)
* useradd: use built-in settings by default (Ludwig Nussel)
* getdefs: add foreign (non-shadow-utils) items (Karel Zak)
* buffer overflow fixes (Tobias Stoeckmann)
* Adding run-parts style for pre and post useradd/del (ed@s5h.net)
2020-01-23 Serge Hallyn <serge@hallyn.com>
* selinux: inclue stdio (Michael Vetter)
@@ -262,7 +443,7 @@
2013-08-15 Nicolas François <nicolas.francois@centraliens.net>
* src/usermod.c: Check early if /etc/subuid (/etc/subgid) exists
when option -v/-V (-w/-W) are provided.
when option -v/-V (-w/-W) are provided.
2013-08-15 Nicolas François <nicolas.francois@centraliens.net>
@@ -639,8 +820,8 @@
* configure.in: Prepare for next point release 4.2.
* if using the static char* for pw_dir, strdup it so
pw_free() can be used. (Closes: Debian#691459, alioth#313957)
* Kill the child process group, rather than just the
pw_free() can be used. (Closes: Debian#691459, alioth#313957)
* Kill the child process group, rather than just the
immediate child; this is needed now that su no
longer starts a controlling terminal when not running an
interactive shell (closes: Debian#713979)
@@ -867,7 +1048,7 @@
* po/pt.po: Updated to 557t.
2012-01-19 Holger Wansing <linux@wansing-online.de>
2012-01-19 Holger Wansing <linux@wansing-online.de>
* po/de.po: Updated to 557t.
@@ -1454,8 +1635,8 @@
* NEWS, src/chpasswd.c: Create a shadow entry if the password is
set to 'x' in passwd and there are no entry in shadow for the
user.
* NEWS, src/chgpasswd.c: Create a gshadow entry if the password is
set to 'x' in group and there are no entry in gshadow for the
* NEWS, src/chgpasswd.c: Create a gshadow entry if the password is
set to 'x' in group and there are no entry in gshadow for the
group.
2011-07-28 Nicolas François <nicolas.francois@centraliens.net>
@@ -1527,7 +1708,7 @@
2011-07-22 Nicolas François <nicolas.francois@centraliens.net>
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Fail in case of
invalid configuration.
invalid configuration.
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Updated
comments.
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Be more strict
@@ -1764,7 +1945,7 @@
man/login.defs.d/DEFAULT_HOME.xml,
man/login.defs.d/LOGIN_RETRIES.xml,
man/login.defs.d/MD5_CRYPT_ENAB.xml,
man/login.defs.d/PORTTIME_CHECKS_ENAB.xml,
man/login.defs.d/PORTTIME_CHECKS_ENAB.xml,
man/login.defs.d/SHA_CRYPT_MIN_ROUNDS.xml:
Fix typos
* man/po/de.po: German translation of manpages completed
@@ -1811,7 +1992,7 @@
2011-03-30 YunQiang Su <wzssyqa@gmail.com>
* man/po/zh_CN.po: convert Simplified Chinese translation
* man/po/zh_CN.po: convert Simplified Chinese translation
of manpages to gettext
* po/zh_CN.po: Simplified Chinese translation completed
@@ -1950,7 +2131,7 @@
boolean. safe_system last argument is a boolean.
* libmisc/system.c: Check return value of dup2.
* libmisc/system.c: Do not check *printf/*puts return value.
* libmisc/system.c: Do not check execve return value.
* libmisc/system.c: Do not check execve return value.
* libmisc/salt.c: Do not check *printf/*puts return value.
* libmisc/loginprompt.c: Do not check gethostname return value.
* libmisc/find_new_gid.c, libmisc/find_new_uid.c: Do not check
@@ -2103,7 +2284,7 @@
2010-04-04 Nicolas François <nicolas.francois@centraliens.net>
* src/useradd.c: spool is a constant string.
* src/useradd.c: Set the new copy_tree's paramater 'copy_root' to false
* src/useradd.c: Set the new copy_tree's paramater 'copy_root' to false
2010-04-04 Nicolas François <nicolas.francois@centraliens.net>
@@ -4952,7 +5133,7 @@
<sgrubb@redhat.com>
* src/groupadd.c: Log to audit with type AUDIT_ADD_GROUP instead
of AUDIT_USER_CHAUTHTOK.
* src/groupdel.c: Log to audit with type AUDIT_DEL_GROUP instead
* src/groupdel.c: Log to audit with type AUDIT_DEL_GROUP instead
of AUDIT_USER_CHAUTHTOK.
* src/useradd.c: Log to audit with type AUDIT_ADD_USER /
AUDIT_ADD_GROUP / AUDIT_USYS_CONFIG instead of
@@ -5208,7 +5389,7 @@
* NEWS, src/gpasswd.c: Use getopt_long instead of getopt. Added
support for long options --add (-a), --delete (-d),
--remove-password (-r), --restrict (-R), --administrators (-A),
and --members (-M)
and --members (-M)
* man/gpasswd.1.xml: Document the new long options.
* src/gpasswd.c: The sgrp structure is only used if SHADOWGRP is
defined.
@@ -7397,7 +7578,7 @@
to mimic useradd's behavior choices of UID and GID.
* src/newusers.c: Reuse the generic find_new_uid() and
find_new_gid() functions. This permits to respect the
UID_MIN/UID_MAX and GID_MIN/GID_MAX variables, should
UID_MIN/UID_MAX and GID_MIN/GID_MAX variables, should
* src/newusers.c: Check if the user or group exist using the
external databases (with the libc getpwnam/getgrnam functions).
Refuse to update an user which exist in an external database but
@@ -9194,7 +9375,7 @@
Debian's patch 202_it_man_uses_gettext. Thanks to Giuseppe
Sacco who contributed the Italian translation.
* man/de/de.po: (nearly) complete German translation of man pages
Imported from Debian's patch 203_de-man-update. Thanks to
Imported from Debian's patch 203_de-man-update. Thanks to
Simon Brandmair
* src/usermod.c: Clarify the online help of usermod for "-a"
Imported from Debian's patch 402-clarify_usermod_usage
@@ -9377,7 +9558,7 @@
* NEWS: release date corrected.
* NEWS, src/su.c:
fixed set enviroment too early when using PAM, so move it to !USE_PAM
fixed set environment too early when using PAM, so move it to !USE_PAM
(patch submitted by Mike Frysinger <vapier@gentoo.org>).
2006-07-30 Tomasz Kłoczko <kloczek@pld.org.pl>
@@ -10064,7 +10245,7 @@
* NEWS: cleanups.
* autogen.sh:
by default in development enviroment use CFLAGS="-O2 -Wall".
by default in development environment use CFLAGS="-O2 -Wall".
* src/chgpasswd.c (main): remove two unused variables (newgr and now).
@@ -11473,7 +11654,7 @@
in OPTIONS section). Describe -a and -k options.
* NEWS, src/su.c:
fixed twice copy enviroment which causes auth problems (bug was introduced in 4.0.12;
fixed twice copy environment which causes auth problems (bug was introduced in 4.0.12;
fix by Nicolas François <nicolas.francois@centraliens.net>).
* src/passwd.c, po/ja.po, po/ko.po, po/nb.po, po/nl.po, po/nn.po, po/pl.po, po/pt.po, po/pt_BR.po, po/ro.po, po/ru.po, po/sk.po, po/sq.po, po/sv.po, po/tl.po, po/tr.po, po/uk.po, po/vi.po, po/zh_CN.po, po/zh_TW.po, po/bs.po, po/ca.po, po/cs.po, po/da.po, po/de.po, po/el.po, po/es.po, po/eu.po, po/fi.po, po/fr.po, po/he.po, po/id.po, po/it.po:
@@ -12403,7 +12584,7 @@
http://bugs.debian.org/48002
* src/login.c, NEWS:
fixed loggin of username on succesful login (was using the normal username,
fixed loggin of username on successful login (was using the normal username,
when it should have used pam_user) http://bugs.debian.org/47819
2005-06-02 Tomasz Kłoczko <kloczek@pld.org.pl>
@@ -12848,7 +13029,7 @@
* man/pl/usermod.8: finish sync with english version.
* man/hu/login.1, man/pl/login.1, NEWS, man/Attic/login.1, man/de/login.1:
removed fragment about abilities pass enviroment variables in login prompt.
removed fragment about abilities pass environment variables in login prompt.
* man/Attic/gpasswd.1, man/Attic/newgrp.1:
fixes by Nicolas Nicolas François <nicolas.francois@centraliens.net> (not all
@@ -13327,7 +13508,7 @@
removed not used translations.
* NEWS, src/su.c:
fix adding of pam_env env variables to enviroment (Martin Schlemmer <azarah@nosferatu.za.org>).
fix adding of pam_env env variables to environment (Martin Schlemmer <azarah@nosferatu.za.org>).
* NEWS, configure.in:
fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables which was allways
@@ -13424,7 +13605,7 @@
* NEWS, src/su.c:
add pam_open_session() support. If builded without PAM support
propagate $DISPLAY and $XAUTHORITY enviroment variables.
propagate $DISPLAY and $XAUTHORITY environment variables.
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
2004-10-23 Tomasz Kłoczko <kloczek@pld.org.pl>

View File

@@ -1,6 +1,18 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = NEWS README TODO shadow.spec.in
EXTRA_DIST = NEWS README
SUBDIRS = po man libmisc lib src \
contrib doc etc
SUBDIRS = lib
if ENABLE_SUBIDS
SUBDIRS += libsubid
endif
SUBDIRS += src po contrib doc etc tests/unit
if ENABLE_REGENERATE_MAN
SUBDIRS += man
endif
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
EXTRA_DIST = tests/

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -87,9 +87,18 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@ENABLE_SUBIDS_TRUE@am__append_1 = libsubid
@ENABLE_REGENERATE_MAN_TRUE@am__append_2 = man
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -99,7 +108,7 @@ am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES = man/po/Makefile shadow.spec
CONFIG_CLEAN_FILES = man/po/Makefile
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
@@ -136,8 +145,8 @@ am__recursive_targets = \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
$(LISP)config.h.in
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
config.h.in
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
@@ -154,15 +163,11 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
CSCOPE = cscope
DIST_SUBDIRS = $(SUBDIRS)
DIST_SUBDIRS = lib libsubid src po contrib doc etc tests/unit man
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(srcdir)/shadow.spec.in $(top_srcdir)/man/po/Makefile.in \
ABOUT-NLS COPYING ChangeLog NEWS README TODO compile \
config.guess config.rpath config.sub install-sh ltmain.sh \
missing
$(top_srcdir)/man/po/Makefile.in ABOUT-NLS AUTHORS.md COPYING \
ChangeLog NEWS README compile config.guess config.rpath \
config.sub install-sh ltmain.sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
@@ -201,6 +206,8 @@ am__relativize = \
DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz
GZIP_ENV = --best
DIST_TARGETS = dist-xz dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
@@ -216,8 +223,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -229,6 +240,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
@@ -246,9 +258,15 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBCRACK = @LIBCRACK@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
@@ -260,13 +278,21 @@ LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBSEMANAGE = @LIBSEMANAGE@
LIBSKEY = @LIBSKEY@
LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LIYESCRYPT = @LIYESCRYPT@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -289,6 +315,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
@@ -360,10 +389,10 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = NEWS README TODO shadow.spec.in
SUBDIRS = po man libmisc lib src \
contrib doc etc
EXTRA_DIST = tests/
SUBDIRS = lib $(am__append_1) src po contrib doc etc tests/unit \
$(am__append_2)
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -418,8 +447,6 @@ distclean-hdr:
-rm -f config.h stamp-h1
man/po/Makefile: $(top_builddir)/config.status $(top_srcdir)/man/po/Makefile.in
cd $(top_builddir) && $(SHELL) ./config.status $@
shadow.spec: $(top_builddir)/config.status $(srcdir)/shadow.spec.in
cd $(top_builddir) && $(SHELL) ./config.status $@
mostlyclean-libtool:
-rm -f *.lo
@@ -535,7 +562,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -618,6 +644,10 @@ dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@@ -660,6 +690,8 @@ distcheck: dist
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
@@ -675,7 +707,7 @@ distcheck: dist
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
@@ -753,6 +785,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -837,18 +870,18 @@ uninstall-am:
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip distcheck distclean distclean-generic \
distclean-hdr distclean-libtool distclean-tags distcleancheck \
distdir distuninstallcheck dvi dvi-am html html-am info \
info-am install install-am install-data install-data-am \
install-dvi install-dvi-am install-exec install-exec-am \
install-html install-html-am install-info install-info-am \
install-man install-pdf install-pdf-am install-ps \
install-ps-am install-strip installcheck installcheck-am \
installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
dist-xz dist-zip dist-zstd distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-tags distcleancheck distdir distuninstallcheck dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-man install-pdf \
install-pdf-am install-ps install-ps-am install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am
.PRECIOUS: Makefile

38
NEWS
View File

@@ -15,7 +15,7 @@ shadow-4.1.5.1 -> shadow-4.2 UNRELEASED
- su
* When su receives a signal (SIGTERM, or SIGINT/SIGQUIT in non
interactive mode), kill the child process group, rather than just the
interactive mode), kill the child process group, rather than just the
immediate child.
* Fix segmentation faults for users without a proper home or shell in
their passwd entries.
@@ -622,7 +622,7 @@ shadow-4.0.18.2 -> shadow-4.1.0 09-12-2007
- Add support for uClibc with no l64a().
- userdel, usermod: Fix infinite loop caused by erroneous group file
containing two entries with the same name. (The fix strategy differs
from
from
(https://bugzilla.redhat.com/show_bug.cgi?id=240915)
- userdel: Abort if an error is detected while updating the passwd or group
databases. The passwd or group files will not be written.
@@ -696,7 +696,7 @@ shadow-4.0.18 -> shadow-4.0.18.1 03-08-2006
shadow-4.0.17 -> shadow-4.0.18 01-08-2006
*** general:
- su: fixed set enviroment too early when using PAM, so move it to !USE_PAM
- su: fixed set environment too early when using PAM, so move it to !USE_PAM
(patch submitted by Mike Frysinger <vapier@gentoo.org>),
- groupadd, groupmod, useradd, usermod: fixed UID/GID overflow (fixed
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=198920)
@@ -855,7 +855,7 @@ shadow-4.0.14 -> shadow-4.0.15 13-03-2006
- su: move exit() outside libmisc/shell.c::shell() for handle shell() errors
on higher level (now is better visable where some programs exit with 126
and 127 exit codes); added new shell() parameter (char *const envp[])
which allow fix preserving enviroment in su on using -p, (patch by
which allow fix preserving environment in su on using -p, (patch by
Alexander Gattin <xrgtn@yandex.ru>),
- su: added handle -c,--command option for GNU su compliance (merge
437_su_-c_option Debian patch),
@@ -966,7 +966,7 @@ shadow-4.0.12 -> shadow-4.0.13 10-10-2005
to example described in ident(1) man page (modern compilers like latest GCC
removes not used functions by global optimization).
So "ident /usr/bin/passwd" will show again some useable informations
- su: fixed twice copy enviroment which causes auth problems
- su: fixed twice copy environment which causes auth problems
(bug was introduced in 4.0.12; fix by Nicolas François <nicolas.francois@centraliens.net>),
- chage: differentiate the different failure causes by the exit value
This will permit to adduser Debian script to detect if chage failed because the
@@ -1001,9 +1001,9 @@ shadow-4.0.12 -> shadow-4.0.13 10-10-2005
shadow-4.0.11.1 -> shadow-4.0.12 22-08-2005
*** general:
- newgrp, login: remove using login.defs::CLOSE_SESSIONS variable and always
- newgrp, login: remove using login.defs::CLOSE_SESSIONS variable and always
close PAM session,
- fixed configure.in: really enable shadow group support by default (pointed by
- fixed configure.in: really enable shadow group support by default (pointed by
Greg Schafer <gschafer@zip.com.au> and Peter Vrabec <pvrabec@redhat.com>),
- login.defs: removed handle QMAIL_DIR variable,
- login: allow regular user to login on read-only root file system (not only for root)
@@ -1080,7 +1080,7 @@ shadow-4.0.10 -> shadow-4.0.11 18-07-2005
- S/Key support is back,
- usermod: added -a option. This flag can only be used in conjunction with the -G
option. It cause usermod to append user to the current supplementary group list.
(patch by Peter Vrabec <pvrabec@redhat.com>)
(patch by Peter Vrabec <pvrabec@redhat.com>)
- chage: added missing \n in error messages,
- useradd, groupadd: change -O option to -K and document it in man page,
- su, sulogin, login: fixed erroneous warning messages when used with PAM about some
@@ -1130,10 +1130,10 @@ shadow-4.0.9 -> shadow-4.0.10 28-06-2005
http://bugs.debian.org/53570 http://bugs.debian.org/195048 http://bugs.debian.org/211884
- login: made login's -f option also able to use the username after -- if none
was passed as it's optarg
http://bugs.debian.org/53702
http://bugs.debian.org/53702
- login: check for hushed login and pass PAM_SILENT if true,
http://bugs.debian.org/48002
- login: fixed username on succesful login (was using the normal username,
- login: fixed username on successful login (was using the normal username,
when it should have used pam_user) http://bugs.debian.org/47819
- remove using SHADOWPWD #define so now shadow is always built with shadow
password support,
@@ -1208,11 +1208,11 @@ shadow-4.0.7 -> shadow-4.0.8 26-04-2005
-- new: chage.1, chpasswd.8, expiry.1, faillog.5, faillog.8, getspnam.3,
logoutd.8, porttime.5, pwck.8, shadow.3, shadowconfig.8, su.1,
- passwd(1): fix #160477 Debian bug: improve -S output description,
- newgrp(1): fix #251926, #166173, #113191 Debian bugs: explain why editing /etc/group
- newgrp(1): fix #251926, #166173, #113191 Debian bugs: explain why editing /etc/group
(without gshadow) doesn't permit to use newgrp,
- newgrp(1): newgrp uses /bin/sh (not bash),
- faillog(8): updated after rewritten faillog command for use getopt_long(),
- login(1): removed fragment about abilities pass enviroment variables in login prompt,
- login(1): removed fragment about abilities pass environment variables in login prompt,
- gshadow(5): new file (by Nicolas Nicolas François <nicolas.francois@centraliens.net>),
- usermod(8): fixed #302388 Debian bug: added separated -o option description,
@@ -1238,11 +1238,11 @@ shadow-4.0.6 -> shadow-4.0.7 26-01-2005
- chpasswd:
-- switch chpasswd to use getopt_long() and adds a --md5 option
(by Ian Gulliver <ian@penguinhosting.net>),
-- rewritten chpasswd(8) man page.
-- rewritten chpasswd(8) man page.
shadow-4.0.5 -> shadow-4.0.6 08-11-2004
- su: fixed adding of pam_env env variables to enviroment
- su: fixed adding of pam_env env variables to environment
(Martin Schlemmer <azarah@nosferatu.za.org>),
- autoconf: fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables
which was always empty (Gregorio Guidi <g.guidi@sns.it>),
@@ -1275,7 +1275,7 @@ shadow-4.0.4.1 -> shadow-4.0.5 27-10-2004
including symlinks placed into /etc/skel/public_html for example.
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=66819
- su: add pam_open_session() support. If built without PAM support
propagate $DISPLAY and $XAUTHORITY enviroment variables.
propagate $DISPLAY and $XAUTHORITY environment variables.
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
- applied 036_pam_access_with_preauth.patch Debian patch submited by Bjorn
Torkelsson <Bjorn.Torkelsson@hpc2n.umu.se>: add support for PAM account
@@ -1309,7 +1309,7 @@ shadow-4.0.4 => shadow-4.0.4.1 14-01-2004
- bug fixes in automake files for generate correct tar ball on "make dist":
added missing "EXTRA_DIST = $(man_MANS)" in man/*/Makefile.am.
shadow-4.0.3 => shadow-4.0.4 14-01-2004
shadow-4.0.3 => shadow-4.0.4 14-01-2004
*** general:
- added missing information about -f options in groupadd usage message
@@ -1408,7 +1408,7 @@ shadow-4.0.0 => shadow-4.0.1
- fixes for handle/print correctly 32bit uid/gid (Thorsten Kukuk <kukuk@suse.de>),
- implemented functions for better reloading the nscd cache (per NSS map)
(Thorsten Kukuk <kukuk@suse.de>),
- fixed warnings "not used but defined" on compile using gcc 3.0.x
- fixed warnings "not used but defined" on compile using gcc 3.0.x
(bulletpr00ph <bullet@users.sourceforge.net>),
- added ja, ko translations found in SuSE,
- added symlinks: newgrp -> sg, vipw -> vigr,
@@ -1416,7 +1416,7 @@ shadow-4.0.0 => shadow-4.0.1
- added sg(1) man page as roff .so link to newgrp(1),
- installed fix for SEGV when using pwck -s on /etc/passwd file with
empty lines in it.
shadow-20001016 => shadow-4.0.0 06-01-2002
- fix bug discovered and fixed by Marcel Ritter
@@ -1466,7 +1466,7 @@ shadow-20000902 => shadow-20001012
overwrite previously existing groups in adduser,
- added PAM support for chage (bind to "chage" PAM config file) also
added PAM support for all other small tools like chpasswd, groupadd,
groupdel, groupmod, newusers, useradd, userdel, usermod (bind to common
groupdel, groupmod, newusers, useradd, userdel, usermod (bind to common
"shadow" PAM config file) - this modifications mainly based on
modifications prepared by Janek Rękojarski <baggins@pld.org.pl>,
- many small fixes and improvements in automake (mow "make dist"

149
README
View File

@@ -1,122 +1,47 @@
Shadow SITES
============
# shadow-utils
Homepage
http://github.com/shadow-maint/shadow
## Introduction
The shadow-utils package includes the necessary programs for
converting UNIX password files to the shadow password format, plus
programs for managing user and group accounts. The pwconv command
converts passwords to the shadow password format. The pwunconv command
unconverts shadow passwords and generates a passwd file (a standard
UNIX password file). The pwck command checks the integrity of password
and shadow files. The lastlog command prints out the last login times
for all users. The useradd, userdel, and usermod commands are used for
managing user accounts. The groupadd, groupdel, and groupmod commands
are used for managing group accounts.
Issue tracker
http://github.com/shadow-maint/shadow/issues
## Sites
* [Homepage](https://github.com/shadow-maint/shadow)
* [Issue tracker](https://github.com/shadow-maint/shadow/issues)
* [Releases](https://github.com/shadow-maint/shadow/releases)
Releases
https://github.com/shadow-maint/shadow/releases
## Code
Mailing lists
for general discuss: pkg-shadow-devel@alioth-lists.debian.net
commit list: pkg-shadow-commits@alioth-lists.debian.net
The main development branch is at [https://github.com/shadow-maint/shadow.git](https://github.com/shadow-maint/shadow)
Mailing lists subscription
http://alioth-lists.debian.net/mailman/listinfo/pkg-shadow-devel
http://alioth-lists.debian.net/mailman/listinfo/pkg-shadow-commits
See [STABLE.md](https://github.com/shadow-maint/shadow/blob/master/STABLE.md) for a list of supported stable branches.
Mailing lists archives:
http://alioth-lists.debian.net/pipermail/pkg-shadow-devel/
http://alioth-lists.debian.net/pipermail/pkg-shadow-commits/
## Contacts
There are several ways to contact us:
* [the general discussion mailing list](
https://alioth-lists.debian.net/mailman/listinfo/pkg-shadow-devel)
* the #shadow IRC channel on libera.chat:
* irc://irc.libera.chat/shadow
S/Key support:
Shadow can be built with S/Key support using the S/Key package from:
### Mailing archives
* [the general discussion mailing list archive](
https://alioth-lists.debian.net/pipermail/pkg-shadow-devel/)
* [the commit mailing list archive](
https://alioth-lists-archive.debian.net/pipermail/pkg-shadow-commits/),
only used for historical purposes
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libskey/
or
http://gentoo.osuosl.org/distfiles/skey-1.1.5.tar.bz2
## Contributions
Authors and contributors
========================
Thanks to at least the following people for sending patches, bug
reports and various comments. This list may be incomplete, I received
a lot of mail...
Adam Rudnicki <adam@v-lo.krakow.pl>
Alan Curry <pacman@tardis.mars.net>
Aleksa Sarai <cyphar@cyphar.com>
Alexander O. Yuriev <alex@bach.cis.temple.edu>
Algis Rudys <arudys@rice.edu>
Andreas Jaeger <aj@arthur.rhein-neckar.de>
Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
Anton Gluck <gluc@midway.uchicago.edu>
Arkadiusz Miskiewicz <misiek@pld.org.pl>
Ben Collins <bcollins@debian.org>
Brian R. Gaeke <brg@dgate.org>
Calle Karlsson <ckn@kash.se>
Chip Rosenthal <chip@unicom.com>
Chris Evans <lady0110@sable.ox.ac.uk>
Chris Lamb <chris@chris-lamb.co.uk>
Cristian Gafton <gafton@sorosis.ro>
Dan Walsh <dwalsh@redhat.com>
Darcy Boese <possum@chardonnay.niagara.com>
Dave Hagewood <admin@arrowweb.com>
David A. Holland <dholland@hcs.harvard.edu>
David Frey <David.Frey@lugs.ch>
Ed Carp <ecarp@netcom.com>
Eric W. Biederman" <ebiederm@xmission.com>
Floody <flood@evcom.net>
Frank Denis <j@4u.net>
George Kraft IV <gk4@us.ibm.com>
Greg Mortensen <loki@world.std.com>
Guido van Rooij
Guy Maor <maor@debian.org>
Hrvoje Dogan <hdogan@bjesomar.srce.hr>
Jakub Hrozek <jhrozek@redhat.com>
Janos Farkas <chexum@bankinf.banki.hu>
Jay Soffian <jay@lw.net>
Jesse Thilo <Jesse.Thilo@pobox.com>
Joey Hess <joey@kite.ml.org>
John Adelsberger <jja@umr.edu>
Jonathan Hankins <jhankins@mailserv.homewood.k12.al.us>
Jon Lewis <jlewis@lewis.org>
Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
Judd Bourgeois <shagboy@bluesky.net>
Juergen Heinzl <unicorn@noris.net>
Juha Virtanen <jiivee@iki.fi>
Julian Pidancet <julian.pidancet@gmail.com>
Julianne Frances Haugh <jockgrrl@ix.netcom.com>
Leonard N. Zubkoff <lnz@dandelion.com>
Luca Berra <bluca@www.polimi.it>
Lukáš Kuklínek <lkukline@redhat.com>
Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
Marc Ewing <marc@redhat.com>
Martin Bene <mb@sime.com>
Martin Mares <mj@gts.cz>
Michael Meskes <meskes@topsystem.de>
Michael Talbot-Wilson <mike@calypso.bns.com.au>
Michael Vetter <jubalh@iodoru.org>
Mike Frysinger <vapier@gentoo.org>
Mike Pakovic <mpakovic@users.southeast.net>
Nicolas François <nicolas.francois@centraliens.net>
Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
Pavel Machek <pavel@bug.ucw.cz>
Peter Vrabec <pvrabec@redhat.com>
Phillip Street
Rafał Maszkowski <rzm@icm.edu.pl>
Rani Chouha <ranibey@smartec.com>
Sami Kerola <kerolasa@rocketmail.com>
Scott Garman <scott.a.garman@intel.com>
Sebastian Rick Rijkers <srrijkers@gmail.com>
Seraphim Mellos <mellos@ceid.upatras.gr>
Shane Watts <shane@nexus.mlckew.edu.au>
Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
Thorsten Kukuk <kukuk@suse.de>
Tim Hockin <thockin@eagle.ais.net>
Timo Karjalainen <timok@iki.fi>
Ulisses Alonso Camaro <ulisses@pusa.eleinf.uv.es>
Werner Fink <werner@suse.de>
Maintainers
===========
Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
Serge E. Hallyn <serge@hallyn.com> (2014-now)
Christian Brauner <christian@brauner.io> (2019-now)
Contributions are welcome. Follow the
[guidelines](doc/contributions/introduction.md) before posting any patches.
## Authors and maintainers
Authors and maintainers are listed in [AUTHORS.md](
https://github.com/shadow-maint/shadow/blob/master/AUTHORS.md).

127
TODO
View File

@@ -1,127 +0,0 @@
* Create a common usage function that'd take the array of
long options and an array of descriptions and output that so things would
be standardized across the utils.
Usage strings should be normalized and split first.
Investigate optparse.
/etc/default/useradd
* GROUP=1000 should accept a group name.
Check when RLOGIN is enabled if ruserok() exists
Move selinux_file_context out of libmisc/copydir.c
Review hardcoded root account?
review all call to strto
libmisc/cleanup_user.c
cleanup needed (cleanup_report_add_user* not used)
libxcrypt support
* http://wiki.linuxfromscratch.org/patches/browser/trunk/shadow/shadow-4.0.18.1-owl_blowfish-1.patch
implement getlong, getulong.
avoid atoi, atol, atoul, strtol, strtoul, ...
manpages: comment the RLOGIN parts
Replace build_list (in lib/gshadow.c) and list (in lib/sgetgrent.c) by
comma_to_list()
Revert the modified files if all files could not be changed.
* or warn and indicate which files were modified and which were not.
* check the order the files are modified.
report nscd_flush_cache failures?
call nscd from the programs or from lib (commonio?)
PAM: check if a non-interactive conversation function could be used to set
the password in chpasswd and newusers
WITH_SELINUX
- review all tools to check that the strategies are consistent
chage, chfn, chsh: same change needed as in passwd.
- probably need moving check_selinux_access to a separate file.
testsuite
- newgrp
- test with unknown user's GID
newusers
- add logging to SYSLOG & AUDIT
- use CREATE_HOME
- Add a -Z option (see useradd / usermod)
Document when/where option appeared, document whether an option is standard
or not.
Check all the expiry semantics
ALL:
- move base passwd/shadow/group/gshadow operation to module for allow write
different backend modules for db, NIS, LDAP and others. Default backend it
will be goot if will be chosen depending on /etc/nsswitch.conf and allow
override this by -r <repository> options (where the <repository> can be
file, db, nis nisplus, ldap .. like on /etc/nsswitch.conf in service column).
passwd have old piece of code with handling -r option and it will be good
finish this and propagate on other shadow tools for allow operate on other
user databases by well known tools.
- Protect against signals. Register do_cleanups in a signal handler.
- login.defs
- generate depending on configuration
- useradd:
- add handle create user mail spool in maildir format.
- Add support for -k in -D mode
- Add support for -K in -D mode
- Add option to create or not the mail spool (and set the default in -D
mode)
- Change -l to reset the entry if an entry was already there
- set the mask in mkdir?
- userdel:
- add backup option for the removal of user resources,
- user_busy: check that the user is not running any processes.
- missing "deleting group" FAILED
- home dir removed, but userdel may fail and may leave the user
=> warning needed
- usermod
- add an option equivalent to useradd's -l (only when uid is changed)
- the mode of new home directories should be set according to the
original mode. Does copy_tree does this?
- user renamed, order is not kept in /etc/group (see
47_usermod-l_no_shadow_file). This is a problem when the first user is
considered as the admin.
- see mail "user ID change" on April, 15
+ fix call to chown (combination of -m and -u/-g)
+ add tests
- passwd:
- check combination of options (e.g. -u/-l)
- when -u refuse to unlock because it would create an empty password, it
should not display "Password changed."
exit instead?
- newgrp: check the USE_PAM section.
- pwck
- Add check to move passwd passwords to shadow if there is a shadow
entry (with a password).
- Add check to move passwd passwords to shadow if there is a shadow
file.
- Support an alternative /etc/tcb directory as second parameter.
- add options -g / -G to specify alternative group / gshadow files
- su
- add a login.defs configuration parameter to add variables to keep in
the environment with "su -l" (TERM/TERMCOLOR/...)
- vipw
- set ACLs and XATTRs on the temporary file (and backups?)
- vipw + selinux -> use lib/selinux.c

View File

@@ -6,7 +6,7 @@ AC_DEFUN([JH_PATH_XML_CATALOG],
[
# check for the presence of the XML catalog
AC_ARG_WITH([xml-catalog],
AC_HELP_STRING([--with-xml-catalog=CATALOG],
AS_HELP_STRING([--with-xml-catalog=CATALOG],
[path to xml catalog to use]),,
[with_xml_catalog=/etc/xml/catalog])
jh_found_xmlcatalog=true

12609
aclocal.m4 vendored

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# Written by Tom Tromey <tromey@cygnus.com>.
#
# This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@ func_file_conv ()
MINGW*)
file_conv=mingw
;;
CYGWIN*)
CYGWIN* | MSYS*)
file_conv=cygwin
;;
*)
@@ -67,7 +67,7 @@ func_file_conv ()
mingw/*)
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
;;
cygwin/*)
cygwin/* | msys/*)
file=`cygpath -m "$file" || echo "$file"`
;;
wine/*)

1500
config.guess vendored

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,12 @@
authenticate the callers */
#undef ACCT_TOOLS_SETUID
/* Define to support lastlog. */
#undef ENABLE_LASTLOG
/* Define to manage session support with logind. */
#undef ENABLE_LOGIND
/* Define to 1 if translation of program messages to the user's native
language is requested. */
#undef ENABLE_NLS
@@ -30,6 +36,9 @@
/* Define to 1 if you have the <acl/libacl.h> header file. */
#undef HAVE_ACL_LIBACL_H
/* Define to 1 if you have the `arc4random_buf' function. */
#undef HAVE_ARC4RANDOM_BUF
/* Define to 1 if you have the <attr/error_context.h> header file. */
#undef HAVE_ATTR_ERROR_CONTEXT_H
@@ -44,10 +53,17 @@
the CoreFoundation framework. */
#undef HAVE_CFPREFERENCESCOPYAPPVALUE
/* Define to 1 if you have the <crypt.h> header file. */
#undef HAVE_CRYPT_H
/* Define if the GNU dcgettext() function is already present or preinstalled.
*/
#undef HAVE_DCGETTEXT
/* Define to 1 if you have the declaration of `cygwin_conv_path', and to 0 if
you don't. */
#undef HAVE_DECL_CYGWIN_CONV_PATH
/* Define to 1 if you have the declaration of `PAM_DATA_SILENT', and to 0 if
you don't. */
#undef HAVE_DECL_PAM_DATA_SILENT
@@ -64,51 +80,32 @@
if you don't. */
#undef HAVE_DECL_PAM_NEW_AUTHTOK_REQD
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define if you have the GNU dld library. */
#undef HAVE_DLD
/* Define to 1 if you have the `dlerror' function. */
#undef HAVE_DLERROR
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* Define if you have the _dyld_func_lookup function. */
#undef HAVE_DYLD
/* Define to 1 if you have the `fchmod' function. */
#undef HAVE_FCHMOD
/* Define to 1 if you have the `explicit_bzero' function. */
#undef HAVE_EXPLICIT_BZERO
/* Define to 1 if you have the `fchown' function. */
#undef HAVE_FCHOWN
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fsync' function. */
#undef HAVE_FSYNC
/* Defined to 1 if you have the declaration of 'fgetpwent_r' */
#undef HAVE_FGETPWENT_R
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the `getentropy' function. */
#undef HAVE_GETENTROPY
/* Define to 1 if you have the `getgrgid_r' function. */
#undef HAVE_GETGRGID_R
/* Define to 1 if you have the `getgrnam_r' function. */
#undef HAVE_GETGRNAM_R
/* Define to 1 if you have the `getgroups' function. */
#undef HAVE_GETGROUPS
/* Define to 1 if you have the `gethostname' function. */
#undef HAVE_GETHOSTNAME
/* Define to 1 if you have the `getpwnam_r' function. */
#undef HAVE_GETPWNAM_R
/* Define to 1 if you have the `getpwuid_r' function. */
#undef HAVE_GETPWUID_R
/* Define to 1 if you have the `getrandom' function. */
#undef HAVE_GETRANDOM
/* Define to 1 if you have the `getspnam' function. */
#undef HAVE_GETSPNAM
@@ -119,15 +116,9 @@
/* Define if the GNU gettext() function is already present or preinstalled. */
#undef HAVE_GETTEXT
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the `getusershell' function. */
#undef HAVE_GETUSERSHELL
/* Define to 1 if you have the `getutent' function. */
#undef HAVE_GETUTENT
/* Define to 1 if you have the <gshadow.h> header file. */
#undef HAVE_GSHADOW_H
@@ -143,29 +134,17 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `l64a' function. */
#undef HAVE_L64A
/* Define to 1 if you have the <lastlog.h> header file. */
#undef HAVE_LASTLOG_H
/* Define to 1 if you have the `lchown' function. */
#undef HAVE_LCHOWN
/* Define to 1 if you have the `lckpwdf' function. */
#undef HAVE_LCKPWDF
/* Defined if you have libcrack. */
#undef HAVE_LIBCRACK
/* Define if you have the libdl library or equivalent. */
#undef HAVE_LIBDL
/* Defined if you have the ts&szs cracklib. */
#undef HAVE_LIBCRACK_HIST
/* Defined if it includes *Pw functions. */
#undef HAVE_LIBCRACK_PW
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define if libdlloader will be built on this platform */
#undef HAVE_LIBDLLOADER
/* Define to 1 if you have the <linux/btrfs_tree.h> header file. */
#undef HAVE_LINUX_BTRFS_TREE_H
@@ -176,32 +155,14 @@
/* Define if struct lastlog has ll_host */
#undef HAVE_LL_HOST
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
/* Define to 1 if you have the `lutimes' function. */
#undef HAVE_LUTIMES
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the `memset_explicit' function. */
#undef HAVE_MEMSET_EXPLICIT
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the `mkdir' function. */
#undef HAVE_MKDIR
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the <minix/config.h> header file. */
#undef HAVE_MINIX_CONFIG_H
/* Define to 1 if you have the <paths.h> header file. */
#undef HAVE_PATHS_H
@@ -215,17 +176,14 @@
/* Define to 1 if you have the `putspent' function. */
#undef HAVE_PUTSPENT
/* Define to 1 if you have the `rename' function. */
#undef HAVE_RENAME
/* Define to 1 if you have the `rmdir' function. */
#undef HAVE_RMDIR
/* Define to 1 if you have the <readpassphrase.h> header file. */
#undef HAVE_READPASSPHRASE_H
/* Define to 1 if you have the <rpc/key_prot.h> header file. */
#undef HAVE_RPC_KEY_PROT_H
/* Define to 1 if you have the `ruserok' function. */
#undef HAVE_RUSEROK
/* Define to 1 if you have the `rpmatch' function. */
#undef HAVE_RPMATCH
/* Define to 1 if you have the <security/openpam.h> header file. */
#undef HAVE_SECURITY_OPENPAM_H
@@ -257,35 +215,23 @@
/* Have working shadow group support in libc */
#undef HAVE_SHADOWGRP
/* Define to 1 if you have the `sigaction' function. */
#undef HAVE_SIGACTION
/* Define to 1 if you have the `snprintf' function. */
#undef HAVE_SNPRINTF
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* Define if you have the shl_load function. */
#undef HAVE_SHL_LOAD
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `stpecpy' function. */
#undef HAVE_STPECPY
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the `stpeprintf' function. */
#undef HAVE_STPEPRINTF
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
@@ -293,24 +239,6 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strstr' function. */
#undef HAVE_STRSTR
/* Define to 1 if `st_atim' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_ATIM
/* Define to 1 if `st_atimensec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_ATIMENSEC
/* Define to 1 if `st_mtim' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIM
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV
/* Define to 1 if `ut_addr' is a member of `struct utmpx'. */
#undef HAVE_STRUCT_UTMPX_UT_ADDR
@@ -332,58 +260,14 @@
/* Define to 1 if `ut_xtime' is a member of `struct utmpx'. */
#undef HAVE_STRUCT_UTMPX_UT_XTIME
/* Define to 1 if `ut_addr' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_ADDR
/* Define to 1 if `ut_addr_v6' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_ADDR_V6
/* Define to 1 if `ut_host' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_HOST
/* Define to 1 if `ut_id' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_ID
/* Define to 1 if `ut_name' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_NAME
/* Define to 1 if `ut_syslen' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_SYSLEN
/* Define to 1 if `ut_time' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_TIME
/* Define to 1 if `ut_tv' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_TV
/* Define to 1 if `ut_type' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_TYPE
/* Define to 1 if `ut_user' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_USER
/* Define to 1 if `ut_xtime' is a member of `struct utmp'. */
#undef HAVE_STRUCT_UTMP_UT_XTIME
/* Define to 1 if you have the <syslog.h> header file. */
#undef HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/capability.h> header file. */
#undef HAVE_SYS_CAPABILITY_H
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/random.h> header file. */
#undef HAVE_SYS_RANDOM_H
/* Define to 1 if you have the <sys/statfs.h> header file. */
#undef HAVE_SYS_STATFS_H
@@ -391,33 +275,18 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the <tcb.h> header file. */
#undef HAVE_TCB_H
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <termio.h> header file. */
#undef HAVE_TERMIO_H
/* Define to 1 if you have the <ulimit.h> header file. */
#undef HAVE_ULIMIT_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `updwtmp' function. */
#undef HAVE_UPDWTMP
/* Define to 1 if you have the `updwtmpx' function. */
#undef HAVE_UPDWTMPX
@@ -427,14 +296,14 @@
/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
#undef HAVE_UTIME_NULL
/* Define to 1 if you have the <utmpx.h> header file. */
#undef HAVE_UTMPX_H
/* Define to 1 if you have the <utmp.h> header file. */
#undef HAVE_UTMP_H
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Define to support vendor settings. */
#undef HAVE_VENDORDIR
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Path for lastlog file. */
#undef LASTLOG_FILE
@@ -472,15 +341,6 @@
/* Path to passwd program. */
#undef PASSWD_PROGRAM
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define if login should support the -r flag for rlogind. */
#undef RLOGIN
/* Define to the ruserok() "success" return value (0 or 1). */
#undef RUSEROK
/* Define to support the shadow group file. */
#undef SHADOWGRP
@@ -502,21 +362,14 @@
/* Define to support newer BSD S/Key API */
#undef SKEY_BSD_STYLE
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
#undef STAT_MACROS_BROKEN
/* Define to 1 if you have the ANSI C header files. */
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
#undef STDC_HEADERS
/* Define to support /etc/suauth su access control. */
#undef SU_ACCESS
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
/* Define to allow the bcrypt password encryption algorithm */
#undef USE_BCRYPT
@@ -532,33 +385,99 @@
/* Define to support flushing of sssd caches */
#undef USE_SSSD
/* Define to use syslog(). */
#undef USE_SYSLOG
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
/* Enable general extensions on macOS. */
#ifndef _DARWIN_C_SOURCE
# undef _DARWIN_C_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable X/Open compliant socket functions that do not require linking
with -lxnet on HP-UX 11.11. */
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
# undef _HPUX_ALT_XOPEN_SOCKET_API
#endif
/* Identify the host operating system as Minix.
This macro does not affect the system headers' behavior.
A future release of Autoconf may stop defining this macro. */
#ifndef _MINIX
# undef _MINIX
#endif
/* Enable general extensions on NetBSD.
Enable NetBSD compatibility extensions on Minix. */
#ifndef _NETBSD_SOURCE
# undef _NETBSD_SOURCE
#endif
/* Enable OpenBSD compatibility extensions on NetBSD.
Oddly enough, this does nothing on OpenBSD. */
#ifndef _OPENBSD_SOURCE
# undef _OPENBSD_SOURCE
#endif
/* Define to 1 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_SOURCE
# undef _POSIX_SOURCE
#endif
/* Define to 2 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_1_SOURCE
# undef _POSIX_1_SOURCE
#endif
/* Enable POSIX-compatible threading on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
# undef __STDC_WANT_IEC_60559_BFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
#ifndef __STDC_WANT_LIB_EXT2__
# undef __STDC_WANT_LIB_EXT2__
#endif
/* Enable extensions specified by ISO/IEC 24747:2009. */
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
# undef __STDC_WANT_MATH_SPEC_FUNCS__
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable X/Open extensions. Define to 500 only if necessary
to make mbstate_t available. */
#ifndef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
#endif
/* Define if utmpx should be used */
#undef USE_UTMPX
/* Define to allow the yescrypt password encryption algorithm */
#undef USE_YESCRYPT
/* Directory for distribution provided configuration files */
#undef VENDORDIR
/* Version number of package */
#undef VERSION
@@ -575,6 +494,9 @@
/* Build shadow with BtrFS support */
#undef WITH_BTRFS
/* Build shadow without libbsd support */
#undef WITH_LIBBSD
/* Build shadow with SELinux support */
#undef WITH_SELINUX
@@ -584,47 +506,20 @@
/* Build shadow with tcb support (incomplete) */
#undef WITH_TCB
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Path for utmp file. */
#undef _UTMP_FILE
/* Path for wtmp file. */
#undef _WTMP_FILE
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define to `int' if <sys/types.h> does not define. */
#undef mode_t
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t

View File

@@ -2,7 +2,7 @@
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2006 Free Software Foundation, Inc.
# Copyright 1996-2014 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
@@ -25,7 +25,7 @@
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# All known linkers require a '.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
@@ -47,7 +47,7 @@ for cc_temp in $CC""; do
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
# Code taken from libtool.m4's _LT_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
@@ -57,14 +57,7 @@ else
aix*)
wl='-Wl,'
;;
darwin*)
case $cc_basename in
xlc*)
wl='-Wl,'
;;
esac
;;
mingw* | pw32* | os2*)
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
@@ -72,24 +65,37 @@ else
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
newsos6)
;;
linux*)
linux* | k*bsd*-gnu | kopensolaris*-gnu)
case $cc_basename in
icc* | ecc*)
ecc*)
wl='-Wl,'
;;
pgcc | pgf77 | pgf90)
icc* | ifort*)
wl='-Wl,'
;;
lf95*)
wl='-Wl,'
;;
nagfor*)
wl='-Wl,-Wl,,'
;;
pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
xl* | bgxl* | bgf* | mpixl*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ F* | *Sun*Fortran*)
wl=
;;
*Sun\ C*)
wl='-Wl,'
;;
@@ -97,22 +103,36 @@ else
;;
esac
;;
newsos6)
;;
*nto* | *qnx*)
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
sco3.2v5*)
rdos*)
;;
solaris*)
wl='-Wl,'
case $cc_basename in
f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
wl='-Qoption ld '
;;
*)
wl='-Wl,'
;;
esac
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
@@ -121,7 +141,7 @@ else
esac
fi
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
@@ -129,7 +149,7 @@ hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32*)
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
@@ -155,22 +175,21 @@ if test "$with_gnu_ld" = yes; then
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix3* | aix4* | aix5*)
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
# that the semantics of dynamic libraries on AmigaOS, at least up
# to version 4, is to share data among multiple programs linked
# with the same dynamic library. Since this doesn't match the
# behavior of shared libraries on other platforms, we cannot use
# them.
ld_shlibs=no
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
@@ -179,7 +198,7 @@ if test "$with_gnu_ld" = yes; then
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32*)
cygwin* | mingw* | pw32* | cegcc*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
@@ -189,11 +208,13 @@ if test "$with_gnu_ld" = yes; then
ld_shlibs=no
fi
;;
interix3*)
haiku*)
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
linux*)
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
@@ -251,7 +272,7 @@ else
hardcode_direct=unsupported
fi
;;
aix4* | aix5*)
aix[4-9]*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
@@ -261,7 +282,7 @@ else
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
@@ -280,7 +301,7 @@ else
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
hardcode_direct=yes
:
else
# We have old collect2
hardcode_direct=unsupported
@@ -316,14 +337,18 @@ else
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# see comment about different semantics on the GNU ld section
ld_shlibs=no
case "$host_cpu" in
powerpc)
;;
m68k)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
esac
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32*)
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
@@ -333,24 +358,15 @@ else
;;
darwin* | rhapsody*)
hardcode_direct=no
if test "$GCC" = yes ; then
if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then
:
else
case $cc_basename in
xlc*)
;;
*)
ld_shlibs=no
;;
esac
ld_shlibs=no
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd1*)
ld_shlibs=no
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
@@ -359,7 +375,7 @@ else
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | kfreebsd*-gnu | dragonfly*)
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
@@ -411,19 +427,25 @@ else
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
*nto* | *qnx*)
;;
openbsd*)
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
ld_shlibs=no
fi
;;
os2*)
@@ -471,7 +493,7 @@ else
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7*)
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
@@ -487,34 +509,58 @@ else
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix4* | aix5*)
aix[4-9]*)
library_names_spec='$libname$shrext'
;;
amigaos*)
case "$host_cpu" in
powerpc*)
library_names_spec='$libname$shrext' ;;
m68k)
library_names_spec='$libname.a' ;;
esac
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32*)
cygwin* | mingw* | pw32* | cegcc*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
;;
freebsd1*)
;;
kfreebsd*-gnu)
library_names_spec='$libname$shrext'
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
haiku*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
@@ -528,10 +574,13 @@ case "$host_os" in
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix3*)
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
@@ -548,41 +597,62 @@ case "$host_os" in
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux*)
linux* | k*bsd*-gnu | kopensolaris*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
nto-qnx*)
*nto* | *qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
tpf*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
@@ -596,6 +666,12 @@ libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"

2855
config.sub vendored

File diff suppressed because it is too large Load Diff

11030
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,79 +1,61 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
AC_INIT([shadow], [4.8.1], [pkg-shadow-devel@lists.alioth.debian.org], [],
AC_PREREQ([2.69])
m4_define([libsubid_abi_major], 5)
m4_define([libsubid_abi_minor], 0)
m4_define([libsubid_abi_micro], 0)
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
AC_INIT([shadow], [4.16.0], [pkg-shadow-devel@lists.alioth.debian.org], [],
[https://github.com/shadow-maint/shadow])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
AC_CONFIG_MACRO_DIRS([m4])
AM_SILENT_RULES([yes])
AC_CONFIG_HEADERS([config.h])
AC_SUBST([LIBSUBID_ABI_MAJOR], [libsubid_abi_major])
AC_SUBST([LIBSUBID_ABI_MINOR], [libsubid_abi_minor])
AC_SUBST([LIBSUBID_ABI_MICRO], [libsubid_abi_micro])
AC_SUBST([LIBSUBID_ABI], [libsubid_abi])
dnl Some hacks...
test "$prefix" = "NONE" && prefix="/usr"
test "$prefix" = "/usr" && exec_prefix=""
AC_GNU_SOURCE
AC_USE_SYSTEM_EXTENSIONS
AM_DISABLE_SHARED
AM_ENABLE_STATIC
AC_ENABLE_STATIC
AC_ENABLE_SHARED
AM_MAINTAINER_MODE
dnl Checks for programs.
AC_PROG_CC
AC_ISC_POSIX
AC_PROG_LN_S
AC_PROG_YACC
AM_PROG_LIBTOOL
LT_INIT
LT_LIB_DLLOAD
dnl Checks for libraries.
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_STDBOOL
AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
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)
AC_CHECK_HEADERS(crypt.h utmp.h \
termio.h sgtty.h sys/ioctl.h paths.h \
sys/capability.h sys/random.h \
gshadow.h lastlog.h rpc/key_prot.h acl/libacl.h \
attr/libattr.h attr/error_context.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])])
AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \
gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \
lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \
getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \
ruserok)
AC_CHECK_FUNCS(arc4random_buf futimes \
getentropy getrandom getspnam getusershell \
initgroups lckpwdf lutimes \
setgroups updwtmpx innetgr \
getspnam_r \
rpmatch \
memset_explicit explicit_bzero stpecpy stpeprintf)
AC_SYS_LARGEFILE
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_UID_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_MODE_T
AC_HEADER_STAT
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_MEMBERS([struct stat.st_atim])
AC_CHECK_MEMBERS([struct stat.st_atimensec])
AC_CHECK_MEMBERS([struct stat.st_mtim])
AC_CHECK_MEMBERS([struct stat.st_mtimensec])
AC_HEADER_TIME
AC_STRUCT_TM
AC_CHECK_MEMBERS([struct utmp.ut_type,
struct utmp.ut_id,
struct utmp.ut_name,
struct utmp.ut_user,
struct utmp.ut_host,
struct utmp.ut_syslen,
struct utmp.ut_addr,
struct utmp.ut_addr_v6,
struct utmp.ut_time,
struct utmp.ut_xtime,
struct utmp.ut_tv],,,[[#include <utmp.h>]])
AC_CHECK_MEMBERS([struct utmpx.ut_name,
struct utmpx.ut_host,
@@ -83,31 +65,11 @@ AC_CHECK_MEMBERS([struct utmpx.ut_name,
struct utmpx.ut_time,
struct utmpx.ut_xtime],,,[[#include <utmpx.h>]])
if test "$ac_cv_header_lastlog_h" = "yes"; then
AC_CACHE_CHECK(for ll_host in struct lastlog,
ac_cv_struct_lastlog_ll_host,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <lastlog.h>],
[struct lastlog ll; char *cp = ll.ll_host;]
)],
[ac_cv_struct_lastlog_ll_host=yes],
[ac_cv_struct_lastlog_ll_host=no]
)
)
if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
AC_DEFINE(HAVE_LL_HOST, 1,
[Define if struct lastlog has ll_host])
fi
fi
dnl Checks for library functions.
AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL
AC_FUNC_UTIME_NULL
AC_FUNC_STRFTIME
AC_REPLACE_FUNCS(mkdir putgrent putpwent putspent rename rmdir)
AC_REPLACE_FUNCS(putgrent putpwent putspent)
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
AC_REPLACE_FUNCS(snprintf strcasecmp strdup strerror strstr)
AC_CHECK_FUNC(setpgrp)
AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
@@ -119,6 +81,10 @@ if test "$ac_cv_header_shadow_h" = "yes"; then
ac_cv_libc_shadowgrp,
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <shadow.h>
#ifdef HAVE_GSHADOW_H
#include <gshadow.h>
#endif
int
main()
{
struct sgrp *sg = sgetsgent("test:x::");
@@ -193,15 +159,8 @@ fi])
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
[Path to passwd program.])
dnl XXX - quick hack, should disappear before anyone notices :).
AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog().])
if test "$ac_cv_func_ruserok" = "yes"; then
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
fi
AC_ARG_ENABLE(shadowgrp,
[AC_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
[case "${enableval}" in
yes) enable_shadowgrp="yes" ;;
no) enable_shadowgrp="no" ;;
@@ -211,15 +170,15 @@ AC_ARG_ENABLE(shadowgrp,
)
AC_ARG_ENABLE(man,
[AC_HELP_STRING([--enable-man],
[AS_HELP_STRING([--enable-man],
[regenerate roff man pages from Docbook @<:@default=no@:>@])],
[enable_man="${enableval}"],
[enable_man="no"]
)
AC_ARG_ENABLE(account-tools-setuid,
[AC_HELP_STRING([--enable-account-tools-setuid],
[Install the user and group management tools setuid and authenticate the callers. This requires --with-pam.])],
[AS_HELP_STRING([--enable-account-tools-setuid],
[Install the user and group management tools setuid and authenticate the callers. This requires --with-libpam.])],
[case "${enableval}" in
yes) enable_acct_tools_setuid="yes" ;;
no) enable_acct_tools_setuid="no" ;;
@@ -229,79 +188,86 @@ AC_ARG_ENABLE(account-tools-setuid,
[enable_acct_tools_setuid="no"]
)
AC_ARG_ENABLE(utmpx,
[AC_HELP_STRING([--enable-utmpx],
[enable loggin in utmpx / wtmpx @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_utmpx="yes" ;;
no) enable_utmpx="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-utmpx) ;;
esac],
[enable_utmpx="no"]
)
AC_ARG_ENABLE(subordinate-ids,
[AC_HELP_STRING([--enable-subordinate-ids],
[AS_HELP_STRING([--enable-subordinate-ids],
[support subordinate ids @<:@default=yes@:>@])],
[enable_subids="${enableval}"],
[enable_subids="maybe"]
)
AC_ARG_ENABLE(lastlog,
[AS_HELP_STRING([--enable-lastlog],
[enable lastlog @<:@default=no@:>@])],
[enable_lastlog="${enableval}"],
[enable_lastlog="no"]
)
AC_ARG_ENABLE(logind,
[AS_HELP_STRING([--enable-logind],
[enable logind @<:@default=yes@:>@])],
[enable_logind="${enableval}"],
[enable_logind="yes"]
)
AC_ARG_WITH(audit,
[AC_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
[with_audit=$withval], [with_audit=maybe])
AC_ARG_WITH(libpam,
[AC_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
[with_libpam=$withval], [with_libpam=maybe])
AC_ARG_WITH(btrfs,
[AC_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])],
[with_btrfs=$withval], [with_btrfs=maybe])
AC_ARG_WITH(selinux,
[AC_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
[with_selinux=$withval], [with_selinux=maybe])
AC_ARG_WITH(acl,
[AC_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
[with_acl=$withval], [with_acl=maybe])
AC_ARG_WITH(attr,
[AC_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
[with_attr=$withval], [with_attr=maybe])
AC_ARG_WITH(skey,
[AC_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
[AS_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
[with_skey=$withval], [with_skey=no])
AC_ARG_WITH(tcb,
[AC_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
[AS_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
[with_tcb=$withval], [with_tcb=maybe])
AC_ARG_WITH(libcrack,
[AC_HELP_STRING([--with-libcrack], [use libcrack @<:@default=no@:>@])],
[with_libcrack=$withval], [with_libcrack=no])
AC_ARG_WITH(sha-crypt,
[AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
[AS_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
[with_sha_crypt=$withval], [with_sha_crypt=yes])
AC_ARG_WITH(bcrypt,
[AC_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
[AS_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
[with_bcrypt=$withval], [with_bcrypt=no])
AC_ARG_WITH(yescrypt,
[AS_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])],
[with_yescrypt=$withval], [with_yescrypt=no])
AC_ARG_WITH(nscd,
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[AS_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes])
AC_ARG_WITH(sssd,
[AC_HELP_STRING([--with-sssd], [enable support for flushing sssd caches @<:@default=yes@:>@])],
[AS_HELP_STRING([--with-sssd], [enable support for flushing sssd caches @<:@default=yes@:>@])],
[with_sssd=$withval], [with_sssd=yes])
AC_ARG_WITH(group-name-max-length,
[AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])],
[AS_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=32@:>@])],
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
AC_ARG_WITH(su,
[AC_HELP_STRING([--with-su], [build and install su program and man page @<:@default=yes@:>@])],
[AS_HELP_STRING([--with-su], [build and install su program and man page @<:@default=yes@:>@])],
[with_su=$withval], [with_su=yes])
AC_ARG_WITH(libbsd,
[AS_HELP_STRING([--with-libbsd], [use libbsd support @<:@default=yes if found@:>@])],
[with_libbsd=$withval], [with_libbsd=yes])
if test "$with_group_name_max_length" = "no" ; then
with_group_name_max_length=0
elif test "$with_group_name_max_length" = "yes" ; then
with_group_name_max_length=16
with_group_name_max_length=32
fi
AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max group name length])
AC_SUBST(GROUP_NAME_MAX_LENGTH)
GROUP_NAME_MAX_LENGTH="$with_group_name_max_length"
AM_CONDITIONAL(USE_SHA_CRYPT, test "x$with_sha_crypt" = "xyes")
if test "$with_sha_crypt" = "yes"; then
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
@@ -312,6 +278,11 @@ if test "$with_bcrypt" = "yes"; then
AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm])
fi
AM_CONDITIONAL(USE_YESCRYPT, test "x$with_yescrypt" = "xyes")
if test "$with_yescrypt" = "yes"; then
AC_DEFINE(USE_YESCRYPT, 1, [Define to allow the yescrypt password encryption algorithm])
fi
if test "$with_nscd" = "yes"; then
AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
@@ -324,19 +295,23 @@ if test "$with_sssd" = "yes"; then
[AC_MSG_ERROR([posix_spawn is needed for sssd support])])
fi
AS_IF([test "$with_su" != "no"], AC_DEFINE(WITH_SU, 1, [Build with su])])
AS_IF([test "$with_su" != "no"], AC_DEFINE(WITH_SU, 1, [Build with su]))
AM_CONDITIONAL([WITH_SU], [test "x$with_su" != "xno"])
dnl Check for some functions in libc first, only if not found check for
dnl other libraries. This should prevent linking libnsl if not really
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
AC_SEARCH_LIBS(inet_ntoa, inet)
AC_SEARCH_LIBS(socket, socket)
AC_SEARCH_LIBS(gethostbyname, nsl)
PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"],
[AC_MSG_WARN([libcmocka not found, cmocka tests will not be built])])
AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
if test -n "$LIBECONF"; then
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
[Directory for distribution provided configuration files])
ECONF_CPPFLAGS="-DUSE_ECONF=1"
AC_ARG_ENABLE([vendordir],
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
@@ -344,6 +319,9 @@ fi
AC_SUBST(ECONF_CPPFLAGS)
AC_SUBST(LIBECONF)
AC_SUBST([VENDORDIR], [$enable_vendordir])
if test "x$enable_vendordir" != x; then
AC_DEFINE(HAVE_VENDORDIR, 1, [Define to support vendor settings.])
fi
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
if test "$enable_shadowgrp" = "yes"; then
@@ -388,10 +366,69 @@ if test "$enable_subids" != "no"; then
fi
AM_CONDITIONAL(ENABLE_SUBIDS, test "x$enable_subids" != "xno")
if test "$enable_lastlog" = "yes" && test "$ac_cv_header_lastlog_h" = "yes"; then
AC_CACHE_CHECK(for ll_host in struct lastlog,
ac_cv_struct_lastlog_ll_host,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <lastlog.h>],
[struct lastlog ll; char *cp = ll.ll_host;]
)],
[ac_cv_struct_lastlog_ll_host=yes],
[ac_cv_struct_lastlog_ll_host=no]
)
)
if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
AC_DEFINE(HAVE_LL_HOST, 1,
[Define if struct lastlog has ll_host])
AC_DEFINE(ENABLE_LASTLOG, 1, [Define to support lastlog.])
enable_lastlog="yes"
else
AC_MSG_ERROR([Cannot enable support for lastlog on systems where the data structures aren't available])
enable_subids="no"
fi
fi
AM_CONDITIONAL(ENABLE_LASTLOG, test "x$enable_lastlog" != "xno")
AC_SUBST(LIBSYSTEMD)
if test "$enable_logind" = "yes"; then
AC_CHECK_LIB(systemd, sd_session_get_remote_host,
[enable_logind="yes"; [LIBSYSTEMD=-lsystemd];
AC_DEFINE(ENABLE_LOGIND, 1,
[Define to manage session support with logind.])],
[enable_logind="no"])
fi
AM_CONDITIONAL(ENABLE_LOGIND, test "x$enable_logind" != "xno")
AC_SUBST(LIBCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])])
AC_SUBST(LIYESCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])])
AC_SUBST(LIBBSD)
if test "$with_libbsd" != "no"; then
AC_SEARCH_LIBS([readpassphrase], [bsd], [], [
AC_MSG_ERROR([readpassphrase() is missing, either from libc or libbsd])
])
AS_IF([test "$ac_cv_search_readpassphrase" = "-lbsd"], [
PKG_CHECK_MODULES([LIBBSD], [libbsd-overlay])
])
dnl Make sure either the libc or libbsd provide the header.
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $LIBBSD_CFLAGS"
AC_CHECK_HEADERS([readpassphrase.h])
AS_IF([test "$ac_cv_header_readpassphrase_h" != "yes"], [
AC_MSG_ERROR([readpassphrase.h is missing])
])
CFLAGS="$save_CFLAGS"
AC_DEFINE(WITH_LIBBSD, 1, [Build shadow with libbsd support])
else
AC_DEFINE(WITH_LIBBSD, 0, [Build shadow without libbsd support])
fi
AM_CONDITIONAL(WITH_LIBBSD, test x$with_libbsd = xyes)
AC_SUBST(LIBACL)
if test "$with_acl" != "no"; then
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
@@ -476,17 +513,6 @@ if test "$with_audit" != "no"; then
fi
fi
AC_SUBST(LIBCRACK)
if test "$with_libcrack" = "yes"; then
echo "checking cracklib flavour, don't be surprised by the results"
AC_CHECK_LIB(crack, FascistCheck,
[LIBCRACK=-lcrack AC_DEFINE(HAVE_LIBCRACK, 1, [Defined if you have libcrack.])])
AC_CHECK_LIB(crack, FascistHistory,
AC_DEFINE(HAVE_LIBCRACK_HIST, 1, [Defined if you have the ts&szs cracklib.]))
AC_CHECK_LIB(crack, FascistHistoryPw,
AC_DEFINE(HAVE_LIBCRACK_PW, 1, [Defined if it includes *Pw functions.]))
fi
if test "$with_btrfs" != "no"; then
AC_CHECK_HEADERS([sys/statfs.h linux/magic.h linux/btrfs_tree.h], \
[btrfs_headers="yes"], [btrfs_headers="no"])
@@ -647,7 +673,7 @@ AM_CONDITIONAL(ACCT_TOOLS_SETUID, test "x$enable_acct_tools_setuid" = "xyes")
AC_ARG_WITH(fcaps,
[AC_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
[AS_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
[with_fcaps=$withval], [with_fcaps=no])
AM_CONDITIONAL(FCAPS, test "x$with_fcaps" = "xyes")
@@ -665,26 +691,19 @@ if test "$with_skey" = "yes"; then
AC_CHECK_LIB(skey, skeychallenge, [LIBSKEY=-lskey],
[AC_MSG_ERROR([liskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
AC_DEFINE(SKEY, 1, [Define to support S/Key logins.])
AC_TRY_COMPILE([
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <stdio.h>
#include <skey.h>
],[
]], [[
skeychallenge((void*)0, (void*)0, (void*)0, 0);
],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])])
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
fi
if test "$enable_utmpx" = "yes"; then
if test "$ac_cv_header_utmpx_h" != "yes"; then
AC_MSG_ERROR([The utmpx.h header file is required for utmpx support.])
fi
AC_DEFINE(USE_UTMPX,
1,
[Define if utmpx should be used])
fi
AC_CHECK_FUNC(fgetpwent_r, [AC_DEFINE(HAVE_FGETPWENT_R, 1, [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
AM_GNU_GETTEXT_VERSION(0.16)
AM_GNU_GETTEXT_VERSION([0.19])
AM_GNU_GETTEXT([external], [need-ngettext])
AM_CONDITIONAL(USE_NLS, test "x$USE_NLS" = "xyes")
@@ -711,15 +730,18 @@ AC_CONFIG_FILES([
man/ru/Makefile
man/sv/Makefile
man/tr/Makefile
man/uk/Makefile
man/zh_CN/Makefile
man/zh_TW/Makefile
libmisc/Makefile
lib/Makefile
libsubid/Makefile
libsubid/subid.h
src/Makefile
contrib/Makefile
etc/Makefile
etc/pam.d/Makefile
shadow.spec
etc/shadow-maint/Makefile
tests/unit/Makefile
])
AC_OUTPUT
@@ -727,7 +749,6 @@ echo
echo "shadow will be compiled with the following features:"
echo
echo " auditing support: $with_audit"
echo " CrackLib support: $with_libcrack"
echo " PAM support: $with_libpam"
if test "$with_libpam" = "yes"; then
echo " suid account management tools: $enable_acct_tools_setuid"
@@ -741,9 +762,13 @@ echo " shadow group support: $enable_shadowgrp"
echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt"
echo " bcrypt passwords encryption: $with_bcrypt"
echo " yescrypt passwords encryption: $with_yescrypt"
echo " nscd support: $with_nscd"
echo " sssd support: $with_sssd"
echo " subordinate IDs support: $enable_subids"
echo " enable lastlog: $enable_lastlog"
echo " enable logind: $enable_logind"
echo " use file caps: $with_fcaps"
echo " install su: $with_su"
echo " enabled vendor dir: $enable_vendordir"
echo

View File

@@ -1,6 +1,4 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh \
atudel groupmems.shar pwdauth.c shadow-anonftp.patch \
udbachk.tgz
EXTRA_DIST = README adduser.c adduser.sh adduser2.sh

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -92,7 +92,14 @@ build_triplet = @build@
host_triplet = @host@
subdir = contrib
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -134,8 +141,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -147,6 +158,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
@@ -164,9 +176,15 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBCRACK = @LIBCRACK@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
@@ -178,13 +196,21 @@ LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBSEMANAGE = @LIBSEMANAGE@
LIBSKEY = @LIBSKEY@
LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LIYESCRYPT = @LIYESCRYPT@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -207,6 +233,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
@@ -278,10 +307,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh \
atudel groupmems.shar pwdauth.c shadow-anonftp.patch \
udbachk.tgz
EXTRA_DIST = README adduser.c adduser.sh adduser2.sh
all: all-am
.SUFFIXES:
@@ -326,7 +352,6 @@ ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am

View File

@@ -2,9 +2,6 @@ People keep sending various adduser programs and scripts... They are
all in this directory. I haven't tested them, use at your own risk.
Anyway, the best one I've seen so far is adduser-3.x from Debian.
atudel is a perl script to remove at jobs owned by the specified user
(atrm in at-2.9 for Linux can't do that).
udbachk.tgz is a passwd/group/shadow file integrity checker.
--marekm

View File

@@ -1,300 +0,0 @@
/****
** 03/17/96
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
** --marekm
**
** 02/26/96
** modified to call shadow utils (useradd,chage,passwd) on shadowed
** systems - Cristian Gafton, gafton@sorosis.ro
**
** 6/27/95
** shadow-adduser 1.4:
**
** now it copies the /etc/skel dir into the person's dir,
** makes the mail folders, changed some defaults and made a 'make
** install' just for the hell of it.
**
** Greg Gallagher
** CIN.Net
**
** 1/28/95
** shadow-adduser 1.3:
**
** Basically a bug-fix on my additions in 1.2. Thanks to Terry Stewart
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
** It was such a stupid bug that I would have never seen it myself.
**
** Brandon
*****
** 01/27/95
**
** shadow-adduser 1.2:
** I took the C source from adduser-shadow (credits are below) and made
** it a little more worthwhile. Many small changes... Here's
** the ones I can remember:
**
** Removed support for non-shadowed systems (if you don't have shadow,
** use the original adduser, don't get this shadow version!)
** Added support for the correct /etc/shadow fields (Min days before
** password change, max days before password change, Warning days,
** and how many days from expiry date does the account go invalid)
** The previous version just left all of those fields blank.
** There is still one field left (expiry date for the account, period)
** which I have left blank because I do not use it and didn't want to
** spend any more time on this. I'm sure someone will put it in and
** tack another plethora of credits on here. :)
** Added in the password date field, which should always reflect the last
** date the password was changed, for expiry purposes. "passwd" always
** updates this field, so the adduser program should set it up right
** initially (or a user could keep thier initial password forever ;)
** The number is in days since Jan 1st, 1970.
**
** Have fun with it, and someone please make
** a real version(this is still just a hack)
** for us all to use (and Email it to me???)
**
** Brandon
** photon@usis.com
**
*****
** adduser 1.0: add a new user account (For systems not using shadow)
** With a nice little interface and a will to do all the work for you.
**
** Craig Hagan
** hagan@opine.cs.umass.edu
**
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
** chris@slinky.cs.umass.edu
**
*****
**
** 01/19/95
**
** FURTHER modifications to enable shadow passwd support (kludged, but
** no more so than the original) by Dan Crowson - dcrowson@mo.net
**
** Search on DAN for all changes...
**
*****
**
** cc -O -o adduser adduser.c
** Use gcc if you have it... (political reasons beyond my control) (chris)
**
** I've gotten this program to work with success under Linux (without
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
** on any system that uses no shadow. (chris)
**
** If you have no crypt() then try
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
** I'm not sure how login operates with no crypt()... I guess
** the same way we're doing it here.
*/
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/stat.h>
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
#define DEFAULT_HOME "/home"
#define USERADD_PATH "/usr/sbin/useradd"
#define CHAGE_PATH "/usr/sbin/chage"
#define PASSWD_PATH "/usr/bin/passwd"
#define DEFAULT_GROUP 100
#define DEFAULT_MAX_PASS 60
#define DEFAULT_WARN_PASS 10
/* if you use this feature, you will get a lot of complaints from users
who rarely use their accounts :) (something like 3 months would be
more reasonable) --marekm */
#define DEFAULT_USER_DIE /* 10 */ 0
void main()
{
char foo[32];
char uname[9],person[32],dir[32],shell[32];
unsigned int group,min_pass,max_pass,warn_pass,user_die;
/* the group and uid of the new user */
int bad=0,done=0,correct=0,gets_warning=0;
char cmd[255];
struct group *grp;
/* flags, in order:
* bad to see if the username is in /etc/passwd, or if strange stuff has
* been typed if the user might be put in group 0
* done allows the program to exit when a user has been added
* correct loops until a password is found that isn't in /etc/passwd
* gets_warning allows the fflush to be skipped for the first gets
* so that output is still legible
*/
/* The real program starts HERE! */
if(geteuid()!=0)
{
printf("It seems you don't have access to add a new user. Try\n");
printf("logging in as root or su root to gain super-user access.\n");
exit(1);
}
/* Sanity checks
*/
if (!(grp=getgrgid(DEFAULT_GROUP))){
printf("Error: the default group %d does not exist on this system!\n",
DEFAULT_GROUP);
printf("adduser must be recompiled.\n");
exit(1);
};
while(!correct) { /* loop until a "good" uname is chosen */
while(!done) {
printf("\nLogin to add (^C to quit): ");
if(gets_warning) /* if the warning was already shown */
fflush(stdout); /* fflush stdout, otherwise set the flag */
else
gets_warning=1;
gets(uname);
if(!strlen(uname)) {
printf("Empty input.\n");
done=0;
continue;
};
/* what I saw here before made me think maybe I was running DOS */
/* might this be a solution? (chris) */
if (getpwnam(uname) != NULL) {
printf("That name is in use, choose another.\n");
done=0;
} else
done=1;
}; /* done, we have a valid new user name */
/* all set, get the rest of the stuff */
printf("\nEditing information for new user [%s]\n",uname);
printf("\nFull Name [%s]: ",uname);
gets(person);
if (!strlen(person)) {
bzero(person,sizeof(person));
strcpy(person,uname);
};
do {
bad=0;
printf("GID [%d]: ",DEFAULT_GROUP);
gets(foo);
if (!strlen(foo))
group=DEFAULT_GROUP;
else
if (isdigit (*foo)) {
group = atoi(foo);
if (! (grp = getgrgid (group))) {
printf("unknown gid %s\n",foo);
group=DEFAULT_GROUP;
bad=1;
};
} else
if ((grp = getgrnam (foo)))
group = grp->gr_gid;
else {
printf("unknown group %s\n",foo);
group=DEFAULT_GROUP;
bad=1;
}
if (group==0){ /* You're not allowed to make root group users! */
printf("Creation of root group users not allowed (must be done by hand)\n");
group=DEFAULT_GROUP;
bad=1;
};
} while(bad);
fflush(stdin);
printf("\nIf home dir ends with a / then [%s] will be appended to it\n",uname);
printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname);
fflush(stdout);
gets(dir);
if (!strlen(dir)) { /* hit return */
sprintf(dir,"%s/%s",DEFAULT_HOME,uname);
fflush(stdin);
} else
if (dir[strlen(dir)-1]=='/')
sprintf(dir+strlen(dir),"%s",uname);
printf("\nShell [%s]: ",DEFAULT_SHELL);
fflush(stdout);
gets(shell);
if (!strlen(shell))
sprintf(shell,"%s",DEFAULT_SHELL);
printf("\nMin. Password Change Days [0]: ");
gets(foo);
min_pass=atoi(foo);
printf("Max. Password Change Days [%d]: ",DEFAULT_MAX_PASS);
gets(foo);
if (strlen(foo) > 1)
max_pass = atoi(foo);
else
max_pass = DEFAULT_MAX_PASS;
printf("Password Warning Days [%d]: ",DEFAULT_WARN_PASS);
gets(foo);
warn_pass = atoi(foo);
if (warn_pass==0)
warn_pass = DEFAULT_WARN_PASS;
printf("Days after Password Expiry for Account Locking [%d]: ",DEFAULT_USER_DIE);
gets(foo);
user_die = atoi(foo);
if (user_die == 0)
user_die = DEFAULT_USER_DIE;
printf("\nInformation for new user [%s] [%s]:\n",uname,person);
printf("Home directory: [%s] Shell: [%s]\n",dir,shell);
printf("GID: [%d]\n",group);
printf("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
min_pass,max_pass,warn_pass,user_die);
printf("\nIs this correct? [y/N]: ");
fflush(stdout);
gets(foo);
done=bad=correct=(foo[0]=='y'||foo[0]=='Y');
if(bad!=1)
printf("\nUser [%s] not added\n",uname);
}
bzero(cmd,sizeof(cmd));
sprintf(cmd,"%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
USERADD_PATH,group,dir,shell,person,uname);
printf("Calling useradd to add new user:\n%s\n",cmd);
if(system(cmd)){
printf("User add failed!\n");
exit(errno);
};
bzero(cmd,sizeof(cmd));
sprintf(cmd,"%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
min_pass,max_pass,warn_pass,user_die,uname);
printf("%s\n",cmd);
if(system(cmd)){
printf("There was an error setting password expire values\n");
exit(errno);
};
bzero(cmd,sizeof(cmd));
sprintf(cmd,"%s %s",PASSWD_PATH,uname);
system(cmd);
printf("\nDone.\n");
}

View File

@@ -60,7 +60,7 @@
** Added in the password date field, which should always reflect the last
** date the password was changed, for expiry purposes. "passwd" always
** updates this field, so the adduser program should set it up right
** initially (or a user could keep thier initial password forever ;)
** initially (or a user could keep their initial password forever ;)
** The number is in days since Jan 1st, 1970.
**
** Have fun with it, and someone please make
@@ -489,7 +489,7 @@ safeget (char *buf, int maxlen)
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
{
bad = (!isalnum (c) && (c != '_') && (c != ' '));
*(buf++) = (char) c;
*(buf++) = c;
}
*buf = '\0';

View File

@@ -1,85 +0,0 @@
#!/usr/bin/perl
#
# Copyright (c) 1996 Brian R. Gaeke
# 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. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Brian R. Gaeke.
# 4. The name of the author, Brian R. Gaeke, may not be used to endorse
# or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY BRIAN R. GAEKE ``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 BRIAN R. GAEKE 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.
#
# Additionally:
#
# This software is provided without support and without any obligation
# on the part of Brian R. Gaeke to assist in its use, correction,
# modification or enhancement.
#
#######################################################################
#
# this is atudel, version 2, by Brian R. Gaeke <brg@dgate.org>
#
require "getopts.pl";
&Getopts('v');
$username = shift(@ARGV);
&usage unless $username;
sub usage
{
print STDERR "atudel - remove all at jobs owned by a user\n";
print STDERR "usage: $0 [-v] username\n";
exit(1);
}
# odd. unless getpwnam($uname) doesn't seem to work for $uname eq "root" on
# my linux system. but this does.
die "user $username does not exist; stopping"
unless defined(getpwnam($username));
print "searching for at jobs owned by user $username ..." if $opt_v;
chdir "/var/spool/atjobs" ||
die "can't chdir to /var/spool/atjobs: $!\nstopping";
opendir(DIR,".") || die "can't opendir(/var/spool/atjobs): $!\nstopping";
@files = grep(!/^\./,grep(-f,readdir(DIR)));
closedir DIR;
foreach $x (@files)
{
$owner = (getpwuid((stat($x))[4]))[0];
push(@nuke_bait,$x) if $owner eq $username;
}
if (@nuke_bait)
{
print "removed jobIDs: @{nuke_bait}.\n" if $opt_v;
unlink @nuke_bait;
}
elsif ($opt_v)
{
print "\n";
}
exit 0;

View File

@@ -1,546 +0,0 @@
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2000-05-25 14:41 CDT by <gk4@gnu.austin.ibm.com>.
# Source directory was `/home/gk4/src/groupmem'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 1960 -rw-r--r-- Makefile
# 6348 -rw-r--r-- groupmems.c
# 3372 -rw------- groupmems.8
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
shar_touch='touch -am $3$4$5$6$2 "$8"'
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
if mkdir _sh10937; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
$echo 'x -' extracting 'Makefile' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
/*
# Copyright 2000, International Business Machines, Inc.
# All rights reserved.
#
# original author: George Kraft IV, gk4@us.ibm.com
#
# 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. Neither the name of International Business Machines, Inc., nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. 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
# INTERNATIONAL BUSINESS MACHINES, INC. 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.
#
X
all: groupmems
X
groupmems: groupmems.c
X cc -g -o groupmems groupmems.c -L. -lshadow
X
install: groupmems
X -/usr/sbin/groupadd groups
X install -o root -g groups -m 4770 groupmems /usr/bin
X
install.man: groupmems.8
X install -o root -g root -m 644 groupmems.8 /usr/man/man8
X
SHAR_EOF
(set 20 00 05 25 14 40 28 'Makefile'; eval "$shar_touch") &&
chmod 0644 'Makefile' ||
$echo 'restore of' 'Makefile' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'Makefile:' 'MD5 check failed'
b46cf7ef8d59149093c011ced3f3103c Makefile
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
test 1960 -eq "$shar_count" ||
$echo 'Makefile:' 'original size' '1960,' 'current size' "$shar_count!"
fi
fi
# ============= groupmems.c ==============
if test -f 'groupmems.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'groupmems.c' '(file already exists)'
else
$echo 'x -' extracting 'groupmems.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' &&
/*
X * Copyright 2000, International Business Machines, Inc.
X * All rights reserved.
X *
X * original author: George Kraft IV, gk4@us.ibm.com
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. Neither the name of International Business Machines, Inc., nor the
X * names of its contributors may be used to endorse or promote products
X * derived from this software without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
X * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
X * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
X * INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
/*
**
** Utility "groupmem" adds and deletes members from a user's group.
**
** Setup (as "root"):
**
** groupadd -r groups
** chmod 2770 groupmems
** chown root.groups groupmems
** groupmems -g groups -a gk4
**
** Usage (as "gk4"):
**
** groupmems -a olive
** groupmems -a jordan
** groupmems -a meghan
** groupmems -a morgan
** groupmems -a jake
** groupmems -l
** groupmems -d jake
** groupmems -l
*/
X
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "defines.h"
#include "groupio.h"
X
/* Exit Status Values */
X
#define EXIT_SUCCESS 0 /* success */
#define EXIT_USAGE 1 /* invalid command syntax */
#define EXIT_GROUP_FILE 2 /* group file access problems */
#define EXIT_NOT_ROOT 3 /* not superuser */
#define EXIT_NOT_EROOT 4 /* not effective superuser */
#define EXIT_NOT_PRIMARY 5 /* not primary owner of group */
#define EXIT_NOT_MEMBER 6 /* member of group does not exist */
#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */
X
#define TRUE 1
#define FALSE 0
X
/* Globals */
X
extern int optind;
extern char *optarg;
static char *adduser = NULL;
static char *deluser = NULL;
static char *thisgroup = NULL;
static int purge = FALSE;
static int list = FALSE;
static int exclusive = 0;
X
static int isroot(void) {
X return getuid() ? FALSE : TRUE;
}
X
static int isgroup(void) {
X gid_t g = getgid();
X struct group *grp = getgrgid(g);
X
X return TRUE;
}
X
static char *whoami(void) {
X struct group *grp = getgrgid(getgid());
X struct passwd *usr = getpwuid(getuid());
X
X if (0 == strcmp(usr->pw_name, grp->gr_name)) {
X return (char *)strdup(usr->pw_name);
X } else {
X return NULL;
X }
}
X
static void
addtogroup(char *user, char **members) {
X int i;
X char **pmembers;
X
X for (i = 0; NULL != members[i]; i++ ) {
X if (0 == strcmp(user, members[i])) {
X fprintf(stderr, "Member already exists\n");
X exit(EXIT_MEMBER_EXISTS);
X }
X }
X
X if (0 == i) {
X pmembers = (char **)calloc(2, sizeof(char *));
X } else {
X pmembers = (char **)realloc(members, sizeof(char *)*(i+1));
X }
X
X *members = *pmembers;
X members[i] = user;
X members[i+1] = NULL;
}
X
static void
rmfromgroup(char *user, char **members) {
X int i;
X int found = FALSE;
X
X i = 0;
X while (!found && NULL != members[i]) {
X if (0 == strcmp(user, members[i])) {
X found = TRUE;
X } else {
X i++;
X }
X }
X
X while (found && NULL != members[i]) {
X members[i] = members[++i];
X }
X
X if (!found) {
X fprintf(stderr, "Member to remove could not be found\n");
X exit(EXIT_NOT_MEMBER);
X }
}
X
static void
nomembers(char **members) {
X int i;
X
X for (i = 0; NULL != members[i]; i++ ) {
X members[i] = NULL;
X }
}
X
static void
members(char **members) {
X int i;
X
X for (i = 0; NULL != members[i]; i++ ) {
X printf("%s ", members[i]);
X
X if (NULL == members[i+1]) {
X printf("\n");
X } else {
X printf(" ");
X }
X }
}
X
static void usage(void) {
X fprintf(stderr, "usage: groupmems -a username | -d username | -D | -l [-g groupname]\n");
X exit(EXIT_USAGE);
}
X
main(int argc, char **argv) {
X int arg, i;
X char *name;
X struct group *grp;
X
X while ((arg = getopt(argc, argv, "a:d:g:Dl")) != EOF) {
X switch (arg) {
X case 'a':
X adduser = strdup(optarg);
X ++exclusive;
X break;
X case 'd':
X deluser = strdup(optarg);
X ++exclusive;
X break;
X case 'g':
X thisgroup = strdup(optarg);
X break;
X case 'D':
X purge = TRUE;
X ++exclusive;
X break;
X case 'l':
X list = TRUE;
X ++exclusive;
X break;
X default:
X usage();
X }
X }
X
X if (exclusive > 1 || optind < argc) {
X usage();
X }
X
X if (!isroot() && NULL != thisgroup) {
X fprintf(stderr, "Only root can add members to different groups\n");
X exit(EXIT_NOT_ROOT);
X } else if (isroot() && NULL != thisgroup) {
X name = thisgroup;
X } else if (!isgroup()) {
X fprintf(stderr, "Group access is required\n");
X exit(EXIT_NOT_EROOT);
X } else if (NULL == (name = whoami())) {
X fprintf(stderr, "Not primary owner of current group\n");
X exit(EXIT_NOT_PRIMARY);
X }
X
X if (!gr_lock()) {
X fprintf(stderr, "Unable to lock group file\n");
X exit(EXIT_GROUP_FILE);
X }
X
X if (!gr_open(O_RDWR)) {
X fprintf(stderr, "Unable to open group file\n");
X exit(EXIT_GROUP_FILE);
X }
X
X grp = (struct group *)gr_locate(name);
X
X if (NULL != adduser) {
X addtogroup(adduser, grp->gr_mem);
X gr_update(grp);
X } else if (NULL != deluser) {
X rmfromgroup(deluser, grp->gr_mem);
X gr_update(grp);
X } else if (purge) {
X nomembers(grp->gr_mem);
X gr_update(grp);
X } else if (list) {
X members(grp->gr_mem);
X }
X
X if (!gr_close()) {
X fprintf(stderr, "Cannot close group file\n");
X exit(EXIT_GROUP_FILE);
X }
X
X gr_unlock();
X
X exit(EXIT_SUCCESS);
}
X
/* EOF */
SHAR_EOF
(set 20 00 05 25 14 36 38 'groupmems.c'; eval "$shar_touch") &&
chmod 0644 'groupmems.c' ||
$echo 'restore of' 'groupmems.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'groupmems.c:' 'MD5 check failed'
f0dd68f8d762d89d24d3ce1f4141f981 groupmems.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.c'`"
test 6348 -eq "$shar_count" ||
$echo 'groupmems.c:' 'original size' '6348,' 'current size' "$shar_count!"
fi
fi
# ============= groupmems.8 ==============
if test -f 'groupmems.8' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'groupmems.8' '(file already exists)'
else
$echo 'x -' extracting 'groupmems.8' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' &&
X.\"
X.\" Copyright 2000, International Business Machines, Inc.
X.\" All rights reserved.
X.\"
X.\" original author: George Kraft IV, gk4@us.ibm.com
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\"
X.\" 1. Redistributions of source code must retain the above copyright
X.\" notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\" notice, this list of conditions and the following disclaimer in the
X.\" documentation and/or other materials provided with the distribution.
X.\" 3. Neither the name of International Business Machines, Inc., nor the
X.\" names of its contributors may be used to endorse or promote products
X.\" derived from this software without specific prior written permission.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
X.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
X.\" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
X.\" INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.\" $Id$
X.\"
X.TH GROUPMEMS 8
X.SH NAME
groupmems \- Administer members of a user's primary group
X.SH SYNOPSIS
X.B groupmems
\fB-a\fI user_name \fR |
\fB-d\fI user_name \fR |
\fB-l\fR |
\fB-D\fR |
[\fB-g\fI group_name \fR]
X.SH DESCRIPTION
The \fBgroupmems\fR utility allows a user to administer their own
group membership list without the requirement of superuser privileges.
The \fBgroupmems\fR utility is for systems that configure its users to
be in their own name sake primary group (i.e., guest / guest).
X.P
Only the superuser, as administrator, can use \fBgroupmems\fR to alter
the memberships of other groups.
X.IP "\fB-a \fIuser_name\fR"
Add a new user to the group membership list.
X.IP "\fB-d \fIuser_name\fR"
Delete a user from the group membership list.
X.IP "\fB-l\fR"
List the group membership list.
X.IP "\fB-D\fR"
Delete all users from the group membership list.
X.IP "\fB-g \fIgroup_name\fR"
The superuser can specify which group membership list to modify.
X.SH SETUP
The \fBgroupmems\fR executable should be in mode \fB2770\fR as user \fBroot\fR
and in group \fBgroups\fR. The system administrator can add users to
group groups to allow or disallow them using the \fBgroupmems\fR utility
to manager their own group membership list.
X.P
X $ groupadd -r groups
X.br
X $ chmod 2770 groupmems
X.br
X $ chown root.groups groupmems
X.br
X $ groupmems -g groups -a gk4
X.SH FILES
/etc/group
X.br
/etc/gshadow
X.SH SEE ALSO
X.BR chfn (1),
X.BR chsh (1),
X.BR useradd (8),
X.BR userdel (8),
X.BR usermod (8),
X.BR passwd (1),
X.BR groupadd (8),
X.BR groupdel (8)
X.SH AUTHOR
George Kraft IV (gk4@us.ibm.com)
X.\" EOF
SHAR_EOF
(set 20 00 05 25 14 38 23 'groupmems.8'; eval "$shar_touch") &&
chmod 0600 'groupmems.8' ||
$echo 'restore of' 'groupmems.8' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'groupmems.8:' 'MD5 check failed'
181e6cd3a3c9d3df320197fa2cde2b4a groupmems.8
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.8'`"
test 3372 -eq "$shar_count" ||
$echo 'groupmems.8:' 'original size' '3372,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh10937
exit 0

View File

@@ -1,308 +0,0 @@
/*
* pwdauth.c - program to verify a given username/password pair.
*
* Run it with username in argv[1] (may be omitted - default is the
* current user), and send it the password over a pipe on stdin.
* Exit status: 0 - correct password, 1 - wrong password, >1 - other
* errors. For use with shadow passwords, this program should be
* installed setuid root.
*
* This can be used, for example, by xlock - you don't have to install
* this large and complex (== possibly insecure) program setuid root,
* just modify it to run this simple program to do the authentication.
*
* Recent versions (xlockmore-3.9) are cleaner, and drop privileges as
* soon as possible after getting the user's encrypted password.
* Using this program probably doesn't make it more secure, and has one
* disadvantage: since we don't get the encrypted user's password at
* startup (but at the time the user is authenticated), it is not clear
* how we should handle errors (like getpwnam() returning NULL).
* - fail the authentication? Problem: no way to unlock (other than kill
* the process from somewhere else) if the NIS server stops responding.
* - succeed and unlock? Problem: it's too easy to unlock by unplugging
* the box from the network and waiting until NIS times out...
*
* This program is Copyright (C) 1996 Marek Michalkiewicz
* <marekm@i17linuxb.ists.pwr.wroc.pl>.
*
* It may be used and distributed freely for any purposes. There is no
* warranty - use at your own risk. I am not liable for any damages etc.
* If you improve it, please send me your changes.
*/
static char rcsid[] = "$Id$";
/*
* Define USE_SYSLOG to use syslog() to log successful and failed
* authentication. This should be safe even if your system has
* the infamous syslog buffer overrun security problem...
*/
#define USE_SYSLOG
/*
* Define HAVE_GETSPNAM to get shadow passwords using getspnam().
* Some systems don't have getspnam(), but getpwnam() returns
* encrypted passwords only if running as root.
*
* According to the xlock source (not tested, except Linux) -
* define: Linux, Solaris 2.x, SVR4, ...
* undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX.
* Known not supported (yet): Ultrix, OSF/1, SCO.
*/
#define HAVE_GETSPNAM
/*
* Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt().
* pw_encrypt() is like the standard crypt(), except that it may
* support better password hashing algorithms.
*
* Define if linking with libshadow.a from the shadow password
* suite (Linux, SunOS 4.x?).
*/
#undef HAVE_PW_ENCRYPT
/*
* Define HAVE_AUTH_METHODS to support the shadow suite specific
* extension: the encrypted password field contains a list of
* administrator defined authentication methods, separated by
* semicolons. This program only supports the standard password
* authentication method (a string that doesn't start with '@').
*/
#undef HAVE_AUTH_METHODS
/*
* FAIL_DELAY - number of seconds to sleep before exiting if the
* password was wrong, to slow down password guessing attempts.
*/
#define FAIL_DELAY 2
/* No user-serviceable parts below :-). */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pwd.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#ifndef LOG_AUTHPRIV
#define LOG_AUTHPRIV LOG_AUTH
#endif
#endif
#ifdef HAVE_GETSPNAM
#include <shadow.h>
#endif
#ifdef HAVE_PW_ENCRYPT
extern char *pw_encrypt();
#define crypt pw_encrypt
#endif
/*
* Read the password (one line) from fp. We don't turn off echo
* because we expect input from a pipe.
*/
static char *
get_line(fp)
FILE *fp;
{
static char buf[128];
char *cp;
int ch;
cp = buf;
while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') {
if (cp >= buf + sizeof buf - 1)
break;
*cp++ = ch;
}
*cp = '\0';
return buf;
}
/*
* Get the password file entry for the current user. If the name
* returned by getlogin() is correct (matches the current real uid),
* return the entry for that user. Otherwise, return the entry (if
* any) matching the current real uid. Return NULL on failure.
*/
static struct passwd *
get_my_pwent()
{
uid_t uid = getuid();
char *name = getlogin();
if (name && *name) {
struct passwd *pw = getpwnam(name);
if (pw && pw->pw_uid == uid)
return pw;
}
return getpwuid(uid);
}
/*
* Verify the password. The system-dependent shadow support is here.
*/
static int
password_auth_ok(pw, pass)
const struct passwd *pw;
const char *pass;
{
int result;
char *cp;
#ifdef HAVE_AUTH_METHODS
char *buf;
#endif
#ifdef HAVE_GETSPNAM
struct spwd *sp;
#endif
if (pw) {
#ifdef HAVE_GETSPNAM
sp = getspnam(pw->pw_name);
if (sp)
cp = sp->sp_pwdp;
else
#endif
cp = pw->pw_passwd;
} else
cp = "xx";
#ifdef HAVE_AUTH_METHODS
buf = strdup(cp); /* will be modified by strtok() */
if (!buf) {
fprintf(stderr, "Out of memory.\n");
exit(13);
}
cp = strtok(buf, ";");
while (cp && *cp == '@')
cp = strtok(NULL, ";");
/* fail if no password authentication for this user */
if (!cp)
cp = "xx";
#endif
if (*pass || *cp)
result = (strcmp(crypt(pass, cp), cp) == 0);
else
result = 1; /* user with no password */
#ifdef HAVE_AUTH_METHODS
free(buf);
#endif
return result;
}
/*
* Main program.
*/
int
main(argc, argv)
int argc;
char **argv;
{
struct passwd *pw;
char *pass, *name;
char myname[32];
#ifdef USE_SYSLOG
openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
#endif
pw = get_my_pwent();
if (!pw) {
#ifdef USE_SYSLOG
syslog(LOG_ERR, "can't get login name for uid %d.\n",
(int) getuid());
#endif
fprintf(stderr, "Who are you?\n");
exit(2);
}
strncpy(myname, pw->pw_name, sizeof myname - 1);
myname[sizeof myname - 1] = '\0';
name = myname;
if (argc > 1) {
name = argv[1];
pw = getpwnam(name);
}
pass = get_line(stdin);
if (password_auth_ok(pw, pass)) {
#ifdef USE_SYSLOG
syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE,
"user `%s' entered correct password for `%.32s'.\n",
myname, name);
#endif
exit(0);
}
#ifdef USE_SYSLOG
/* be careful not to overrun the syslog buffer */
syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING,
"user `%s' entered incorrect password for `%.32s'.\n",
myname, name);
#endif
#ifdef FAIL_DELAY
sleep(FAIL_DELAY);
#endif
fprintf(stderr, "Wrong password.\n");
exit(1);
}
#if 0
/*
* You can use code similar to the following to run this program.
* Return values: >=0 - program exit status (use the <sys/wait.h>
* macros to get the exit code, it is shifted left by 8 bits),
* -1 - check errno.
*/
int
verify_password(const char *username, const char *password)
{
int pipe_fd[2];
int pid, wpid, status;
if (pipe(pipe_fd))
return -1;
if ((pid = fork()) == 0) {
char *arg[3];
char *env[1];
/* child */
close(pipe_fd[1]);
if (pipe_fd[0] != 0) {
if (dup2(pipe_fd[0], 0) != 0)
_exit(127);
close(pipe_fd[0]);
}
arg[0] = "/usr/bin/pwdauth";
arg[1] = username;
arg[2] = NULL;
env[0] = NULL;
execve(arg[0], arg, env);
_exit(127);
} else if (pid == -1) {
/* error */
close(pipe_fd[0]);
close(pipe_fd[1]);
return -1;
}
/* parent */
close(pipe_fd[0]);
write(pipe_fd[1], password, strlen(password));
write(pipe_fd[1], "\n", 1);
close(pipe_fd[1]);
while ((wpid = wait(&status)) != pid) {
if (wpid == -1)
return -1;
}
return status;
}
#endif

View File

@@ -1,147 +0,0 @@
Hello Marek,
I have created a diffile against the 980403 release that adds
functionality to newusers for automatic handling of users with only
anonymous ftp login (using the guestgroup feature in ftpaccess, which
means that the users home directory looks like '/home/user/./'). It also
adds a commandline argument to specify an initial directory structure
for such users, with a tarball normally containing the bin,lib,etc
directories used in the chrooted environment.
I am using it to automatically create chunks of users with only ftp
access for a webserver.
I have tried to follow your coding standards and I believe it is bug
free but.. well, who knows. :) It's not much code however.
I hope you find it useful. Do what you like with it, feel free to ask if
anything is unclear.
Best rgds,
Calle Karlsson
ckn@kash.se
diff -uNr shadow-980403.orig/src/newusers.c shadow-980403/src/newusers.c
--- shadow-980403.orig/src/newusers.c Fri Jan 30 00:22:43 1998
+++ shadow-980403/src/newusers.c Fri Apr 17 16:55:33 1998
@@ -76,11 +76,35 @@
static void
usage(void)
{
- fprintf(stderr, "Usage: %s [ input ]\n", Prog);
+ fprintf (stderr, "Usage: %s [-p prototype tarfile] [ input ]\n", Prog);
+ fprintf (stderr, "The prototype tarfile is only used for users\n");
+ fprintf (stderr, "marked as anonymous ftp users. It must be a full pathname.\n");
exit(1);
}
/*
+ * createuserdir - create a directory and chmod it
+ */
+
+static int
+createuserdir (char * dir, int uid, int gid, int line)
+{
+ if (mkdir (dir, 0777 & ~getdef_num("UMASK", 077))) {
+ fprintf (stderr, "%s: line %d: mkdir %s failed\n",
+ Prog, line, dir);
+ return -1;
+ }
+
+ if (chown (dir, uid, gid)) {
+ fprintf (stderr, "%s: line %d: chown %s failed\n",
+ Prog, line, dir);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
* add_group - create a new group or add a user to an existing group
*/
@@ -328,6 +352,8 @@
main(int argc, char **argv)
{
char buf[BUFSIZ];
+ char anonproto[BUFSIZ];
+ int flag;
char *fields[8];
int nfields;
char *cp;
@@ -340,12 +366,23 @@
Prog = Basename(argv[0]);
- if (argc > 1 && argv[1][0] == '-')
- usage ();
+ * anonproto = '\0';
+
+ while ((flag = getopt (argc, argv, "p:h")) != EOF) {
+ switch (flag) {
+ case 'p':
+ STRFCPY(anonproto, optarg);
+ break;
+ case 'h':
+ default:
+ usage ();
+ break;
+ }
+ }
- if (argc == 2) {
- if (! freopen (argv[1], "r", stdin)) {
- snprintf(buf, sizeof buf, "%s: %s", Prog, argv[1]);
+ if (optind < argc) {
+ if (! freopen (argv[optind], "r", stdin)) {
+ snprintf(buf, sizeof buf, "%s: %s", Prog, argv[optind]);
perror (buf);
exit (1);
}
@@ -499,15 +536,36 @@
if (fields[6][0])
newpw.pw_shell = fields[6];
- if (newpw.pw_dir[0] && access(newpw.pw_dir, F_OK)) {
- if (mkdir (newpw.pw_dir,
- 0777 & ~getdef_num("UMASK", 077)))
- fprintf (stderr, "%s: line %d: mkdir failed\n",
- Prog, line);
- else if (chown (newpw.pw_dir,
- newpw.pw_uid, newpw.pw_gid))
- fprintf (stderr, "%s: line %d: chown failed\n",
- Prog, line);
+ if (newpw.pw_dir[0]) {
+ char * userdir = strdup (newpw.pw_dir);
+ char * anonpart;
+ int rc;
+
+ if ((anonpart = strstr (userdir, "/./"))) {
+ * anonpart = '\0';
+ anonpart += 2;
+ }
+
+ if (access(userdir, F_OK))
+ rc = createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line);
+ else
+ rc = 0;
+
+ if (rc == 0 && anonpart) {
+ if (* anonproto) {
+ char cmdbuf [BUFSIZ];
+ snprintf(cmdbuf, sizeof cmdbuf,
+ "cd %s; tar xf %s",
+ userdir, anonproto);
+ system (cmdbuf);
+ }
+ if (strlen (anonpart) > 1) {
+ strcat (userdir, anonpart);
+ if (access (userdir, F_OK))
+ createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line);
+ }
+ }
+ free (userdir);
}
/*

Binary file not shown.

View File

@@ -3,7 +3,7 @@
scriptversion=2018-03-07.03; # UTC
# Copyright (C) 1999-2018 Free Software Foundation, Inc.
# Copyright (C) 1999-2021 Free Software Foundation, Inc.
# 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

View File

@@ -1311,7 +1311,7 @@
This means that fred's password is valid, it was last changed on
03/04/96, it can be changed at any time, it expires after 60 days,
fred will not be warned, and and the account won't be disabled when
fred will not be warned, and the account won't be disabled when
the password expires.
This simply means that if fred logs in after the password expires, he
@@ -1487,7 +1487,7 @@
If a user logs into a line that is listed in /etc/dialups, and his
shell is listed in the file /etc/d_passwd he will be allowed access
only by suppling the correct password.
only by supplying the correct password.
Another useful purpose for using dial-up passwords might be to setup a
line that only allows a certain type of connect (perhaps a PPP or UUCP

View File

@@ -1,5 +1,4 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
EXTRA_DIST = HOWTO README.limits \
README.platforms WISHLIST console.c.spec.txt cracklib26.diff
EXTRA_DIST = HOWTO README.limits

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -92,7 +92,14 @@ build_triplet = @build@
host_triplet = @host@
subdir = doc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -134,8 +141,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -147,6 +158,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
@@ -164,9 +176,15 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBCRACK = @LIBCRACK@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
@@ -178,13 +196,21 @@ LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBSEMANAGE = @LIBSEMANAGE@
LIBSKEY = @LIBSKEY@
LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LIYESCRYPT = @LIYESCRYPT@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -207,6 +233,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
@@ -278,9 +307,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
EXTRA_DIST = HOWTO README.limits \
README.platforms WISHLIST console.c.spec.txt cracklib26.diff
EXTRA_DIST = HOWTO README.limits
all: all-am
.SUFFIXES:
@@ -325,7 +352,6 @@ ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am

View File

@@ -63,4 +63,3 @@ To completely disable limits for a user, a single dash (-) will do.
Also, please note that all limit settings are set PER LOGIN. They are
not global, nor are they permanent. Perhaps global limits will come, but
for now this will have to do ;)

View File

@@ -1,33 +0,0 @@
# $Id$
#
# This is the current (still incomplete) list of platforms this
# package has been verified to work on. Additions (preferably
# in the format as described below) are welcome. Thanks!
#
# V: last version reported to work
# H: host type
# L: Linux libc version
# D: Linux distribution, or other OS name and version
# C: changes (if any)
# R: reported by
V: 980529
H: sparc-unknown-linux-gnu
L: glibc-2.0.7
D: Ultrapenguin-1.0.9
C: had to explicitly disable desrpc.
R: Bjorn Christianson <bjorn@cascade.psychology.mcmaster.ca>
V: 980724
H: i486-pc-linux-gnulibc1
L: libc-5.4.33
D: Debian-1.3.1.r6
C: none (use dpkg-buildpackage)
R: Marek Michalkiewicz <marekm@linux.org.pl>
V: current
H: i686-pc-linux-gnu
L: glibc-2.0.7.19981211
D: Debian-2.1
C: none (use dpkg-buildpackage)
R: Marek Michalkiewicz <marekm@linux.org.pl>

View File

@@ -1,40 +0,0 @@
$Id$
This is my wishlist for the shadow suite, in no particular order. Feel
free to do anything from this list and mail me the diffs :-).
Patches in diff -u format, against the latest version (sometimes in the
"beta" directory) are preferred and make my job easier. Please, no
MIME, base64, quoted-printable, or HTML. For very big patches, or if
your mailer can corrupt them, please use gzip and uuencode. Thanks!
New ideas to add to this list are welcome, too. --marekm
- fix all the bugs, of course
- implement "su only" accounts (no logins, only su from other account)
- rewrite getdef.c to be more general? (no hardcoded names)
- patch for rlogind/telnetd to create utmp entry and fill in ut_addr
- option to specify encrypted password in passwd (for yppasswdd, so it
doesn't need to know about shadow/non-shadow); should probably use a pipe
(less insecure than command line arguments)
- add support for changing NIS passwords
- add option to check passwords by piping them to external programs
- add functionality of the contrib/rpasswd.c wrapper to passwd
- option to generate pronounceable passwords (like on SCO), external program?
- poppassd (remote password change for eudora etc.)
- add support for passwd/shadow db files (glibc)
- vipw: check password files for errors after editing
- add "maximum time users allowed to stay logged in" limit option to logoutd
- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
- better utmpx support (logoutd, ...)
- better OPIE support (report number of logins left, etc.)
- new option for /etc/suauth: don't load user's environment (force "su -")
suggested by Ulisses Alonso Camaro
- find out why recent releases won't compile on Solaris
- newusers should be able to copy /etc/skel to the new home directory
(like useradd)
- add directories where other packages can add hooks for package-specific
per-user configuration, to be executed with run-parts. Some hooks should
be executed at package install time for existing users, likewise for
package removal and possibly modification. (Debian Bug#36019)

View File

@@ -1,36 +0,0 @@
$Id$
Specification for console.c source file --
input values --
tty -- character pointer to device name with leading "/dev/"
removed.
return values --
0 -- false
1 -- true
int console (char * tty)
if "CONSOLE" string value is not present in login.defs
return true
if the first character of "CONSOLE" string value is not "/"
treat the string as a ":" delimited list of device
names and search for the value of tty in that
tokenized list.
if a match is found
return true
return false
if the file named by "CONSOLE" cannot be opened
return true
scan the file looking for a match between the input line
and the value of tty
if a match is found
return true
return false

View File

@@ -1,340 +0,0 @@
diff -ur orig/cracklib26_small/cracklib/fascist.c cracklib26_small/cracklib/fascist.c
--- orig/cracklib26_small/cracklib/fascist.c Mon Dec 15 02:56:55 1997
+++ cracklib26_small/cracklib/fascist.c Sat Apr 4 22:14:45 1998
@@ -12,6 +12,7 @@
#include <ctype.h>
#include <sys/types.h>
#include <pwd.h>
+#include <string.h>
#define ISSKIP(x) (isspace(x) || ispunct(x))
@@ -460,28 +461,27 @@
}
char *
-FascistGecos(password, uid)
+FascistGecosPw(password, pwd)
char *password;
- int uid;
+ struct passwd *pwd;
{
int i;
int j;
int wc;
char *ptr;
- struct passwd *pwp;
char gbuffer[STRINGSIZE];
char tbuffer[STRINGSIZE];
char *uwords[STRINGSIZE];
char longbuffer[STRINGSIZE * 2];
- if (!(pwp = getpwuid(uid)))
+ if (!pwd)
{
return ("you are not registered in the password file");
}
/* lets get really paranoid and assume a dangerously long gecos entry */
- strncpy(tbuffer, pwp->pw_name, STRINGSIZE);
+ strncpy(tbuffer, pwd->pw_name, STRINGSIZE);
tbuffer[STRINGSIZE-1] = '\0';
if (GTry(tbuffer, password))
{
@@ -490,12 +490,13 @@
/* it never used to be that you got passwd strings > 1024 chars, but now... */
- strncpy(tbuffer, pwp->pw_gecos, STRINGSIZE);
+ strncpy(tbuffer, pwd->pw_gecos, STRINGSIZE);
tbuffer[STRINGSIZE-1] = '\0';
strcpy(gbuffer, Lowercase(tbuffer));
wc = 0;
ptr = gbuffer;
+ uwords[0] = (char *) 0;
while (*ptr)
{
@@ -530,6 +531,8 @@
*(ptr++) = '\0';
}
}
+ if (!uwords[0])
+ return ((char *) 0); /* empty gecos */
#ifdef DEBUG
for (i = 0; uwords[i]; i++)
{
@@ -586,9 +589,10 @@
}
char *
-FascistLook(pwp, instring)
+FascistLookPw(pwp, instring, pwd)
PWDICT *pwp;
char *instring;
+ struct passwd *pwd;
{
int i;
char *ptr;
@@ -667,7 +671,7 @@
return ("it looks like a National Insurance number.");
}
- if (ptr = FascistGecos(password, getuid()))
+ if (ptr = FascistGecosPw(password, pwd ? pwd : getpwuid(getuid())))
{
return (ptr);
}
@@ -715,9 +719,10 @@
}
char *
-FascistCheck(password, path)
+FascistCheckPw(password, path, pwd)
char *password;
char *path;
+ struct passwd *pwd;
{
static char lastpath[STRINGSIZE];
static PWDICT *pwp;
@@ -750,5 +755,29 @@
strncpy(lastpath, path, STRINGSIZE);
}
- return (FascistLook(pwp, pwtrunced));
+ return (FascistLookPw(pwp, pwtrunced, pwd));
+}
+
+char *
+FascistGecos(password, uid)
+ char *password;
+ int uid;
+{
+ return (FascistGecosPw(password, getpwuid(uid)));
+}
+
+char *
+FascistLook(pwp, instring)
+ PWDICT *pwp;
+ char *instring;
+{
+ return (FascistLookPw(pwp, instring, (char *) 0));
+}
+
+char *
+FascistCheck(password, path)
+ char *password;
+ char *path;
+{
+ return (FascistCheckPw(password, path, (char *) 0));
}
diff -ur orig/cracklib26_small/cracklib/packer.h cracklib26_small/cracklib/packer.h
--- orig/cracklib26_small/cracklib/packer.h Mon Dec 15 00:09:30 1997
+++ cracklib26_small/cracklib/packer.h Sat Jan 10 22:13:46 1998
@@ -34,6 +34,7 @@
FILE *dfp;
FILE *wfp;
+ int canfree;
int32 flags;
#define PFOR_WRITE 0x0001
#define PFOR_FLUSH 0x0002
diff -ur orig/cracklib26_small/cracklib/packlib.c cracklib26_small/cracklib/packlib.c
--- orig/cracklib26_small/cracklib/packlib.c Fri Jul 9 22:22:58 1993
+++ cracklib26_small/cracklib/packlib.c Sat Jan 10 22:28:49 1998
@@ -16,7 +16,7 @@
char *mode;
{
int32 i;
- static PWDICT pdesc;
+ PWDICT *pdesc;
char iname[STRINGSIZE];
char dname[STRINGSIZE];
char wname[STRINGSIZE];
@@ -25,92 +25,94 @@
FILE *ifp;
FILE *wfp;
- if (pdesc.header.pih_magic == PIH_MAGIC)
- {
- fprintf(stderr, "%s: another dictionary already open\n", prefix);
+ if ((pdesc = (PWDICT *) malloc(sizeof(PWDICT))) == 0)
return ((PWDICT *) 0);
- }
- memset(&pdesc, '\0', sizeof(pdesc));
+ memset(pdesc, '\0', sizeof(*pdesc));
sprintf(iname, "%s.pwi", prefix);
sprintf(dname, "%s.pwd", prefix);
sprintf(wname, "%s.hwm", prefix);
- if (!(pdesc.dfp = fopen(dname, mode)))
+ if (!(pdesc->dfp = fopen(dname, mode)))
{
perror(dname);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (!(pdesc.ifp = fopen(iname, mode)))
+ if (!(pdesc->ifp = fopen(iname, mode)))
{
- fclose(pdesc.dfp);
+ fclose(pdesc->dfp);
perror(iname);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.wfp = fopen(wname, mode))
+ if (pdesc->wfp = fopen(wname, mode))
{
- pdesc.flags |= PFOR_USEHWMS;
+ pdesc->flags |= PFOR_USEHWMS;
}
- ifp = pdesc.ifp;
- dfp = pdesc.dfp;
- wfp = pdesc.wfp;
+ ifp = pdesc->ifp;
+ dfp = pdesc->dfp;
+ wfp = pdesc->wfp;
if (mode[0] == 'w')
{
- pdesc.flags |= PFOR_WRITE;
- pdesc.header.pih_magic = PIH_MAGIC;
- pdesc.header.pih_blocklen = NUMWORDS;
- pdesc.header.pih_numwords = 0;
+ pdesc->flags |= PFOR_WRITE;
+ pdesc->header.pih_magic = PIH_MAGIC;
+ pdesc->header.pih_blocklen = NUMWORDS;
+ pdesc->header.pih_numwords = 0;
- fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
+ fwrite((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp);
} else
{
- pdesc.flags &= ~PFOR_WRITE;
+ pdesc->flags &= ~PFOR_WRITE;
- if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
+ if (!fread((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp))
{
fprintf(stderr, "%s: error reading header\n", prefix);
- pdesc.header.pih_magic = 0;
+ pdesc->header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.header.pih_magic != PIH_MAGIC)
+ if (pdesc->header.pih_magic != PIH_MAGIC)
{
fprintf(stderr, "%s: magic mismatch\n", prefix);
- pdesc.header.pih_magic = 0;
+ pdesc->header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.header.pih_blocklen != NUMWORDS)
+ if (pdesc->header.pih_blocklen != NUMWORDS)
{
fprintf(stderr, "%s: size mismatch\n", prefix);
- pdesc.header.pih_magic = 0;
+ pdesc->header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.flags & PFOR_USEHWMS)
+ if (pdesc->flags & PFOR_USEHWMS)
{
- if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
+ if (fread(pdesc->hwms, 1, sizeof(pdesc->hwms), wfp) != sizeof(pdesc->hwms))
{
- pdesc.flags &= ~PFOR_USEHWMS;
+ pdesc->flags &= ~PFOR_USEHWMS;
}
}
}
-
- return (&pdesc);
+ pdesc->canfree = 1;
+ return (pdesc);
}
int
@@ -159,8 +161,13 @@
fclose(pwp->ifp);
fclose(pwp->dfp);
+ if (pwp->wfp)
+ fclose(pwp->wfp);
- pwp->header.pih_magic = 0;
+ if (pwp->canfree)
+ free(pwp);
+ else
+ pwp->header.pih_magic = 0;
return (0);
}
@@ -307,6 +314,11 @@
register char *this;
int idx;
+/*
+ * comment in npasswd-2.0beta4 says this:
+ * This does not work under all circumstances, so don't bother
+ */
+#if 0
if (pwp->flags & PFOR_USEHWMS)
{
idx = string[0] & 0xff;
@@ -317,6 +329,10 @@
lwm = 0;
hwm = PW_WORDS(pwp) - 1;
}
+#else
+ lwm = 0;
+ hwm = PW_WORDS(pwp);
+#endif
#ifdef DEBUG
printf("---- %lu, %lu ----\n", lwm, hwm);
diff -ur orig/cracklib26_small/util/mkdict cracklib26_small/util/mkdict
--- orig/cracklib26_small/util/mkdict Fri Jul 9 22:23:03 1993
+++ cracklib26_small/util/mkdict Sat Apr 4 22:31:45 1998
@@ -14,9 +14,16 @@
SORT="sort"
###SORT="sort -T /tmp"
-cat $* |
+### Use zcat to read compressed (as well as uncompressed) dictionaries.
+### Compressed dictionaries can save quite a lot of disk space.
+
+CAT="gzip -cdf"
+###CAT="zcat"
+###CAT="cat"
+
+$CAT $* |
tr '[A-Z]' '[a-z]' |
- tr -cd '[\012a-z0-9]' |
+ tr -cd '\012[a-z][0-9]' |
$SORT |
uniq |
grep -v '^#' |

View File

@@ -4,8 +4,7 @@
sysconf_DATA = login.defs
defaultdir = $(sysconfdir)/default
default_DATA = \
useradd
default_DATA =
nonpam_files = \
limits \
@@ -21,4 +20,4 @@ EXTRA_DIST = \
$(sysconf_DATA) \
$(default_DATA)
SUBDIRS = pam.d
SUBDIRS = pam.d shadow-maint

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -93,7 +93,14 @@ build_triplet = @build@
host_triplet = @host@
subdir = etc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -184,8 +191,6 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -225,8 +230,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -238,6 +247,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
@@ -255,9 +265,15 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBCRACK = @LIBCRACK@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
@@ -269,13 +285,21 @@ LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBSEMANAGE = @LIBSEMANAGE@
LIBSKEY = @LIBSKEY@
LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LIYESCRYPT = @LIYESCRYPT@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -298,6 +322,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
@@ -371,9 +398,7 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
sysconf_DATA = login.defs
defaultdir = $(sysconfdir)/default
default_DATA = \
useradd
default_DATA =
nonpam_files = \
limits \
login.access
@@ -385,7 +410,7 @@ EXTRA_DIST = \
$(sysconf_DATA) \
$(default_DATA)
SUBDIRS = pam.d
SUBDIRS = pam.d shadow-maint
all: all-recursive
.SUFFIXES:
@@ -586,7 +611,6 @@ cscopelist-am: $(am__tagged_files)
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am

View File

@@ -1,20 +1,20 @@
# $Id$
#
# Login access control table.
#
#
# When someone logs in, the table is scanned for the first entry that
# matches the (user, host) combination, or, in case of non-networked
# logins, the first entry that matches the (user, tty) combination. The
# permissions field of that table entry determines whether the login will
# permissions field of that table entry determines whether the login will
# be accepted or refused.
#
#
# Format of the login access control table is three fields separated by a
# ":" character:
#
#
# permission : users : origins
#
#
# The first field should be a "+" (access granted) or "-" (access denied)
# character.
# character.
#
# The second field should be a list of one or more login names, group
# names, or ALL (always matches). A pattern of the form user@host is
@@ -37,7 +37,7 @@
# listed: the program does not look at a user's primary group id value.
#
##############################################################################
#
#
# Disallow console logins to all but a few accounts.
#
#-:ALL EXCEPT wheel shutdown sync:console

View File

@@ -227,11 +227,6 @@ PASS_WARN_AGE 7
#
SU_WHEEL_ONLY no
#
# If compiled with cracklib support, sets the path to the dictionaries
#
CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict
#
# Min/max values for automatic uid selection in useradd(8)
#
@@ -295,7 +290,7 @@ CHFN_AUTH yes
# any combination of letters "frwh" (full name, room number, work
# phone, home phone). If not defined, no changes are allowed.
# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
#
#
CHFN_RESTRICT rwh
#
@@ -326,7 +321,9 @@ CHFN_RESTRICT rwh
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password
# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default)
# MD5 and DES should not be used for new hashes, see crypt(5) for recommendations.
# Overrides the MD5_CRYPT_ENAB option
#
# Note: If you use PAM, it is recommended to use a value consistent with
@@ -342,7 +339,8 @@ CHFN_RESTRICT rwh
# However, more CPU resources will be needed to authenticate users if
# this value is increased.
#
# If not specified, the libc will choose the default number of rounds (5000).
# If not specified, the libc will choose the default number of rounds (5000),
# which is orders of magnitude too low for modern hardware.
# The values must be within the 1000-999999999 range.
# If only one of the MIN or MAX values is set, then this value will be used.
# If MIN > MAX, the highest value will be used.
@@ -365,6 +363,19 @@ CHFN_RESTRICT rwh
#BCRYPT_MIN_ROUNDS 13
#BCRYPT_MAX_ROUNDS 13
#
# Only works if ENCRYPT_METHOD is set to YESCRYPT.
#
# Define the YESCRYPT cost factor.
# With a higher cost factor, it is more difficult to brute-force the password.
# However, more CPU time and more memory will be needed to authenticate users
# if this value is increased.
#
# If not specified, a cost factor of 5 will be used.
# The value must be within the 1-11 range.
#
#YESCRYPT_COST_FACTOR 5
#
# List of groups to add to the user's supplementary group set
# when logging in from the console (as determined by the CONSOLE
@@ -382,6 +393,14 @@ CHFN_RESTRICT rwh
#
DEFAULT_HOME yes
#
# The pwck(8) utility emits a warning for any system account with a home
# directory that does not exist. Some system accounts intentionally do
# not have a home directory. Such accounts may have this string as
# their home directory in /etc/passwd to avoid a spurious warning.
#
NONEXISTENT /nonexistent
#
# If this file exists and is readable, login environment will be
# read from it. Every line should be in the form name=value.
@@ -428,3 +447,27 @@ USERGROUPS_ENAB yes
# missing.
#
#FORCE_SHADOW yes
#
# Allow newuidmap and newgidmap when running under an alternative
# primary group.
#
#GRANT_AUX_GROUP_SUBIDS yes
#
# Prevents an empty password field to be interpreted as "no authentication
# required".
# Set to "yes" to prevent for all accounts
# Set to "superuser" to prevent for UID 0 / root (default)
# Set to "no" to not prevent for any account (dangerous, historical default)
PREVENT_NO_AUTH superuser
#
# Select the HMAC cryptography algorithm.
# Used in pam_timestamp module to calculate the keyed-hash message
# authentication code.
#
# Note: It is recommended to check hmac(3) to see the possible algorithms
# that are available in your system.
#
#HMAC_CRYPTO_ALGO SHA512

View File

@@ -2,20 +2,20 @@
# and also cooperate to make a distribution for `make dist'
pamd_files = \
chpasswd \
chfn \
chsh \
groupmems \
login \
newusers \
passwd
pamd_acct_tools_files = \
chage \
chgpasswd \
chpasswd \
groupadd \
groupdel \
groupmod \
newusers \
useradd \
userdel \
usermod

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.1 from Makefile.am.
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -95,7 +95,14 @@ host_triplet = @host@
@WITH_SU_TRUE@am__append_2 = su
subdir = etc/pam.d
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -166,8 +173,12 @@ AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
@@ -179,6 +190,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
@@ -196,9 +208,15 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBCRACK = @LIBCRACK@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
@@ -210,13 +228,21 @@ LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBSEMANAGE = @LIBSEMANAGE@
LIBSKEY = @LIBSKEY@
LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LIYESCRYPT = @LIYESCRYPT@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
@@ -239,6 +265,9 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
@@ -310,15 +339,14 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
pamd_files = chfn chsh groupmems login passwd $(am__append_2)
pamd_files = chpasswd chfn chsh groupmems login newusers passwd \
$(am__append_2)
pamd_acct_tools_files = \
chage \
chgpasswd \
chpasswd \
groupadd \
groupdel \
groupmod \
newusers \
useradd \
userdel \
usermod
@@ -391,7 +419,6 @@ ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am

View File

@@ -4,8 +4,8 @@ auth include system-auth
account required pam_nologin.so
account include system-auth
password include system-auth
session required pam_selinux.so close
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
session include system-auth
session required pam_loginuid.so
session optional pam_console.so
session required pam_selinux.so open
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open

View File

@@ -7,7 +7,7 @@ auth required pam_wheel.so use_uid
auth include system-auth
account include system-auth
password include system-auth
session required pam_selinux.so close
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
session include system-auth
session required pam_selinux.so open multiple
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
session optional pam_xauth.so

View File

@@ -0,0 +1,5 @@
shadowmaint_files = \
groupdel-pre.d/01-kill_group_procs.sh \
userdel-pre.d/01-kill_user_procs.sh
EXTRA_DIST = $(shadowmaint_files)

View File

@@ -0,0 +1,508 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = etc/shadow-maint
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
$(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
am__DIST_COMMON = $(srcdir)/Makefile.in
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CMOCKA_CFLAGS = @CMOCKA_CFLAGS@
CMOCKA_LIBS = @CMOCKA_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
ECONF_CPPFLAGS = @ECONF_CPPFLAGS@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
GROUP_NAME_MAX_LENGTH = @GROUP_NAME_MAX_LENGTH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBACL = @LIBACL@
LIBADD_DL = @LIBADD_DL@
LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
LIBADD_DLOPEN = @LIBADD_DLOPEN@
LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
LIBATTR = @LIBATTR@
LIBAUDIT = @LIBAUDIT@
LIBBSD = @LIBBSD@
LIBBSD_CFLAGS = @LIBBSD_CFLAGS@
LIBBSD_LIBS = @LIBBSD_LIBS@
LIBCRYPT = @LIBCRYPT@
LIBECONF = @LIBECONF@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBMD = @LIBMD@
LIBOBJS = @LIBOBJS@
LIBPAM = @LIBPAM@
LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBSEMANAGE = @LIBSEMANAGE@
LIBSKEY = @LIBSKEY@
LIBSUBID_ABI = @LIBSUBID_ABI@
LIBSUBID_ABI_MAJOR = @LIBSUBID_ABI_MAJOR@
LIBSUBID_ABI_MICRO = @LIBSUBID_ABI_MICRO@
LIBSUBID_ABI_MINOR = @LIBSUBID_ABI_MINOR@
LIBSYSTEMD = @LIBSYSTEMD@
LIBTCB = @LIBTCB@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LIYESCRYPT = @LIYESCRYPT@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
LTLIBOBJS = @LTLIBOBJS@
LT_DLLOADERS = @LT_DLLOADERS@
LT_DLPREOPEN = @LT_DLPREOPEN@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
POSUB = @POSUB@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
USE_NLS = @USE_NLS@
VENDORDIR = @VENDORDIR@
VERSION = @VERSION@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
capcmd = @capcmd@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
shadowmaint_files = \
groupdel-pre.d/01-kill_group_procs.sh \
userdel-pre.d/01-kill_user_procs.sh
EXTRA_DIST = $(shadowmaint_files)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign etc/shadow-maint/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign etc/shadow-maint/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
tags TAGS:
ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
cscopelist-am ctags-am distclean distclean-generic \
distclean-libtool distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am install-man \
install-pdf install-pdf-am install-ps install-ps-am \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags-am uninstall uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -0,0 +1,26 @@
#!/bin/sh
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
GROUPID=`awk -F: '$1 == "'"${SUBJECT}"'" { print $3 }' /etc/group`
if [ "${GROUPID}" = "" ]; then
exit 0
fi
for status in /proc/*/status; do
# either this isn't a process or its already dead since expanding the list
[ -f "$status" ] || continue
tbuf=${status%/status}
pid=${tbuf#/proc/}
case "$pid" in
"$$") continue;;
[0-9]*) :;;
*) continue
esac
grep -q '^Groups:.*\b'"${GROUPID}"'\b.*' "/proc/$pid/status" || continue
kill -9 "$pid" || echo "cannot kill $pid" 1>&2
done

View File

@@ -0,0 +1,31 @@
#!/bin/sh
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Check user exists, and if so, send sigkill to processes that the user owns
ps -eo user >/dev/null 2>&1
if [ $? -eq 0 ]; then
RUNNING=`ps -eo user | grep -Fx "$SUBJECT" | wc -l`
# if the user does not exist, RUNNING will be 0
if [ "${RUNNING}x" = "0x" ]; then
exit 0
fi
fi
# If there is no ps -eo, traverse the process directly.
ls -1 /proc | while IFS= read -r PROC; do
echo "$PROC" | grep -E '^[0-9]+$' >/dev/null
if [ $? -ne 0 ]; then
continue
fi
if [ -d "/proc/${PROC}" ]; then
USR=`stat -c "%U" /proc/${PROC}`
if [ "${USR}" = "${SUBJECT}" ]; then
echo "Killing ${SUBJECT} owned ${PROC}"
kill -9 "${PROC}"
fi
fi
done

View File

@@ -1,8 +0,0 @@
# useradd defaults file
GROUP=1000
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2018-03-11.20; # UTC
scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@ posix_mkdir=
# Desired mode of installed file.
mode=0755
# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22
backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
@@ -99,18 +104,28 @@ Options:
--version display version info and exit.
-c (ignored)
-C install only if different (preserve the last data modification time)
-C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-p pass -p to $cpprog.
-s $stripprog installed files.
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.
If -S is not specified, no backups are attempted.
Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
@@ -137,8 +152,13 @@ while test $# -ne 0; do
-o) chowncmd="$chownprog $2"
shift;;
-p) cpprog="$cpprog -p";;
-s) stripcmd=$stripprog;;
-S) backupsuffix="$2"
shift;;
-t)
is_target_a_directory=always
dst_arg=$2
@@ -255,6 +275,10 @@ do
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
# Don't chown directories that already exist.
if test $dstdir_status = 0; then
chowncmd=""
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -301,22 +325,6 @@ do
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# Create intermediate dirs using mode 755 as modified by the umask.
# This is like FreeBSD 'install' as of 1997-10-28.
umask=`umask`
case $stripcmd.$umask in
# Optimize common cases.
*[2367][2367]) mkdir_umask=$umask;;
.*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
*[0-7])
mkdir_umask=`expr $umask + 22 \
- $umask % 100 % 40 + $umask % 20 \
- $umask % 10 % 4 + $umask % 2
`;;
*) mkdir_umask=$umask,go-w;;
esac
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
@@ -326,52 +334,49 @@ do
fi
posix_mkdir=false
case $umask in
*[123567][0-7][0-7])
# POSIX mkdir -p sets u+wx bits regardless of umask, which
# is incompatible with FreeBSD 'install' when (umask & 300) != 0.
;;
*)
# Note that $RANDOM variable is not portable (e.g. dash); Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
# The $RANDOM variable is not portable (e.g., dash). Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
trap '
ret=$?
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
exit $ret
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p' feature.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac;;
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac
if
@@ -382,7 +387,7 @@ do
then :
else
# The umask is ridiculous, or mkdir does not conform to POSIX,
# mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
@@ -411,7 +416,7 @@ do
prefixes=
else
if $posix_mkdir; then
(umask=$mkdir_umask &&
(umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
@@ -451,7 +456,18 @@ do
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
@@ -477,6 +493,13 @@ do
then
rm -f "$dsttmp"
else
# If $backupsuffix is set, and the file being installed
# already exists, attempt a backup. Don't worry if it fails,
# e.g., if mv doesn't support -f.
if test -n "$backupsuffix" && test -f "$dst"; then
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
fi
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
@@ -491,9 +514,9 @@ do
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd -f "$dst" 2>/dev/null ||
$doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1

View File

@@ -1,54 +1,132 @@
AUTOMAKE_OPTIONS = 1.0 foreign
DEFS =
DEFS =
noinst_LTLIBRARIES = libshadow.la
libshadow_la_LDFLAGS = -version-info 0:0:0
if USE_PAM
LIBCRYPT_PAM = $(LIBCRYPT)
else
LIBCRYPT_PAM =
endif
AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) $(ECONF_CPPFLAGS)
libshadow_la_CPPFLAGS = $(ECONF_CPPFLAGS)
if HAVE_VENDORDIR
libshadow_la_CPPFLAGS += -DVENDORDIR=\"$(VENDORDIR)\"
endif
libshadow_la_CPPFLAGS += -I$(top_srcdir)
libshadow_la_CFLAGS = $(LIBBSD_CFLAGS) $(LIBCRYPT_PAM) $(LIBSYSTEMD)
libshadow_la_LIBADD = $(LIBADD_DLOPEN)
libshadow_la_SOURCES = \
addgrps.c \
adds.c \
adds.h \
age.c \
agetpass.c \
agetpass.h \
alloc.c \
alloc.h \
atoi/a2i.c \
atoi/a2i.h \
atoi/str2i.c \
atoi/str2i.h \
atoi/strtoi.c \
atoi/strtoi.h \
atoi/strtou_noneg.c \
atoi/strtou_noneg.h \
attr.h \
audit_help.c \
basename.c \
bit.c \
bit.h \
cast.h \
chkname.c \
chkname.h \
chowndir.c \
chowntty.c \
cleanup.c \
cleanup_group.c \
cleanup_user.c \
commonio.c \
commonio.h \
console.c \
copydir.c \
csrand.c \
defines.h \
encrypt.c \
env.c \
exitcodes.h \
faillog.h \
failure.c \
failure.h \
fd.c \
fields.c \
find_new_gid.c \
find_new_uid.c \
find_new_sub_gids.c \
find_new_sub_uids.c \
fputsx.c \
getdef.c \
getdef.h \
get_gid.c \
getlong.c \
get_pid.c \
get_uid.c \
getulong.c \
getdate.h \
getdate.y \
getdef.c \
getdef.h \
getgr_nam_gid.c \
getrange.c \
gettime.c \
groupio.c \
groupmem.c \
groupio.h \
gshadow.c \
hushed.c \
idmapping.h \
idmapping.c \
isexpired.c \
limits.c \
list.c \
lockpw.c \
loginprompt.c \
mail.c \
memzero.c \
memzero.h \
motd.c \
must_be.h \
myname.c \
nss.c \
nscd.c \
nscd.h \
sssd.c \
sssd.h \
obscure.c \
pam_defs.h \
pam_pass.c \
pam_pass_non_interactive.c \
port.c \
port.h \
prefix_flag.c \
prototypes.h \
pwauth.c \
pwauth.h \
pwio.c \
pwio.h \
pwd_init.c \
pwd2spwd.c \
pwdcheck.c \
pwmem.c \
subordinateio.h \
subordinateio.c \
remove_tree.c \
root_flag.c \
run_part.h \
run_part.c \
salt.c \
selinux.c \
semanage.c \
setugid.c \
setupenv.c \
sgetgrent.c \
sgetpwent.c \
sgetspent.c \
@@ -57,14 +135,74 @@ libshadow_la_SOURCES = \
shadow.c \
shadowio.c \
shadowio.h \
shadowlog.c \
shadowlog.h \
shadowlog_internal.h \
shadowmem.c \
shell.c \
sizeof.h \
spawn.c \
utent.c
sssd.c \
sssd.h \
string/sprintf.c \
string/sprintf.h \
string/stpecpy.c \
string/stpecpy.h \
string/stpeprintf.c \
string/stpeprintf.h \
string/strftime.c \
string/strftime.h \
string/strncpy.h \
string/strtcpy.c \
string/strtcpy.h \
string/zustr2stp.h \
strtoday.c \
sub.c \
subordinateio.h \
subordinateio.c \
sulog.c \
time/day_to_str.c \
time/day_to_str.h \
ttytype.c \
tz.c \
ulimit.c \
user_busy.c \
valid.c \
write_full.c \
xgetpwnam.c \
xprefix_getpwnam.c \
xgetpwuid.c \
xgetgrnam.c \
xgetgrgid.c \
xgetspnam.c \
yesno.c
if WITH_TCB
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h
endif
if WITH_BTRFS
libshadow_la_SOURCES += btrfs.c
endif
if ENABLE_LASTLOG
libshadow_la_SOURCES += log.c
endif
if ENABLE_LOGIND
libshadow_la_SOURCES += logind.c
else
libshadow_la_SOURCES += utmp.c
endif
if !WITH_LIBBSD
libshadow_la_SOURCES += \
freezero.h \
freezero.c \
readpassphrase.h \
readpassphrase.c
endif
# These files are unneeded for some reason, listed in
# order of appearance:
#
@@ -72,4 +210,5 @@ endif
EXTRA_DIST = \
.indent.pro \
gshadow_.h
gshadow_.h \
xgetXXbyYY.c

File diff suppressed because it is too large Load Diff

114
lib/addgrps.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#include <grp.h>
#include <errno.h>
#include "alloc.h"
#include "shadowlog.h"
#ident "$Id$"
#define SEP ",:"
/*
* Add groups with names from LIST (separated by commas or colons)
* to the supplementary group set. Silently ignore groups which are
* already there. Warning: uses strtok().
*/
int add_groups (const char *list)
{
GETGROUPS_T *grouplist;
size_t i;
int ngroups;
bool added;
char *token;
char buf[1024];
int ret;
FILE *shadow_logfd = log_get_logfd();
if (strlen (list) >= sizeof (buf)) {
errno = EINVAL;
return -1;
}
strcpy (buf, list);
i = 16;
for (;;) {
grouplist = MALLOC(i, GETGROUPS_T);
if (NULL == grouplist) {
return -1;
}
ngroups = getgroups (i, grouplist);
if ( ( (-1 == ngroups)
&& (EINVAL != errno))
|| (i > (size_t)ngroups)) {
/* Unexpected failure of getgroups or successful
* reception of the groups */
break;
}
/* not enough room, so try allocating a larger buffer */
free (grouplist);
i *= 2;
}
if (ngroups < 0) {
free (grouplist);
return -1;
}
added = false;
for (token = strtok (buf, SEP); NULL != token; token = strtok (NULL, SEP)) {
struct group *grp;
grp = getgrnam (token); /* local, no need for xgetgrnam */
if (NULL == grp) {
fprintf (shadow_logfd, _("Warning: unknown group %s\n"),
token);
continue;
}
for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++);
if (i < (size_t)ngroups) {
continue;
}
if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
fputs (_("Warning: too many groups\n"), shadow_logfd);
break;
}
grouplist = REALLOCF(grouplist, (size_t) ngroups + 1, GETGROUPS_T);
if (grouplist == NULL) {
return -1;
}
grouplist[ngroups] = grp->gr_gid;
ngroups++;
added = true;
}
if (added) {
ret = setgroups (ngroups, grouplist);
free (grouplist);
return ret;
}
free (grouplist);
return 0;
}
#else /* HAVE_SETGROUPS && !USE_PAM */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* HAVE_SETGROUPS && !USE_PAM */

15
lib/adds.c Normal file
View File

@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "adds.h"
#include <stddef.h>
extern inline long addsl2(long a, long b);
extern inline long addslN(size_t n, long addend[n]);
extern inline int cmpl(const void *p1, const void *p2);

86
lib/adds.h Normal file
View File

@@ -0,0 +1,86 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ADDS_H_
#define SHADOW_INCLUDE_LIB_ADDS_H_
#include <config.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
#include "sizeof.h"
#define addsl(a, b, ...) \
({ \
long addend_[] = {a, b, __VA_ARGS__}; \
\
addslN(NITEMS(addend_), addend_); \
})
inline long addsl2(long a, long b);
inline long addslN(size_t n, long addend[n]);
inline int cmpl(const void *p1, const void *p2);
inline long
addsl2(long a, long b)
{
if (a > 0 && b > LONG_MAX - a) {
errno = EOVERFLOW;
return LONG_MAX;
}
if (a < 0 && b < LONG_MIN - a) {
errno = EOVERFLOW;
return LONG_MIN;
}
return a + b;
}
inline long
addslN(size_t n, long addend[n])
{
int e;
if (n == 0) {
errno = EDOM;
return 0;
}
e = errno;
while (n > 1) {
qsort(addend, n, sizeof(addend[0]), cmpl);
errno = 0;
addend[0] = addsl2(addend[0], addend[--n]);
if (errno == EOVERFLOW)
return addend[0];
}
errno = e;
return addend[0];
}
inline int
cmpl(const void *p1, const void *p2)
{
const long *l1 = p1;
const long *l2 = p2;
if (*l1 < *l2)
return -1;
if (*l1 > *l2)
return +1;
return 0;
}
#endif // include guard

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 - 2009, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -36,12 +13,15 @@
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include "prototypes.h"
#include "defines.h"
#include "exitcodes.h"
#include <pwd.h>
#include <grp.h>
#include "adds.h"
#include "defines.h"
#include "exitcodes.h"
#include "prototypes.h"
#ident "$Id$"
#ifndef PASSWD_PROGRAM
@@ -135,7 +115,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
_exit (126);
}
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0);
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) NULL);
err = errno;
perror ("Can't execute " PASSWD_PROGRAM);
_exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
@@ -162,7 +142,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
void agecheck (/*@null@*/const struct spwd *sp)
{
long now = (long) time ((time_t *) 0) / SCALE;
long now = time(NULL) / DAY;
long remain;
if (NULL == sp) {
@@ -185,9 +165,9 @@ void agecheck (/*@null@*/const struct spwd *sp)
return;
}
remain = sp->sp_lstchg + sp->sp_max - now;
remain = addsl(sp->sp_lstchg, sp->sp_max, -now);
if (remain <= sp->sp_warn) {
remain /= DAY / SCALE;
if (remain > 1) {
(void) printf (_("Your password will expire in %ld days.\n"),
remain);

145
lib/agetpass.c Normal file
View File

@@ -0,0 +1,145 @@
/*
* SPDX-FileCopyrightText: 2022, Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#include "agetpass.h"
#include <limits.h>
#include <readpassphrase.h>
#include <stdlib.h>
#include <string.h>
#ident "$Id$"
#include "alloc.h"
#if WITH_LIBBSD == 0
#include "freezero.h"
#endif /* WITH_LIBBSD */
/*
* SYNOPSIS
* [[gnu::malloc(erase_pass)]]
* char *agetpass(const char *prompt);
* char *agetpass_stdin();
*
* void erase_pass(char *pass);
*
* ARGUMENTS
* agetpass()
* prompt String to be printed before reading a password.
*
* erase_pass()
* pass password previously returned by agetpass().
*
* DESCRIPTION
* agetpass()
* This function is very similar to getpass(3). It has several
* advantages compared to getpass(3):
*
* - Instead of using a static buffer, agetpass() allocates memory
* through malloc(3). This makes the function thread-safe, and
* also reduces the visibility of the buffer.
*
* - agetpass() doesn't reallocate internally. Some
* implementations of getpass(3), such as glibc, do that, as a
* consequence of calling getline(3). That's a bug in glibc,
* which allows leaking prefixes of passwords in freed memory.
*
* - agetpass() doesn't overrun the output buffer. If the input
* password is too long, it simply fails. Some implementations
* of getpass(3), share the same bug that gets(3) has.
*
* As soon as possible, the password obtained from agetpass() be
* erased by calling erase_pass(), to avoid possibly leaking the
* password.
*
* agetpass_stdin()
* This function is the same as previous one (agetpass). Just the
* password is read from stdin and terminal is not required.
*
* erase_pass()
* This function first clears the password, by calling
* explicit_bzero(3) (or an equivalent call), and then frees the
* allocated memory by calling free(3).
*
* NULL is a valid input pointer, and in such a case, this call is
* a no-op.
*
* RETURN VALUE
* agetpass() returns a newly allocated buffer containing the
* password on success. On error, errno is set to indicate the
* error, and NULL is returned.
*
* ERRORS
* agetpass()
* This function may fail for any errors that malloc(3) or
* readpassphrase(3) may fail, and in addition it may fail for the
* following errors:
*
* ENOBUFS
* The input password was longer than PASS_MAX.
*
* CAVEATS
* If a password is passed twice to erase_pass(), the behavior is
* undefined.
*/
static char *
agetpass_internal(const char *prompt, int flags)
{
char *pass;
size_t len;
/*
* Since we want to support passwords upto PASS_MAX, we need
* PASS_MAX bytes for the password itself, and one more byte for
* the terminating '\0'. We also want to detect truncation, and
* readpassphrase(3) doesn't detect it, so we need some trick.
* Let's add one more byte, and if the password uses it, it
* means the introduced password was longer than PASS_MAX.
*/
pass = MALLOC(PASS_MAX + 2, char);
if (pass == NULL)
return NULL;
if (readpassphrase(prompt, pass, PASS_MAX + 2, flags) == NULL)
goto fail;
len = strlen(pass);
if (len == PASS_MAX + 1) {
errno = ENOBUFS;
goto fail;
}
return pass;
fail:
freezero(pass, PASS_MAX + 2);
return NULL;
}
char *
agetpass(const char *prompt)
{
return agetpass_internal(prompt, RPP_REQUIRE_TTY);
}
char *
agetpass_stdin()
{
return agetpass_internal(NULL, RPP_STDIN);
}
void
erase_pass(char *pass)
{
freezero(pass, PASS_MAX + 2);
}

23
lib/agetpass.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* SPDX-FileCopyrightText: 2022-2023, Alejandro Colomar <alx@kernel.org>
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SHADOW_INCLUDE_LIB_AGETPASS_H_
#define SHADOW_INCLUDE_LIB_AGETPASS_H_
#include <config.h>
#include "attr.h"
#include "defines.h"
void erase_pass(char *pass);
ATTR_MALLOC(erase_pass)
char *agetpass(const char *prompt);
char *agetpass_stdin();
#endif // include guard

73
lib/alloc.c Normal file
View File

@@ -0,0 +1,73 @@
/*
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 , Nicolas François
* SPDX-FileCopyrightText: 2023 , Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Replacements for malloc and strdup with error checking. Too trivial
to be worth copyrighting :-). I did that because a lot of code used
malloc and strdup without checking for NULL pointer, and I like some
message better than a core dump... --marekm
Yeh, but. Remember that bailing out might leave the system in some
bizarre state. You really want to put in error checking, then add
some back-out failure recovery code. -- jfh */
#include <config.h>
#ident "$Id$"
#include "alloc.h"
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
extern inline void *xmalloc(size_t size);
extern inline void *xmallocarray(size_t nmemb, size_t size);
extern inline void *mallocarray(size_t nmemb, size_t size);
extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
extern inline char *xstrdup(const char *str);
void *
xcalloc(size_t nmemb, size_t size)
{
void *p;
p = calloc(nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
}
void *
xreallocarray(void *p, size_t nmemb, size_t size)
{
p = reallocarrayf(p, nmemb, size);
if (p == NULL)
goto x;
return p;
x:
fprintf(log_get_logfd(), _("%s: %s\n"),
log_get_progname(), strerror(errno));
exit(13);
}

101
lib/alloc.h Normal file
View File

@@ -0,0 +1,101 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
#define SHADOW_INCLUDE_LIB_MALLOC_H_
#include <config.h>
#include <assert.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "attr.h"
#include "defines.h"
#define CALLOC(n, type) ((type *) calloc(n, sizeof(type)))
#define XCALLOC(n, type) ((type *) xcalloc(n, sizeof(type)))
#define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
#define XMALLOC(n, type) ((type *) xmallocarray(n, sizeof(type)))
#define REALLOC(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) reallocarray(ptr, n, sizeof(type))) \
)
#define REALLOCF(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) reallocarrayf(ptr, n, sizeof(type))) \
)
#define XREALLOC(ptr, n, type) \
( \
_Generic(ptr, type *: (type *) xreallocarray(ptr, n, sizeof(type))) \
)
ATTR_MALLOC(free)
inline void *xmalloc(size_t size);
ATTR_MALLOC(free)
inline void *xmallocarray(size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline void *mallocarray(size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
ATTR_MALLOC(free)
inline char *xstrdup(const char *str);
ATTR_MALLOC(free)
void *xcalloc(size_t nmemb, size_t size);
ATTR_MALLOC(free)
void *xreallocarray(void *p, size_t nmemb, size_t size);
inline void *
xmalloc(size_t size)
{
return xmallocarray(1, size);
}
inline void *
xmallocarray(size_t nmemb, size_t size)
{
return xreallocarray(NULL, nmemb, size);
}
inline void *
mallocarray(size_t nmemb, size_t size)
{
return reallocarray(NULL, nmemb, size);
}
inline void *
reallocarrayf(void *p, size_t nmemb, size_t size)
{
void *q;
q = reallocarray(p, nmemb, size);
/* realloc(p, 0) is equivalent to free(p); avoid double free. */
if (q == NULL && nmemb != 0 && size != 0)
free(p);
return q;
}
inline char *
xstrdup(const char *str)
{
return strcpy(XMALLOC(strlen(str) + 1, char), str);
}
#endif // include guard

46
lib/atoi/a2i.c Normal file
View File

@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/a2i.h"
extern inline int a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max);
extern inline int a2si_c(int *restrict n, const char *s,
const char **restrict endp, int base, int min, int max);
extern inline int a2sl_c(long *restrict n, const char *s,
const char **restrict endp, int base, long min, long max);
extern inline int a2sll_c(long long *restrict n, const char *s,
const char **restrict endp, int base, long long min, long long max);
extern inline int a2uh_c(unsigned short *restrict n, const char *s,
const char **restrict endp, int base, unsigned short min,
unsigned short max);
extern inline int a2ui_c(unsigned int *restrict n, const char *s,
const char **restrict endp, int base, unsigned int min, unsigned int max);
extern inline int a2ul_c(unsigned long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long min, unsigned long max);
extern inline int a2ull_c(unsigned long long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long long min,
unsigned long long max);
extern inline int a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max);
extern inline int a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max);
extern inline int a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max);
extern inline int a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max);
extern inline int a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min, unsigned short max);
extern inline int a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max);
extern inline int a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max);
extern inline int a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max);

386
lib/atoi/a2i.h Normal file
View File

@@ -0,0 +1,386 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_A2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_A2I_H_
#include <config.h>
#include <errno.h>
#include "atoi/strtoi.h"
#include "atoi/strtou_noneg.h"
#include "attr.h"
/*
* See the manual of these macros in liba2i's documentation:
* <http://www.alejandro-colomar.es/share/dist/liba2i/git/HEAD/liba2i-HEAD.pdf>
*/
#define a2i(TYPE, n, s, ...) \
( \
_Generic((void (*)(TYPE, typeof(s))) 0, \
void (*)(short, const char *): a2sh_c, \
void (*)(short, const void *): a2sh_c, \
void (*)(short, char *): a2sh_nc, \
void (*)(short, void *): a2sh_nc, \
void (*)(int, const char *): a2si_c, \
void (*)(int, const void *): a2si_c, \
void (*)(int, char *): a2si_nc, \
void (*)(int, void *): a2si_nc, \
void (*)(long, const char *): a2sl_c, \
void (*)(long, const void *): a2sl_c, \
void (*)(long, char *): a2sl_nc, \
void (*)(long, void *): a2sl_nc, \
void (*)(long long, const char *): a2sll_c, \
void (*)(long long, const void *): a2sll_c, \
void (*)(long long, char *): a2sll_nc, \
void (*)(long long, void *): a2sll_nc, \
void (*)(unsigned short, const char *): a2uh_c, \
void (*)(unsigned short, const void *): a2uh_c, \
void (*)(unsigned short, char *): a2uh_nc, \
void (*)(unsigned short, void *): a2uh_nc, \
void (*)(unsigned int, const char *): a2ui_c, \
void (*)(unsigned int, const void *): a2ui_c, \
void (*)(unsigned int, char *): a2ui_nc, \
void (*)(unsigned int, void *): a2ui_nc, \
void (*)(unsigned long, const char *): a2ul_c, \
void (*)(unsigned long, const void *): a2ul_c, \
void (*)(unsigned long, char *): a2ul_nc, \
void (*)(unsigned long, void *): a2ul_nc, \
void (*)(unsigned long long, const char *): a2ull_c, \
void (*)(unsigned long long, const void *): a2ull_c, \
void (*)(unsigned long long, char *): a2ull_nc, \
void (*)(unsigned long long, void *): a2ull_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sh(n, s, ...) \
( \
_Generic(s, \
const char *: a2sh_c, \
const void *: a2sh_c, \
char *: a2sh_nc, \
void *: a2sh_nc \
)(n, s, __VA_ARGS__) \
)
#define a2si(n, s, ...) \
( \
_Generic(s, \
const char *: a2si_c, \
const void *: a2si_c, \
char *: a2si_nc, \
void *: a2si_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sl(n, s, ...) \
( \
_Generic(s, \
const char *: a2sl_c, \
const void *: a2sl_c, \
char *: a2sl_nc, \
void *: a2sl_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sll(n, s, ...) \
( \
_Generic(s, \
const char *: a2sll_c, \
const void *: a2sll_c, \
char *: a2sll_nc, \
void *: a2sll_nc \
)(n, s, __VA_ARGS__) \
)
#define a2uh(n, s, ...) \
( \
_Generic(s, \
const char *: a2uh_c, \
const void *: a2uh_c, \
char *: a2uh_nc, \
void *: a2uh_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ui(n, s, ...) \
( \
_Generic(s, \
const char *: a2ui_c, \
const void *: a2ui_c, \
char *: a2ui_nc, \
void *: a2ui_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ul(n, s, ...) \
( \
_Generic(s, \
const char *: a2ul_c, \
const void *: a2ul_c, \
char *: a2ul_nc, \
void *: a2ul_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ull(n, s, ...) \
( \
_Generic(s, \
const char *: a2ull_c, \
const void *: a2ull_c, \
char *: a2ull_nc, \
void *: a2ull_nc \
)(n, s, __VA_ARGS__) \
)
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2si_c(int *restrict n, const char *s,
const char **restrict endp, int base, int min, int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sl_c(long *restrict n, const char *s,
const char **restrict endp, int base, long min, long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sll_c(long long *restrict n, const char *s,
const char **restrict endp, int base, long long min, long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2uh_c(unsigned short *restrict n, const char *s,
const char **restrict endp, int base, unsigned short min,
unsigned short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ui_c(unsigned int *restrict n, const char *s,
const char **restrict endp, int base, unsigned int min, unsigned int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ul_c(unsigned long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long min, unsigned long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ull_c(unsigned long long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long long min,
unsigned long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min, unsigned short max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
inline int a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max);
inline int
a2sh_c(short *restrict n, const char *s,
const char **restrict endp, int base, short min, short max)
{
return a2sh(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2si_c(int *restrict n, const char *s,
const char **restrict endp, int base, int min, int max)
{
return a2si(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2sl_c(long *restrict n, const char *s,
const char **restrict endp, int base, long min, long max)
{
return a2sl(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2sll_c(long long *restrict n, const char *s,
const char **restrict endp, int base, long long min, long long max)
{
return a2sll(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2uh_c(unsigned short *restrict n, const char *s,
const char **restrict endp, int base, unsigned short min,
unsigned short max)
{
return a2uh(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2ui_c(unsigned int *restrict n, const char *s,
const char **restrict endp, int base, unsigned int min, unsigned int max)
{
return a2ui(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2ul_c(unsigned long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long min, unsigned long max)
{
return a2ul(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2ull_c(unsigned long long *restrict n, const char *s,
const char **restrict endp, int base, unsigned long long min,
unsigned long long max)
{
return a2ull(n, (char *) s, (char **) endp, base, min, max);
}
inline int
a2sh_nc(short *restrict n, char *s,
char **restrict endp, int base, short min, short max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2si_nc(int *restrict n, char *s,
char **restrict endp, int base, int min, int max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2sl_nc(long *restrict n, char *s,
char **restrict endp, int base, long min, long max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2sll_nc(long long *restrict n, char *s,
char **restrict endp, int base, long long min, long long max)
{
int status;
*n = strtoi_(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2uh_nc(unsigned short *restrict n, char *s,
char **restrict endp, int base, unsigned short min,
unsigned short max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2ui_nc(unsigned int *restrict n, char *s,
char **restrict endp, int base, unsigned int min, unsigned int max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2ul_nc(unsigned long *restrict n, char *s,
char **restrict endp, int base, unsigned long min, unsigned long max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
inline int
a2ull_nc(unsigned long long *restrict n, char *s,
char **restrict endp, int base, unsigned long long min,
unsigned long long max)
{
int status;
*n = strtou_noneg(s, endp, base, min, max, &status);
if (status != 0) {
errno = status;
return -1;
}
return 0;
}
#endif // include guard

18
lib/atoi/str2i.c Normal file
View File

@@ -0,0 +1,18 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/str2i.h"
extern inline int str2sh(short *restrict n, const char *restrict s);
extern inline int str2si(int *restrict n, const char *restrict s);
extern inline int str2sl(long *restrict n, const char *restrict s);
extern inline int str2sll(long long *restrict n, const char *restrict s);
extern inline int str2uh(unsigned short *restrict n, const char *restrict s);
extern inline int str2ui(unsigned int *restrict n, const char *restrict s);
extern inline int str2ul(unsigned long *restrict n, const char *restrict s);
extern inline int str2ull(unsigned long long *restrict n, const char *restrict s);

108
lib/atoi/str2i.h Normal file
View File

@@ -0,0 +1,108 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include "atoi/a2i.h"
#include "attr.h"
#define str2i(TYPE, ...) \
( \
_Generic((TYPE) 0, \
short: str2sh, \
int: str2si, \
long: str2sl, \
long long: str2sll, \
unsigned short: str2uh, \
unsigned int: str2ui, \
unsigned long: str2ul, \
unsigned long long: str2ull \
)(__VA_ARGS__) \
)
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sh(short *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2si(int *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sl(long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sll(long long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2uh(unsigned short *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ui(unsigned int *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ul(unsigned long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ull(unsigned long long *restrict n, const char *restrict s);
inline int
str2sh(short *restrict n, const char *restrict s)
{
return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX);
}
inline int
str2si(int *restrict n, const char *restrict s)
{
return a2si(n, s, NULL, 0, INT_MIN, INT_MAX);
}
inline int
str2sl(long *restrict n, const char *restrict s)
{
return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX);
}
inline int
str2sll(long long *restrict n, const char *restrict s)
{
return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX);
}
inline int
str2uh(unsigned short *restrict n, const char *restrict s)
{
return a2uh(n, s, NULL, 0, 0, USHRT_MAX);
}
inline int
str2ui(unsigned int *restrict n, const char *restrict s)
{
return a2ui(n, s, NULL, 0, 0, UINT_MAX);
}
inline int
str2ul(unsigned long *restrict n, const char *restrict s)
{
return a2ul(n, s, NULL, 0, 0, ULONG_MAX);
}
inline int
str2ull(unsigned long long *restrict n, const char *restrict s)
{
return a2ull(n, s, NULL, 0, 0, ULLONG_MAX);
}
#endif // include guard

15
lib/atoi/strtoi.c Normal file
View File

@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/strtoi.h"
#include <stdint.h>
extern inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status);
extern inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status);

96
lib/atoi/strtoi.h Normal file
View File

@@ -0,0 +1,96 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_
#include <config.h>
#include <errno.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/param.h>
#include "attr.h"
#define strtoNmax(TYPE, ...) \
( \
_Generic((TYPE) 0, \
intmax_t: strtoimax, \
uintmax_t: strtoumax \
)(__VA_ARGS__) \
)
#define strtoN(s, endp, base, min, max, status, TYPE) \
({ \
const char *s_ = s; \
char **endp_ = endp; \
int base_ = base; \
TYPE min_ = min; \
TYPE max_ = max; \
int *status_ = status; \
\
int e_, st_; \
char *end_; \
TYPE n_; \
\
if (endp_ == NULL) \
endp_ = &end_; \
if (status_ == NULL) \
status_ = &st_; \
\
if (base_ != 0 && (base_ < 0 || base_ > 36)) { \
*status_ = EINVAL; \
n_ = 0; \
\
} else { \
e_ = errno; \
errno = 0; \
n_ = strtoNmax(TYPE, s_, endp_, base_); \
\
if (*endp_ == s_) \
*status_ = ECANCELED; \
else if (errno == ERANGE || n_ < min_ || n_ > max_) \
*status_ = ERANGE; \
else if (**endp_ != '\0') \
*status_ = ENOTSUP; \
else \
*status_ = 0; \
\
errno = e_; \
} \
MAX(min_, MIN(max_, n_)); \
})
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status);
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status);
inline intmax_t
strtoi_(const char *s, char **restrict endp, int base,
intmax_t min, intmax_t max, int *restrict status)
{
return strtoN(s, endp, base, min, max, status, intmax_t);
}
inline uintmax_t
strtou_(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status)
{
return strtoN(s, endp, base, min, max, status, uintmax_t);
}
#endif // include guard

13
lib/atoi/strtou_noneg.c Normal file
View File

@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/strtou_noneg.h"
#include <stdint.h>
extern inline uintmax_t strtou_noneg(const char *s, char **restrict endp,
int base, uintmax_t min, uintmax_t max, int *restrict status);

39
lib/atoi/strtou_noneg.h Normal file
View File

@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_
#define SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_
#include <config.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include "atoi/strtoi.h"
#include "attr.h"
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
inline uintmax_t strtou_noneg(const char *s, char **restrict endp,
int base, uintmax_t min, uintmax_t max, int *restrict status);
inline uintmax_t
strtou_noneg(const char *s, char **restrict endp, int base,
uintmax_t min, uintmax_t max, int *restrict status)
{
int st;
if (status == NULL)
status = &st;
if (strtoi_(s, endp, base, 0, 1, status) == 0 && *status == ERANGE)
return min;
return strtou_(s, endp, base, min, max, status);
}
#endif // include guard

33
lib/attr.h Normal file
View File

@@ -0,0 +1,33 @@
#ifndef SHADOW_INCLUDE_LIB_ATTR_H_
#define SHADOW_INCLUDE_LIB_ATTR_H_
#include "config.h"
#if defined(__GNUC__)
# define MAYBE_UNUSED __attribute__((unused))
# define NORETURN __attribute__((__noreturn__))
# define format_attr(type, fmt, va) __attribute__((format(type, fmt, va)))
# define ATTR_ACCESS(...) __attribute__((access(__VA_ARGS__)))
#else
# define MAYBE_UNUSED
# define NORETURN
# define format_attr(type, fmt, va)
# define ATTR_ACCESS(...)
#endif
#if (__GNUC__ >= 11) && !defined(__clang__)
# define ATTR_MALLOC(deallocator) [[gnu::malloc(deallocator)]]
#else
# define ATTR_MALLOC(deallocator)
#endif
#if (__GNUC__ >= 14)
# define ATTR_STRING(...) [[gnu::null_terminated_string_arg(__VA_ARGS__)]]
#else
# define ATTR_STRING(...)
#endif
#endif // include guard

89
lib/audit_help.c Normal file
View File

@@ -0,0 +1,89 @@
/*
* SPDX-FileCopyrightText: 2005 , Red Hat, Inc.
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Audit helper functions used throughout shadow
*
*/
#include <config.h>
#ifdef WITH_AUDIT
#include <stdlib.h>
#include <syslog.h>
#include <stdarg.h>
#include <libaudit.h>
#include <errno.h>
#include <stdio.h>
#include "attr.h"
#include "prototypes.h"
#include "shadowlog.h"
int audit_fd;
void audit_help_open (void)
{
audit_fd = audit_open ();
if (audit_fd < 0) {
/* You get these only when the kernel doesn't have
* audit compiled in. */
if ( (errno == EINVAL)
|| (errno == EPROTONOSUPPORT)
|| (errno == EAFNOSUPPORT)) {
return;
}
(void) fputs (_("Cannot open audit interface - aborting.\n"),
log_get_logfd());
exit (EXIT_FAILURE);
}
}
/*
* 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
* 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.
*/
void audit_logger (int type, MAYBE_UNUSED const char *pgname, const char *op,
const char *name, unsigned int id,
shadow_audit_result result)
{
if (audit_fd < 0) {
return;
} else {
audit_log_acct_message (audit_fd, type, NULL, op, name, id,
NULL, NULL, NULL, result);
}
}
void audit_logger_message (const char *message, shadow_audit_result result)
{
if (audit_fd < 0) {
return;
} else {
audit_log_user_message (audit_fd,
AUDIT_USYS_CONFIG,
message,
NULL, /* hostname */
NULL, /* addr */
NULL, /* tty */
result);
}
}
#else /* WITH_AUDIT */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* WITH_AUDIT */

31
lib/basename.c Normal file
View File

@@ -0,0 +1,31 @@
/*
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* basename.c - not worth copyrighting :-). Some versions of Linux libc
* already have basename(), other versions don't. To avoid confusion,
* we will not use the function from libc and use a different name here.
* --marekm
*/
#include <config.h>
#ident "$Id$"
#include "defines.h"
#include "prototypes.h"
/*@observer@*/const char *Basename (const char *str)
{
if (str == NULL) {
abort ();
}
char *cp = strrchr (str, '/');
return (NULL != cp) ? cp + 1 : str;
}

19
lib/bit.c Normal file
View File

@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include "bit.h"
#include <limits.h>
extern inline unsigned long bit_ceilul(unsigned long x);
extern inline unsigned long bit_ceil_wrapul(unsigned long x);
extern inline int leading_zerosul(unsigned long x);

53
lib/bit.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SHADOW_INCLUDE_LIB_BIT_H_
#define SHADOW_INCLUDE_LIB_BIT_H_
#include <config.h>
#include <limits.h>
#ifndef ULONG_WIDTH
#define ULONG_WIDTH (sizeof(unsigned long) * CHAR_BIT)
#endif
inline unsigned long bit_ceilul(unsigned long x);
inline unsigned long bit_ceil_wrapul(unsigned long x);
inline int leading_zerosul(unsigned long x);
/* stdc_bit_ceilul(3) */
inline unsigned long
bit_ceilul(unsigned long x)
{
return 1 + (ULONG_MAX >> leading_zerosul(x));
}
/* stdc_bit_ceilul(3), but wrap instead of having Undefined Behavior */
inline unsigned long
bit_ceil_wrapul(unsigned long x)
{
if (x == 0)
return 0;
return bit_ceilul(x);
}
/* stdc_leading_zerosul(3) */
inline int
leading_zerosul(unsigned long x)
{
return (x == 0) ? ULONG_WIDTH : __builtin_clzl(x);
}
#endif // include guard

View File

@@ -14,7 +14,7 @@ static bool path_exists(const char *p)
static const char *btrfs_cmd(void)
{
const char *btrfs_paths[] = {"/sbin/btrfs",
const char *const btrfs_paths[] = {"/sbin/btrfs",
"/bin/btrfs", "/usr/sbin/btrfs", "/usr/bin/btrfs", NULL};
const char *p;
int i;
@@ -39,7 +39,7 @@ static int run_btrfs_subvolume_cmd(const char *subcmd, const char *arg1, const c
NULL
};
if (access(cmd, X_OK)) {
if (!cmd || access(cmd, X_OK)) {
return 1;
}

15
lib/cast.h Normal file
View File

@@ -0,0 +1,15 @@
// SPDX-FileCopyrightText: 2022-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_CAST_H_
#define SHADOW_INCLUDE_LIB_CAST_H_
#include <config.h>
#define const_cast(T, p) _Generic(p, const T: (T) (p))
#endif // include guard

120
lib/chkname.c Normal file
View File

@@ -0,0 +1,120 @@
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-2000, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2001-2005, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2005-2008, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
/*
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
* return values:
* true - OK
* false - bad name
*/
#include <config.h>
#ident "$Id$"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <unistd.h>
#include "defines.h"
#include "chkname.h"
int allow_bad_names = false;
size_t
login_name_max_size(void)
{
long conf;
errno = 0;
conf = sysconf(_SC_LOGIN_NAME_MAX);
if (conf == -1 && errno != 0)
return LOGIN_NAME_MAX;
return conf;
}
static bool is_valid_name (const char *name)
{
if (allow_bad_names) {
return true;
}
/*
* User/group names must match BRE regex:
* [a-zA-Z0-9_.][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 (!((*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 !numeric;
}
bool
is_valid_user_name(const char *name)
{
if (strlen(name) >= login_name_max_size())
return false;
return is_valid_name(name);
}
bool is_valid_group_name (const char *name)
{
/*
* Arbitrary limit for group names.
* HP-UX 10 limits to 16 characters
*/
if ( (GROUP_NAME_MAX_LENGTH > 0)
&& (strlen (name) > GROUP_NAME_MAX_LENGTH)) {
return false;
}
return is_valid_name (name);
}

34
lib/chkname.h Normal file
View File

@@ -0,0 +1,34 @@
/*
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* $Id$ */
#ifndef _CHKNAME_H_
#define _CHKNAME_H_
/*
* is_valid_user_name(), is_valid_group_name() - check the new user/group
* name for validity;
* return values:
* true - OK
* false - bad name
*/
#include <config.h>
#include <stdbool.h>
#include <stddef.h>
extern size_t login_name_max_size(void);
extern bool is_valid_user_name (const char *name);
extern bool is_valid_group_name (const char *name);
#endif

146
lib/chowndir.c Normal file
View File

@@ -0,0 +1,146 @@
/*
* SPDX-FileCopyrightText: 1992 - 1993, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2010 - , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <sys/types.h>
#include <sys/stat.h>
#include "prototypes.h"
#include "defines.h"
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
static int chown_tree_at (int at_fd,
const char *path,
uid_t old_uid,
uid_t new_uid,
gid_t old_gid,
gid_t new_gid)
{
DIR *dir;
const struct dirent *ent;
struct stat dir_sb;
int dir_fd, rc = 0;
dir_fd = openat (at_fd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
if (dir_fd < 0) {
return -1;
}
dir = fdopendir (dir_fd);
if (!dir) {
(void) close (dir_fd);
return -1;
}
/*
* Open the directory and read each entry. Every entry is tested
* to see if it is a directory, and if so this routine is called
* recursively. If not, it is checked to see if an ownership
* shall be changed.
*/
while ((ent = readdir (dir))) {
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
struct stat ent_sb;
/*
* Skip the "." and ".." entries
*/
if ( (strcmp (ent->d_name, ".") == 0)
|| (strcmp (ent->d_name, "..") == 0)) {
continue;
}
rc = fstatat (dirfd(dir), ent->d_name, &ent_sb, AT_SYMLINK_NOFOLLOW);
if (rc < 0) {
break;
}
if (S_ISDIR (ent_sb.st_mode)) {
/*
* Do the entire subdirectory.
*/
rc = chown_tree_at (dirfd(dir), ent->d_name, old_uid, new_uid, old_gid, new_gid);
if (0 != rc) {
break;
}
}
/*
* By default, the IDs are not changed (-1).
*
* If the file is not owned by the user, the owner is not
* changed.
*
* If the file is not group-owned by the group, the
* group-owner is not changed.
*/
if (((uid_t) -1 == old_uid) || (ent_sb.st_uid == old_uid)) {
tmpuid = new_uid;
}
if (((gid_t) -1 == old_gid) || (ent_sb.st_gid == old_gid)) {
tmpgid = new_gid;
}
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
rc = fchownat (dirfd(dir), ent->d_name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW);
if (0 != rc) {
break;
}
}
}
/*
* Now do the root of the tree
*/
if ((0 == rc) && (fstat (dirfd(dir), &dir_sb) == 0)) {
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
if (((uid_t) -1 == old_uid) || (dir_sb.st_uid == old_uid)) {
tmpuid = new_uid;
}
if (((gid_t) -1 == old_gid) || (dir_sb.st_gid == old_gid)) {
tmpgid = new_gid;
}
if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) {
rc = fchown (dirfd(dir), tmpuid, tmpgid);
}
} else {
rc = -1;
}
(void) closedir (dir);
return rc;
}
/*
* chown_tree - change ownership of files in a directory tree
*
* chown_dir() walks a directory tree and changes the ownership
* of all files owned by the provided user ID.
*
* Only files owned (resp. group-owned) by old_uid (resp. by old_gid)
* will have their ownership (resp. group-ownership) modified, unless
* old_uid (resp. old_gid) is set to -1.
*
* new_uid and new_gid can be set to -1 to indicate that no owner or
* group-owner shall be changed.
*/
int chown_tree (const char *root,
uid_t old_uid,
uid_t new_uid,
gid_t old_gid,
gid_t new_gid)
{
return chown_tree_at (AT_FDCWD, root, old_uid, new_uid, old_gid, new_gid);
}

79
lib/chowntty.c Normal file
View File

@@ -0,0 +1,79 @@
/*
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <grp.h>
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
#include "getdef.h"
#include "shadowlog.h"
/*
* chown_tty() sets the login tty to be owned by the new user ID
* with TTYPERM modes
*/
void chown_tty (const struct passwd *info)
{
struct group *grent;
gid_t gid;
/*
* See if login.defs has some value configured for the port group
* ID. Otherwise, use the user's primary group ID.
*/
grent = getgr_nam_gid (getdef_str ("TTYGROUP"));
if (NULL != grent) {
gid = grent->gr_gid;
gr_free (grent);
} else {
gid = info->pw_gid;
}
/*
* Change the permissions on the TTY to be owned by the user with
* the group as determined above.
*/
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|| (fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600)) != 0)) {
int err = errno;
FILE *shadow_logfd = log_get_logfd();
fprintf (shadow_logfd,
_("Unable to change owner or mode of tty stdin: %s"),
strerror (err));
SYSLOG ((LOG_WARN,
"unable to change owner or mode of tty stdin for user `%s': %s\n",
info->pw_name, strerror (err)));
if (EROFS != err) {
closelog ();
exit (EXIT_FAILURE);
}
}
#ifdef __linux__
/*
* Please don't add code to chown /dev/vcs* to the user logging in -
* it's a potential security hole. I wouldn't like the previous user
* to hold the file descriptor open and watch my screen. We don't
* have the *BSD revoke() system call yet, and vhangup() only works
* for tty devices (which vcs* is not). --marekm
*/
#endif
}

View File

@@ -1,30 +1,7 @@
/*
* Copyright (c) 2008 - 2011, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 2008 - 2011, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>

View File

@@ -1,30 +1,7 @@
/*
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 2008 , Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -32,10 +9,12 @@
#include <assert.h>
#include <stdio.h>
#include "attr.h"
#include "defines.h"
#include "groupio.h"
#include "sgroupio.h"
#include "prototypes.h"
#include "shadowlog.h"
/*
* cleanup_report_add_group - Report failure to add a group to the system
@@ -44,11 +23,11 @@
*/
void cleanup_report_add_group (void *group_name)
{
const char *name = (const char *)group_name;
const char *name = group_name;
SYSLOG ((LOG_ERR, "failed to add group %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -62,11 +41,11 @@ void cleanup_report_add_group (void *group_name)
*/
void cleanup_report_del_group (void *group_name)
{
const char *name = (const char *)group_name;
const char *name = group_name;
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_GROUP, Prog,
audit_logger (AUDIT_DEL_GROUP, log_get_progname(),
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -83,7 +62,7 @@ void cleanup_report_mod_group (void *cleanup_info)
gr_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, Prog,
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -101,7 +80,7 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
sgr_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, Prog,
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -117,11 +96,11 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
*/
void cleanup_report_add_group_group (void *group_name)
{
const char *name = (const char *)group_name;
const char *name = group_name;
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"adding group to /etc/group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -137,11 +116,11 @@ void cleanup_report_add_group_group (void *group_name)
*/
void cleanup_report_add_group_gshadow (void *group_name)
{
const char *name = (const char *)group_name;
const char *name = group_name;
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"adding group to /etc/gshadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -158,13 +137,13 @@ void cleanup_report_add_group_gshadow (void *group_name)
*/
void cleanup_report_del_group_group (void *group_name)
{
const char *name = (const char *)group_name;
const char *name = group_name;
SYSLOG ((LOG_ERR,
"failed to remove group %s from %s",
name, gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"removing group from /etc/group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -181,13 +160,13 @@ void cleanup_report_del_group_group (void *group_name)
*/
void cleanup_report_del_group_gshadow (void *group_name)
{
const char *name = (const char *)group_name;
const char *name = group_name;
SYSLOG ((LOG_ERR,
"failed to remove group %s from %s",
name, sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, Prog,
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"removing group from /etc/gshadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -200,12 +179,12 @@ void cleanup_report_del_group_gshadow (void *group_name)
*
* It should be registered after the group file is successfully locked.
*/
void cleanup_unlock_group (unused void *arg)
void cleanup_unlock_group (MAYBE_UNUSED void *arg)
{
if (gr_unlock () == 0) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: failed to unlock %s\n"),
Prog, gr_dbname ());
log_get_progname(), gr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking group file",
@@ -220,12 +199,12 @@ void cleanup_unlock_group (unused void *arg)
*
* It should be registered after the gshadow file is successfully locked.
*/
void cleanup_unlock_gshadow (unused void *arg)
void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg)
{
if (sgr_unlock () == 0) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: failed to unlock %s\n"),
Prog, sgr_dbname ());
log_get_progname(), sgr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking gshadow file",

131
lib/cleanup_user.c Normal file
View File

@@ -0,0 +1,131 @@
/*
* SPDX-FileCopyrightText: 2008 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "attr.h"
#include "defines.h"
#include "pwio.h"
#include "shadowio.h"
#include "prototypes.h"
#include "shadowlog.h"
/*
* cleanup_report_add_user - Report failure to add a user to the system
*
* It should be registered when it is decided to add a user to the system.
*/
void cleanup_report_add_user (void *user_name)
{
const char *name = user_name;
SYSLOG ((LOG_ERR, "failed to add user %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, log_get_progname(),
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
void cleanup_report_mod_passwd (void *cleanup_info)
{
const struct cleanup_info_mod *info;
info = (const struct cleanup_info_mod *)cleanup_info;
SYSLOG ((LOG_ERR,
"failed to change %s (%s)",
pw_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_report_add_user_passwd - Report failure to add a user to
* /etc/passwd
*
* It should be registered when it is decided to add a user to the
* /etc/passwd database.
*/
void cleanup_report_add_user_passwd (void *user_name)
{
const char *name = user_name;
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, log_get_progname(),
"adding user to /etc/passwd",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_report_add_user_shadow - Report failure to add a user to
* /etc/shadow
*
* It should be registered when it is decided to add a user to the
* /etc/shadow database.
*/
void cleanup_report_add_user_shadow (void *user_name)
{
const char *name = user_name;
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, log_get_progname(),
"adding user to /etc/shadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_unlock_passwd - Unlock the /etc/passwd database
*
* It should be registered after the passwd database is successfully locked.
*/
void cleanup_unlock_passwd (MAYBE_UNUSED void *arg)
{
if (pw_unlock () == 0) {
fprintf (log_get_logfd(),
_("%s: failed to unlock %s\n"),
log_get_progname(), pw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking passwd file",
SHADOW_AUDIT_FAILURE);
#endif
}
}
/*
* cleanup_unlock_shadow - Unlock the /etc/shadow database
*
* It should be registered after the shadow database is successfully locked.
*/
void cleanup_unlock_shadow (MAYBE_UNUSED void *arg)
{
if (spw_unlock () == 0) {
fprintf (log_get_logfd(),
_("%s: failed to unlock %s\n"),
log_get_progname(), spw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking shadow file",
SHADOW_AUDIT_FAILURE);
#endif
}
}

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2001, Marek Michałkiewicz
* Copyright (c) 2001 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2011, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2011, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -44,6 +21,9 @@
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include "alloc.h"
#include "memzero.h"
#include "nscd.h"
#include "sssd.h"
#ifdef WITH_TCB
@@ -51,10 +31,13 @@
#endif /* WITH_TCB */
#include "prototypes.h"
#include "commonio.h"
#include "shadowlog_internal.h"
#include "string/sprintf.h"
/* local function prototypes */
static int lrename (const char *, const char *);
static int check_link_count (const char *file);
static int check_link_count (const char *file, bool log);
static int do_lock_file (const char *file, const char *lock, bool log);
static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
const char *name,
@@ -87,7 +70,6 @@ int lrename (const char *old, const char *new)
int res;
char *r = NULL;
#if defined(S_ISLNK)
#ifndef __GLIBC__
char resolved_path[PATH_MAX];
#endif /* !__GLIBC__ */
@@ -104,28 +86,35 @@ int lrename (const char *old, const char *new)
new = r;
}
}
#endif /* S_ISLNK */
res = rename (old, new);
#ifdef __GLIBC__
if (NULL != r) {
free (r);
}
free (r);
#endif /* __GLIBC__ */
return res;
}
static int check_link_count (const char *file)
static int check_link_count (const char *file, bool log)
{
struct stat sb;
if (stat (file, &sb) != 0) {
if (log) {
(void) fprintf (shadow_logfd,
"%s: %s file stat error: %s\n",
shadow_progname, file, strerror (errno));
}
return 0;
}
if (sb.st_nlink != 2) {
if (log) {
fprintf(shadow_logfd,
"%s: %s: lock file already used (nlink: %ju)\n",
shadow_progname, file, (uintmax_t) sb.st_nlink);
}
return 0;
}
@@ -135,30 +124,40 @@ static int check_link_count (const char *file)
static int do_lock_file (const char *file, const char *lock, bool log)
{
int fd;
pid_t pid;
ssize_t len;
int retval;
char buf[32];
int fd;
int retval;
char buf[32];
pid_t pid;
ssize_t len;
fd = open (file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
if (-1 == fd) {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: %s: %s\n",
Prog, file, strerror (errno));
shadow_progname, file, strerror (errno));
}
return 0;
}
pid = getpid ();
snprintf (buf, sizeof buf, "%lu", (unsigned long) pid);
SNPRINTF(buf, "%lu", (unsigned long) pid);
len = (ssize_t) strlen (buf) + 1;
if (write (fd, buf, (size_t) len) != len) {
if (write_full(fd, buf, len) == -1) {
if (log) {
(void) fprintf (stderr,
"%s: %s: %s\n",
Prog, file, strerror (errno));
(void) fprintf (shadow_logfd,
"%s: %s file write error: %s\n",
shadow_progname, file, strerror (errno));
}
(void) close (fd);
unlink (file);
return 0;
}
if (fdatasync (fd) == -1) {
if (log) {
(void) fprintf (shadow_logfd,
"%s: %s file sync error: %s\n",
shadow_progname, file, strerror (errno));
}
(void) close (fd);
unlink (file);
@@ -167,12 +166,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
close (fd);
if (link (file, lock) == 0) {
retval = check_link_count (file);
if ((0==retval) && log) {
(void) fprintf (stderr,
"%s: %s: lock file already used\n",
Prog, file);
}
retval = check_link_count (file, log);
unlink (file);
return retval;
}
@@ -180,9 +174,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
fd = open (lock, O_RDWR);
if (-1 == fd) {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: %s: %s\n",
Prog, lock, strerror (errno));
shadow_progname, lock, strerror (errno));
}
unlink (file);
errno = EINVAL;
@@ -192,20 +186,20 @@ static int do_lock_file (const char *file, const char *lock, bool log)
close (fd);
if (len <= 0) {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: existing lock file %s without a PID\n",
Prog, lock);
shadow_progname, lock);
}
unlink (file);
errno = EINVAL;
return 0;
}
buf[len] = '\0';
if (get_pid (buf, &pid) == 0) {
if (get_pid(buf, &pid) == -1) {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: existing lock file %s with an invalid PID '%s'\n",
Prog, lock, buf);
shadow_progname, lock, buf);
}
unlink (file);
errno = EINVAL;
@@ -213,9 +207,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
}
if (kill (pid, 0) == 0) {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: lock %s already used by PID %lu\n",
Prog, lock, (unsigned long) pid);
shadow_progname, lock, (unsigned long) pid);
}
unlink (file);
errno = EEXIST;
@@ -223,9 +217,9 @@ static int do_lock_file (const char *file, const char *lock, bool log)
}
if (unlink (lock) != 0) {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: cannot get lock %s: %s\n",
Prog, lock, strerror (errno));
shadow_progname, lock, strerror (errno));
}
unlink (file);
return 0;
@@ -233,17 +227,12 @@ static int do_lock_file (const char *file, const char *lock, bool log)
retval = 0;
if (link (file, lock) == 0) {
retval = check_link_count (file);
if ((0==retval) && log) {
(void) fprintf (stderr,
"%s: %s: lock file already used\n",
Prog, file);
}
retval = check_link_count (file, log);
} else {
if (log) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: cannot get lock %s: %s\n",
Prog, lock, strerror (errno));
shadow_progname, lock, strerror (errno));
}
}
@@ -267,25 +256,13 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
return NULL;
}
#ifdef HAVE_FCHOWN
if (fchown (fileno (fp), sb->st_uid, sb->st_gid) != 0) {
goto fail;
}
#else /* !HAVE_FCHOWN */
if (chown (name, sb->st_mode) != 0) {
goto fail;
}
#endif /* !HAVE_FCHOWN */
#ifdef HAVE_FCHMOD
if (fchmod (fileno (fp), sb->st_mode & 0664) != 0) {
goto fail;
}
#else /* !HAVE_FCHMOD */
if (chmod (name, sb->st_mode & 0664) != 0) {
goto fail;
}
#endif /* !HAVE_FCHMOD */
return fp;
fail:
@@ -326,8 +303,12 @@ static int create_backup (const char *backup, FILE * fp)
/* FIXME: unlink the backup file? */
return -1;
}
if ( (fsync (fileno (bkfp)) != 0)
|| (fclose (bkfp) != 0)) {
if (fsync (fileno (bkfp)) != 0) {
(void) fclose (bkfp);
/* FIXME: unlink the backup file? */
return -1;
}
if (fclose (bkfp) != 0) {
/* FIXME: unlink the backup file? */
return -1;
}
@@ -347,9 +328,7 @@ static void free_linked_list (struct commonio_db *db)
p = db->head;
db->head = p->next;
if (NULL != p->line) {
free (p->line);
}
free (p->line);
if (NULL != p->eptr) {
db->ops->free (p->eptr);
@@ -363,7 +342,7 @@ static void free_linked_list (struct commonio_db *db)
int commonio_setname (struct commonio_db *db, const char *name)
{
snprintf (db->filename, sizeof (db->filename), "%s", name);
SNPRINTF(db->filename, "%s", name);
db->setname = true;
return 1;
}
@@ -377,38 +356,28 @@ bool commonio_present (const struct commonio_db *db)
int commonio_lock_nowait (struct commonio_db *db, bool log)
{
char* file = NULL;
char* lock = NULL;
size_t lock_file_len;
size_t file_len;
int err = 0;
int err = 0;
char *file = NULL;
char *lock = NULL;
if (db->locked) {
return 1;
}
file_len = strlen(db->filename) + 11;/* %lu max size */
lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */
file = (char*)malloc(file_len);
if(file == NULL) {
if (asprintf(&file, "%s.%ju", db->filename, (uintmax_t) getpid()) == -1)
goto cleanup_ENOMEM;
}
lock = (char*)malloc(lock_file_len);
if(lock == NULL) {
if (asprintf(&lock, "%s.lock", db->filename) == -1)
goto cleanup_ENOMEM;
}
snprintf (file, file_len, "%s.%lu",
db->filename, (unsigned long) getpid ());
snprintf (lock, lock_file_len, "%s.lock", db->filename);
if (do_lock_file (file, lock, log) != 0) {
db->locked = true;
lock_count++;
err = 1;
}
cleanup_ENOMEM:
if(file)
free(file);
if(lock)
free(lock);
free(file);
free(lock);
return err;
}
@@ -432,9 +401,9 @@ int commonio_lock (struct commonio_db *db)
if (0 == lock_count) {
if (lckpwdf () == -1) {
if (geteuid () != 0) {
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
"%s: Permission denied.\n",
Prog);
shadow_progname);
}
return 0; /* failure */
}
@@ -468,8 +437,8 @@ int commonio_lock (struct commonio_db *db)
}
/* no unnecessary retries on "permission denied" errors */
if (geteuid () != 0) {
(void) fprintf (stderr, "%s: Permission denied.\n",
Prog);
(void) fprintf (shadow_logfd, "%s: Permission denied.\n",
shadow_progname);
return 0;
}
}
@@ -499,7 +468,7 @@ static void dec_lock_count (void)
int commonio_unlock (struct commonio_db *db)
{
char lock[1024];
char lock[1029];
if (db->isopen) {
db->readonly = true;
@@ -516,7 +485,7 @@ int commonio_unlock (struct commonio_db *db)
* then call ulckpwdf() (if used) on last unlock.
*/
db->locked = false;
snprintf (lock, sizeof lock, "%s.lock", db->filename);
SNPRINTF(lock, "%s.lock", db->filename);
unlink (lock);
dec_lock_count ();
return 1;
@@ -634,7 +603,7 @@ int commonio_open (struct commonio_db *db, int mode)
fd = open (db->filename,
(db->readonly ? O_RDONLY : O_RDWR)
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW | O_CLOEXEC);
saved_errno = errno;
db->fp = NULL;
if (fd >= 0) {
@@ -665,22 +634,19 @@ int commonio_open (struct commonio_db *db, int mode)
return 0;
}
/* Do not inherit fd in spawned processes (e.g. nscd) */
fcntl (fileno (db->fp), F_SETFD, FD_CLOEXEC);
buflen = BUFLEN;
buf = (char *) malloc (buflen);
buf = MALLOC(buflen, char);
if (NULL == buf) {
goto cleanup_ENOMEM;
}
while (db->ops->fgets (buf, (int) buflen, db->fp) == buf) {
while ( ((cp = strrchr (buf, '\n')) == NULL)
while (db->ops->fgets (buf, buflen, db->fp) == buf) {
while ( (strrchr (buf, '\n') == NULL)
&& (feof (db->fp) == 0)) {
size_t len;
buflen += BUFLEN;
cp = (char *) realloc (buf, buflen);
cp = REALLOC(buf, buflen, char);
if (NULL == cp) {
goto cleanup_buf;
}
@@ -714,7 +680,7 @@ int commonio_open (struct commonio_db *db, int mode)
}
}
p = (struct commonio_entry *) malloc (sizeof *p);
p = MALLOC(1, struct commonio_entry);
if (NULL == p) {
goto cleanup_entry;
}
@@ -791,7 +757,7 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
return 0;
}
entries = malloc (n * sizeof (struct commonio_entry *));
entries = MALLOC(n, struct commonio_entry *);
if (entries == NULL) {
return -1;
}
@@ -928,9 +894,9 @@ static int write_all (const struct commonio_db *db)
int commonio_close (struct commonio_db *db)
{
char buf[1024];
int errors = 0;
struct stat sb;
int errors = 0;
char buf[1024];
struct stat sb;
if (!db->isopen) {
errno = EINVAL;
@@ -961,10 +927,14 @@ int commonio_close (struct commonio_db *db)
/*
* Create backup file.
*/
snprintf (buf, sizeof buf, "%s-", db->filename);
if (SNPRINTF(buf, "%s-", db->filename) == -1) {
(void) fclose (db->fp);
db->fp = NULL;
goto fail;
}
#ifdef WITH_SELINUX
if (set_selinux_file_context (buf) != 0) {
if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
errors++;
}
#endif
@@ -976,15 +946,15 @@ int commonio_close (struct commonio_db *db)
errors++;
}
db->fp = NULL;
#ifdef WITH_SELINUX
if (reset_selinux_file_context () != 0) {
errors++;
}
#endif
if (errors != 0) {
db->fp = NULL;
if (errors != 0)
goto fail;
}
} else {
/*
* Default permissions for new [g]shadow files.
@@ -994,10 +964,11 @@ int commonio_close (struct commonio_db *db)
sb.st_gid = db->st_gid;
}
snprintf (buf, sizeof buf, "%s+", db->filename);
if (SNPRINTF(buf, "%s+", db->filename) == -1)
goto fail;
#ifdef WITH_SELINUX
if (set_selinux_file_context (buf) != 0) {
if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
errors++;
}
#endif
@@ -1014,13 +985,11 @@ int commonio_close (struct commonio_db *db)
if (fflush (db->fp) != 0) {
errors++;
}
#ifdef HAVE_FSYNC
if (fsync (fileno (db->fp)) != 0) {
errors++;
}
#else /* !HAVE_FSYNC */
sync ();
#endif /* !HAVE_FSYNC */
if (fclose (db->fp) != 0) {
errors++;
}
@@ -1099,7 +1068,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
p = find_entry_by_name (db, db->ops->getname (eptr));
if (NULL != p) {
if (next_entry_by_name (db, p->next, db->ops->getname (eptr)) != NULL) {
fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename);
fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename);
db->ops->free (nentry);
return 0;
}
@@ -1112,7 +1081,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
return 1;
}
/* not found, new entry */
p = (struct commonio_entry *) malloc (sizeof *p);
p = MALLOC(1, struct commonio_entry);
if (NULL == p) {
db->ops->free (nentry);
errno = ENOMEM;
@@ -1149,7 +1118,7 @@ int commonio_append (struct commonio_db *db, const void *eptr)
return 0;
}
/* new entry */
p = (struct commonio_entry *) malloc (sizeof *p);
p = MALLOC(1, struct commonio_entry);
if (NULL == p) {
db->ops->free (nentry);
errno = ENOMEM;
@@ -1204,20 +1173,20 @@ int commonio_remove (struct commonio_db *db, const char *name)
return 0;
}
if (next_entry_by_name (db, p->next, name) != NULL) {
fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename);
fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), name, db->filename);
return 0;
}
commonio_del_entry (db, p);
if (NULL != p->line) {
free (p->line);
}
free (p->line);
if (NULL != p->eptr) {
db->ops->free (p->eptr);
}
free(p);
return 1;
}

View File

@@ -1,45 +1,21 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
/* $Id$ */
#ifndef COMMONIO_H
#define COMMONIO_H
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#include "attr.h"
#include "defines.h" /* bool */
/*
* Linked list entry.
*/
@@ -64,7 +40,7 @@ struct commonio_ops {
/*
* free() the object including any strings pointed by it.
*/
void (*free) (/*@out@*/ /*@only@*/void *);
void (*free)(/*@only@*/void *);
/*
* Return the name of the object (for example, pw_name
@@ -88,7 +64,9 @@ struct commonio_ops {
* fgets and fputs (can be replaced by versions that
* understand line continuation conventions).
*/
/*@null@*/char *(*fgets) (/*@returned@*/ /*@out@*/char *s, int n, FILE *stream);
ATTR_ACCESS(write_only, 1, 2)
/*@null@*/char *(*fgets)(/*@returned@*/char *restrict s, int n,
FILE *restrict stream);
int (*fputs) (const char *, FILE *);
/*
@@ -121,7 +99,7 @@ struct commonio_db {
/*@dependent@*/ /*@null@*/FILE *fp;
#ifdef WITH_SELINUX
/*@null@*/security_context_t scontext;
/*@null@*/char *scontext;
#endif
/*
* Default permissions and owner for newly created data file.
@@ -150,6 +128,7 @@ extern int commonio_setname (struct commonio_db *, const char *);
extern bool commonio_present (const struct commonio_db *db);
extern int commonio_lock (struct commonio_db *);
extern int commonio_lock_nowait (struct commonio_db *, bool log);
extern int do_fcntl_lock (const char *file, bool log, short type);
extern int commonio_open (struct commonio_db *, int);
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
extern int commonio_update (struct commonio_db *, const void *);

109
lib/console.c Normal file
View File

@@ -0,0 +1,109 @@
/*
* SPDX-FileCopyrightText: 1991 , Julianne Frances Haugh
* SPDX-FileCopyrightText: 1991 , Chip Rosenthal
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#include "defines.h"
#include <stdio.h>
#include "getdef.h"
#include "prototypes.h"
#include "string/strtcpy.h"
#ident "$Id$"
/*
* This is now rather generic function which decides if "tty" is listed
* under "cfgin" in config (directly or indirectly). Fallback to default if
* something is bad.
*/
static bool is_listed (const char *cfgin, const char *tty, bool def)
{
FILE *fp;
char buf[1024], *s;
const char *cons;
/*
* If the CONSOLE configuration definition isn't given,
* fallback to default.
*/
cons = getdef_str (cfgin);
if (NULL == cons) {
return def;
}
/*
* If this isn't a filename, then it is a ":" delimited list of
* console devices upon which root logins are allowed.
*/
if (*cons != '/') {
char *pbuf;
STRTCPY(buf, cons);
pbuf = &buf[0];
while ((s = strtok (pbuf, ":")) != NULL) {
if (strcmp (s, tty) == 0) {
return true;
}
pbuf = NULL;
}
return false;
}
/*
* If we can't open the console list, then call everything a
* console - otherwise root will never be allowed to login.
*/
fp = fopen (cons, "r");
if (NULL == fp) {
return def;
}
/*
* See if this tty is listed in the console file.
*/
while (fgets (buf, sizeof (buf), fp) != NULL) {
/* Remove optional trailing '\n'. */
buf[strcspn (buf, "\n")] = '\0';
if (strcmp (buf, tty) == 0) {
(void) fclose (fp);
return true;
}
}
/*
* This tty isn't a console.
*/
(void) fclose (fp);
return false;
}
/*
* console - return 1 if the "tty" is a console device, else 0.
*
* Note - we need to take extreme care here to avoid locking out root logins
* if something goes awry. That's why we do things like call everything a
* console if the consoles file can't be opened. Because of this, we must
* warn the user to protect against the remove of the consoles file since
* that would allow an unauthorized root login.
*/
bool console (const char *tty)
{
if (strncmp (tty, "/dev/", 5) == 0) {
tty += 5;
}
return is_listed ("CONSOLE", tty, true);
}

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2001, Marek Michałkiewicz
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -40,6 +17,9 @@
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include "alloc.h"
#include "attr.h"
#include "prototypes.h"
#include "defines.h"
#ifdef WITH_SELINUX
@@ -55,6 +35,8 @@
#ifdef WITH_ATTR
#include <attr/libattr.h>
#endif /* WITH_ATTR */
#include "shadowlog.h"
#include "string/sprintf.h"
static /*@null@*/const char *src_orig;
@@ -69,42 +51,43 @@ struct link_name {
};
static /*@exposed@*/struct link_name *links;
static int copy_entry (const char *src, const char *dst,
struct path_info {
const char *full_path;
int dirfd;
const char *name;
};
static int copy_entry (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int copy_dir (const char *src, const char *dst,
static int copy_dir (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
#ifdef S_IFLNK
static /*@null@*/char *readlink_malloc (const char *filename);
static int copy_symlink (const char *src, const char *dst,
unused bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
#endif /* S_IFLNK */
static int copy_hardlink (const char *dst,
unused bool reset_selinux,
static int copy_hardlink (const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
struct link_name *lp);
static int copy_special (const char *src, const char *dst,
static int copy_special (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int copy_file (const char *src, const char *dst,
static int copy_file (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int chown_if_needed (const char *dst, const struct stat *statp,
static int chownat_if_needed (const struct path_info *dst, const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int lchown_if_needed (const char *dst, const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
static int fchown_if_needed (int fdst, const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
@@ -113,11 +96,13 @@ static int fchown_if_needed (int fdst, const struct stat *statp,
/*
* error_acl - format the error messages for the ACL and EQ libraries.
*/
static void error_acl (struct error_context *ctx, const char *fmt, ...)
format_attr(printf, 2, 3)
static void error_acl (MAYBE_UNUSED struct error_context *ctx, const char *fmt, ...)
{
va_list ap;
FILE *shadow_logfd = log_get_logfd();
/* ignore the case when destination does not support ACLs
/* ignore the case when destination does not support ACLs
* or extended attributes */
if (ENOTSUP == errno) {
errno = 0;
@@ -125,19 +110,70 @@ static void error_acl (struct error_context *ctx, const char *fmt, ...)
}
va_start (ap, fmt);
(void) fprintf (stderr, _("%s: "), Prog);
if (vfprintf (stderr, fmt, ap) != 0) {
(void) fputs (_(": "), stderr);
(void) fprintf (shadow_logfd, _("%s: "), log_get_progname());
if (vfprintf (shadow_logfd, fmt, ap) != 0) {
(void) fputs (_(": "), shadow_logfd);
}
(void) fprintf (stderr, "%s\n", strerror (errno));
(void) fprintf (shadow_logfd, "%s\n", strerror (errno));
va_end (ap);
}
static struct error_context ctx = {
error_acl
error_acl, NULL, NULL
};
#endif /* WITH_ACL || WITH_ATTR */
#ifdef WITH_ACL
static int perm_copy_path(const struct path_info *src,
const struct path_info *dst,
struct error_context *errctx)
{
int src_fd, dst_fd, ret;
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
}
ret = perm_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, errctx);
(void) close (src_fd);
(void) close (dst_fd);
return ret;
}
#endif /* WITH_ACL */
#ifdef WITH_ATTR
static int attr_copy_path(const struct path_info *src,
const struct path_info *dst,
int (*callback) (const char *, struct error_context *),
struct error_context *errctx)
{
int src_fd, dst_fd, ret;
src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
}
ret = attr_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, callback, errctx);
(void) close (src_fd);
(void) close (dst_fd);
return ret;
}
#endif /* WITH_ATTR */
/*
* remove_link - delete a link from the linked list
*/
@@ -174,11 +210,7 @@ static void remove_link (/*@only@*/struct link_name *ln)
static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, const struct stat *sb)
{
struct link_name *lp;
size_t src_len;
size_t dst_len;
size_t name_len;
size_t len;
struct link_name *lp;
/* copy_tree () must be the entry point */
assert (NULL != src_orig);
@@ -194,67 +226,47 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
return NULL;
}
lp = (struct link_name *) xmalloc (sizeof *lp);
src_len = strlen (src_orig);
dst_len = strlen (dst_orig);
name_len = strlen (name);
lp = XMALLOC(1, struct link_name);
lp->ln_dev = sb->st_dev;
lp->ln_ino = sb->st_ino;
lp->ln_count = sb->st_nlink;
len = name_len - src_len + dst_len + 1;
lp->ln_name = (char *) xmalloc (len);
(void) snprintf (lp->ln_name, len, "%s%s", dst_orig, name + src_len);
xasprintf(&lp->ln_name, "%s%s", dst_orig, name + strlen(src_orig));
lp->ln_next = links;
links = lp;
return NULL;
}
/*
* copy_tree - copy files in a directory tree
*
* copy_tree() walks a directory tree and copies ordinary files
* as it goes.
*
* When reset_selinux is enabled, extended attributes (and thus
* SELinux attributes) are not copied.
*
* old_uid and new_uid are used to set the ownership of the copied
* files. Unless old_uid is set to -1, only the files owned by
* old_uid have their ownership changed to new_uid. In addition, if
* new_uid is set to -1, no ownership will be changed.
*
* The same logic applies for the group-ownership and
* old_gid/new_gid.
*/
int copy_tree (const char *src_root, const char *dst_root,
static int copy_tree_impl (const struct path_info *src, const struct path_info *dst,
bool copy_root, bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
int dst_fd, src_fd, err = 0;
bool set_orig = false;
struct DIRECT *ent;
const struct dirent *ent;
DIR *dir;
if (copy_root) {
struct stat sb;
if (access (dst_root, F_OK) == 0) {
if ( fstatat (dst->dirfd, dst->name, &sb, 0) == 0
|| errno != ENOENT) {
return -1;
}
if (LSTAT (src_root, &sb) == -1) {
if (fstatat (src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
return -1;
}
if (!S_ISDIR (sb.st_mode)) {
fprintf (stderr,
fprintf (log_get_logfd(),
"%s: %s is not a directory",
Prog, src_root);
log_get_progname(), src->full_path);
return -1;
}
return copy_entry (src_root, dst_root, reset_selinux,
return copy_entry (src, dst, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
}
@@ -264,8 +276,14 @@ int copy_tree (const char *src_root, const char *dst_root,
* target is created. It assumes the target directory exists.
*/
if ( (access (src_root, F_OK) != 0)
|| (access (dst_root, F_OK) != 0)) {
src_fd = openat (src->dirfd, src->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
if (src_fd < 0) {
return -1;
}
dst_fd = openat (dst->dirfd, dst->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
if (dst_fd < 0) {
(void) close (src_fd);
return -1;
}
@@ -276,58 +294,59 @@ int copy_tree (const char *src_root, const char *dst_root,
* regular files (and directories ...) are copied, and no file
* is made set-ID.
*/
dir = opendir (src_root);
dir = fdopendir (src_fd);
if (NULL == dir) {
(void) close (src_fd);
(void) close (dst_fd);
return -1;
}
if (src_orig == NULL) {
src_orig = src_root;
dst_orig = dst_root;
src_orig = src->full_path;
dst_orig = dst->full_path;
set_orig = true;
}
while ((0 == err) && (ent = readdir (dir)) != NULL) {
char *src_name = NULL;
char *dst_name;
struct path_info src_entry, dst_entry;
/*
* Skip the "." and ".." entries
*/
if ((strcmp (ent->d_name, ".") != 0) &&
(strcmp (ent->d_name, "..") != 0)) {
char *src_name;
char *dst_name;
size_t src_len = strlen (ent->d_name) + 2;
size_t dst_len = strlen (ent->d_name) + 2;
src_len += strlen (src_root);
dst_len += strlen (dst_root);
src_name = (char *) malloc (src_len);
dst_name = (char *) malloc (dst_len);
if ((NULL == src_name) || (NULL == dst_name)) {
err = -1;
} else {
/*
* Build the filename for both the source and
* the destination files.
*/
(void) snprintf (src_name, src_len, "%s/%s",
src_root, ent->d_name);
(void) snprintf (dst_name, dst_len, "%s/%s",
dst_root, ent->d_name);
err = copy_entry (src_name, dst_name,
reset_selinux,
old_uid, new_uid,
old_gid, new_gid);
}
if (NULL != src_name) {
free (src_name);
}
if (NULL != dst_name) {
free (dst_name);
}
if (strcmp(ent->d_name, ".") == 0 ||
strcmp(ent->d_name, "..") == 0)
{
continue;
}
if (asprintf(&src_name, "%s/%s", src->full_path, ent->d_name) == -1)
{
err = -1;
continue;
}
if (asprintf(&dst_name, "%s/%s", dst->full_path, ent->d_name) == -1)
{
err = -1;
goto skip;
}
src_entry.full_path = src_name;
src_entry.dirfd = dirfd(dir);
src_entry.name = ent->d_name;
dst_entry.full_path = dst_name;
dst_entry.dirfd = dst_fd;
dst_entry.name = ent->d_name;
err = copy_entry(&src_entry, &dst_entry, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
free(dst_name);
skip:
free(src_name);
}
(void) closedir (dir);
(void) close (dst_fd);
if (set_orig) {
src_orig = NULL;
@@ -374,87 +393,77 @@ int copy_tree (const char *src_root, const char *dst_root,
* old_gid) will be modified, unless old_uid (resp. old_gid) is set
* to -1.
*/
static int copy_entry (const char *src, const char *dst,
static int copy_entry (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
struct stat sb;
struct stat tmp_sb;
struct link_name *lp;
struct timeval mt[2];
struct timespec mt[2];
if (LSTAT (src, &sb) == -1) {
if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
/* If we cannot stat the file, do not care. */
} else {
#ifdef HAVE_STRUCT_STAT_ST_ATIM
mt[0].tv_sec = sb.st_atim.tv_sec;
mt[0].tv_usec = sb.st_atim.tv_nsec / 1000;
#else /* !HAVE_STRUCT_STAT_ST_ATIM */
mt[0].tv_sec = sb.st_atime;
# ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC
mt[0].tv_usec = sb.st_atimensec / 1000;
# else /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
mt[0].tv_usec = 0;
# endif /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
#endif /* !HAVE_STRUCT_STAT_ST_ATIM */
return 0;
}
#ifdef HAVE_STRUCT_STAT_ST_MTIM
mt[1].tv_sec = sb.st_mtim.tv_sec;
mt[1].tv_usec = sb.st_mtim.tv_nsec / 1000;
#else /* !HAVE_STRUCT_STAT_ST_MTIM */
mt[1].tv_sec = sb.st_mtime;
# ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
mt[1].tv_usec = sb.st_mtimensec / 1000;
# else /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
mt[1].tv_usec = 0;
# endif /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
#endif /* !HAVE_STRUCT_STAT_ST_MTIM */
mt[0].tv_sec = sb.st_atim.tv_sec;
mt[0].tv_nsec = sb.st_atim.tv_nsec;
if (S_ISDIR (sb.st_mode)) {
err = copy_dir (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
mt[1].tv_sec = sb.st_mtim.tv_sec;
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
#ifdef S_IFLNK
/*
* Copy any symbolic links
*/
if (S_ISDIR (sb.st_mode)) {
err = copy_dir (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
else if (S_ISLNK (sb.st_mode)) {
err = copy_symlink (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
#endif /* S_IFLNK */
/*
* If the destination already exists do nothing.
* This is after the copy_dir above to still iterate into subdirectories.
*/
if (fstatat(dst->dirfd, dst->name, &tmp_sb, AT_SYMLINK_NOFOLLOW) != -1) {
return err;
}
/*
* See if this is a previously copied link
*/
/*
* Copy any symbolic links
*/
else if ((lp = check_link (src, &sb)) != NULL) {
err = copy_hardlink (dst, reset_selinux, lp);
}
else if (S_ISLNK (sb.st_mode)) {
err = copy_symlink (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
/*
* Deal with FIFOs and special files. The user really
* shouldn't have any of these, but it seems like it
* would be nice to copy everything ...
*/
/*
* See if this is a previously copied link
*/
else if (!S_ISREG (sb.st_mode)) {
err = copy_special (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
else if ((lp = check_link (src->full_path, &sb)) != NULL) {
err = copy_hardlink (dst, reset_selinux, lp);
}
/*
* Create the new file and copy the contents. The new
* file will be owned by the provided UID and GID values.
*/
/*
* Deal with FIFOs and special files. The user really
* shouldn't have any of these, but it seems like it
* would be nice to copy everything ...
*/
else {
err = copy_file (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
else if (!S_ISREG (sb.st_mode)) {
err = copy_special (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
/*
* Create the new file and copy the contents. The new
* file will be owned by the provided UID and GID values.
*/
else {
err = copy_file (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
return err;
@@ -470,13 +479,14 @@ static int copy_entry (const char *src, const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_dir (const char *src, const char *dst,
static int copy_dir (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
struct stat dst_sb;
/*
* Create a new target directory, make it owned by
@@ -484,19 +494,27 @@ static int copy_dir (const char *src, const char *dst,
*/
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) {
if (set_selinux_file_context (dst->full_path, S_IFDIR) != 0) {
return -1;
}
#endif /* WITH_SELINUX */
if ( (mkdir (dst, statp->st_mode) != 0)
|| (chown_if_needed (dst, statp,
/*
* If the destination is already a directory, don't change it
* but copy into it (recursively).
*/
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
return (copy_tree_impl (src, dst, false, reset_selinux,
old_uid, new_uid, old_gid, new_gid) != 0);
}
if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
|| (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_file (src, dst, &ctx) != 0)
|| ( (perm_copy_path (src, dst, &ctx) != 0)
&& (errno != 0))
#else /* !WITH_ACL */
|| (chmod (dst, statp->st_mode) != 0)
#endif /* !WITH_ACL */
#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
@@ -506,19 +524,18 @@ static int copy_dir (const char *src, const char *dst,
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_file (src, dst, NULL, &ctx) != 0)
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
|| (copy_tree (src, dst, false, reset_selinux,
|| (copy_tree_impl (src, dst, false, reset_selinux,
old_uid, new_uid, old_gid, new_gid) != 0)
|| (utimes (dst, mt) != 0)) {
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
err = -1;
}
return err;
}
#ifdef S_IFLNK
/*
* readlink_malloc - wrapper for readlink
*
@@ -531,7 +548,7 @@ static /*@null@*/char *readlink_malloc (const char *filename)
while (true) {
ssize_t nchars;
char *buffer = (char *) malloc (size);
char *buffer = MALLOC(size, char);
if (NULL == buffer) {
return NULL;
}
@@ -565,9 +582,9 @@ static /*@null@*/char *readlink_malloc (const char *filename)
*
* Return 0 on success, -1 on error.
*/
static int copy_symlink (const char *src, const char *dst,
unused bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
@@ -585,7 +602,7 @@ static int copy_symlink (const char *src, const char *dst,
* destination directory name.
*/
oldlink = readlink_malloc (src);
oldlink = readlink_malloc (src->full_path);
if (NULL == oldlink) {
return -1;
}
@@ -594,24 +611,22 @@ static int copy_symlink (const char *src, const char *dst,
* create a link to the corresponding entry in the dst_orig
* directory.
*/
if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) {
size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1;
char *dummy = (char *) xmalloc (len);
(void) snprintf (dummy, len, "%s%s",
dst_orig,
oldlink + strlen (src_orig));
free (oldlink);
if (strncmp(oldlink, src_orig, strlen(src_orig)) == 0) {
char *dummy;
xasprintf(&dummy, "%s%s", dst_orig, oldlink + strlen(src_orig));
free(oldlink);
oldlink = dummy;
}
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) {
if (set_selinux_file_context (dst->full_path, S_IFLNK) != 0) {
free (oldlink);
return -1;
}
#endif /* WITH_SELINUX */
if ( (symlink (oldlink, dst) != 0)
|| (lchown_if_needed (dst, statp,
if ( (symlinkat (oldlink, dst->dirfd, dst->name) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)) {
/* FIXME: there are no modes on symlinks, right?
* ACL could be copied, but this would be much more
@@ -625,18 +640,12 @@ static int copy_symlink (const char *src, const char *dst,
}
free (oldlink);
#ifdef HAVE_LUTIMES
/* 2007-10-18: We don't care about
* exit status of lutimes because
* it returns ENOSYS on many system
* - not implemented
*/
(void) lutimes (dst, mt);
#endif /* HAVE_LUTIMES */
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
return -1;
}
return 0;
}
#endif /* S_IFLNK */
/*
* copy_hardlink - copy a hardlink
@@ -645,13 +654,13 @@ static int copy_symlink (const char *src, const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_hardlink (const char *dst,
unused bool reset_selinux,
static int copy_hardlink (const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
struct link_name *lp)
{
/* FIXME: selinux, ACL, Extended Attributes needed? */
if (link (lp->ln_name, dst) != 0) {
if (linkat (AT_FDCWD, lp->ln_name, dst->dirfd, dst->name, 0) != 0) {
return -1;
}
@@ -665,6 +674,7 @@ static int copy_hardlink (const char *dst,
return 0;
}
/*
* copy_special - copy a special file
*
@@ -675,30 +685,33 @@ static int copy_hardlink (const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_special (const char *src, const char *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
static int
copy_special(const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) {
#if defined(WITH_SELINUX)
if (set_selinux_file_context(dst->full_path, statp->st_mode & S_IFMT) != 0)
return -1;
}
#endif /* WITH_SELINUX */
#endif
if ( (mknod (dst, statp->st_mode & ~07777, statp->st_rdev) != 0)
|| (chown_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_file (src, dst, &ctx) != 0)
&& (errno != 0))
#else /* !WITH_ACL */
|| (chmod (dst, statp->st_mode & 07777) != 0)
#endif /* !WITH_ACL */
#ifdef WITH_ATTR
if (mknodat(dst->dirfd, dst->name, statp->st_mode & ~07777U, statp->st_rdev) == -1)
return -1;
if (chownat_if_needed(dst, statp, old_uid, new_uid, old_gid, new_gid) == -1)
return -1;
if (fchmodat(dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) == -1)
return -1;
#if defined(WITH_ACL)
if (perm_copy_path(src, dst, &ctx) == -1 && errno != 0)
return -1;
#endif
#if defined(WITH_ATTR)
/*
* If the third parameter is NULL, all extended attributes
* except those that define Access Control Lists are copied.
@@ -706,15 +719,16 @@ static int copy_special (const char *src, const char *dst,
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_file (src, dst, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
|| (utimes (dst, mt) != 0)) {
err = -1;
if (!reset_selinux) {
if (attr_copy_path(src, dst, NULL, &ctx) == -1 && errno != 0)
return -1;
}
#endif
return err;
if (utimensat(dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) == -1)
return -1;
return 0;
}
/*
@@ -727,37 +741,35 @@ static int copy_special (const char *src, const char *dst,
*
* Return 0 on success, -1 on error.
*/
static int copy_file (const char *src, const char *dst,
static int copy_file (const struct path_info *src, const struct path_info *dst,
bool reset_selinux,
const struct stat *statp, const struct timeval mt[],
const struct stat *statp, const struct timespec mt[],
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
int err = 0;
int ifd;
int ofd;
char buf[1024];
ssize_t cnt;
ifd = open (src, O_RDONLY);
ifd = openat (src->dirfd, src->name, O_RDONLY|O_NOFOLLOW|O_CLOEXEC);
if (ifd < 0) {
return -1;
}
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst) != 0) {
if (set_selinux_file_context (dst->full_path, S_IFREG) != 0) {
(void) close (ifd);
return -1;
}
#endif /* WITH_SELINUX */
ofd = open (dst, O_WRONLY | O_CREAT | O_TRUNC, statp->st_mode & 07777);
ofd = openat (dst->dirfd, dst->name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, 0600);
if ( (ofd < 0)
|| (fchown_if_needed (ofd, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
#ifdef WITH_ACL
|| ( (perm_copy_fd (src, ifd, dst, ofd, &ctx) != 0)
&& (errno != 0))
#else /* !WITH_ACL */
|| (fchmod (ofd, statp->st_mode & 07777) != 0)
#endif /* !WITH_ACL */
#ifdef WITH_ACL
|| ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
@@ -767,38 +779,49 @@ static int copy_file (const char *src, const char *dst,
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_fd (src, ifd, dst, ofd, NULL, &ctx) != 0)
&& (attr_copy_fd (src->full_path, ifd, dst->full_path, ofd, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
) {
if (ofd >= 0) {
(void) close (ofd);
}
(void) close (ifd);
return -1;
}
while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
if (write (ofd, buf, (size_t)cnt) != cnt) {
while (true) {
char buf[8192];
ssize_t cnt;
cnt = read (ifd, buf, sizeof buf);
if (cnt < 0) {
if (errno == EINTR) {
continue;
}
(void) close (ofd);
(void) close (ifd);
return -1;
}
if (cnt == 0) {
break;
}
if (write_full(ofd, buf, cnt) == -1) {
(void) close (ofd);
(void) close (ifd);
return -1;
}
}
(void) close (ifd);
#ifdef HAVE_FUTIMES
if (futimes (ofd, mt) != 0) {
return -1;
}
#endif /* HAVE_FUTIMES */
if (close (ofd) != 0) {
if (close (ofd) != 0 && errno != EINTR) {
return -1;
}
#ifndef HAVE_FUTIMES
if (utimes(dst, mt) != 0) {
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
return -1;
}
#endif /* !HAVE_FUTIMES */
return err;
}
@@ -833,7 +856,70 @@ static int chown_function ## _if_needed (type_dst dst, \
return chown_function (dst, tmpuid, tmpgid); \
}
def_chown_if_needed (chown, const char *)
def_chown_if_needed (lchown, const char *)
def_chown_if_needed (fchown, int)
static int chownat_if_needed (const struct path_info *dst,
const struct stat *statp,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
uid_t tmpuid = (uid_t) -1;
gid_t tmpgid = (gid_t) -1;
/* Use new_uid if old_uid is set to -1 or if the file was
* owned by the user. */
if (((uid_t) -1 == old_uid) || (statp->st_uid == old_uid)) {
tmpuid = new_uid;
}
/* Otherwise, or if new_uid was set to -1, we keep the same
* owner. */
if ((uid_t) -1 == tmpuid) {
tmpuid = statp->st_uid;
}
if (((gid_t) -1 == old_gid) || (statp->st_gid == old_gid)) {
tmpgid = new_gid;
}
if ((gid_t) -1 == tmpgid) {
tmpgid = statp->st_gid;
}
return fchownat (dst->dirfd, dst->name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW);
}
/*
* copy_tree - copy files in a directory tree
*
* copy_tree() walks a directory tree and copies ordinary files
* as it goes.
*
* When reset_selinux is enabled, extended attributes (and thus
* SELinux attributes) are not copied.
*
* old_uid and new_uid are used to set the ownership of the copied
* files. Unless old_uid is set to -1, only the files owned by
* old_uid have their ownership changed to new_uid. In addition, if
* new_uid is set to -1, no ownership will be changed.
*
* The same logic applies for the group-ownership and
* old_gid/new_gid.
*/
int copy_tree (const char *src_root, const char *dst_root,
bool copy_root, bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid)
{
const struct path_info src = {
.full_path = src_root,
.dirfd = AT_FDCWD,
.name = src_root
};
const struct path_info dst = {
.full_path = dst_root,
.dirfd = AT_FDCWD,
.name = dst_root
};
return copy_tree_impl(&src, &dst, copy_root, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
}

142
lib/csrand.c Normal file
View File

@@ -0,0 +1,142 @@
/*
* SPDX-FileCopyrightText: Alejandro Colomar <alx@kernel.org>
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#if HAVE_SYS_RANDOM_H
#include <sys/random.h>
#endif
#include "bit.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "sizeof.h"
static uint32_t csrand_uniform32(uint32_t n);
static unsigned long csrand_uniform_slow(unsigned long n);
/*
* Return a uniformly-distributed CS random u_long value.
*/
unsigned long
csrand(void)
{
FILE *fp;
unsigned long r;
#ifdef HAVE_GETENTROPY
/* getentropy may exist but lack kernel support. */
if (getentropy(&r, sizeof(r)) == 0)
return r;
#endif
#ifdef HAVE_GETRANDOM
/* Likewise getrandom. */
if (getrandom(&r, sizeof(r), 0) == sizeof(r))
return r;
#endif
#ifdef HAVE_ARC4RANDOM_BUF
/* arc4random_buf can never fail. */
arc4random_buf(&r, sizeof(r));
return r;
#endif
/* Use /dev/urandom as a last resort. */
fp = fopen("/dev/urandom", "r");
if (NULL == fp) {
goto fail;
}
if (fread(&r, sizeof(r), 1, fp) != 1) {
fclose(fp);
goto fail;
}
fclose(fp);
return r;
fail:
fprintf(log_get_logfd(), _("Unable to obtain random bytes.\n"));
exit(1);
}
/*
* Return a uniformly-distributed CS random value in the interval [0, n-1].
*/
unsigned long
csrand_uniform(unsigned long n)
{
if (n == 0 || n > UINT32_MAX)
return csrand_uniform_slow(n);
return csrand_uniform32(n);
}
/*
* Return a uniformly-distributed CS random value in the interval [min, max].
*/
unsigned long
csrand_interval(unsigned long min, unsigned long max)
{
return csrand_uniform(max - min + 1) + min;
}
/*
* Fast Random Integer Generation in an Interval
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
* <https://arxiv.org/abs/1805.10941>
*/
static uint32_t
csrand_uniform32(uint32_t n)
{
uint32_t bound, rem;
uint64_t r, mult;
if (n == 0)
return csrand();
bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`
do {
r = csrand();
mult = r * n;
rem = mult; // analogous to `mult % 2^32`
} while (rem < bound); // p = (2^32 % n) / 2^32; W.C.: n=2^31+1, p=0.5
r = mult >> WIDTHOF(n); // analogous to `mult / 2^32`
return r;
}
static unsigned long
csrand_uniform_slow(unsigned long n)
{
unsigned long r, max, mask;
max = n - 1;
mask = bit_ceil_wrapul(n) - 1;
do {
r = csrand();
r &= mask; // optimization
} while (r > max); // p = ((mask+1) % n) / (mask+1); W.C.: p=0.5
return r;
}

View File

@@ -4,43 +4,10 @@
#ifndef _DEFINES_H_
#define _DEFINES_H_
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if ! HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# endif
# endif
# define bool _Bool
# define false (0)
# define true (1)
# define __bool_true_false_are_defined 1
#endif
#include "config.h"
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
/* Take care of NLS matters. */
#ifdef S_SPLINT_S
extern char *setlocale(int categories, const char *locale);
# define LC_ALL (6)
extern char * bindtextdomain (const char * domainname, const char * dirname);
extern char * textdomain (const char * domainname);
# define _(Text) Text
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#else
#ifdef HAVE_LOCALE_H
# include <locale.h>
#else
# undef setlocale
# define setlocale(category, locale) (NULL)
# ifndef LC_ALL
# define LC_ALL 6
# endif
#endif
#include <stdbool.h>
#include <locale.h>
#define gettext_noop(String) (String)
/* #define gettext_def(String) "#define String" */
@@ -57,76 +24,31 @@ extern char * textdomain (const char * domainname);
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#endif
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else /* not STDC_HEADERS */
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr (), *strrchr (), *strtok ();
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy((s), (d), (n))
# endif
#endif /* not STDC_HEADERS */
#if HAVE_ERRNO_H
# include <errno.h>
#endif
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#if HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#include <sys/wait.h>
#include <unistd.h>
/*
* crypt(3), crypt_gensalt(3), and their
* feature test macros may be defined in here.
*/
#if HAVE_CRYPT_H
# include <crypt.h>
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <sys/time.h>
#include <time.h>
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else /* not TIME_WITH_SYS_TIME */
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif /* not TIME_WITH_SYS_TIME */
#ifdef HAVE_MEMSET
# define memzero(ptr, size) memset((void *)(ptr), 0, (size))
#else
# define memzero(ptr, size) bzero((char *)(ptr), (size))
#endif
#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
#ifdef HAVE_DIRENT_H /* DIR_SYSV */
# include <dirent.h>
# define DIRECT dirent
#else
# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */
# include <sys/ndir.h>
# endif
# ifdef HAVE_SYS_DIR_H /* DIR_??? */
# include <sys/dir.h>
# endif
# ifdef HAVE_NDIR_H /* DIR_BSD */
# include <ndir.h>
# endif
# define DIRECT direct
#endif
#include <dirent.h>
/*
* Possible cases:
@@ -148,7 +70,6 @@ char *strchr (), *strrchr (), *strtok ();
#endif
#endif
#ifdef USE_SYSLOG
#include <syslog.h>
#ifndef LOG_WARN
@@ -195,14 +116,6 @@ char *strchr (), *strrchr (), *strtok ();
#define SYSLOG(x) syslog x
#endif /* !ENABLE_NLS */
#else /* !USE_SYSLOG */
#define SYSLOG(x) /* empty */
#define openlog(a,b,c) /* empty */
#define closelog() /* empty */
#endif /* !USE_SYSLOG */
/* The default syslog settings can now be changed here,
in just one place. */
@@ -217,87 +130,25 @@ char *strchr (), *strrchr (), *strtok ();
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
#ifndef F_OK
# define F_OK 0
# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#ifndef SEEK_SET
# define SEEK_SET 0
# define SEEK_CUR 1
# define SEEK_END 2
#endif
#ifdef STAT_MACROS_BROKEN
# define S_ISDIR(x) ((x) & S_IFMT) == S_IFDIR)
# define S_ISREG(x) ((x) & S_IFMT) == S_IFREG)
# ifdef S_IFLNK
# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK)
# endif
#endif
#ifndef S_ISLNK
#define S_ISLNK(x) (0)
#endif
#if HAVE_LCHOWN
#define LCHOWN lchown
#else
#define LCHOWN chown
#endif
#if HAVE_LSTAT
#define LSTAT lstat
#else
#define LSTAT stat
#endif
#if HAVE_TERMIOS_H
# include <termios.h>
# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
# define GTTY(fd, termio) tcgetattr(fd, termio)
# define TERMIO struct termios
# define USE_TERMIOS
#else /* assumed HAVE_TERMIO_H */
# include <sys/ioctl.h>
# include <termio.h>
# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
# define TEMRIO struct termio
# define USE_TERMIO
#endif
#include <termios.h>
#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
#define GTTY(fd, termio) tcgetattr(fd, termio)
#define TERMIO struct termios
/*
* Password aging constants
*
* DAY - seconds / day
* WEEK - seconds / week
* SCALE - seconds / aging unit
*/
/* Solaris defines this in shadow.h */
#ifndef DAY
#define DAY (24L*3600L)
#define DAY ((time_t) 24 * 3600)
#endif
#define WEEK (7*DAY)
#ifdef ITI_AGING
#define SCALE 1
#else
#define SCALE DAY
#endif
/* Copy string pointed by B to array A with size checking. It was originally
in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
very sloppy coding used to assume that BUFSIZ will always be enough... */
/* danger - side effects */
#define STRFCPY(A,B) \
(strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
#ifndef PASSWD_FILE
#define PASSWD_FILE "/etc/passwd"
#endif
@@ -310,24 +161,20 @@ char *strchr (), *strrchr (), *strtok ();
#define SHADOW_FILE "/etc/shadow"
#endif
#ifndef SUBUID_FILE
#define SUBUID_FILE "/etc/subuid"
#endif
#ifndef SUBGID_FILE
#define SUBGID_FILE "/etc/subgid"
#endif
#ifdef SHADOWGRP
#ifndef SGROUP_FILE
#define SGROUP_FILE "/etc/gshadow"
#endif
#endif
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifdef sun /* hacks for compiling on SunOS */
# ifndef SOLARIS
extern int fputs ();
extern char *strdup ();
extern char *strerror ();
# endif
#endif
/*
* string to use for the pw_passwd field in /etc/passwd when using
* shadow passwords - most systems use "x" but there are a few
@@ -337,50 +184,18 @@ extern char *strerror ();
#define SHADOW_PASSWD_STRING "x"
#endif
#define SHADOW_SP_FLAG_UNSET ((unsigned long int)-1)
#define SHADOW_SP_FLAG_UNSET ((unsigned long)-1)
#ifdef WITH_AUDIT
#ifdef __u8 /* in case we use pam < 0.80 */
/* in case we use pam < 0.80 */
#undef __u8
#endif
#ifdef __u32
#undef __u32
#endif
#include <libaudit.h>
#endif
/* To be used for verified unused parameters */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define unused __attribute__((unused))
#else
# define unused
#endif
/* ! Arguments evaluated twice ! */
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
/* Maximum length of usernames */
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmpx *)NULL)->ut_user))
#else
# include <utmp.h>
# ifdef HAVE_STRUCT_UTMP_UT_USER
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
# else
# ifdef HAVE_STRUCT_UTMP_UT_NAME
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_name))
# else
# define USER_NAME_MAX_LENGTH 32
# endif
# endif
#endif
/* Maximum length of passwd entry */
#define PASSWD_ENTRY_MAX_LENGTH 32768
#ifdef HAVE_SECURE_GETENV
# define shadow_getenv(name) secure_getenv(name)
@@ -388,4 +203,14 @@ extern char *strerror ();
# define shadow_getenv(name) getenv(name)
#endif
/*
* Maximum password length
*
* Consider that there is also limit in PAM (PAM_MAX_RESP_SIZE)
* currently set to 512.
*/
#if !defined(PASS_MAX)
#define PASS_MAX BUFSIZ - 1
#endif
#endif /* _DEFINES_H_ */

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1990 - 1993, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1990 - 1993, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -39,6 +16,7 @@
#include "prototypes.h"
#include "defines.h"
#include "shadowlog_internal.h"
/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt)
{
@@ -74,6 +52,9 @@
case '6':
method = "SHA512";
break;
case 'y':
method = "YESCRYPT";
break;
default:
{
static char nummethod[4] = "$x$";
@@ -81,7 +62,7 @@
method = &nummethod[0];
}
}
(void) fprintf (stderr,
(void) fprintf (shadow_logfd,
_("crypt method not supported by libcrypt? (%s)\n"),
method);
exit (EXIT_FAILURE);

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1989 - 1992, Julianne Frances Haugh
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1989 - 1992, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 - 2009, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -38,8 +15,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include "shadowlog.h"
#include "string/sprintf.h"
/*
* NEWENVP_STEP must be a power of two. This is the number
* of (char *) pointers to allocate at a time, to avoid using
@@ -48,9 +31,8 @@
#define NEWENVP_STEP 16
size_t newenvc = 0;
/*@null@*/char **newenvp = NULL;
extern char **environ;
static const char *forbid[] = {
static const char *const forbid[] = {
"_RLD_=",
"BASH_ENV=", /* GNU creeping featurism strikes again... */
"ENV=",
@@ -64,16 +46,16 @@ static const char *forbid[] = {
"PATH=",
"SHELL=",
"SHLIB_PATH=",
(char *) 0
NULL
};
/* these are allowed, but with no slashes inside
(to work around security problems in GNU gettext) */
static const char *noslash[] = {
static const char *const noslash[] = {
"LANG=",
"LANGUAGE=",
"LC_", /* anything with the LC_ prefix */
(char *) 0
NULL
};
/*
@@ -81,23 +63,18 @@ static const char *noslash[] = {
*/
void initenv (void)
{
newenvp = (char **) xmalloc (NEWENVP_STEP * sizeof (char *));
newenvp = XMALLOC(NEWENVP_STEP, char *);
*newenvp = NULL;
}
void addenv (const char *string, /*@null@*/const char *value)
{
char *cp, *newstring;
size_t i;
size_t n;
char *cp, *newstring;
size_t i, n;
if (NULL != value) {
size_t len = strlen (string) + strlen (value) + 2;
int wlen;
newstring = xmalloc (len);
wlen = snprintf (newstring, len, "%s=%s", string, value);
assert (wlen == (int) len -1);
xasprintf(&newstring, "%s=%s", string, value);
} else {
newstring = xstrdup (string);
}
@@ -109,7 +86,7 @@ void addenv (const char *string, /*@null@*/const char *value)
cp = strchr (newstring, '=');
if (NULL == cp) {
free (newstring);
free(newstring);
return;
}
@@ -126,7 +103,7 @@ void addenv (const char *string, /*@null@*/const char *value)
}
if (i < newenvc) {
free (newenvp[i]);
free(newenvp[i]);
newenvp[i] = newstring;
return;
}
@@ -149,32 +126,19 @@ void addenv (const char *string, /*@null@*/const char *value)
*/
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
char **__newenvp;
size_t newsize;
bool update_environ;
update_environ = (environ == newenvp);
newenvp = XREALLOC(newenvp, newenvc + NEWENVP_STEP, char *);
/*
* If the resize operation succeeds we can
* happily go on, else print a message.
* If this is our current environment, update
* environ so that it doesn't point to some
* free memory area (realloc() could move it).
*/
newsize = (newenvc + NEWENVP_STEP) * sizeof (char *);
__newenvp = (char **) realloc (newenvp, newsize);
if (NULL != __newenvp) {
/*
* If this is our current environment, update
* environ so that it doesn't point to some
* free memory area (realloc() could move it).
*/
if (environ == newenvp) {
environ = __newenvp;
}
newenvp = __newenvp;
} else {
(void) fputs (_("Environment overflow\n"), stderr);
newenvc--;
free (newenvp[newenvc]);
}
if (update_environ)
environ = newenvp;
}
/*
@@ -190,9 +154,9 @@ void addenv (const char *string, /*@null@*/const char *value)
*/
void set_env (int argc, char *const *argv)
{
int noname = 1;
char variable[1024];
char *cp;
int noname = 1;
char variable[1024];
char *cp;
for (; argc > 0; argc--, argv++) {
if (strlen (*argv) >= sizeof variable) {
@@ -201,13 +165,11 @@ void set_env (int argc, char *const *argv)
cp = strchr (*argv, '=');
if (NULL == cp) {
int wlen;
wlen = snprintf (variable, sizeof variable, "L%d", noname);
assert (wlen < (int) sizeof(variable));
assert(SNPRINTF(variable, "L%d", noname) != -1);
noname++;
addenv (variable, *argv);
} else {
const char **p;
const char *const *p;
for (p = forbid; NULL != *p; p++) {
if (strncmp (*argv, *p, strlen (*p)) == 0) {
@@ -216,8 +178,7 @@ void set_env (int argc, char *const *argv)
}
if (NULL != *p) {
strncpy (variable, *argv, (size_t)(cp - *argv));
variable[cp - *argv] = '\0';
stpcpy(mempcpy(variable, *argv, (size_t)(cp - *argv)), "");
printf (_("You may not change $%s\n"),
variable);
continue;
@@ -240,7 +201,7 @@ void set_env (int argc, char *const *argv)
void sanitize_env (void)
{
char **envp = environ;
const char **bad;
const char *const *bad;
char **cur;
char **move;

View File

@@ -1,30 +1,7 @@
/*
* Copyright (c) 2005 - 2006, Tomasz Kłoczko
* All rights reserved.
* SPDX-FileCopyrightText: 2005 - 2006, Tomasz Kłoczko
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
/* $Id$ */

View File

@@ -1,32 +1,9 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* All rights reserved.
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
@@ -45,8 +22,8 @@
struct faillog {
short fail_cnt; /* failures since last success */
short fail_max; /* failures before turning account off */
char fail_line[12]; /* last failure occured here */
time_t fail_time; /* last failure occured then */
char fail_line[12]; /* last failure occurred here */
time_t fail_time; /* last failure occurred then */
/*
* If nonzero, the account will be re-enabled if there are no
* failures for fail_locktime seconds since last failure.

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2002 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 - 2010, Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2002 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 - 2010, Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -37,10 +14,16 @@
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include "defines.h"
#include "faillog.h"
#include "getdef.h"
#include "failure.h"
#include "memzero.h"
#include "prototypes.h"
#include "string/strftime.h"
#include "string/strtcpy.h"
#define YEAR (365L*DAY)
/*
* failure - make failure entry
@@ -64,7 +47,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
fd = open (FAILLOG_FILE, O_RDWR);
if (fd < 0) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
"Can't write faillog entry for UID %lu in %s: %m",
(unsigned long) uid, FAILLOG_FILE));
return;
}
@@ -76,7 +59,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
*/
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
/* This is not necessarily a failure. The file is
* initially zero length.
*
@@ -98,7 +81,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
fl->fail_cnt++;
}
strncpy (fl->fail_line, tty, sizeof fl->fail_line);
STRTCPY(fl->fail_line, tty);
(void) time (&fl->fail_time);
/*
@@ -109,13 +92,26 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
*/
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
(void) close (fd);
|| (write_full(fd, fl, sizeof *fl) == -1)) {
goto err_write;
}
if (close (fd) != 0 && errno != EINTR) {
goto err_close;
}
return;
err_write:
{
int saved_errno = errno;
(void) close (fd);
errno = saved_errno;
}
err_close:
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu to %s: %m",
(unsigned long) uid, FAILLOG_FILE));
}
static bool too_many_failures (const struct faillog *fl)
@@ -167,7 +163,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
fd = open (FAILLOG_FILE, failed?O_RDONLY:O_RDWR);
if (fd < 0) {
SYSLOG ((LOG_WARN,
"Can't open the faillog file (%s) to check UID %lu. "
"Can't open the faillog file (%s) to check UID %lu: %m; "
"User access authorized.",
FAILLOG_FILE, (unsigned long) uid));
return 1;
@@ -186,7 +182,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
*/
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
(void) close (fd);
return 1;
}
@@ -208,18 +204,30 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
fail.fail_cnt = 0;
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't reset faillog entry for UID %lu in %s.",
(unsigned long) uid, FAILLOG_FILE));
(void) close (fd);
|| (write_full(fd, &fail, sizeof fail) == -1)) {
goto err_write;
}
if (close (fd) != 0 && errno != EINTR) {
goto err_close;
}
} else {
(void) close (fd);
}
return 1;
err_write:
{
int saved_errno = errno;
(void) close (fd);
errno = saved_errno;
}
err_close:
SYSLOG ((LOG_WARN,
"Can't reset faillog entry for UID %lu in %s: %m",
(unsigned long) uid, FAILLOG_FILE));
return 1;
}
/*
@@ -232,13 +240,8 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
void failprint (const struct faillog *fail)
{
struct tm *tp;
#if HAVE_STRFTIME
char lasttimeb[256];
char *lasttime = lasttimeb;
#else
char *lasttime;
#endif
time_t NOW;
if (0 == fail->fail_cnt) {
@@ -248,31 +251,11 @@ void failprint (const struct faillog *fail)
tp = localtime (&(fail->fail_time));
(void) time (&NOW);
#if HAVE_STRFTIME
/*
* Print all information we have.
*/
(void) strftime (lasttimeb, sizeof lasttimeb, "%c", tp);
#else
STRFTIME(lasttimeb, "%c", tp);
/*
* Do the same thing, but don't use strftime since it
* probably doesn't exist on this system
*/
lasttime = asctime (tp);
lasttime[24] = '\0';
if ((NOW - fail->fail_time) < YEAR) {
lasttime[19] = '\0';
}
if ((NOW - fail->fail_time) < DAY) {
lasttime = lasttime + 11;
}
if (' ' == *lasttime) {
lasttime++;
}
#endif
/*@-formatconst@*/
(void) printf (ngettext ("%d failure since last login.\n"
"Last was %s on %s.\n",
@@ -282,62 +265,3 @@ void failprint (const struct faillog *fail)
fail->fail_cnt, lasttime, fail->fail_line);
/*@=formatconst@*/
}
/*
* failtmp - update the cumulative failure log
*
* failtmp updates the (struct utmp) formatted failure log which
* maintains a record of all login failures.
*/
void failtmp (const char *username,
#ifdef USE_UTMPX
const struct utmpx *failent
#else /* !USE_UTMPX */
const struct utmp *failent
#endif /* !USE_UTMPX */
)
{
const char *ftmp;
int fd;
/*
* Get the name of the failure file. If no file has been defined
* in login.defs, don't do this.
*/
ftmp = getdef_str ("FTMP_FILE");
if (NULL == ftmp) {
return;
}
/*
* Open the file for append. It must already exist for this
* feature to be used.
*/
if (access (ftmp, F_OK) != 0) {
return;
}
fd = open (ftmp, O_WRONLY | O_APPEND);
if (-1 == fd) {
SYSLOG ((LOG_WARN,
"Can't append failure of user %s to %s.",
username, ftmp));
return;
}
/*
* Append the new failure record and close the log file.
*/
if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't append failure of user %s to %s.",
username, ftmp));
(void) close (fd);
}
}

44
lib/failure.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
* SPDX-FileCopyrightText: 2008 - 2009, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* $Id$ */
#ifndef _FAILURE_H_
#define _FAILURE_H_
#include "defines.h"
#include "faillog.h"
/*
* failure - make failure entry
*
* failure() creates a new (struct faillog) entry or updates an
* existing one with the current failed login information.
*/
extern void failure (uid_t, const char *, struct faillog *);
/*
* failcheck - check for failures > allowable
*
* failcheck() is called AFTER the password has been validated. If the
* account has been "attacked" with too many login failures, failcheck()
* returns FALSE to indicate that the login should be denied even though
* the password is valid.
*/
extern int failcheck (uid_t uid, struct faillog *fl, bool failed);
/*
* failprint - print line of failure information
*
* failprint takes a (struct faillog) entry and formats it into a
* message which is displayed at login time.
*/
extern void failprint (const struct faillog *);
#endif

41
lib/fd.c Normal file
View File

@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: 2024, Skyler Ferrante <sjf5462@rit.edu>
// SPDX-License-Identifier: BSD-3-Clause
/**
* To protect against file descriptor omission attacks, we open the std file
* descriptors with /dev/null if they are not already open. Code is based on
* fix_fds from sudo.c.
*/
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "prototypes.h"
static void check_fd(int fd);
void
check_fds(void)
{
/**
* Make sure stdin, stdout, stderr are open
* If they are closed, set them to /dev/null
*/
check_fd(STDIN_FILENO);
check_fd(STDOUT_FILENO);
check_fd(STDERR_FILENO);
}
static void
check_fd(int fd)
{
int devnull;
if (fcntl(fd, F_GETFL, 0) != -1)
return;
devnull = open("/dev/null", O_RDWR);
if (devnull != fd)
abort();
}

View File

@@ -1,33 +1,10 @@
/*
* Copyright (c) 1990 , Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* All rights reserved.
* SPDX-FileCopyrightText: 1990 , Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 , Nicolas François
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -44,9 +21,9 @@
*
* The supplied field is scanned for non-printable and other illegal
* characters.
* + -1 is returned if an illegal character is present.
* + 1 is returned if no illegal characters are present, but the field
* contains a non-printable character.
* + -1 is returned if an illegal or control character is present.
* + 1 is returned if no illegal or control characters are present,
* but the field contains a non-printable character.
* + 0 is returned otherwise.
*/
int valid_field (const char *field, const char *illegal)
@@ -60,20 +37,19 @@ int valid_field (const char *field, const char *illegal)
/* For each character of field, search if it appears in the list
* of illegal characters. */
for (cp = field; '\0' != *cp; cp++) {
if (strchr (illegal, *cp) != NULL) {
err = -1;
break;
}
if (illegal && NULL != strpbrk (field, illegal)) {
return -1;
}
if (0 == err) {
/* Search if there are some non-printable characters */
for (cp = field; '\0' != *cp; cp++) {
if (!isprint (*cp)) {
err = 1;
break;
}
/* Search if there are non-printable or control characters */
for (cp = field; '\0' != *cp; cp++) {
unsigned char c = *cp;
if (!isprint (c)) {
err = 1;
}
if (iscntrl (c)) {
err = -1;
break;
}
}
@@ -97,7 +73,7 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
printf ("\t%s [%s]: ", prompt, buf);
(void) fflush (stdout);
if (fgets (newf, (int) maxsize, stdin) != newf) {
if (fgets (newf, maxsize, stdin) != newf) {
return;
}
@@ -114,17 +90,16 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
* entering a space. --marekm
*/
while (--cp >= newf && isspace (*cp));
cp++;
while (newf < cp && isspace (cp[-1])) {
cp--;
}
*cp = '\0';
cp = newf;
while (('\0' != *cp) && isspace (*cp)) {
while (isspace (*cp)) {
cp++;
}
strncpy (buf, cp, maxsize - 1);
buf[maxsize - 1] = '\0';
strcpy (buf, cp);
}
}

View File

@@ -1,32 +1,9 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 2008 - 2011, Nicolas François
* Copyright (c) 2014, Red Hat, Inc.
* All rights reserved.
* SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 2008 - 2011, Nicolas François
* SPDX-FileCopyrightText: 2014, Red Hat, Inc.
*
* 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.
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
@@ -35,9 +12,11 @@
#include <stdio.h>
#include <errno.h>
#include "alloc.h"
#include "prototypes.h"
#include "groupio.h"
#include "getdef.h"
#include "shadowlog.h"
/*
* get_ranges - Get the minimum and maximum ID ranges for the search
@@ -62,32 +41,38 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
*preferred_min = (gid_t) 1;
/* Get the minimum ID range from login.defs or default to 101 */
*min_id = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL);
*min_id = getdef_ulong ("SYS_GID_MIN", 101UL);
/*
* If SYS_GID_MAX is unspecified, we should assume it to be one
* less than the GID_MIN (which is reserved for non-system accounts)
*/
gid_def_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1;
*max_id = (gid_t) getdef_ulong ("SYS_GID_MAX",
(unsigned long) gid_def_max);
gid_def_max = getdef_ulong ("GID_MIN", 1000UL) - 1;
*max_id = getdef_ulong ("SYS_GID_MAX", gid_def_max);
/* Check that the ranges make sense */
if (*max_id < *min_id) {
(void) fprintf (stderr,
(void) fprintf (log_get_logfd(),
_("%s: Invalid configuration: SYS_GID_MIN (%lu), "
"GID_MIN (%lu), SYS_GID_MAX (%lu)\n"),
Prog, (unsigned long) *min_id,
log_get_progname(), (unsigned long) *min_id,
getdef_ulong ("GID_MIN", 1000UL),
(unsigned long) *max_id);
return EINVAL;
}
/*
* Zero is reserved for root and the allocation algorithm does not
* work right with it.
*/
if (*min_id == 0) {
*min_id = (gid_t) 1;
}
} else {
/* Non-system groups */
/* Get the values from login.defs or use reasonable defaults */
*min_id = (gid_t) getdef_ulong ("GID_MIN", 1000UL);
*max_id = (gid_t) getdef_ulong ("GID_MAX", 60000UL);
*min_id = getdef_ulong ("GID_MIN", 1000UL);
*max_id = getdef_ulong ("GID_MAX", 60000UL);
/*
* The preferred minimum should match the standard ID minimum
@@ -97,10 +82,10 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
/* Check that the ranges make sense */
if (*max_id < *min_id) {
(void) fprintf (stderr,
(void) fprintf (log_get_logfd(),
_("%s: Invalid configuration: GID_MIN (%lu), "
"GID_MAX (%lu)\n"),
Prog, (unsigned long) *min_id,
log_get_progname(), (unsigned long) *min_id,
(unsigned long) *max_id);
return EINVAL;
}
@@ -114,19 +99,25 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
*
* On success, return 0
* If the ID is in use, return EEXIST
* If the ID might clash with -1, return EINVAL
* If the ID is outside the range, return ERANGE
* In other cases, return errno from getgrgid()
*/
static int check_gid (const gid_t gid,
const gid_t gid_min,
const gid_t gid_max,
bool *used_gids)
const bool *used_gids)
{
/* First test that the preferred ID is in the range */
if (gid < gid_min || gid > gid_max) {
return ERANGE;
}
/* Check for compatibility with 16b and 32b gid_t error codes */
if (gid == UINT16_MAX || gid == UINT32_MAX) {
return EINVAL;
}
/*
* Check whether we already detected this GID
* using the gr_next() loop
@@ -157,7 +148,7 @@ static int check_gid (const gid_t gid,
* [GID_MIN:GID_MAX] range.
* This ID should be higher than all the used GID, but if not possible,
* the lowest unused ID in the range will be returned.
*
*
* Return 0 on success, -1 if no unused GIDs are available.
*/
int find_new_gid (bool sys_group,
@@ -198,10 +189,10 @@ int find_new_gid (bool sys_group,
* gr_locate_gid() found the GID in an as-yet uncommitted
* entry. We'll proceed below and auto-set a GID.
*/
} else if (result == EEXIST || result == ERANGE) {
} else if (result == EEXIST || result == ERANGE || result == EINVAL) {
/*
* Continue on below. At this time, we won't
* treat these two cases differently.
* treat these three cases differently.
*/
} else {
/*
@@ -213,10 +204,10 @@ int find_new_gid (bool sys_group,
* more likely to want to stop and address the
* issue.
*/
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: Encountered error attempting to use "
"preferred GID: %s\n"),
Prog, strerror (result));
log_get_progname(), strerror (result));
return -1;
}
}
@@ -241,14 +232,13 @@ int find_new_gid (bool sys_group,
*/
/* Create an array to hold all of the discovered GIDs */
used_gids = malloc (sizeof (bool) * (gid_max +1));
used_gids = CALLOC (gid_max + 1, bool);
if (NULL == used_gids) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: failed to allocate memory: %s\n"),
Prog, strerror (errno));
log_get_progname(), strerror (errno));
return -1;
}
memset (used_gids, false, sizeof (bool) * (gid_max + 1));
/* First look for the lowest and highest value in the local database */
(void) gr_rewind ();
@@ -312,8 +302,11 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else {
/*
* An unexpected error occurred.
@@ -323,10 +316,10 @@ int find_new_gid (bool sys_group,
*
*/
if (!nospam) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: Can't get unique system GID (%s). "
"Suppressing additional messages.\n"),
Prog, strerror (result));
log_get_progname(), strerror (result));
SYSLOG ((LOG_ERR,
"Error checking available GIDs: %s",
strerror (result)));
@@ -355,8 +348,11 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else {
/*
* An unexpected error occurred.
@@ -366,10 +362,10 @@ int find_new_gid (bool sys_group,
*
*/
if (!nospam) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: Can't get unique system GID (%s). "
"Suppressing additional messages.\n"),
Prog, strerror (result));
log_get_progname(), strerror (result));
SYSLOG ((LOG_ERR,
"Error checking available GIDs: %s",
strerror (result)));
@@ -415,8 +411,11 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else {
/*
* An unexpected error occurred.
@@ -426,10 +425,10 @@ int find_new_gid (bool sys_group,
*
*/
if (!nospam) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: Can't get unique GID (%s). "
"Suppressing additional messages.\n"),
Prog, strerror (result));
log_get_progname(), strerror (result));
SYSLOG ((LOG_ERR,
"Error checking available GIDs: %s",
strerror (result)));
@@ -458,8 +457,11 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else {
/*
* An unexpected error occurred.
@@ -469,10 +471,10 @@ int find_new_gid (bool sys_group,
*
*/
if (!nospam) {
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: Can't get unique GID (%s). "
"Suppressing additional messages.\n"),
Prog, strerror (result));
log_get_progname(), strerror (result));
SYSLOG ((LOG_ERR,
"Error checking available GIDs: %s",
strerror (result)));
@@ -488,9 +490,9 @@ int find_new_gid (bool sys_group,
}
/* The code reached here and found no available IDs in the range */
fprintf (stderr,
fprintf (log_get_logfd(),
_("%s: Can't get unique GID (no more available GIDs)\n"),
Prog);
log_get_progname());
SYSLOG ((LOG_WARN, "no more available GIDs on the system"));
free (used_gids);
return -1;

64
lib/find_new_sub_gids.c Normal file
View File

@@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2012 Eric Biederman
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ifdef ENABLE_SUBIDS
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include "prototypes.h"
#include "subordinateio.h"
#include "getdef.h"
#include "shadowlog.h"
/*
* find_new_sub_gids - Find a new unused range of GIDs.
*
* If successful, find_new_sub_gids provides a range of unused
* user IDs in the [SUB_GID_MIN:SUB_GID_MAX] range.
*
* Return 0 on success, -1 if no unused GIDs are available.
*/
int find_new_sub_gids (gid_t *range_start, unsigned long *range_count)
{
unsigned long min, max;
unsigned long count;
gid_t start;
assert (range_start != NULL);
assert (range_count != NULL);
min = getdef_ulong ("SUB_GID_MIN", 100000UL);
max = getdef_ulong ("SUB_GID_MAX", 600100000UL);
count = getdef_ulong ("SUB_GID_COUNT", 65536);
if (min > max || count >= max || (min + count - 1) > max) {
(void) fprintf (log_get_logfd(),
_("%s: Invalid configuration: SUB_GID_MIN (%lu),"
" SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"),
log_get_progname(), min, max, count);
return -1;
}
start = sub_gid_find_free_range(min, max, count);
if (start == (gid_t)-1) {
fprintf (log_get_logfd(),
_("%s: Can't get unique subordinate GID range\n"),
log_get_progname());
SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system"));
return -1;
}
*range_start = start;
*range_count = count;
return 0;
}
#else /* !ENABLE_SUBIDS */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !ENABLE_SUBIDS */

64
lib/find_new_sub_uids.c Normal file
View File

@@ -0,0 +1,64 @@
/*
* SPDX-FileCopyrightText: 2012 Eric Biederman
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ifdef ENABLE_SUBIDS
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include "prototypes.h"
#include "subordinateio.h"
#include "getdef.h"
#include "shadowlog.h"
/*
* find_new_sub_uids - Find a new unused range of UIDs.
*
* If successful, find_new_sub_uids provides a range of unused
* user IDs in the [SUB_UID_MIN:SUB_UID_MAX] range.
*
* Return 0 on success, -1 if no unused UIDs are available.
*/
int find_new_sub_uids (uid_t *range_start, unsigned long *range_count)
{
unsigned long min, max;
unsigned long count;
uid_t start;
assert (range_start != NULL);
assert (range_count != NULL);
min = getdef_ulong ("SUB_UID_MIN", 100000UL);
max = getdef_ulong ("SUB_UID_MAX", 600100000UL);
count = getdef_ulong ("SUB_UID_COUNT", 65536);
if (min > max || count >= max || (min + count - 1) > max) {
(void) fprintf (log_get_logfd(),
_("%s: Invalid configuration: SUB_UID_MIN (%lu),"
" SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"),
log_get_progname(), min, max, count);
return -1;
}
start = sub_uid_find_free_range(min, max, count);
if (start == (uid_t)-1) {
fprintf (log_get_logfd(),
_("%s: Can't get unique subordinate UID range\n"),
log_get_progname());
SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system"));
return -1;
}
*range_start = start;
*range_count = count;
return 0;
}
#else /* !ENABLE_SUBIDS */
extern int ISO_C_forbids_an_empty_translation_unit;
#endif /* !ENABLE_SUBIDS */

Some files were not shown because too many files have changed in this diff Show More