Compare commits

..

25 Commits

Author SHA1 Message Date
Chris Hofstaedtler 4c944d236c pristine-tar data for shadow_4.19.3.orig.tar.xz 2026-02-02 07:32:37 +01:00
Chris Hofstaedtler 46cc41933b pristine-tar data for shadow_4.19.2.orig.tar.xz 2026-01-25 14:17:30 +01:00
Chris Hofstaedtler 388cb97893 pristine-tar data for shadow_4.19.0.orig.tar.xz 2026-01-06 00:37:55 +01:00
Chris Hofstaedtler 81c4e06c3b pristine-tar data for shadow_4.18.0.orig.tar.xz 2025-08-26 22:55:39 +02:00
Chris Hofstaedtler 4fcb8d510b pristine-tar data for shadow_4.17.4.orig.tar.xz 2025-03-29 13:24:40 +01:00
Chris Hofstaedtler 2ff61e3c80 pristine-tar data for shadow_4.17.3.orig.tar.xz 2025-03-16 14:48:45 +01:00
Chris Hofstaedtler 61472718df pristine-tar data for shadow_4.15.3.orig.tar.xz 2024-07-06 16:54:26 +02:00
Chris Hofstaedtler b63aced4b3 pristine-tar data for shadow_4.16.0.orig.tar.xz 2024-06-25 20:10:09 +02:00
Chris Hofstaedtler b532614a3b pristine-tar data for shadow_4.15.2.orig.tar.xz 2024-06-22 17:35:40 +02:00
Chris Hofstaedtler 02f8995749 pristine-tar data for shadow_4.15.1.orig.tar.xz 2024-06-13 04:22:50 +02:00
Balint Reczey cb56b9d10e pristine-tar data for shadow_4.13+dfsg1.orig.tar.xz 2022-11-10 16:24:14 +01:00
Balint Reczey bdb2aa7202 pristine-tar data for shadow_4.12.3+dfsg1.orig.tar.xz 2022-08-24 00:06:47 +02:00
Balint Reczey 7a3935ef98 pristine-tar data for shadow_4.12.2+dfsg1.orig.tar.xz 2022-08-20 18:17:23 +02:00
Balint Reczey 9d0f797494 pristine-tar data for shadow_4.11.1+dfsg1.orig.tar.xz 2022-01-21 23:41:20 +01:00
Balint Reczey 862809e6de pristine-tar data for shadow_4.9.orig.tar.xz 2021-11-07 15:19:02 +01:00
Balint Reczey 0e71b4600c pristine-tar data for shadow_4.8.1.orig.tar.xz 2020-02-06 23:15:00 +01:00
Andreas Henriksson fcee2d4028 pristine-tar data for shadow_4.8.orig.tar.xz 2019-12-05 13:30:32 +01:00
Balint Reczey 3ee8ec58bb pristine-tar data for shadow_4.7.orig.tar.xz 2019-06-23 22:06:49 +02:00
Balint Reczey d20c220441 pristine-tar data for shadow_4.6.orig.tar.gz 2019-03-03 23:31:35 +01:00
Balint Reczey 451264e2b2 pristine-tar data for shadow_4.5.orig.tar.gz 2017-08-10 18:26:48 -04:00
Balint Reczey d2ea0055d4 pristine-tar data for shadow_4.4.orig.tar.gz 2016-11-30 02:36:08 +01:00
Christian Perrier d48226e507 pristine-tar data for shadow_4.2.1.orig.tar.xz 2014-05-09 19:06:08 +02:00
Christian Perrier 1a19ece5ee pristine-tar data for shadow_4.2.orig.tar.xz 2014-03-14 21:57:28 +01:00
Christian Perrier a70f9f8694 pristine-tar data for shadow_4.2.orig.tar.xz 2014-03-01 19:59:51 +01:00
Christian Perrier 02ea908972 pristine-tar data for shadow_4.1.5.1.orig.tar.xz 2013-07-27 18:42:28 +02:00
10780 changed files with 111 additions and 777355 deletions
-4
View File
@@ -1,4 +0,0 @@
root = true
[*.{c,h}]
indent_style = tab
@@ -1,12 +0,0 @@
name: 'Install dependencies'
description: 'Install dependencies to build shadow-utils'
runs:
using: "composite"
steps:
- shell: bash
run: |
sudo apt-get update -y
sudo apt-get install -y ubuntu-dev-tools libbsd-dev
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
sudo apt-get update -y
sudo apt-get -y build-dep shadow
-110
View File
@@ -1,110 +0,0 @@
name: CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: debug
run: |
id
which bash
whoami
env
ps -ef
pwd
cat /proc/self/uid_map
cat /proc/self/status
systemd-detect-virt
- name: Install dependencies
run: |
sudo cat /etc/apt/sources.list
sudo sed -i '/deb-src/d' /etc/apt/sources.list
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
export DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND=noninteractive
# let's try to work around upgrade breakage in a pkg we don't care about
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev pkgconf libcmocka-dev
sudo apt-get -y build-dep shadow
- name: configure
run: |
autoreconf -v -f --install
./autogen.sh --without-selinux --disable-man --with-yescrypt
- run: make
- run: make install DESTDIR=${HOME}/rootfs
- run: sudo make install
- name: run tests in shell with tty
shell: 'script -q -e -c "bash {0}"'
run: |
set -e
cd tests
trap 'cat testsuite.log' ERR
sudo ./run_some
trap - ERR
# Make sure that 'make dist' makes a usable tarball with no missing files
dist-build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo cat /etc/apt/sources.list
sudo sed -i '/deb-src/d' /etc/apt/sources.list
sudo sed -i '/^deb /p;s/ /-src /' /etc/apt/sources.list
export DEBIAN_PRIORITY=critical
export DEBIAN_FRONTEND=noninteractive
# let's try to work around upgrade breakage in a pkg we don't care about
sudo apt-mark hold grub-efi-amd64-bin grub-efi-amd64-signed
sudo apt-get update
sudo apt-get -y dist-upgrade
sudo apt-get -y install ubuntu-dev-tools automake autopoint xsltproc gettext expect byacc libtool libbsd-dev pkgconf
sudo apt-get -y build-dep shadow
- name: Test make dist
run: |
./autogen.sh
make dist
f=shadow-*.tar.gz
tar -zxf $f
d=$(basename $f .tar.gz)
cd $d
./configure
make -j5
make check
container-build:
runs-on: ubuntu-latest
strategy:
matrix:
os: [alpine, debian, fedora]
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Build container
run: |
docker buildx build -f ./share/containers/${{ matrix.os }}.dockerfile . --output build-out
- name: Store artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.os }}-build
path: |
./build-out/config.log
./build-out/config.h
if-no-files-found: ignore
@@ -1,58 +0,0 @@
name: "Static code analysis"
on:
push:
branches: [master]
pull_request:
branches: [master]
schedule:
# Everyday at midnight
- cron: '0 0 * * *'
jobs:
codeql:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Install dependencies
id: dependencies
uses: ./.github/actions/install-dependencies
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: cpp
queries: +security-and-quality
- name: Configure shadow-utils
run: ./autogen.sh --without-selinux --disable-man
- name: Build shadow-utils
run: |
PROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
make -Orecurse -j$PROCESSORS
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
differential-shellcheck:
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
# Doc: https://github.com/redhat-plumbers-in-action/differential-shellcheck#usage
- name: Differential ShellCheck
uses: redhat-plumbers-in-action/differential-shellcheck@v3
with:
severity: warning
token: ${{ secrets.GITHUB_TOKEN }}
-56
View File
@@ -1,56 +0,0 @@
*~
lib*.a
*.o
*.lo
*.la
*.mo
*.gmo
.deps
.libs
.dirstamp
*.patch
*.rej
*.orig
Makefile
Makefile.in
test-driver
/ABOUT-NLS
/aclocal.m4
/autom4te.cache
/compile
/config.cache
/config.guess
/config.h
/config.h.in
/config.log
/config.rpath
/config.status
/config.sub
/configure
/depcomp
/install-sh
/libtool
/ltmain.sh
/m4
/missing
/stamp-h1
/test-driver
/ylwrap
/po/*.header
/po/*.sed
/po/*.sin
/po/Makefile.in.in
/po/Makevars.template
/po/POTFILES
/po/Rules-quot
/po/stamp-po
/shadow.spec
/shadow-*.tar.*
/lib/getdate.c
/libsubid/subid.h
-98
View File
@@ -1,98 +0,0 @@
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>
-41
View File
@@ -1,41 +0,0 @@
SPDX-License-Identifier: BSD-3-Clause
All files under this project either
1. fall under the BSD 3 clause license (by default).
2. carry an SPDX header declaring what license applies.
or
3. list a full custom license
This software is originally
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* 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.
-15440
View File
File diff suppressed because it is too large Load Diff
-29
View File
@@ -1,29 +0,0 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = NEWS README
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/
dist-hook:
chmod -R u+w $(distdir)/tests
chmod u+w $(distdir)
mv $(distdir)/tests/unit $(distdir)/realunittest
mv $(distdir)/tests/tests $(distdir)/realtests
rm -rf $(distdir)/tests
mv $(distdir)/realtests $(distdir)/tests
rm -rf $(distdir)/tests/unit $(distdir)/tests/Makefile*
mv $(distdir)/realunittest $(distdir)/tests/unit
-2166
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1 +0,0 @@
README.md
-47
View File
@@ -1,47 +0,0 @@
# shadow-utils
## 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.
## 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)
## Code
The main development branch is at [https://github.com/shadow-maint/shadow.git](https://github.com/shadow-maint/shadow)
See [STABLE.md](https://github.com/shadow-maint/shadow/blob/master/STABLE.md) for a list of supported stable branches.
## 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
### 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
## Contributions
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).
-12
View File
@@ -1,12 +0,0 @@
# Security Policy
## Supported Versions
At the moment only the latest release is supported.
## Reporting a Vulnerability
Security vulnerabilities may be reported to
* Serge Hallyn <serge@hallyn.com> (B175CFA98F192AF2)
* Christian Brauner <christian@brauner.io> (4880B8C9BD0E5106FC070F4F7B3C391EFEA93624)
* Iker Pedrosa <ipedrosa@redhat.com> (4E80EF49C7987B6DE2F81F5005079C6C3A653E57)
-11
View File
@@ -1,11 +0,0 @@
# Supported stable branches
The following stable branches are kindly maintained by trusted volunteers:
- 4.15.x
- git
- [main](https://www.alejandro-colomar.es/src/alx/shadow/stable/shadow.git/log/?h=4.15.x)
- [mirror](https://github.com/shadow-maint/shadow/tree/4.15.x)
- tarballs
- [main](https://www.alejandro-colomar.es/share/dist/shadow/4/4.15/)
- [mirror](https://github.com/shadow-maint/shadow/releases/)
-54
View File
@@ -1,54 +0,0 @@
# Checks the location of the XML Catalog
# Usage:
# JH_PATH_XML_CATALOG([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# Defines XMLCATALOG and XML_CATALOG_FILE substitutions
AC_DEFUN([JH_PATH_XML_CATALOG],
[
# check for the presence of the XML catalog
AC_ARG_WITH([xml-catalog],
AS_HELP_STRING([--with-xml-catalog=CATALOG],
[path to xml catalog to use]),,
[with_xml_catalog=/etc/xml/catalog])
jh_found_xmlcatalog=true
XML_CATALOG_FILE="$with_xml_catalog"
AC_SUBST([XML_CATALOG_FILE])
AC_MSG_CHECKING([for XML catalog ($XML_CATALOG_FILE)])
if test -f "$XML_CATALOG_FILE"; then
AC_MSG_RESULT([found])
else
jh_found_xmlcatalog=false
AC_MSG_RESULT([not found])
fi
# check for the xmlcatalog program
AC_PATH_PROG(XMLCATALOG, xmlcatalog, no)
if test "x$XMLCATALOG" = xno; then
jh_found_xmlcatalog=false
fi
if $jh_found_xmlcatalog; then
ifelse([$1],,[:],[$1])
else
ifelse([$2],,[AC_MSG_ERROR([could not find XML catalog])],[$2])
fi
])
# Checks if a particular URI appears in the XML catalog
# Usage:
# JH_CHECK_XML_CATALOG(URI, [FRIENDLY-NAME], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
AC_DEFUN([JH_CHECK_XML_CATALOG],
[
AC_REQUIRE([JH_PATH_XML_CATALOG],[JH_PATH_XML_CATALOG(,[:])])dnl
AC_MSG_CHECKING([for ifelse([$2],,[$1],[$2]) in XML catalog])
if $jh_found_xmlcatalog && \
AC_RUN_LOG([$XMLCATALOG --noout "$XML_CATALOG_FILE" "$1" >&2]); then
AC_MSG_RESULT([found])
ifelse([$3],,,[$3
])dnl
else
AC_MSG_RESULT([not found])
ifelse([$4],,
[AC_MSG_ERROR([could not find ifelse([$2],,[$1],[$2]) in XML catalog])],
[$4])
fi
])
-24
View File
@@ -1,24 +0,0 @@
#! /bin/sh
autoreconf -v -f --install "$(dirname "$0")" || exit 1
CFLAGS="-O2"
CFLAGS="$CFLAGS -Wall"
CFLAGS="$CFLAGS -Wextra"
CFLAGS="$CFLAGS -Werror=implicit-function-declaration"
CFLAGS="$CFLAGS -Werror=implicit-int"
CFLAGS="$CFLAGS -Werror=incompatible-pointer-types"
CFLAGS="$CFLAGS -Werror=int-conversion"
CFLAGS="$CFLAGS -Wno-expansion-to-defined"
CFLAGS="$CFLAGS -Wno-unknown-attributes"
CFLAGS="$CFLAGS -Wno-unknown-warning-option"
"$(dirname "$0")"/configure \
CFLAGS="$CFLAGS" \
--enable-lastlog \
--enable-man \
--enable-maintainer-mode \
--enable-shared \
--without-libpam \
--with-selinux \
"$@"
-781
View File
@@ -1,781 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
m4_define([libsubid_abi_major], 4)
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.15.3], [pkg-shadow-devel@lists.alioth.debian.org], [],
[https://github.com/shadow-maint/shadow])
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_USE_SYSTEM_EXTENSIONS
AC_ENABLE_STATIC
AC_ENABLE_SHARED
AM_MAINTAINER_MODE
dnl Checks for programs.
AC_PROG_CC
AC_PROG_LN_S
AC_PROG_YACC
LT_INIT
LT_LIB_DLLOAD
dnl Checks for libraries.
dnl Checks for header files.
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(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_CHECK_MEMBERS([struct utmpx.ut_name,
struct utmpx.ut_host,
struct utmpx.ut_syslen,
struct utmpx.ut_addr,
struct utmpx.ut_addr_v6,
struct utmpx.ut_time,
struct utmpx.ut_xtime],,,[[#include <utmpx.h>]])
dnl Checks for library functions.
AC_TYPE_GETGROUPS
AC_FUNC_UTIME_NULL
AC_REPLACE_FUNCS(putgrent putpwent putspent)
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
AC_CHECK_FUNC(setpgrp)
AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
1,
[Defined to 1 if you have the declaration of 'secure_getenv'])])
if test "$ac_cv_header_shadow_h" = "yes"; then
AC_CACHE_CHECK(for working shadow group support,
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::");
/* NYS libc on Red Hat 3.0.3 has broken shadow group support */
return !sg || !sg->sg_adm || !sg->sg_mem;
}]
)],
[ac_cv_libc_shadowgrp=yes],
[ac_cv_libc_shadowgrp=no],
[ac_cv_libc_shadowgrp=no]
)
)
if test "$ac_cv_libc_shadowgrp" = "yes"; then
AC_DEFINE(HAVE_SHADOWGRP, 1, [Have working shadow group support in libc])
fi
fi
AC_CACHE_CHECK([location of shared mail directory], shadow_cv_maildir,
[for shadow_cv_maildir in /var/mail /var/spool/mail /usr/spool/mail /usr/mail none; do
if test -d $shadow_cv_maildir; then
break
fi
done])
if test $shadow_cv_maildir != none; then
AC_DEFINE_UNQUOTED(MAIL_SPOOL_DIR, "$shadow_cv_maildir",
[Location of system mail spool directory.])
fi
AC_CACHE_CHECK([location of user mail file], shadow_cv_mailfile,
[for shadow_cv_mailfile in Mailbox mailbox Mail mail .mail none; do
if test -f $HOME/$shadow_cv_mailfile; then
break
fi
done])
if test $shadow_cv_mailfile != none; then
AC_DEFINE_UNQUOTED(MAIL_SPOOL_FILE, "$shadow_cv_mailfile",
[Name of user's mail spool file if stored in user's home directory.])
fi
AC_CACHE_CHECK([location of utmp], shadow_cv_utmpdir,
[for shadow_cv_utmpdir in /var/run /var/adm /usr/adm /etc none; do
if test -f $shadow_cv_utmpdir/utmp; then
break
fi
done])
if test "$shadow_cv_utmpdir" = "none"; then
AC_MSG_WARN(utmp file not found)
fi
AC_DEFINE_UNQUOTED(_UTMP_FILE, "$shadow_cv_utmpdir/utmp",
[Path for utmp file.])
AC_CACHE_CHECK([location of faillog/lastlog/wtmp], shadow_cv_logdir,
[for shadow_cv_logdir in /var/log /var/adm /usr/adm /etc; do
if test -d $shadow_cv_logdir; then
break
fi
done])
AC_DEFINE_UNQUOTED(_WTMP_FILE, "$shadow_cv_logdir/wtmp",
[Path for wtmp file.])
AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$shadow_cv_logdir/lastlog",
[Path for lastlog file.])
AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$shadow_cv_logdir/faillog",
[Path for faillog file.])
AC_CACHE_CHECK([location of the passwd program], shadow_cv_passwd_dir,
[if test -f /usr/bin/passwd; then
shadow_cv_passwd_dir=/usr/bin
else
shadow_cv_passwd_dir=/bin
fi])
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
[Path to passwd program.])
dnl XXX - quick hack, should disappear before anyone notices :).
dnl XXX - I just read the above message :).
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,
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
[case "${enableval}" in
yes) enable_shadowgrp="yes" ;;
no) enable_shadowgrp="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-shadowgrp) ;;
esac],
[enable_shadowgrp="yes"]
)
AC_ARG_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,
[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" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-account-tools-setuid)
;;
esac],
[enable_acct_tools_setuid="no"]
)
AC_ARG_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,
[AS_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
[with_audit=$withval], [with_audit=maybe])
AC_ARG_WITH(libpam,
[AS_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
[with_libpam=$withval], [with_libpam=maybe])
AC_ARG_WITH(btrfs,
[AS_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])],
[with_btrfs=$withval], [with_btrfs=maybe])
AC_ARG_WITH(selinux,
[AS_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
[with_selinux=$withval], [with_selinux=maybe])
AC_ARG_WITH(acl,
[AS_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
[with_acl=$withval], [with_acl=maybe])
AC_ARG_WITH(attr,
[AS_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
[with_attr=$withval], [with_attr=maybe])
AC_ARG_WITH(skey,
[AS_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
[with_skey=$withval], [with_skey=no])
AC_ARG_WITH(tcb,
[AS_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
[with_tcb=$withval], [with_tcb=maybe])
AC_ARG_WITH(sha-crypt,
[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,
[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,
[AS_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes])
AC_ARG_WITH(sssd,
[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,
[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,
[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=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])
fi
AM_CONDITIONAL(USE_BCRYPT, test "x$with_bcrypt" = "xyes")
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])],
[AC_MSG_ERROR([posix_spawn is needed for nscd support])])
fi
if test "$with_sssd" = "yes"; then
AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_SSSD, 1, [Define to support flushing of sssd caches])],
[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]))
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(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]),,[])
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
AC_DEFINE(SHADOWGRP, 1, [Define to support the shadow group file.])
fi
AM_CONDITIONAL(SHADOWGRP, test "x$enable_shadowgrp" = "xyes")
if test "$enable_man" = "yes"; then
dnl
dnl Check for xsltproc
dnl
AC_PATH_PROG([XSLTPROC], [xsltproc])
if test -z "$XSLTPROC"; then
enable_man=no
AC_MSG_ERROR([xsltproc is missing.])
fi
dnl check for DocBook DTD and stylesheets in the local catalog.
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.5//EN],
[DocBook XML DTD V4.5], [], enable_man=no)
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
[DocBook XSL Stylesheets >= 1.70.1], [], enable_man=no)
fi
AM_CONDITIONAL(ENABLE_REGENERATE_MAN, test "x$enable_man" != "xno")
if test "$enable_subids" != "no"; then
dnl
dnl FIXME: check if 32 bit UIDs/GIDs are supported by libc
dnl
AC_CHECK_SIZEOF([uid_t],, [#include "sys/types.h"])
AC_CHECK_SIZEOF([gid_t],, [#include "sys/types.h"])
if test "$ac_cv_sizeof_uid_t" -ge 4 && test "$ac_cv_sizeof_gid_t" -ge 4; then
AC_DEFINE(ENABLE_SUBIDS, 1, [Define to support the subordinate IDs.])
enable_subids="yes"
else
if test "x$enable_subids" = "xyes"; then
AC_MSG_ERROR([Cannot enable support the subordinate IDs on systems where gid_t or uid_t has less than 32 bits])
fi
enable_subids="no"
fi
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"])
if test "$acl_header$with_acl" = "noyes" ; then
AC_MSG_ERROR([acl/libacl.h or attr/error_context.h is missing])
elif test "$acl_header" = "yes" ; then
AC_CHECK_LIB(acl, perm_copy_file,
[AC_CHECK_LIB(acl, perm_copy_fd,
[acl_lib="yes"],
[acl_lib="no"])],
[acl_lib="no"])
if test "$acl_lib$with_acl" = "noyes" ; then
AC_MSG_ERROR([libacl not found])
elif test "$acl_lib" = "no" ; then
with_acl="no"
else
AC_DEFINE(WITH_ACL, 1,
[Build shadow with ACL support])
LIBACL="-lacl"
with_acl="yes"
fi
else
with_acl="no"
fi
fi
AC_SUBST(LIBATTR)
if test "$with_attr" != "no"; then
AC_CHECK_HEADERS(attr/libattr.h attr/error_context.h, [attr_header="yes"], [attr_header="no"])
if test "$attr_header$with_attr" = "noyes" ; then
AC_MSG_ERROR([attr/libattr.h or attr/error_context.h is missing])
elif test "$attr_header" = "yes" ; then
AC_CHECK_LIB(attr, attr_copy_file,
[AC_CHECK_LIB(attr, attr_copy_fd,
[attr_lib="yes"],
[attr_lib="no"])],
[attr_lib="no"])
if test "$attr_lib$with_attr" = "noyes" ; then
AC_MSG_ERROR([libattr not found])
elif test "$attr_lib" = "no" ; then
with_attr="no"
else
AC_DEFINE(WITH_ATTR, 1,
[Build shadow with Extended Attributes support])
LIBATTR="-lattr"
with_attr="yes"
fi
else
with_attr="no"
fi
fi
AC_SUBST(LIBAUDIT)
if test "$with_audit" != "no"; then
AC_CHECK_HEADER(libaudit.h, [audit_header="yes"], [audit_header="no"])
if test "$audit_header$with_audit" = "noyes" ; then
AC_MSG_ERROR([libaudit.h is missing])
elif test "$audit_header" = "yes"; then
AC_CHECK_DECL(AUDIT_ADD_USER,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_DEL_USER,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_ADD_GROUP,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_DEL_GROUP,,[audit_header="no"],[#include <libaudit.h>])
if test "$audit_header$with_audit" = "noyes" ; then
AC_MSG_ERROR([AUDIT_ADD_USER AUDIT_DEL_USER AUDIT_ADD_GROUP or AUDIT_DEL_GROUP missing from libaudit.h])
fi
fi
if test "$audit_header" = "yes"; then
AC_CHECK_LIB(audit, audit_log_acct_message,
[audit_lib="yes"], [audit_lib="no"])
if test "$audit_lib$with_audit" = "noyes" ; then
AC_MSG_ERROR([libaudit not found])
elif test "$audit_lib" = "no" ; then
with_audit="no"
else
AC_DEFINE(WITH_AUDIT, 1,
[Define if you want to enable Audit messages])
LIBAUDIT="-laudit"
with_audit="yes"
fi
else
with_audit="no"
fi
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"])
if test "$btrfs_headers$with_btrfs" = "noyes" ; then
AC_MSG_ERROR([One of sys/statfs.h linux/magic.h linux/btrfs_tree.h is missing])
fi
if test "$btrfs_headers" = "yes" ; then
AC_DEFINE(WITH_BTRFS, 1, [Build shadow with BtrFS support])
with_btrfs="yes"
fi
fi
AM_CONDITIONAL(WITH_BTRFS, test x$with_btrfs = xyes)
AC_SUBST(LIBSELINUX)
AC_SUBST(LIBSEMANAGE)
if test "$with_selinux" != "no"; then
AC_CHECK_HEADERS(selinux/selinux.h, [selinux_header="yes"], [selinux_header="no"])
if test "$selinux_header$with_selinux" = "noyes" ; then
AC_MSG_ERROR([selinux/selinux.h is missing])
fi
AC_CHECK_HEADERS(semanage/semanage.h, [semanage_header="yes"], [semanage_header="no"])
if test "$semanage_header$with_selinux" = "noyes" ; then
AC_MSG_ERROR([semanage/semanage.h is missing])
fi
if test "$selinux_header$semanage_header" = "yesyes" ; then
AC_CHECK_LIB(selinux, is_selinux_enabled, [selinux_lib="yes"], [selinux_lib="no"])
if test "$selinux_lib$with_selinux" = "noyes" ; then
AC_MSG_ERROR([libselinux not found])
fi
AC_CHECK_LIB(semanage, semanage_connect, [semanage_lib="yes"], [semanage_lib="no"])
if test "$semanage_lib$with_selinux" = "noyes" ; then
AC_MSG_ERROR([libsemanage not found])
fi
if test "$selinux_lib$semanage_lib" = "yesyes" ; then
AC_DEFINE(WITH_SELINUX, 1,
[Build shadow with SELinux support])
LIBSELINUX="-lselinux"
LIBSEMANAGE="-lsemanage"
with_selinux="yes"
else
with_selinux="no"
fi
else
with_selinux="no"
fi
fi
AC_SUBST(LIBTCB)
if test "$with_tcb" != "no"; then
AC_CHECK_HEADERS(tcb.h, [tcb_header="yes"], [tcb_header="no"])
if test "$tcb_header$with_tcb" = "noyes" ; then
AC_MSG_ERROR([tcb.h is missing])
elif test "$tcb_header" = "yes" ; then
AC_CHECK_LIB(tcb, tcb_is_suspect, [tcb_lib="yes"], [tcb_lib="no"])
if test "$tcb_lib$with_tcb" = "noyes" ; then
AC_MSG_ERROR([libtcb not found])
elif test "$tcb_lib" = "no" ; then
with_tcb="no"
else
AC_DEFINE(WITH_TCB, 1, [Build shadow with tcb support (incomplete)])
LIBTCB="-ltcb"
with_tcb="yes"
fi
else
with_tcb="no"
fi
fi
AM_CONDITIONAL(WITH_TCB, test x$with_tcb = xyes)
AC_SUBST(LIBPAM)
if test "$with_libpam" != "no"; then
AC_CHECK_LIB(pam, pam_start,
[pam_lib="yes"], [pam_lib="no"])
if test "$pam_lib$with_libpam" = "noyes" ; then
AC_MSG_ERROR(libpam not found)
fi
LIBPAM="-lpam"
pam_conv_function="no"
AC_CHECK_LIB(pam, openpam_ttyconv,
[pam_conv_function="openpam_ttyconv"],
AC_CHECK_LIB(pam_misc, misc_conv,
[pam_conv_function="misc_conv"; LIBPAM="$LIBPAM -lpam_misc"])
)
if test "$pam_conv_function$with_libpam" = "noyes" ; then
AC_MSG_ERROR(PAM conversation function not found)
fi
pam_headers_found=no
AC_CHECK_HEADERS( [security/openpam.h security/pam_misc.h],
[ pam_headers_found=yes ; break ], [],
[ #include <security/pam_appl.h> ] )
if test "$pam_headers_found$with_libpam" = "noyes" ; then
AC_MSG_ERROR(PAM headers not found)
fi
if test "$pam_lib$pam_headers_found" = "yesyes" -a "$pam_conv_function" != "no" ; then
with_libpam="yes"
else
with_libpam="no"
unset LIBPAM
fi
fi
dnl Now with_libpam is either yes or no
if test "$with_libpam" = "yes"; then
AC_CHECK_DECLS([PAM_ESTABLISH_CRED,
PAM_DELETE_CRED,
PAM_NEW_AUTHTOK_REQD,
PAM_DATA_SILENT],
[], [], [#include <security/pam_appl.h>])
save_libs=$LIBS
LIBS="$LIBS $LIBPAM"
# We do not use AC_CHECK_FUNCS to avoid duplicated definition with
# Linux PAM.
AC_CHECK_FUNC(pam_fail_delay, [AC_DEFINE(HAS_PAM_FAIL_DELAY, 1, [Define to 1 if you have the declaration of 'pam_fail_delay'])])
LIBS=$save_libs
AC_DEFINE(USE_PAM, 1, [Define to support Pluggable Authentication Modules])
AC_DEFINE_UNQUOTED(SHADOW_PAM_CONVERSATION, [$pam_conv_function],[PAM conversation to use])
AM_CONDITIONAL(USE_PAM, [true])
AC_MSG_CHECKING(use login and su access checking if PAM not used)
AC_MSG_RESULT(no)
else
AC_DEFINE(SU_ACCESS, 1, [Define to support /etc/suauth su access control.])
AM_CONDITIONAL(USE_PAM, [false])
AC_MSG_CHECKING(use login and su access checking if PAM not used)
AC_MSG_RESULT(yes)
fi
if test "$enable_acct_tools_setuid" != "no"; then
if test "$with_libpam" != "yes"; then
if test "$enable_acct_tools_setuid" = "yes"; then
AC_MSG_ERROR(PAM support is required for --enable-account-tools-setuid)
else
enable_acct_tools_setuid="no"
fi
else
enable_acct_tools_setuid="yes"
fi
if test "$enable_acct_tools_setuid" = "yes"; then
AC_DEFINE(ACCT_TOOLS_SETUID,
1,
[Define if account management tools should be installed setuid and authenticate the callers])
fi
fi
AM_CONDITIONAL(ACCT_TOOLS_SETUID, test "x$enable_acct_tools_setuid" = "xyes")
AC_ARG_WITH(fcaps,
[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")
if test "x$with_fcaps" = "xyes"; then
AC_CHECK_PROGS(capcmd, "setcap")
if test "x$capcmd" = "x" ; then
AC_MSG_ERROR([setcap command not available])
fi
fi
AC_SUBST(LIBSKEY)
AC_SUBST(LIBMD)
if test "$with_skey" = "yes"; then
AC_CHECK_LIB(md, MD5Init, [LIBMD=-lmd])
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_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])],[])
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.19])
AM_GNU_GETTEXT([external], [need-ngettext])
AM_CONDITIONAL(USE_NLS, test "x$USE_NLS" = "xyes")
AC_CONFIG_FILES([
Makefile
po/Makefile.in
doc/Makefile
man/Makefile
man/config.xml
man/po/Makefile
man/cs/Makefile
man/da/Makefile
man/de/Makefile
man/es/Makefile
man/fi/Makefile
man/fr/Makefile
man/hu/Makefile
man/id/Makefile
man/it/Makefile
man/ja/Makefile
man/ko/Makefile
man/pl/Makefile
man/pt_BR/Makefile
man/ru/Makefile
man/sv/Makefile
man/tr/Makefile
man/uk/Makefile
man/zh_CN/Makefile
man/zh_TW/Makefile
lib/Makefile
libsubid/Makefile
libsubid/subid.h
src/Makefile
contrib/Makefile
etc/Makefile
etc/pam.d/Makefile
etc/shadow-maint/Makefile
tests/unit/Makefile
])
AC_OUTPUT
echo
echo "shadow will be compiled with the following features:"
echo
echo " auditing support: $with_audit"
echo " PAM support: $with_libpam"
if test "$with_libpam" = "yes"; then
echo " suid account management tools: $enable_acct_tools_setuid"
fi
echo " SELinux support: $with_selinux"
echo " BtrFS support: $with_btrfs"
echo " ACL support: $with_acl"
echo " Extended Attributes support: $with_attr"
echo " tcb support (incomplete): $with_tcb"
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
-4
View File
@@ -1,4 +0,0 @@
# 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.sh adduser2.sh
-7
View File
@@ -1,7 +0,0 @@
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.
udbachk.tgz is a passwd/group/shadow file integrity checker.
--marekm
-502
View File
@@ -1,502 +0,0 @@
/****
** 04/21/96
** hacked even more, replaced gets() with something slightly harder to buffer
** overflow. Added support for setting a default quota on new account, with
** edquota -p. Other cleanups for security, I let some users run adduser suid
** root to add new accounts. (overflow checks, clobber environment, valid
** shell checks, restrictions on gid + home dir settings).
** Added max. username length. Used syslog() a bit for important events.
** Support to immediately expire account with passwd -e.
** Called it version 2.0! Because I felt like it!
** -- Chris, chris@ferret.lmh.ox.ac.uk
** 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 their 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 <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <syslog.h>
#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
* immediately upon next login */
#define HAVE_QUOTAS /* Obvious */
#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change
* password expiry values (if running suid root) */
#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */
#define LOGGING /* If we want to log various things to syslog */
#define MAX_USRNAME 8 /* Longer usernames seem to work on my system....
* But they're probably a poor idea */
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
#define DEFAULT_HOME "/home"
#define USERADD_PATH "/usr/sbin/useradd"
#define CHAGE_PATH "/usr/bin/chage"
#define PASSWD_PATH "/usr/bin/passwd"
#define EDQUOTA_PATH "/usr/sbin/edquota"
#define QUOTA_DEFAULT "defuser"
#define DEFAULT_GROUP 100
#define DEFAULT_MIN_PASS 0
#define DEFAULT_MAX_PASS 100
#define DEFAULT_WARN_PASS 14
#define DEFAULT_USER_DIE 366
void safeget (char *, int);
void
main (void)
{
char foo[32];
char usrname[32], 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, olduid;
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 username is found that isn't in /etc/passwd
*/
/* 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 superuser access.\n");
exit (1);
}
/* Sanity checks
*/
#ifdef LOGGING
openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
#endif
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");
#ifdef LOGGING
syslog (LOG_ERR, "warning: failed. no such default group\n");
closelog ();
#endif
exit (1);
};
while (!correct)
{ /* loop until a "good" usrname is chosen */
while (!done)
{
printf ("\nLogin to add (^C to quit): ");
fflush (stdout);
safeget (usrname, sizeof (usrname));
if (!strlen (usrname))
{
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 (strlen (usrname) > MAX_USRNAME)
{
printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
done = 0;
}
else if (getpwnam (usrname) != NULL)
{
printf ("That name is in use, choose another.\n");
done = 0;
}
else if (strchr (usrname, ' ') != NULL)
{
printf ("No spaces in username!!\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", usrname);
printf ("\nFull Name [%s]: ", usrname);
fflush (stdout);
safeget (person, sizeof (person));
if (!strlen (person))
{
bzero (person, sizeof (person));
strcpy (person, usrname);
};
if (getuid () == 0)
{
do
{
bad = 0;
printf ("GID [%d]: ", DEFAULT_GROUP);
fflush (stdout);
safeget (foo, sizeof (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);
}
else
{
printf ("Group will be default of: %d\n", DEFAULT_GROUP);
group = DEFAULT_GROUP;
}
if (getuid () == 0)
{
printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
fflush (stdout);
safeget (dir, sizeof (dir));
if (!strlen (dir))
{ /* hit return */
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
else if (dir[strlen (dir) - 1] == '/')
sprintf (dir+strlen(dir), "%s", usrname);
}
else
{
printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
printf ("\nShell [%s]: ", DEFAULT_SHELL);
fflush (stdout);
safeget (shell, sizeof (shell));
if (!strlen (shell))
sprintf (shell, "%s", DEFAULT_SHELL);
else
{
char *sh;
int ok = 0;
#ifdef HAVE_GETUSERSHELL
setusershell ();
while ((sh = getusershell ()) != NULL)
if (!strcmp (shell, sh))
ok = 1;
endusershell ();
#endif
if (!ok)
{
if (getuid () == 0)
printf ("Warning: root allowed non standard shell\n");
else
{
printf ("Shell NOT in /etc/shells, DEFAULT used\n");
sprintf (shell, "%s", DEFAULT_SHELL);
}
}
}
#ifdef EXPIRE_VALS_SET
if (getuid () == 0)
{
#endif
printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
if (strlen (foo) > 1)
min_pass = DEFAULT_MIN_PASS;
else
min_pass = atoi (foo);
printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
if (strlen (foo) > 1)
max_pass = atoi (foo);
else
max_pass = DEFAULT_MAX_PASS;
printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
fflush (stdout);
safeget (foo, sizeof (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);
fflush (stdout);
safeget (foo, sizeof (foo));
user_die = atoi (foo);
if (user_die == 0)
user_die = DEFAULT_USER_DIE;
#ifdef EXPIRE_VALS_SET
}
else
{
printf ("\nSorry, account expiry values are set.\n");
user_die = DEFAULT_USER_DIE;
warn_pass = DEFAULT_WARN_PASS;
max_pass = DEFAULT_MAX_PASS;
min_pass = DEFAULT_MIN_PASS;
}
#endif
printf ("\nInformation for new user [%s] [%s]:\n", usrname, 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);
safeget (foo, sizeof (foo));
done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
if (bad != 1)
printf ("\nUser [%s] not added\n", usrname);
}
/* Clobber the environment, I run this suid root sometimes to let
* non root privileged accounts add users --chris */
*environ = NULL;
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, usrname);
printf ("Calling useradd to add new user:\n%s\n", cmd);
if (system (cmd))
{
printf ("User add failed!\n");
#ifdef LOGGING
syslog (LOG_ERR, "could not add new user\n");
closelog ();
#endif
exit (errno);
};
olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root
*/
setuid (0);
bzero (cmd, sizeof (cmd));
/* Chage runs suid root. => we need ruid root to run it with
* anything other than chage -l
*/
sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
min_pass, max_pass, warn_pass, user_die, usrname);
printf ("%s\n", cmd);
if (system (cmd))
{
printf ("There was an error setting password expire values\n");
#ifdef LOGGING
syslog (LOG_ERR, "password expire values could not be set\n");
#endif
};
/* I want to add a user completely with one easy command --chris */
#ifdef HAVE_QUOTAS
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
printf ("%s\n", cmd);
if (system (cmd))
{
printf ("\nWarning: error setting quota\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
#endif /* LOGGING */
}
else
printf ("\nDefault quota set.\n");
#endif /* HAVE_QUOTAS */
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
if (system (cmd))
{
printf ("\nWarning: error setting password\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: password set failed!\n");
#endif
}
#ifdef IMMEDIATE_CHANGE
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
if (system (cmd))
{
printf ("\nWarning: error expiring password\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: password expire failed!\n");
#endif /* LOGGING */
}
#endif /* IMMEDIATE_CHANGE */
setuid (olduid);
#ifdef LOGGING
closelog ();
#endif
printf ("\nDone.\n");
}
void
safeget (char *buf, int maxlen)
{
int c, i = 0, bad = 0;
char *bstart = buf;
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
{
bad = (!isalnum (c) && (c != '_') && (c != ' '));
*(buf++) = c;
}
*buf = '\0';
if (bad)
{
printf ("\nString contained banned character. Please stick to alphanumerics.\n");
*bstart = '\0';
}
}
-90
View File
@@ -1,90 +0,0 @@
#!/bin/sh
# adduser script for use with shadow passwords and useradd command.
# by Hrvoje Dogan <hdogan@student.math.hr>, Dec 1995.
echo -n "Login name for new user []:"
read LOGIN
if [ -z $LOGIN ]
then echo "Come on, man, you can't leave the login field empty...";exit
fi
echo
echo -n "User id for $LOGIN [ defaults to next available]:"
read ID
GUID="-u $ID"
if [ -z $ID ]
then GUID=""
fi
echo
echo -n "Initial group for $LOGIN [users]:"
read GID
GGID="-g $GID"
if [ -z $GID ]
then GGID=""
fi
echo
echo -n "Additional groups for $LOGIN []:"
read AGID
GAGID="-G $AGID"
if [ -z $AGID ]
then GAGID=""
fi
echo
echo -n "$LOGIN's home directory [/home/$LOGIN]:"
read HME
GHME="-d $HME"
if [ -z $HME ]
then GHME=""
fi
echo
echo -n "$LOGIN's shell [/bin/bash]:"
read SHL
GSHL="-s $SHL"
if [ -z $SHL ]
then GSHL=""
fi
echo
echo -n "$LOGIN's account expiry date (MM/DD/YY) []:"
read EXP
GEXP="-e $EXP"
if [ -z $EXP ]
then GEXP=""
fi
echo
echo OK, I'm about to make a new account. Here's what you entered so far:
echo New login name: $LOGIN
if [ -z $GUID ]
then echo New UID: [Next available]
else echo New UID: $UID
fi
if [ -z $GGID ]
then echo Initial group: users
else echo Initial group: $GID
fi
if [ -z $GAGID ]
then echo Additional groups: [none]
else echo Additional groups: $AGID
fi
if [ -z $GHME ]
then echo Home directory: /home/$LOGIN
else echo Home directory: $HME
fi
if [ -z $GSHL ]
then echo Shell: /bin/bash
else echo Shell: $SHL
fi
if [ -z $GEXP ]
then echo Expiry date: [no expiration]
else echo Expiry date: $EXP
fi
echo "This is it... if you want to bail out, you'd better do it now."
read FOO
echo Making new account...
/usr/sbin/useradd $GHME -m $GEXP $GGID $GAGID $GSHL $GUID $LOGIN
/usr/bin/chfn $LOGIN
/usr/bin/passwd $LOGIN
echo "Done..."
-743
View File
@@ -1,743 +0,0 @@
#!/bin/bash
#
# adduser Interactive user adding program.
#
# Copyright (C) 1996 Petri Mattila, Prihateam Networks
# petri@prihateam.fi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# Changes:
# 220496 v0.01 Initial version
# 230496 v0.02 More checks, embolden summary
# 240496 Even more checks
# 250496 Help with ?
# 040596 v0.03 Cleanups
# 050596 v0.04 Bug fixes, expire date checks
# 070596 v0.05 Iso-latin-1 names
#
## Defaults
# default groups
def_group="users"
def_other_groups=""
# default home directory
def_home_dir=/home/users
# default shell
def_shell=/bin/tcsh
# Default expiration date (mm/dd/yy)
def_expire=""
# default dates
def_pwd_min=0
def_pwd_max=90
def_pwd_warn=14
def_pwd_iact=14
# possible UIDs
uid_low=1000
uid_high=64000
# skel directory
skel=/etc/skel
# default mode for home directory
def_mode=711
# Regex, that the login name must meet, only ANSI characters
login_regex='^[0-9a-zA-Z_-]*$'
# Regex, that the user name must meet
# ANSI version
##name_regex='^[0-9a-zA-Z_-\ ]*$'
# ISO-LATIN-1 version
name_regex='^[0-9a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ_-\ ]*$'
# set PATH
export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
# Some special characters
case "$TERM" in
vt*|ansi*|con*|xterm*|linux*)
S='' # start embolden
E='' # end embolden
;;
*)
S=''
E=''
;;
esac
## Functions
check_root() {
if test "$EUID" -ne 0
then
echo "You must be root to run this program."
exit 1
fi
}
check_user() {
local usr pwd uid gid name home sh
cat /etc/passwd | (
while IFS=":" read usr pwd uid gid name home sh
do
if test "$1" = "${usr}"
then
return 1
fi
done
return 0
)
}
check_group() {
local read grp pwd gid members
cat /etc/group | (
while IFS=":" read grp pwd gid members
do
if test "$1" = "${grp}"
then
return 1
fi
done
return 0
)
}
check_other_groups() {
local grp check IFS
check="$1"
IFS=","
set ${check}
for grp
do
if check_group "${grp}"
then
echo "Group ${grp} does not exist."
return 1
fi
done
return 0
}
check_uid() {
local usr pwd uid gid name home sh
cat /etc/passwd | (
while IFS=":" read usr pwd uid gid name home sh
do
if test "$1" = "${uid}"
then
return 1
fi
done
return 0
)
}
read_yn() {
local ans ynd
ynd="$1"
while :
do
read ans
case "${ans}" in
"") return ${ynd} ;;
[nN]) return 1 ;;
[yY]) return 0 ;;
*) echo -n "Y or N, please ? " ;;
esac
done
}
read_login() {
echo
while :
do
echo -n "Login: ${def_login:+[${def_login}] }"
read login
if test "${login}" = '?'
then
less /etc/passwd
echo
continue
fi
if test -z "${login}" -a -n "${def_login}"
then
login="${def_login}"
echo "Using ${login}"
return
fi
if test "${#login}" -gt 8
then
echo "Login must be at most 8 characters long"
continue
fi
if test "${#login}" -lt 2
then
echo "Login must be at least 2 characters long"
continue
fi
if ! expr "${login}" : "${login_regex}" &> /dev/null
then
echo "Please use letters, numbers and special characters _-,."
continue
fi
if ! check_user "${login}"
then
echo "Username ${login} is already in use"
continue
fi
def_login="${login}"
return
done
}
read_name () {
echo
while :
do
echo -n "Real name: ${def_name:+[${def_name}] }"
read name
if test "${name}" = '?'
then
less /etc/passwd
echo
continue
fi
if test -z "${name}" -a -n "${def_name}"
then
name="${def_name}"
echo "Using ${name}"
fi
if test "${#name}" -gt 32
then
echo "Name should be at most 32 characters long"
continue
fi
if ! expr "${name}" : "${name_regex}" &> /dev/null
then
echo "Please use letters, numbers, spaces and special characters ,._-"
continue
fi
def_name="${name}"
return
done
}
read_home() {
local x
echo
while :
do
echo -n "Home Directory: [${def_home_dir}/${login}] "
read home
if test -z "${home}"
then
home="${def_home_dir}/${login}"
echo "Using ${home}"
fi
if ! expr "${home}" : '^[0-9a-zA-Z,._-\/]*$' &> /dev/null
then
echo "Please use letters, numbers, spaces and special characters ,._-/"
continue
fi
x="$(basename ${home})"
if test "${x}" != "${login}"
then
echo "Warning: you are about to use different login name and home directory."
fi
x="$(dirname ${home})"
if ! test -d "${x}"
then
echo "Directory ${x} does not exist."
echo "If you still want to use it, please make it manually."
continue
fi
def_home_dir="${x}"
return
done
}
read_shell () {
local x
echo
while :
do
echo -n "Shell: [${def_shell}] "
read shell
if test -z "${shell}"
then
shell="${def_shell}"
echo "Using ${shell}"
fi
for x in $(cat /etc/shells)
do
if test "${x}" = "${shell}"
then
def_shell="${shell}"
return
fi
done
echo "Possible shells are:"
cat /etc/shells
done
}
read_group () {
echo
while :
do
echo -n "Group: [${def_group}] "
read group
if test -z "${group}"
then
group="${def_group}"
echo "Using ${group}"
fi
if test "${group}" = '?'
then
less /etc/group
echo
continue
fi
if check_group "${group}"
then
echo "Group ${group} does not exist."
continue
fi
def_group="${group}"
return
done
}
read_other_groups () {
echo
while :
do
echo -n "Other groups: [${def_og:-none}] "
read other_groups
if test "${other_groups}" = '?'
then
less /etc/group
echo
continue
fi
if test -z "${other_groups}"
then
if test -n "${def_og}"
then
other_groups="${def_og}"
echo "Using ${other_groups}"
else
echo "No other groups"
return
fi
fi
if ! check_other_groups "${other_groups}"
then
continue
fi
def_og="${other_groups}"
return
done
}
read_uid () {
echo
while :
do
echo -n "uid: [first free] "
read uid
if test -z "${uid}"
then
echo "Using first free UID."
return
fi
if test "${uid}" = '?'
then
less /etc/passwd
echo
continue
fi
if ! expr "${uid}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${uid}" -lt "${uid_low}"
then
echo "UID must be greater than ${uid_low}"
continue
fi
if test "${uid}" -gt "${uid_high}"
then
echo "UID must be smaller than ${uid_high}"
continue
fi
if ! check_uid "${uid}"
then
echo "UID ${uid} is already in use"
continue
fi
return
done
}
read_max_valid_days() {
echo
while :
do
echo -en "Maximum days between password changes: [${def_pwd_max}] "
read max_days
if test -z "${max_days}"
then
max_days="${def_pwd_max}"
echo "Using ${max_days}"
return
fi
if ! expr "${max_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${max_days}" -lt 7
then
echo "Warning: you are using a value shorter than a week."
fi
def_pwd_max="${max_days}"
return
done
}
read_min_valid_days() {
echo
while :
do
echo -en "Minimum days between password changes: [${def_pwd_min}] "
read min_days
if test -z "${min_days}"
then
min_days="${def_pwd_min}"
echo "Using ${min_days}"
return
fi
if ! expr "${min_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${min_days}" -gt 7
then
echo "Warning: you are using a value longer than a week."
fi
def_pwd_min="${min_days}"
return
done
}
read_warning_days() {
echo
while :
do
echo -en "Number of warning days before password expires: [${def_pwd_warn}] "
read warn_days
if test -z "${warn_days}"
then
warn_days="${def_pwd_warn}"
echo "Using ${warn_days}"
fi
if ! expr "${warn_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${warn_days}" -gt 14
then
echo "Warning: you are using a value longer than two week."
fi
def_pwd_warn="${warn_days}"
return
done
}
read_inactive_days() {
echo
while :
do
echo -en "Number of usable days after expiration: [${def_pwd_iact}] "
read iact_days
if test -z "${iact_days}"
then
iact_days="${def_pwd_iact}"
echo "Using ${iact_days}"
return
fi
if ! expr "${iact_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${iact_days}" -gt 14
then
echo "Warning: you are using a value that is more than two weeks."
fi
def_pwd_iact="${iact_days}"
return
done
}
read_expire_date() {
local ans
echo
while :
do
echo -en "Expire date of this account (mm/dd/yy): [${def_expire:-never}] "
read ans
if test -z "${ans}"
then
if test -z "${def_expire}"
then
ans="never"
else
ans="${def_expire}"
echo "Using ${def_expire}"
fi
fi
if test "${ans}" = "never"
then
echo "Account will never expire."
def_expire=""
expire=""
return
fi
if ! expr "${ans}" : '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]$' &> /dev/null
then
echo "Please use format mm/dd/yy"
continue
fi
if ! expire_date="$(date -d ${ans} '+%A, %B %d %Y')"
then
continue
fi
def_expire="${expire}"
return
done
}
read_passwd_yn() {
echo -en "\nDo you want to set password [Y/n] ? "
if read_yn 0
then
set_pwd="YES"
else
set_pwd=""
fi
}
print_values() {
clear
cat << EOM
Login: ${S}${login}${E}
Group: ${S}${group}${E}
Other groups: ${S}${other_groups:-[none]}${E}
Real Name: ${S}${name}${E}
uid: ${S}${uid:-[first free]}${E}
home: ${S}${home}${E}
shell: ${S}${shell}${E}
Account expiration date: ${S}${expire_date:-never}${E}
Minimum days between password changes: ${S}${min_days}${E}
Maximum days between password changes: ${S}${max_days}${E}
Number of usable days after expiration: ${S}${iact_days}${E}
Number of warning days before expiration: ${S}${warn_days}${E}
${S}${set_pwd:+Set password for this account.}${E}
EOM
}
set_user() {
if ! useradd \
-c "${name}" \
-d "${home}" \
-g "${group}" \
-s "${shell}" \
${expire:+-e ${expire}} \
${uid:+-u ${uid}} \
${other_groups:+-G ${other_groups}} \
${login}
then
echo "Error ($?) in useradd...exiting..."
exit 1
fi
}
set_aging() {
if ! passwd \
-x ${max_days} \
-n ${min_days} \
-w ${warn_days} \
-i ${iact_days} \
${login}
then
echo "Error ($?) in setting password aging...exiting..."
exit 1
fi
}
set_password() {
if test -n "${set_pwd}"
then
echo
passwd ${login}
echo
fi
}
set_system() {
if test -d "${home}"
then
echo "Directory ${home} already exists."
echo "Skeleton files not copied."
return
fi
echo -n "Copying skeleton files..."
(
mkdir ${home}
cd ${skel} && cp -af . ${home}
chmod ${def_mode} ${home}
chown -R ${login}:${group} ${home}
)
echo "done."
## Add your own stuff here:
echo -n "Setting up other files..."
(
mailbox="/var/spool/mail/${login}"
touch ${mailbox}
chown "${login}:mail" ${mailbox}
chmod 600 ${mailbox}
)
echo "done."
}
read_values() {
clear
echo -e "\nPlease answer the following questions about the new user to be added."
while :
do
read_login
read_name
read_group
read_other_groups
read_home
read_shell
read_uid
read_expire_date
read_max_valid_days
read_min_valid_days
read_warning_days
read_inactive_days
read_passwd_yn
print_values
echo -n "Is this correct [N/y] ? "
read_yn 1 && return
done
}
main() {
check_root
read_values
set_user
set_aging
set_system
set_password
}
## Run it 8-)
main
# End.
-1918
View File
File diff suppressed because it is too large Load Diff
-4
View File
@@ -1,4 +0,0 @@
# 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
-65
View File
@@ -1,65 +0,0 @@
ABOUT shadow-login limits:
This code is merged into shadow login program from the original LShell 2.01
written by Joel Katz. The port and some additional features have been added
by Cristian Gafton (gafton@sorosis.ro).
Changes:
- 96/04/16
- {spaces,tabs} allowed within limits string
- Warn via syslog multiple default limits
- added few paragraphs to the login man page
- 96/04/14
- code merged into lmain.c --cristiang
TODO: - support groups in the limits file
(only usernames are supported at this moment :-( )
Setting user limits for shadow login program
First, make a root-only-readable file (/etc/limits by default or LIMITS_FILE
defined config.h) that describes the resource limits you wish to impose. By
default no quotas are imposed on 'root'. In fact, there is no way to impose
limits via this procedure to root-equiv accounts (accounts with UID 0).
Each line describes a limit for a user in the form:
user LIMITS_STRING
The LIMITS_STRING is a string of a concatenated list of resource limits.
Each limit consists of a letter identifier followed by a numerical limit.
The valid identifiers are:
A: max address space (KB)
C: max core file size (KB)
D: max data size (KB)
F: maximum filesize (KB)
M: max locked-in-memory address space (KB)
N: max number of open files
R: max resident set size (KB)
S: max stack size (KB)
T: max CPU time (MIN)
U: max number of processes
L: max number of logins for this user
For example, L2D2048N5 is a valid LIMITS_STRING. For reading convenience,
the following entries are equivalent:
username L2D2048N5
username L2 D2048 N5
Be aware that after <username> the rest of the line is considered a limit
string, thus comments are not allowed. A invalid limits string will be
rejected (not considered) by the login program.
The default entry is denoted by username '*'. If you have multiple 'default'
entries in your LIMITS_FILE, then the last one will be used as the default
entry.
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 ;)
-4
View File
@@ -1,4 +0,0 @@
# S/Key support
shadow-utils can be built with S/Key support using the S/Key package from:
* http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libskey/ or
* https://gentoo.osuosl.org/distfiles/skey-1.1.5.tar.bz2
-73
View File
@@ -1,73 +0,0 @@
# Build & install
The following page explains how to build and install the shadow project.
Additional information on how to do this in a container environment is provided
at the end of the page.
## Local
### Dependency installation
This projects depends on other software packages that need to be installed
before building it. We recommend using the dependency installation commands
provided by the distributions to install them. Some examples below.
Debian:
```
apt-get build-dep shadow
```
Fedora:
```
dnf builddep shadow-utils
```
An alternative would be to take a look at the CI workflow [file](../../.github/workflows/runner.yml)
and get the package names from there. This has the advantage that it
also includes new dependencies needed for the development version
which might have not been present in the last release.
### Configure
The first step is to configure it. You can use the
`autogen.sh` script provided by the project. Example:
```
./autogen.sh --without-selinux --enable-man --with-yescrypt
```
### Build
The next step is to build the project:
```
make -j4
```
### Install
The last step is to install it. We recommend avoiding this step and using a
disposable system like a VM or a container instead.
```
make install
```
## Containers
Alternatively, you can use any of the preconfigured container images builders
to build and install shadow.
You can either generate a single image by running the following command from
the root folder of the project (i.e. Alpine):
```
docker build -f share/containers/alpine.dockerfile . --output build-out/alpine
```
Or generate all of the images with the `container-build.sh` script, as if you
were running some of the CI checks locally:
```
share/container-build.sh
```
-25
View File
@@ -1,25 +0,0 @@
# Continuous Integration (CI)
Shadow runs a CI workflow every time a pull-request (PR) is updated. This
workflow contains several checks to assure the quality of the project, and
only pull-requests with green results are merged.
## Build & install
The project is built & installed on Ubuntu, Alpine, Debian and Fedora. The last
three distributions are built & installed on containers, and the workflow can
be triggered locally by following the instructions specified in the
[Build & install](build_install.md#containers) page.
## System tests
The project is tested on Ubuntu. For that purpose it is built & installed in
this distribution in a VM. You can run this step locally by following the
instructions provided in the [Tests](tests.md#system-tests) page.
## Static code analysis
C and shell static code analysis is also executed. For that purpose
[CodeQL](https://codeql.github.com/) and
[Differential ShellCheck](https://github.com/marketplace/actions/differential-shellcheck)
are used.
-12
View File
@@ -1,12 +0,0 @@
# Coding style
* For a general guidance refer to the
[Linux kernel coding style](https://www.kernel.org/doc/html/latest/process/coding-style.html)
* Patches that change the existing coding style are not welcome, as they make
downstream porting harder for the distributions
## Indentation
Tabs are preferred over spaces for indentation. Loading the `.editorconfig`
file in your preferred IDE may help you configure it.
-77
View File
@@ -1,77 +0,0 @@
# Introduction
## Git and Github
We recommend you to get familiar with the
[git](https://guides.github.com/introduction/git-handbook) and
[Github](https://guides.github.com) workflows before posting any changes.
### Set up in a nut shell
The following steps describe the process in a nut shell to provide you a basic
template:
* Create an account on [GitHub](https://github.com)
* Fork the [shadow repository](https://github.com/shadow-maint/shadow)
* Clone the shadow repository
```
git clone https://github.com/shadow-maint/shadow.git
```
* Add your fork as an extra remote
```
git remote add $ghusername git@github.com:$ghusername/shadow.git
```
* Setup your name contact e-mail that you want to use for the development
```
git config user.name "John Smith"
git config user.email "john.smith@home.com"
```
**Note**: this will setup the user information only for this repository. You
can also add `--global` switch to the `git config` command to setup these
options globally and thus making them available in every git repository.
* Create a working branch
```
git checkout -b my-changes
```
* Commit changes
```
vim change-what-you-need
git commit -s
```
Check
[the kernel patches guide](https://www.kernel.org/doc/html/v4.14/process/submitting-patches.html#describe-your-changes)
to get an idea on how to write a good commit message.
* Push your changes to your GitHub repository
```
git push $ghusername my-changes --force
```
* Open a Pull Request against shadow project by clicking on the link provided
in the output of the previous step
* Make sure that all Continuous Integration checks are green and wait review
## Internal guidelines
Additionally, you should also check the following internal guidelines to
understand the project's development model:
* [Build & install](build_install.md)
* [Coding style](coding_style.md)
* [Tests](tests.md)
* [Continuous Integration](CI.md)
* [Releases](releases.md)
* [License](license.md)
-10
View File
@@ -1,10 +0,0 @@
# License
All new source code committed to the shadow project is assumed to be made
available under the [BSD-3-Clause](../../COPYING) license unless the submitter
specifies another license at that time. The shadow maintainers reserve the
right to refuse a submission if the license is deemed incompatible with the
goals of the project.
**Note**: old code may be made available under another license, check the
license tag for each file to get additional information.
-7
View File
@@ -1,7 +0,0 @@
# Releases
The shadow project doesn't follow any specific timeline to release new software
versions. Usually, they are released when a major milestone is finished.
Released source code, alongside the release notes, are provided in the
[release Github page](https://github.com/shadow-maint/shadow/releases).
-34
View File
@@ -1,34 +0,0 @@
# Tests
Currently, shadow provides unit and system tests.
## Unit tests
Unit testing is provided by the [cmocka](https://cmocka.org/) framework. It's
recommended to read the
[basics](https://cmocka.org/talks/cmocka_unit_testing_and_mocking.pdf) and
[API](https://api.cmocka.org/) before writing any test case.
In addition, you can check [test_logind.c](../../tests/unit/test_logind.c) to
get a general idea on how to implement unit tests for shadow using cmocka.
You can execute unit tests by running:
```
make check
```
## System tests
These type of tests are written in shell. Unfortunately, the testing framework
is tightly coupled to the Ubuntu distribution and it can only be run in this
distribution. Besides, if anything fails during the execution the system can
be left in an unstable state. Taking that into account you shouldn't run this
workflow in your host machine, we recommend to use a disposable system like a
VM or a container instead.
You can execute system tests by running:
```
cd tests && ./run_all`.
```
-23
View File
@@ -1,23 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
sysconf_DATA = login.defs
defaultdir = $(sysconfdir)/default
default_DATA =
nonpam_files = \
limits \
login.access
if !USE_PAM
nonpamdir = $(sysconfdir)
nonpam_DATA = $(nonpam_files)
endif
EXTRA_DIST = \
$(nonpam_files) \
$(sysconf_DATA) \
$(default_DATA)
SUBDIRS = pam.d shadow-maint
-30
View File
@@ -1,30 +0,0 @@
# /etc/limits contains user resource limits.
# See limits(5).
#
# Format:
# <username> <limits-string>
#
# default entry is '*' for username
#
# Valid flags are:
# A: max address space (KB)
# C: max core file size (KB)
# D: max data size (KB)
# F: maximum filesize (KB)
# M: max locked-in-memory address space (KB) [only for root on Linux 2.0.x]
# N: max number of open files
# R: max resident set size (KB) [no effect on Linux 2.0.x]
# S: max stack size (KB)
# T: max CPU time (MIN)
# U: max number of processes
# L: max number of logins for this user
# I: max nice value (0..39 translates to 20..-19)
# O: max real time priority (0..MAX_RT_PRIO)
#
# Examples:
# the default entry
#* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0 I20 O0
# another way of suspending a user login
#guest L0
# this account has no limits
#sysadm -
-54
View File
@@ -1,54 +0,0 @@
# $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
# 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.
#
# 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
# matched when the login name matches the "user" part, and when the
# "host" part matches the local machine name.
#
# The third field should be a list of one or more tty names (for
# non-networked logins), host names, domain names (begin with "."), host
# addresses, internet network numbers (end with "."), ALL (always
# matches) or LOCAL (matches any string that does not contain a "."
# character).
#
# If you run NIS you can use @netgroupname in host or user patterns; this
# even works for @usergroup@@hostgroup patterns. Weird.
#
# The EXCEPT operator makes it possible to write very compact rules.
#
# The group file is searched only when a name does not match that of the
# logged-in user. Only groups are matched in which users are explicitly
# 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
#
# Disallow non-local logins to privileged accounts (group wheel).
#
#-:wheel:ALL EXCEPT LOCAL .win.tue.nl
#
# Some accounts are not allowed to login from anywhere:
#
#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL
#
# All other accounts are allowed to login from anywhere.
#
-473
View File
@@ -1,473 +0,0 @@
#
# /etc/login.defs - Configuration control definitions for the shadow package.
#
# $Id$
#
#
# Delay in seconds before being allowed another attempt after a login failure
# Note: When PAM is used, some modules may enforce a minimum delay (e.g.
# pam_unix(8) enforces a 2s delay)
#
FAIL_DELAY 3
#
# Enable logging and display of /var/log/faillog login(1) failure info.
#
FAILLOG_ENAB yes
#
# Enable display of unknown usernames when login(1) failures are recorded.
#
LOG_UNKFAIL_ENAB no
#
# Enable logging of successful logins
#
LOG_OK_LOGINS no
#
# Enable logging and display of /var/log/lastlog login(1) time info.
#
LASTLOG_ENAB yes
#
# Limit the highest user ID number for which the lastlog entries should
# be updated.
#
# No LASTLOG_UID_MAX means that there is no user ID limit for writing
# lastlog entries.
#
#LASTLOG_UID_MAX
#
# Enable checking and display of mailbox status upon login.
#
# Disable if the shell startup files already check for mail
# ("mailx -e" or equivalent).
#
MAIL_CHECK_ENAB yes
#
# Enable additional checks upon password changes.
#
OBSCURE_CHECKS_ENAB yes
#
# Enable checking of time restrictions specified in /etc/porttime.
#
PORTTIME_CHECKS_ENAB yes
#
# Enable setting of ulimit, umask, and niceness from passwd(5) gecos field.
#
QUOTAS_ENAB yes
#
# Enable "syslog" logging of su(1) activity - in addition to sulog file logging.
# SYSLOG_SG_ENAB does the same for newgrp(1) and sg(1).
#
SYSLOG_SU_ENAB yes
SYSLOG_SG_ENAB yes
#
# If defined, either full pathname of a file containing device names or
# a ":" delimited list of device names. Root logins will be allowed only
# from these devices.
#
CONSOLE /etc/securetty
#CONSOLE console:tty01:tty02:tty03:tty04
#
# If defined, all su(1) activity is logged to this file.
#
#SULOG_FILE /var/log/sulog
#
# If defined, ":" delimited list of "message of the day" files to
# be displayed upon login.
#
MOTD_FILE /etc/motd
#MOTD_FILE /etc/motd:/usr/lib/news/news-motd
#
# If defined, this file will be output before each login(1) prompt.
#
#ISSUE_FILE /etc/issue
#
# If defined, file which maps tty line to TERM environment parameter.
# Each line of the file is in a format similar to "vt100 tty01".
#
#TTYTYPE_FILE /etc/ttytype
#
# If defined, login(1) failures will be logged here in a utmp format.
# last(1), when invoked as lastb(1), will read /var/log/btmp, so...
#
FTMP_FILE /var/log/btmp
#
# If defined, name of file whose presence will inhibit non-root
# logins. The content of this file should be a message indicating
# why logins are inhibited.
#
NOLOGINS_FILE /etc/nologin
#
# If defined, the command name to display when running "su -". For
# example, if this is defined as "su" then ps(1) will display the
# command as "-su". If not defined, then ps(1) will display the
# name of the shell actually being run, e.g. something like "-sh".
#
SU_NAME su
#
# *REQUIRED*
# Directory where mailboxes reside, _or_ name of file, relative to the
# home directory. If you _do_ define both, MAIL_DIR takes precedence.
#
MAIL_DIR /var/spool/mail
#MAIL_FILE .mail
#
# If defined, file which inhibits all the usual chatter during the login
# sequence. If a full pathname, then hushed mode will be enabled if the
# user's name or shell are found in the file. If not a full pathname, then
# hushed mode will be enabled if the file exists in the user's home directory.
#
HUSHLOGIN_FILE .hushlogin
#HUSHLOGIN_FILE /etc/hushlogins
#
# If defined, either a TZ environment parameter spec or the
# fully-rooted pathname of a file containing such a spec.
#
#ENV_TZ TZ=CST6CDT
#ENV_TZ /etc/tzname
#
# If defined, an HZ environment parameter spec.
#
# for Linux/x86
ENV_HZ HZ=100
# For Linux/Alpha...
#ENV_HZ HZ=1024
#
# *REQUIRED* The default PATH settings, for superuser and normal users.
#
# (they are minimal, add the rest in the shell startup files)
ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin
ENV_PATH PATH=/bin:/usr/bin
#
# Terminal permissions
#
# TTYGROUP Login tty will be assigned this group ownership.
# TTYPERM Login tty will be set to this permission.
#
# If you have a write(1) program which is "setgid" to a special group
# which owns the terminals, define TTYGROUP as the number of such group
# and TTYPERM as 0620. Otherwise leave TTYGROUP commented out and
# set TTYPERM to either 622 or 600.
#
TTYGROUP tty
TTYPERM 0600
#
# Login configuration initializations:
#
# ERASECHAR Terminal ERASE character ('\010' = backspace).
# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
# ULIMIT Default "ulimit" value.
#
# The ERASECHAR and KILLCHAR are used only on System V machines.
# The ULIMIT is used only if the system supports it.
# (now it works with setrlimit too; ulimit is in 512-byte units)
#
# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
#
ERASECHAR 0177
KILLCHAR 025
#ULIMIT 2097152
# Default initial "umask" value used by login(1) on non-PAM enabled systems.
# Default "umask" value for pam_umask(8) on PAM enabled systems.
# UMASK is also used by useradd(8) and newusers(8) to set the mode for new
# home directories if HOME_MODE is not set.
# 022 is the default value, but 027, or even 077, could be considered
# for increased privacy. There is no One True Answer here: each sysadmin
# must make up their mind.
UMASK 022
# HOME_MODE is used by useradd(8) and newusers(8) to set the mode for new
# home directories.
# If HOME_MODE is not set, the value of UMASK is used to create the mode.
#HOME_MODE 0700
#
# Password aging controls:
#
# PASS_MAX_DAYS Maximum number of days a password may be used.
# PASS_MIN_DAYS Minimum number of days allowed between password changes.
# PASS_MIN_LEN Minimum acceptable password length.
# PASS_WARN_AGE Number of days warning given before a password expires.
#
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
#
# If "yes", the user must be listed as a member of the first gid 0 group
# in /etc/group (called "root" on most Linux systems) to be able to "su"
# to uid 0 accounts. If the group doesn't exist or is empty, no one
# will be able to "su" to uid 0.
#
SU_WHEEL_ONLY no
#
# Min/max values for automatic uid selection in useradd(8)
#
UID_MIN 1000
UID_MAX 60000
# System accounts
SYS_UID_MIN 101
SYS_UID_MAX 999
# Extra per user uids
SUB_UID_MIN 100000
SUB_UID_MAX 600100000
SUB_UID_COUNT 65536
#
# Min/max values for automatic gid selection in groupadd(8)
#
GID_MIN 1000
GID_MAX 60000
# System accounts
SYS_GID_MIN 101
SYS_GID_MAX 999
# Extra per user group ids
SUB_GID_MIN 100000
SUB_GID_MAX 600100000
SUB_GID_COUNT 65536
#
# Max number of login(1) retries if password is bad
#
LOGIN_RETRIES 5
#
# Max time in seconds for login(1)
#
LOGIN_TIMEOUT 60
#
# Maximum number of attempts to change password if rejected (too easy)
#
PASS_CHANGE_TRIES 5
#
# Warn about weak passwords (but still allow them) if you are root.
#
PASS_ALWAYS_WARN yes
#
# Number of significant characters in the password for crypt().
# Default is 8, don't change unless your crypt() is better.
# Ignored if MD5_CRYPT_ENAB set to "yes".
#
#PASS_MAX_LEN 8
#
# Require password before chfn(1)/chsh(1) can make any changes.
#
CHFN_AUTH yes
#
# Which fields may be changed by regular users using chfn(1) - use
# any combination of letters "frwh" (full name, room number, work
# phone, home phone). If not defined, no changes are allowed.
# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
#
CHFN_RESTRICT rwh
#
# Password prompt (%s will be replaced by user name).
#
# XXX - it doesn't work correctly yet, for now leave it commented out
# to use the default which is just "Password: ".
#LOGIN_STRING "%s's Password: "
#
# Only works if compiled with MD5_CRYPT defined:
# If set to "yes", new passwords will be encrypted using the MD5-based
# algorithm compatible with the one used by recent releases of FreeBSD.
# It supports passwords of unlimited length and longer salt strings.
# Set to "no" if you need to copy encrypted passwords to other systems
# which don't understand the new algorithm. Default is "no".
#
# Note: If you use PAM, it is recommended to use a value consistent with
# the PAM modules configuration.
#
# This variable is deprecated. You should use ENCRYPT_METHOD instead.
#
#MD5_CRYPT_ENAB no
#
# Only works if compiled with ENCRYPTMETHOD_SELECT defined:
# If set to MD5, MD5-based algorithm will be used for encrypting password
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
# If set to BCRYPT, BCRYPT-based algorithm will be used for encrypting password
# If set to YESCRYPT, YESCRYPT-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default)
# 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
# the PAM modules configuration.
#
#ENCRYPT_METHOD DES
#
# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512.
#
# Define the number of SHA rounds.
# With a lot of rounds, it is more difficult to brute-force the password.
# However, more CPU resources will be needed to authenticate users if
# this value is increased.
#
# If not specified, the libc will choose the default number of rounds (5000),
# 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.
#
#SHA_CRYPT_MIN_ROUNDS 5000
#SHA_CRYPT_MAX_ROUNDS 5000
#
# Only works if ENCRYPT_METHOD is set to BCRYPT.
#
# Define the number of BCRYPT rounds.
# With a lot of rounds, it is more difficult to brute-force the password.
# However, more CPU resources will be needed to authenticate users if
# this value is increased.
#
# If not specified, 13 rounds will be attempted.
# If only one of the MIN or MAX values is set, then this value will be used.
# If MIN > MAX, the highest value will be used.
#
#BCRYPT_MIN_ROUNDS 13
#BCRYPT_MAX_ROUNDS 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
# setting). Default is none.
#
# Use with caution - it is possible for users to gain permanent
# access to these groups, even when not logged in from the console.
# How to do it is left as an exercise for the reader...
#
#CONSOLE_GROUPS floppy:audio:cdrom
#
# Should login be allowed if we can't cd to the home directory?
# Default is no.
#
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.
#
ENVIRON_FILE /etc/environment
#
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#
#USERDEL_CMD /usr/sbin/userdel_local
#
# Enable setting of the umask group bits to be the same as owner bits
# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
# the same as gid, and username is the same as the primary group name.
#
# This also enables userdel(8) to remove user groups if no members exist.
#
USERGROUPS_ENAB yes
#
# If set to a non-zero number, the shadow utilities will make sure that
# groups never have more than this number of users on one line.
# This permits to support split groups (groups split into multiple lines,
# with the same group ID, to avoid limitation of the line length in the
# group file).
#
# 0 is the default value and disables this feature.
#
#MAX_MEMBERS_PER_GROUP 0
#
# If useradd(8) should create home directories for users by default (non
# system users only).
# This option is overridden with the -M or -m flags on the useradd(8)
# command-line.
#
#CREATE_HOME yes
#
# Force use shadow, even if shadow passwd & shadow group files are
# missing.
#
#FORCE_SHADOW yes
#
# 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
-35
View File
@@ -1,35 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# 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 \
groupadd \
groupdel \
groupmod \
useradd \
userdel \
usermod
if USE_PAM
pamddir = $(sysconfdir)/pam.d
pamd_DATA = $(pamd_files)
if ACCT_TOOLS_SETUID
pamd_DATA += $(pamd_acct_tools_files)
endif
endif
if WITH_SU
pamd_files += su
endif
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-11
View File
@@ -1,11 +0,0 @@
#%PAM-1.0
auth required pam_securetty.so
auth include system-auth
account required pam_nologin.so
account include system-auth
password include system-auth
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 [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
-13
View File
@@ -1,13 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
auth required pam_wheel.so use_uid
auth include system-auth
account include system-auth
password include system-auth
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
session include system-auth
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
session optional pam_xauth.so
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-5
View File
@@ -1,5 +0,0 @@
shadowmaint_files = \
groupdel-pre.d/01-kill_group_procs.sh \
userdel-pre.d/01-kill_user_procs.sh
EXTRA_DIST = $(shadowmaint_files)
@@ -1,26 +0,0 @@
#!/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
@@ -1,31 +0,0 @@
#!/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
File diff suppressed because it is too large Load Diff
@@ -1,58 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
wc44x8aaET0FtmmJmRfxzQSEkczkR4AM
=K+Fs
-----END PGP PUBLIC KEY BLOCK-----
@@ -1,185 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
=xU87
-----END PGP PUBLIC KEY BLOCK-----
@@ -1,147 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGI/tA8BEACYC5fPDOMDrT8SxNlsB9fRj9YAZt7okGtbCIlVuSPs81YMkeJm
BxtPPnps5Vw2whZS13zaoyPykMg6k+komDWctWQKIF0VgpVYtIuezq4q8kMNmKLc
MnHiZRKRh8dOqlK6jHcUlF8rBgQhk+RUBUPOqFEYeTveoZ9qqVmWhOVce5uUX01k
iU2SjoGAGkNDBqmOkhhVUSQg/AVcc4web6Gu184VUbOXx7J5MPpRmXE610fAUeeJ
1VzyB8U/hgPLrbZX3jQMJbcCSM+Qdxdr/gsptfx1XIm4NsvKXTUOpWg1DQFiQYTJ
FN6Kz0NKN6MV/3AqbKGtWDqKhFt3u3a7T+uUP/qzi9jma+DruQuzQztI6xnthZCb
RjFkQ/iUUtuGgmpOB14HrgwNaRjKWddzab+A7BL971Q3fFqDsvrntD+koYVUgTfq
ErcQo9ZdGRAUL5icyyDg4cC6xgjdmYfnX1s4Rlo3cXJXTZpIOx5AvZV6HYNNm9pu
EoPm5gjNtk4F+FENNjkB3c2ntFr2prpoxaN9ceNd8a1tkWAgh6ueFVA/tkd1hy+2
bP7e5+Nk9NjsWLvnL2slep1cX38DU9hx91t21+x/8hCxN4gqtvDJY/eqUZ2d0uAR
KhPEDZ8GzchxVtX9bGx1HSAVcdnkSzKIGFOJi3ivYqUEihXd5WQE57UovQARAQAB
tCJBbGVqYW5kcm8gQ29sb21hciA8YWx4QGtlcm5lbC5vcmc+iQJOBBMBCgA4FiEE
qTSFlM4xKDqCb73Y1XYz1EHiW7UFAmNDAAYCGwEFCwkIBwIGFQoJCAsCBBYCAwEC
HgECF4AACgkQ1XYz1EHiW7Vm4g/+NDfrYWHAHSMBkQnTZdhrOFCR1tJsWTLABwe1
fMLBW7djLZMZweDMU76UBrucAEsarKkIHyhqpBES5EXwmlvKSnEhzPjXZ+PoHmM0
M8Lq7QFZ5IEbrhuJbvpfTCa0gleHKIVYCCeaf2AUpgwX1XMkG2mmRdvUDQ2M8NMH
ljM/OZ+6tBGpw7zvx1kYsSfBerlHxmLXlRxHrr9nWi7zXa+HrHZQAhopuufIb1we
8lI/gdfywq7s/e5Xelk4dnr/pEFx56G1vh0bc+zU36+C9gX5IXOJv2WrTmOfG3Am
gaJgWZapJQlPFEByk+2oJf5UOgPRhdX7qLR8mVnQ4EHM1sr9B6UGwcySZpVwag9n
51WhjgdqYoSPt9dpPSNfNavLJDR+paM0aEHi3/t3mGJSyOPM4E6ejrYk7791fOJF
0J3VhKr9KR1rMxQpE1kMs7qO1uUJvnF+opzrueMELffwTfDDyvY1bV/ZNou/MPi4
EbUJyZDvsq2shaKj/NB4nzYJIoGbUzUrz008buTagf+WZ+uTDIdOJbaVPcUUjtzr
21KifSWxcokNhqSIrsCLzCJkbiKEK7nUoOvl9q3Wl9L5CWAOflr5499iyGqxlJ+E
7xzerWy1ZqgQHJ3Zp0wVMgHTKvPsmDvwaXBvEZkrUQ4PnInWTNJ2yiNxJU/we7Xx
kxo4Qk2JATMEEAEKAB0WIQRm0Dh9uF0yD4QIFm2xdc+pjxkq8gUCZTrVZwAKCRCx
dc+pjxkq8s7uB/4yKEi2S+So2YHaIstBo0+9Uxcuqy1NUHuDRFTiNhocph+exjbn
t09TK1NM9Sc3ErwnUoItLp2rW7D81TMXNnUsIfdusKkVkxC5xs4oLTpoIb+uBzDR
O4KYebALpcPz2Y5I/jI9kiXYxd/pXUeyBQDN3zKwpM6Y8eax0h+EUh904ZGO4BRB
tl0V1rnQ3AybSIi2dUVn2e8MGEW7hddMc1B85Bf7jCYuesR1FXMcHMs2v/S4kRH1
179xFi6wxrNwBYY+YRwbX0OjSENls6I9vGC6+UoPaCHDS3MOcNuD77otYLK1Up46
6G/KfcDLQsWsgPEdION3cE0+JCa3Kz9jn05DtDFBbGVqYW5kcm8gQ29sb21hciBB
bmRyZXMgPGFseC5tYW5wYWdlc0BnbWFpbC5jb20+iQJOBBMBCgA4FiEEqTSFlM4x
KDqCb73Y1XYz1EHiW7UFAmI/tA8CGwEFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AA
CgkQ1XYz1EHiW7U3bA//e10l6Nw6m3mgFoY63ik8DvbD4fZ+/bUuQmTJ3uOI7wuz
gjRnhWKvzBspNGgz3Hzdu3TuGEiVzXfNrdiubwvOVufrW50RDfjkzcvG+lOF8aXk
IRz+46+cXkLdGk5FB9xKPtJs1KuH0ocTDHIeBbg7zHKIZDkLOizCsrzaNI1wDN5x
OpyXkYqQYxuXfCipcfXapkuWXnvRQGGsopEhae+2khiL1hXo00t2A2jfwD6LTdUo
XhFh7RkWNc72z2xiiSjMv5PDtG9EyYBhntEcxZj2kEgnP2ZaRto5OQa557KQg06t
SP9s3KYHcHEd/9yLsNlQJTlOPMO0LH2XnL2MPvM5a7CZQfzTVOrNWM3k4t+46ON2
qoMsOBO4nr9fH9eFtmULiEGN+oVJn+M+PYQJYlnKKu0mS+rbHZnkD42FiW9ZcXbP
LPohB9T1LBjm1lJI8tYiHyfoFwnvBLimSjxmO0VsGKEgZYglVV34Jg9l0I2vYt6Y
0Yieku7GI2Z7oDcBWlW3qbRxPDS+CWN3kSaWXRos1ufM038Yb1PwI4wzIaqrIVvG
UmwCESNOXhsc8JPNqhqvnFFcbAXlPO4vQ26jThedHGMpbWFVSfajwMTvubAbVuq6
vssZCwK405aSESbK10ohSRagKexZAqVMeusb1fC4AFTCng9qPgHvJgk5mCX4gmmJ
AjMEEwEIAB0WIQTlIllbUu2k5r/My16FYZkROjXOXgUCYpTOnQAKCRCFYZkROjXO
XhBrD/wPSTPIlpcHO0MLKeF/hjOYyf48YRvbwZ9Ys1wbjfFX9bL/s3S/zli80dma
EGXJALcml1WA+LmpTDri3otG70Em5vTdoocnqwgnlXjiKbB4UzDLtwln7wHinQK0
UaE5R33p8qNZRR9Ydg3C8EFEriZ0/AZkFUE+/Le8+yeGU/Dg//GOt84OzB/GKh+p
SLwA+bJL9xv7ipGI6kOEzKTYceyqj8+KA0VE+rnLeqIdBsH+fp8iCZ2g0Aobv1IW
wPvMcYfNYAoza99hfi5NFTmST/gZcE6Jb+U3/KBsCUEWfV6zhGlMcTHEgoCUBoMS
KWY6nHC/NPSMi2Q3I4l89CCsVcJqABxlY8wrK9axdvv7zPYIpn4JRvGr3HQa5Y5d
2HhQyHtRhElVXe/3DGiErLkzKJORxbn0miyC/F6WOUMnLQEWqUHqd0VspqavQ3PS
OjIKShtlXiLX51q8BED+wOhpuafhFcq8NAAUXLBQDHdViVvH6+sazRNUl+vbujod
eMv7tLtnhpXiwCryb+MPW1alwVcLbnU3xhXazvPRUpG5MtPmir6B++4WtC3El8J/
szPeGY6MZUyxgEzxAGGIOycS9fB4Gw8cxWpmWwwOF31icb6w5ZIrTD/4Q7DaZ/fy
qjgS4duDfHur8ajN0FpkHc0LpkUfLl3rOpGxXh9EkAqtNk6kfIkBMwQQAQoAHRYh
BGbQOH24XTIPhAgWbbF1z6mPGSryBQJlOtVoAAoJELF1z6mPGSryH7IH/A7PoxLI
Dc1rgbLaGbn1Qrt5AU5IFUVHZh5fW06rDHzEYJjk57f+FNJgz8VfGQ61zk14k1+b
eboVTUSW2xZuSBQSRsSVOcj05vJHUpdMK0w1l5W5tbOR9nfn1c5qnQ6lhmFNrlJ6
BEN5IU0swN3s3p7bRl0v0Axx0dZFF41ERDcQ1waqc0Sbp+s4dgdyXhvmu19Vtw6i
WoMjPhMWCnP0DDjGOKA6ogWRlQcO2DuWGpGqmic5eH4VUheXS7orIATslU9VCvbz
GmHrHmqTUj2pAkbvbYDycwK0/O317QHXecv5ErtKOdjtzrULlsFzDEt/b3y6bz5/
YTka4L8CBNzGkye5Ag0EYj+7OQEQAJLWRpWSI3JRdHZEMSKSdnENBThIM8xtIWcy
Hx8y1k+x77mNFx1gCOuMmWw0nR5Ck0im1Z606AmsgQ7tKCEmt4GYfnHeWviIH+Db
CJBjUWrJBp5mWFDPkT9T8yj5VanTyHF3nWb03q5kRyMju9396eZMPrw68hsrm67d
p9iBWye0qKTXndpFyLOXcpPPZryfprjwgw+cGB23V36RB/is50TjBzlR88Hx2EPv
n4p7sNnI3SWwMmc+kEqKQEHoOOlBAJP2kxriN3BBSMw6unKakvH76Wxxi+Touue7
dotUy81AqP+BStNu2S5E16XAfIW5ihVoX1rng8d2kTb25aCZ+5Kve0YZxN7YHsIv
rMibCgqzpR3Naw/PyTS/ZXK9srkk5sGPNEA1TVN1NmXqi3cceOzt9c0eVQqRrtPU
aOe2yY+WGjLpMJmC4j8ExMZE6qq8n+0LC6uO04HftGJ1Mqu/VxL9Ou6MPhQsWyKE
jZUFgVti2zYtyXjTwjNKVnYBbokBNihR9LOKrpSsRGxLcKVVzh/X5lDdt1ZCNU52
q30ZRl4EnTiEkW12tDvU2vOQRfzbaAV0VOArQ3XJk+9+Nz40T2wBdYsVPijoQw7m
gwVFeYg+gV6sh8i+q3ImL6h0MJoNs7XRZk3sGqVdddlb9sKar28q87M07TMPHPdm
Oyn4Hn2PABEBAAGJAjwEGAEKACYWIQSpNIWUzjEoOoJvvdjVdjPUQeJbtQUCYj+7
OQIbDAUJAeEzgAAKCRDVdjPUQeJbtZgLD/0f+BOvEbe6FCP99Hk7okW/Qv2cehGm
VSCQcBtnMCgfRpFOLxkdj1NX9ub8pvdn8sEj/Tmr1sg3larTfAK+FOAmw/y/X9iY
GTE16xxYMVPeLssCjsYSxC/MpYGlPPZemn9QcpwZ92FP5i0MjBwDE7NLmon4wHnX
jSatPF1j921XcUcsI/66gH+digPWPwufZgn8eL5mLtq9o28AglVjrC+bIFsk4chi
rjb9QO/pNCWCZbCfGq6PbEtH47HL6MsWow19rtDKv3U24xVoiUG3U9pljIIjh8aR
gxrLfTR+fiW2GRlf033iRQyAFvz8N4JLSreNCD9resub48lAhxBJ9hOqX569V5mO
hDmnuYT2CUDVGycPfEXaTz2N5eBWOPTN9dr+naYQI9pAZjL+5m8i6yGaE7B8OUPv
ooPN1YvyNbuLU72aJhZ9qaNzDt/kC9BU6s8D44k8lJkjuKzIuRGYiyReSE0mhEhV
zRkG+FAU7l2ICl2OLKVnmKUgdqkRIa5F4F6w1hCQcCASVuKaTyOIUYXnxlesB00c
RduDaIlT8+AAWk0BZL2W6ck0/g09Ai/LRzMBe06t8BUOEa/NiwUv31sYM3smE4Gc
F11BWGKjOzl8CSlY5YAtgfjhMIF3HUcQeMuWrHf/w/cFXg9KX4lpPjoZov2BfVph
YJq1nryud52VB7kCDQRiP7d1ARAAq/ZXcWpJDXSqfz3PPn0c50f/m9vQn0FozhL9
p4wcoUGuQlNfIzE+gyDqJL9r1O8cGjSb4gaLmilgCHuYsmtwVh4UaZOntlp0k/19
2cZpvDYwWQDFZdSV0v7wxA4VLu+sv2fNmHB2Yudn0V0a948M2v4xhcoy8HptOBvw
q0vrVB4lnd3G3odPS5UP8ze3DvKDqGGVsqF9BjbV21KL8rLHVLdUTg60lXXvvHnO
wEJvH4O5kbdxwl4Y8K3S8b6lUYBt8GAkd058y/qxroWMWkxJm3Izy6yqkn2WrbJl
Yq9SSdgp/DvTbOUTrKp7pWGtH6E6OCw8IKkfNrnpfJhGmREIeAe6G/Jr6jyygR20
F1XkU8bqi3cnd1v9sruZyFIu5AOgiJuZnSvDE+goh6mGMUA99x0zeDrRaq39028o
wRucJcwg9pkqxgedhWIK5H0oilwTsYqqBaPvkqStcErhzWtoHtYZCHZRPMBDwwQ0
kaj7WvLfGWszT7nObUeoNAfyVEyGuq/Gw5OTYDY/I6xqrzL01pfrcXEObmKOTpb3
YsB8tv2MxA4VnG9ZbNH2kEB59gmBa+kvQHfXTrDCWdhNvSuL/2qRpxhIy6qql1ny
MTwatNW2WNaUCPH8vjyZKfCB2X0Nka5lBWkjrnyzoEBO3MPI/0sZUnWxawWQO3DH
xizy09EAEQEAAYkEbAQYAQoAIBYhBKk0hZTOMSg6gm+92NV2M9RB4lu1BQJiP7d1
AhsCAkAJENV2M9RB4lu1wXQgBBkBCgAdFiEE6jqH8KTroDDkXfJAnowa+77/2zIF
AmI/t3UACgkQnowa+77/2zJKtw/+PGO4y3yAeY2PXc1QpopG7nsTgG9GA0mUEtz7
ehpz68iJtYC2kbdI8PB1lSPNGzEb0yryew+/pHOhgiyvdDI8TAXZS/wXwRY/Izbl
XmjXyO3U26J9JK4uemzCNwHfxu468kXJz60WaP58xinDA1sVd7YGZGpodKR2Fo0r
bbdH6/Ldql8yu+Fztz51NUZBmNUAJTGvPRSV1Mlvr3hacgCVjVvc2FWrYzyj8jC6
/CO7fSi474iQQVsBNn214L0+fCKoagAyrfmCXV5TYg9TJ2WgW2wQjuzJ/mhvsgCQ
SSj6po6DdXTl8tRbbjaxx502CB8qEQ/yEdQ7RMJSGB5YWfvLstq1zzAPyPIUgsRY
DBCWmPCM3z+PbD78BTHxoJxBZO45kwHMz+68Eng7r0Z1kM7SarvT0Kd1pnpP3mu1
lfd6wZiOlYqZfD+vZtws0BK57iGVLrbIz9AWolPoRDaF7mZpVdDLZzYsdI9vLEyH
uPb7W+VE1USYyMMCNQQxrTOFJIo/bTZA5J7a05KQRNzBZPUmIvGgDffZAQjZpMEX
WNKKcDYRhScARMMnL+yO3e7P2O/WUrmQa4wepweYFPl4dbQ3UGccxy3LZ2dnAIxP
AXFNsK4GYIVokWe2JSNG6M15ev1SWgFYWVO3+nm5JV0mBScE6wsGpvFW3IKIrpDL
Hb/N9TZpDw/+LI0iX6KnROJBhx1/0vzf0PC4n5Xn2Iry11/1rRskYLrmB/vGA6hm
ghnKPCCppUQ4WjBNWnIYzKfzvNPAdq8aIKbC1rtPABeDyfe8NNUX4wa/GgOar2V5
wnwJ5qUc0Iw64yLjTpXvN+HV7zgADboEdtnQW47+zEbTqV59cIcgBCSMAXgICnvq
dc8FskDb9hqvvQtCENsOLibKHYzYumMxZ075tx7pZza+LC/sf4vtuIrs9Bn9imxo
kdhbQsiiHpNDdjQIT6rqCOy9BxD9hSodznhB9GgnRXGX/w8NfX46hETmiYVb0oE7
1yFYd3ZweHu6pWLDEjUMagnCkA+A+/ZIxazsoMklPusTKb1ELzoheOjKz8fCrX4r
j07hI4tGNBfas9bub6sHpbIOb6aGtdofaknV/7lim0aqkMeYBxES6E10+2jCmLg1
N1ADMRBBDml5zrVjZa95+B+8zK2d6r5E0UZhoh/IhpEhZ8Nljt66/35XyEACS0lB
+ZU5keI/1wTbThkgFimkVNzeXF9sx3EuWMZGgcd7uBMPg6pwTS+qGs6XtYmiKMbM
gvDDhcqFh5r/4r7+xW6ZFhR4Dfkdp3pyDIh7h0Hf+tv0Qj1RKBpmi/lwn0qZrLWM
/aYXo0Vuy2nAbeATAle4Iag+r2AkdEAaBDadFeZisl0Oj0djrGERRhu5Ag0EY9v+
KgEQAMOFV6nHZR7Jwg6nAseVPpxwzjLMhKhuxfJor7fXKL15BlBqCyN2ZRlP+RKE
cEAfdbhyTFPcycLpkOLS7LM4TgfwjQUg2eF0wnBHo/nYUKLp0SHW2Pg3F5+HVXcf
5mAhT1W+zrVHuvJur8omotihtvPEG455MzQNttnGj0DQ8ujbCBofFeVgygmuyZNG
bYvrU3Yvr4ZBY5O/m64eSKs2oX7pP7lQ1gVFU9zojUcsLaLkwXX099yYUMkakjLc
uoI5JGMsV9EA+a+RCFa7a4K3umgVsN3cuuKVbPZ8VQYVQh+Iej8EXlxQeJH44MPN
kNfw5Bf2TLB/Gzz7b4yNTWM/kzGi3FEF+31pVu2G0El0sBeJlEjGIHTmfAkzUIyp
qZ6VYR2Li+u3Btunr//k+Dq3E9dN4/yJy4qSr2FAtx8BTG6tj//Xnan/OXfzZdSj
HQcid6lVRTLl44ia9Ln9SqHO53z95qpD1BxHY7B50J6TVmTwa+cbPIjbRpoJbZyR
No2nFxarbyejPboKzGrqCrObDTIar3/88mYi1pHGfG1ounBpfyQ9UUuulYhRZlXo
OcaVYLKVALAAwmS53kwgFuOgydhLKvdmnyFUs/wFLVYy1CcmSDgWlc2NiV0fbOf3
jyQHeE+NnINSna3bItHT2DDsD40AaYrnrQOHQlni+arnJ0gFABEBAAGJAjwEGAEK
ACYWIQSpNIWUzjEoOoJvvdjVdjPUQeJbtQUCY9v+KgIbDAUJAeEzgAAKCRDVdjPU
QeJbteydD/9yzfrnjkeKuBuSjpywOfrtcvOHdCyNemeN4gJtjcgFgjZL4xo90akA
/GcBZnJLpX9OZobyznMMRIvGgJxHLCuGH7Bo4EEQySAoT52Qn7LApBVY308hHDIC
OLK/IQY26flCy+Czpx7uAS41o3lnOPHbVUO6nHrVcO7vWQAX0QT8VQYGPCHcb9al
TkBNdz9rD822CrBc/tph+eeFZzDuuM6gm3nMYFeDURXE3jVGg4Jeg+8zZTZoeI+n
O7Co6BM2CFYswKTOMTLTgbMi+Hxl0XDbXp7gQ3P9fz3h3Q4ahhpWXbNUZkyyZvoA
s1YqOM+RFzyTCowFQR2qTDTJeE4k2suoDBukCTMJIFZkthdvMMY/Ss7ZHZwvtmFi
XVg3jNOy3tt9V9oZ0UBPw3qTeDKLh6HzgdyN1mPrEkdilIpPVnHi/iAiL1IrAjZN
xr11YOoWFyLpDfGUeEn9wK0T6Xj6HwytL2XliBremZLFWPQNxkHNHDGoKoAkytIF
MXg5P7Tx/Mcs/1b0WTxmghpc3kkNYIksIDV19RQ35xjnZ/6yYf2qA5dT80wY8mXG
debPR0jwOod+kzIAq0gmopFo25PJjiYSIU28XJciPSS7tgHirvsz+NRotABBBpIR
SmfXBunBhuwLkrImdzqjrrMpv2Ss9brlxqNYiSYJGdsoqt6MeyhzGQ==
=2CmL
-----END PGP PUBLIC KEY BLOCK-----
-5
View File
@@ -1,5 +0,0 @@
-kr
-i8
-bad
-pcs
-l80
-215
View File
@@ -1,215 +0,0 @@
AUTOMAKE_OPTIONS = 1.0 foreign
DEFS =
noinst_LTLIBRARIES = libshadow.la
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 \
get_gid.c \
get_pid.c \
get_uid.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 \
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 \
remove_tree.c \
rlogin.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 \
sgroupio.c \
sgroupio.h\
shadow.c \
shadowio.c \
shadowio.h \
shadowlog.c \
shadowlog.h \
shadowlog_internal.h \
shadowmem.c \
shell.c \
sizeof.h \
spawn.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:
#
# sources for dbm support (not yet used)
EXTRA_DIST = \
.indent.pro \
gshadow_.h \
xgetXXbyYY.c
-114
View File
@@ -1,114 +0,0 @@
/*
* 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
View File
@@ -1,15 +0,0 @@
// 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
View File
@@ -1,86 +0,0 @@
// 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
-181
View File
@@ -1,181 +0,0 @@
/*
* 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
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#include <sys/types.h>
#include <stdio.h>
#include <time.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include "adds.h"
#include "defines.h"
#include "exitcodes.h"
#include "prototypes.h"
#ident "$Id$"
#ifndef PASSWD_PROGRAM
#define PASSWD_PROGRAM "/bin/passwd"
#endif
/*
* expire - force password change if password expired
*
* expire() calls /bin/passwd to change the user's password
* if it has expired.
*/
int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
{
int status;
pid_t child;
pid_t pid;
if (NULL == sp) {
return 0;
}
/*
* See if the user's password has expired, and if so
* force them to change their password.
*/
status = isexpired (pw, sp);
switch (status) {
case 0:
return 0;
case 1:
(void) fputs (_("Your password has expired."), stdout);
break;
case 2:
(void) fputs (_("Your password is inactive."), stdout);
break;
case 3:
(void) fputs (_("Your login has expired."), stdout);
break;
}
/*
* Setting the maximum valid period to less than the minimum
* valid period means that the minimum period will never
* occur while the password is valid, so the user can never
* change that password.
*/
if ((status > 1) || (sp->sp_max < sp->sp_min)) {
(void) puts (_(" Contact the system administrator."));
exit (EXIT_FAILURE);
}
(void) puts (_(" Choose a new password."));
(void) fflush (stdout);
/*
* Close all the files so that unauthorized access won't
* occur. This needs to be done anyway because those files
* might become stale after "passwd" is executed.
*/
endspent ();
endpwent ();
#ifdef SHADOWGRP
endsgent ();
#endif
endgrent ();
/*
* Execute the /bin/passwd command. The exit status will be
* examined to see what the result is. If there are any
* errors the routine will exit. This forces the user to
* change their password before being able to use the account.
*/
pid = fork ();
if (0 == pid) {
int err;
/*
* Set the UID to be that of the user. This causes
* passwd to work just like it would had they executed
* it from the command line while logged in.
*/
#if defined(HAVE_INITGROUPS) && ! defined(USE_PAM)
if (setup_uid_gid (pw, false) != 0)
#else
if (setup_uid_gid (pw) != 0)
#endif
{
_exit (126);
}
(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);
} else if ((pid_t) -1 == pid) {
perror ("fork");
exit (EXIT_FAILURE);
}
while (((child = wait (&status)) != pid) && (child != (pid_t)-1));
if ((child == pid) && (0 == status)) {
return 1;
}
exit (EXIT_FAILURE);
/*@notreached@*/}
/*
* agecheck - see if warning is needed for password expiration
*
* agecheck sees how many days until the user's password is going
* to expire and warns the user of the pending password expiration.
*/
void agecheck (/*@null@*/const struct spwd *sp)
{
long now = time(NULL) / DAY;
long remain;
if (NULL == sp) {
return;
}
/*
* The last, max, and warn fields must be supported or the
* warning period cannot be calculated.
*/
if ( (-1 == sp->sp_lstchg)
|| (-1 == sp->sp_max)
|| (-1 == sp->sp_warn)) {
return;
}
if (0 == sp->sp_lstchg) {
(void) puts (_("You must change your password."));
return;
}
remain = addsl(sp->sp_lstchg, sp->sp_max, -now);
if (remain <= sp->sp_warn) {
if (remain > 1) {
(void) printf (_("Your password will expire in %ld days.\n"),
remain);
} else if (1 == remain) {
(void) puts (_("Your password will expire tomorrow."));
} else if (remain == 0) {
(void) puts (_("Your password will expire today."));
}
}
}
-145
View File
@@ -1,145 +0,0 @@
/*
* 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
View File
@@ -1,23 +0,0 @@
/*
* 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
View File
@@ -1,73 +0,0 @@
/*
* 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
View File
@@ -1,101 +0,0 @@
// 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
View File
@@ -1,46 +0,0 @@
// 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
View File
@@ -1,386 +0,0 @@
// 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
View File
@@ -1,18 +0,0 @@
// 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
View File
@@ -1,108 +0,0 @@
// 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
View File
@@ -1,15 +0,0 @@
// 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
View File
@@ -1,96 +0,0 @@
// 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
View File
@@ -1,13 +0,0 @@
// 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
View File
@@ -1,39 +0,0 @@
// 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
View File
@@ -1,33 +0,0 @@
#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
View File
@@ -1,89 +0,0 @@
/*
* 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
View File
@@ -1,31 +0,0 @@
/*
* 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
View File
@@ -1,19 +0,0 @@
/*
* 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
View File
@@ -1,53 +0,0 @@
/*
* 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
-110
View File
@@ -1,110 +0,0 @@
#include <linux/btrfs_tree.h>
#include <linux/magic.h>
#include <sys/statfs.h>
#include <stdbool.h>
#include "prototypes.h"
static bool path_exists(const char *p)
{
struct stat sb;
return stat(p, &sb) == 0;
}
static const char *btrfs_cmd(void)
{
const char *const btrfs_paths[] = {"/sbin/btrfs",
"/bin/btrfs", "/usr/sbin/btrfs", "/usr/bin/btrfs", NULL};
const char *p;
int i;
for (i = 0, p = btrfs_paths[i]; p; i++, p = btrfs_paths[i])
if (path_exists(p))
return p;
return NULL;
}
static int run_btrfs_subvolume_cmd(const char *subcmd, const char *arg1, const char *arg2)
{
int status = 0;
const char *cmd = btrfs_cmd();
const char *argv[] = {
"btrfs",
"subvolume",
subcmd,
arg1,
arg2,
NULL
};
if (!cmd || access(cmd, X_OK)) {
return 1;
}
if (run_command(cmd, argv, NULL, &status))
return -1;
return status;
}
int btrfs_create_subvolume(const char *path)
{
return run_btrfs_subvolume_cmd("create", path, NULL);
}
int btrfs_remove_subvolume(const char *path)
{
return run_btrfs_subvolume_cmd("delete", "-C", path);
}
/* Adapted from btrfsprogs */
/*
* This intentionally duplicates btrfs_util_is_subvolume_fd() instead of opening
* a file descriptor and calling it, because fstat() and fstatfs() don't accept
* file descriptors opened with O_PATH on old kernels (before v3.6 and before
* v3.12, respectively), but stat() and statfs() can be called on a path that
* the user doesn't have read or write permissions to.
*
* returns:
* 1 - btrfs subvolume
* 0 - not btrfs subvolume
* -1 - error
*/
int btrfs_is_subvolume(const char *path)
{
struct stat st;
int ret;
ret = is_btrfs(path);
if (ret <= 0)
return ret;
ret = stat(path, &st);
if (ret == -1)
return -1;
if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode)) {
return 0;
}
return 1;
}
/* Adapted from btrfsprogs */
int is_btrfs(const char *path)
{
struct statfs sfs;
int ret;
ret = statfs(path, &sfs);
if (ret == -1)
return -1;
return sfs.f_type == BTRFS_SUPER_MAGIC;
}
-15
View File
@@ -1,15 +0,0 @@
// 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
View File
@@ -1,120 +0,0 @@
// 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
View File
@@ -1,34 +0,0 @@
/*
* 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
View File
@@ -1,146 +0,0 @@
/*
* 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
View File
@@ -1,79 +0,0 @@
/*
* 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
}
-121
View File
@@ -1,121 +0,0 @@
/*
* SPDX-FileCopyrightText: 2008 - 2011, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
/*
* The cleanup_functions stack.
*/
#define CLEANUP_FUNCTIONS 10
typedef /*@null@*/void * parg_t;
static cleanup_function cleanup_functions[CLEANUP_FUNCTIONS];
static parg_t cleanup_function_args[CLEANUP_FUNCTIONS];
static pid_t cleanup_pid = 0;
/*
* - Cleanup functions shall not fail.
* - You should register do_cleanups with atexit.
* - You should add cleanup functions to the stack with add_cleanup when
* an operation is expected to be executed later, and remove it from the
* stack with del_cleanup when it has been executed.
*
**/
/*
* do_cleanups - perform the actions stored in the cleanup_functions stack.
*
* Cleanup action are not executed on exit of the processes started by the
* parent (first caller of add_cleanup).
*
* It is intended to be used as:
* atexit (do_cleanups);
*/
void do_cleanups (void)
{
unsigned int i;
/* Make sure there were no overflow */
assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-1]);
if (getpid () != cleanup_pid) {
return;
}
i = CLEANUP_FUNCTIONS;
do {
i--;
if (cleanup_functions[i] != NULL) {
cleanup_functions[i] (cleanup_function_args[i]);
}
} while (i>0);
}
/*
* add_cleanup - Add a cleanup_function to the cleanup_functions stack.
*/
void add_cleanup (/*@notnull@*/cleanup_function pcf, /*@null@*/void *arg)
{
unsigned int i;
assert (NULL != pcf);
assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-2]);
if (0 == cleanup_pid) {
cleanup_pid = getpid ();
}
/* Add the cleanup_function at the end of the stack */
for (i=0; NULL != cleanup_functions[i]; i++);
cleanup_functions[i] = pcf;
cleanup_function_args[i] = arg;
}
/*
* del_cleanup - Remove a cleanup_function from the cleanup_functions stack.
*/
void del_cleanup (/*@notnull@*/cleanup_function pcf)
{
unsigned int i;
assert (NULL != pcf);
/* Find the pcf cleanup function */
for (i=0; i<CLEANUP_FUNCTIONS; i++) {
if (cleanup_functions[i] == pcf) {
break;
}
}
/* Make sure the cleanup function was found */
assert (i<CLEANUP_FUNCTIONS);
/* Move the rest of the cleanup functions */
for (; i<CLEANUP_FUNCTIONS; i++) {
/* Make sure the cleanup function was specified only once */
assert ( (i == (CLEANUP_FUNCTIONS -1))
|| (cleanup_functions[i+1] != pcf));
if (i == (CLEANUP_FUNCTIONS -1)) {
cleanup_functions[i] = NULL;
cleanup_function_args[i] = NULL;
} else {
cleanup_functions[i] = cleanup_functions[i+1];
cleanup_function_args[i] = cleanup_function_args[i+1];
}
/* A NULL indicates the end of the stack */
if (NULL == cleanup_functions[i]) {
break;
}
}
}
-216
View File
@@ -1,216 +0,0 @@
/*
* 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 "groupio.h"
#include "sgroupio.h"
#include "prototypes.h"
#include "shadowlog.h"
/*
* cleanup_report_add_group - Report failure to add a group to the system
*
* It should be registered when it is decided to add a group to the system.
*/
void cleanup_report_add_group (void *group_name)
{
const char *name = group_name;
SYSLOG ((LOG_ERR, "failed to add group %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
/*
* cleanup_report_del_group - Report failure to remove a group from the system
*
* It should be registered when it is decided to remove a group from the system.
*/
void cleanup_report_del_group (void *group_name)
{
const char *name = group_name;
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
#ifdef WITH_AUDIT
audit_logger (AUDIT_DEL_GROUP, log_get_progname(),
"",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
void cleanup_report_mod_group (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)",
gr_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
}
#ifdef SHADOWGRP
void cleanup_report_mod_gshadow (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)",
sgr_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
}
#endif
/*
* cleanup_report_add_group_group - Report failure to add a group to group
*
* It should be registered when it is decided to add a group to the
* group database.
*/
void cleanup_report_add_group_group (void *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, log_get_progname(),
"adding group to /etc/group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#ifdef SHADOWGRP
/*
* cleanup_report_add_group_gshadow - Report failure to add a group to gshadow
*
* It should be registered when it is decided to add a group to the
* gshadow database.
*/
void cleanup_report_add_group_gshadow (void *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, log_get_progname(),
"adding group to /etc/gshadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#endif
/*
* cleanup_report_del_group_group - Report failure to remove a group from the
* regular group database
*
* It should be registered when it is decided to remove a group from the
* regular group database.
*/
void cleanup_report_del_group_group (void *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, log_get_progname(),
"removing group from /etc/group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#ifdef SHADOWGRP
/*
* cleanup_report_del_group_gshadow - Report failure to remove a group from
* gshadow
*
* It should be registered when it is decided to remove a group from the
* gshadow database.
*/
void cleanup_report_del_group_gshadow (void *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, log_get_progname(),
"removing group from /etc/gshadow",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
}
#endif
/*
* cleanup_unlock_group - Unlock the group file
*
* It should be registered after the group file is successfully locked.
*/
void cleanup_unlock_group (MAYBE_UNUSED void *arg)
{
if (gr_unlock () == 0) {
fprintf (log_get_logfd(),
_("%s: failed to unlock %s\n"),
log_get_progname(), gr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking group file",
SHADOW_AUDIT_FAILURE);
#endif
}
}
#ifdef SHADOWGRP
/*
* cleanup_unlock_gshadow - Unlock the gshadow file
*
* It should be registered after the gshadow file is successfully locked.
*/
void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg)
{
if (sgr_unlock () == 0) {
fprintf (log_get_logfd(),
_("%s: failed to unlock %s\n"),
log_get_progname(), sgr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking gshadow file",
SHADOW_AUDIT_FAILURE);
#endif
}
}
#endif
-131
View File
@@ -1,131 +0,0 @@
/*
* 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
}
}
-1263
View File
File diff suppressed because it is too large Load Diff
-150
View File
@@ -1,150 +0,0 @@
/*
* 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
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* $Id$ */
#ifndef COMMONIO_H
#define COMMONIO_H
#include "attr.h"
#include "defines.h" /* bool */
/*
* Linked list entry.
*/
struct commonio_entry {
/*@null@*/char *line;
/*@null@*/void *eptr; /* struct passwd, struct spwd, ... */
/*@dependent@*/ /*@null@*/struct commonio_entry *prev;
/*@owned@*/ /*@null@*/struct commonio_entry *next;
bool changed:1;
};
/*
* Operations depending on database type: passwd, group, shadow etc.
*/
struct commonio_ops {
/*
* Make a copy of the object (for example, struct passwd)
* and all strings pointed by it, in malloced memory.
*/
/*@null@*/ /*@only@*/void *(*dup) (const void *);
/*
* free() the object including any strings pointed by it.
*/
void (*free)(/*@only@*/void *);
/*
* Return the name of the object (for example, pw_name
* for struct passwd).
*/
const char *(*getname) (const void *);
/*
* Parse a string, return object (in static area -
* should be copied using the dup operation above).
*/
void *(*parse) (const char *);
/*
* Write the object to the file (this calls putpwent()
* for struct passwd, for example).
*/
int (*put) (const void *, FILE *);
/*
* fgets and fputs (can be replaced by versions that
* understand line continuation conventions).
*/
ATTR_ACCESS(write_only, 1, 2)
/*@null@*/char *(*fgets)(/*@returned@*/char *restrict s, int n,
FILE *restrict stream);
int (*fputs) (const char *, FILE *);
/*
* open_hook and close_hook.
* If non NULL, these functions will be called after the database
* is open or before it is closed.
* They return 0 on failure and 1 on success.
*/
/*@null@*/int (*open_hook) (void);
/*@null@*/int (*close_hook) (void);
};
/*
* Database structure.
*/
struct commonio_db {
/*
* Name of the data file.
*/
char filename[1024];
/*
* Operations from above.
*/
/*@observer@*/const struct commonio_ops *ops;
/*
* Currently open file stream.
*/
/*@dependent@*/ /*@null@*/FILE *fp;
#ifdef WITH_SELINUX
/*@null@*/char *scontext;
#endif
/*
* Default permissions and owner for newly created data file.
*/
mode_t st_mode;
uid_t st_uid;
gid_t st_gid;
/*
* Head, tail, current position in linked list.
*/
/*@owned@*/ /*@null@*/struct commonio_entry *head;
/*@dependent@*/ /*@null@*/struct commonio_entry *tail;
/*@dependent@*/ /*@null@*/struct commonio_entry *cursor;
/*
* Various flags.
*/
bool changed:1;
bool isopen:1;
bool locked:1;
bool readonly:1;
bool setname:1;
};
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 *);
#ifdef ENABLE_SUBIDS
extern int commonio_append (struct commonio_db *, const void *);
#endif /* ENABLE_SUBIDS */
extern int commonio_remove (struct commonio_db *, const char *);
extern int commonio_rewind (struct commonio_db *);
extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *);
extern int commonio_close (struct commonio_db *);
extern int commonio_unlock (struct commonio_db *);
extern void commonio_del_entry (struct commonio_db *,
const struct commonio_entry *);
extern int commonio_sort_wrt (struct commonio_db *shadow,
const struct commonio_db *passwd);
extern int commonio_sort (struct commonio_db *db,
int (*cmp) (const void *, const void *));
#endif
-109
View File
@@ -1,109 +0,0 @@
/*
* 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);
}
-925
View File
@@ -1,925 +0,0 @@
/*
* 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
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#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
#include <selinux/selinux.h>
#endif /* WITH_SELINUX */
#if defined(WITH_ACL) || defined(WITH_ATTR)
#include <stdarg.h>
#include <attr/error_context.h>
#endif /* WITH_ACL || WITH_ATTR */
#ifdef WITH_ACL
#include <acl/libacl.h>
#endif /* WITH_ACL */
#ifdef WITH_ATTR
#include <attr/libattr.h>
#endif /* WITH_ATTR */
#include "shadowlog.h"
#include "string/sprintf.h"
static /*@null@*/const char *src_orig;
static /*@null@*/const char *dst_orig;
struct link_name {
dev_t ln_dev;
ino_t ln_ino;
nlink_t ln_count;
char *ln_name;
/*@dependent@*/struct link_name *ln_next;
};
static /*@exposed@*/struct link_name *links;
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 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);
static /*@null@*/char *readlink_malloc (const char *filename);
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);
static int copy_hardlink (const struct path_info *dst,
MAYBE_UNUSED bool reset_selinux,
struct link_name *lp);
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);
static int copy_file (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);
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 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);
#if defined(WITH_ACL) || defined(WITH_ATTR)
/*
* error_acl - format the error messages for the ACL and EQ libraries.
*/
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
* or extended attributes */
if (ENOTSUP == errno) {
errno = 0;
return;
}
va_start (ap, fmt);
(void) fprintf (shadow_logfd, _("%s: "), log_get_progname());
if (vfprintf (shadow_logfd, fmt, ap) != 0) {
(void) fputs (_(": "), shadow_logfd);
}
(void) fprintf (shadow_logfd, "%s\n", strerror (errno));
va_end (ap);
}
static struct error_context ctx = {
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
*/
static void remove_link (/*@only@*/struct link_name *ln)
{
struct link_name *lp;
if (links == ln) {
links = ln->ln_next;
free (ln->ln_name);
free (ln);
return;
}
for (lp = links; NULL !=lp; lp = lp->ln_next) {
if (lp->ln_next == ln) {
break;
}
}
if (NULL == lp) {
free (ln->ln_name);
free (ln);
return;
}
lp->ln_next = lp->ln_next->ln_next;
free (ln->ln_name);
free (ln);
}
/*
* check_link - see if a file is really a link
*/
static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, const struct stat *sb)
{
struct link_name *lp;
/* copy_tree () must be the entry point */
assert (NULL != src_orig);
assert (NULL != dst_orig);
for (lp = links; NULL != lp; lp = lp->ln_next) {
if ((lp->ln_dev == sb->st_dev) && (lp->ln_ino == sb->st_ino)) {
return lp;
}
}
if (sb->st_nlink == 1) {
return NULL;
}
lp = XMALLOC(1, struct link_name);
lp->ln_dev = sb->st_dev;
lp->ln_ino = sb->st_ino;
lp->ln_count = sb->st_nlink;
xasprintf(&lp->ln_name, "%s%s", dst_orig, name + strlen(src_orig));
lp->ln_next = links;
links = lp;
return NULL;
}
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 dst_fd, src_fd, err = 0;
bool set_orig = false;
const struct dirent *ent;
DIR *dir;
if (copy_root) {
struct stat sb;
if ( fstatat (dst->dirfd, dst->name, &sb, 0) == 0
|| errno != ENOENT) {
return -1;
}
if (fstatat (src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
return -1;
}
if (!S_ISDIR (sb.st_mode)) {
fprintf (log_get_logfd(),
"%s: %s is not a directory",
log_get_progname(), src->full_path);
return -1;
}
return copy_entry (src, dst, reset_selinux,
old_uid, new_uid, old_gid, new_gid);
}
/*
* Make certain both directories exist. This routine is called
* after the home directory is created, or recursively after the
* target is created. It assumes the target directory exists.
*/
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;
}
/*
* Open the source directory and read each entry. Every file
* entry in the directory is copied with the UID and GID set
* to the provided values. As an added security feature only
* regular files (and directories ...) are copied, and no file
* is made set-ID.
*/
dir = fdopendir (src_fd);
if (NULL == dir) {
(void) close (src_fd);
(void) close (dst_fd);
return -1;
}
if (src_orig == NULL) {
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)
{
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;
dst_orig = NULL;
/* FIXME: clean links
* Since there can be hardlinks elsewhere on the device,
* we cannot check that all the hardlinks were found:
assert (NULL == links);
*/
}
#ifdef WITH_SELINUX
/* Reset SELinux to create files with default contexts.
* Note that the context is only reset on exit of copy_tree (it is
* assumed that the program would quit without needing a restored
* context if copy_tree failed previously), and that copy_tree can
* be called recursively (hence the context is set on the
* sub-functions of copy_entry).
*/
if (reset_selinux_file_context () != 0) {
err = -1;
}
#endif /* WITH_SELINUX */
return err;
}
/*
* copy_entry - copy the entry of a directory
*
* Copy the entry src to dst.
* Depending on the type of entry, this function will forward the
* request to copy_dir(), copy_symlink(), copy_hardlink(),
* copy_special(), or copy_file().
*
* The access and modification time will not be modified.
*
* The permissions will be set to new_uid/new_gid.
*
* If new_uid (resp. new_gid) is equal to -1, the user (resp. group) will
* not be modified.
*
* Only the files owned (resp. group-owned) by old_uid (resp.
* old_gid) will be modified, unless old_uid (resp. old_gid) is set
* to -1.
*/
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 timespec mt[2];
if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
/* If we cannot stat the file, do not care. */
return 0;
}
mt[0].tv_sec = sb.st_atim.tv_sec;
mt[0].tv_nsec = sb.st_atim.tv_nsec;
mt[1].tv_sec = sb.st_mtim.tv_sec;
mt[1].tv_nsec = sb.st_mtim.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);
}
/*
* 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;
}
/*
* Copy any symbolic links
*/
else if (S_ISLNK (sb.st_mode)) {
err = copy_symlink (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
/*
* See if this is a previously copied link
*/
else if ((lp = check_link (src->full_path, &sb)) != NULL) {
err = copy_hardlink (dst, reset_selinux, lp);
}
/*
* 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 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;
}
/*
* copy_dir - copy a directory
*
* Copy a directory (recursively) from src to dst.
*
* statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set
* the access and modification and the access rights.
*
* Return 0 on success, -1 on error.
*/
static int copy_dir (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;
struct stat dst_sb;
/*
* Create a new target directory, make it owned by
* the user and then recursively copy that directory.
*/
#ifdef WITH_SELINUX
if (set_selinux_file_context (dst->full_path, S_IFDIR) != 0) {
return -1;
}
#endif /* WITH_SELINUX */
/*
* 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_path (src, dst, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ACL */
#ifdef WITH_ATTR
/*
* If the third parameter is NULL, all extended attributes
* except those that define Access Control Lists are copied.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (attr_copy_path (src, dst, NULL, &ctx) != 0)
&& (errno != 0))
#endif /* WITH_ATTR */
|| (copy_tree_impl (src, dst, false, reset_selinux,
old_uid, new_uid, old_gid, new_gid) != 0)
|| (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) {
err = -1;
}
return err;
}
/*
* readlink_malloc - wrapper for readlink
*
* return NULL on error.
* The return string shall be freed by the caller.
*/
static /*@null@*/char *readlink_malloc (const char *filename)
{
size_t size = 1024;
while (true) {
ssize_t nchars;
char *buffer = MALLOC(size, char);
if (NULL == buffer) {
return NULL;
}
nchars = readlink (filename, buffer, size);
if (nchars < 0) {
free(buffer);
return NULL;
}
if ((size_t) nchars < size) { /* The buffer was large enough */
/* readlink does not nul-terminate */
buffer[nchars] = '\0';
return buffer;
}
/* Try again with a bigger buffer */
free (buffer);
size *= 2;
}
}
/*
* copy_symlink - copy a symlink
*
* Copy a symlink from src to dst.
*
* statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set
* the access and modification and the access rights.
*
* Return 0 on success, -1 on error.
*/
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)
{
char *oldlink;
/* copy_tree () must be the entry point */
assert (NULL != src_orig);
assert (NULL != dst_orig);
/*
* Get the name of the file which the link points
* to. If that name begins with the original
* source directory name, that part of the link
* name will be replaced with the original
* destination directory name.
*/
oldlink = readlink_malloc (src->full_path);
if (NULL == oldlink) {
return -1;
}
/* If src was a link to an entry of the src_orig directory itself,
* create a link to the corresponding entry in the dst_orig
* directory.
*/
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->full_path, S_IFLNK) != 0) {
free (oldlink);
return -1;
}
#endif /* WITH_SELINUX */
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
* complex than calling perm_copy_file.
* Ditto for Extended Attributes.
* We currently only document that ACL and Extended
* Attributes are not copied.
*/
free (oldlink);
return -1;
}
free (oldlink);
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
return -1;
}
return 0;
}
/*
* copy_hardlink - copy a hardlink
*
* Copy a hardlink from src to dst.
*
* Return 0 on success, -1 on error.
*/
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 (linkat (AT_FDCWD, lp->ln_name, dst->dirfd, dst->name, 0) != 0) {
return -1;
}
/* If the file could be unlinked, decrement the links counter,
* and forget about this link if it was the last reference */
lp->ln_count--;
if (lp->ln_count <= 0) {
remove_link (lp);
}
return 0;
}
/*
* copy_special - copy a special file
*
* Copy a special file from src to dst.
*
* statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set
* the access and modification and the access rights.
*
* Return 0 on success, -1 on error.
*/
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)
{
#if defined(WITH_SELINUX)
if (set_selinux_file_context(dst->full_path, statp->st_mode & S_IFMT) != 0)
return -1;
#endif
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.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
if (!reset_selinux) {
if (attr_copy_path(src, dst, NULL, &ctx) == -1 && errno != 0)
return -1;
}
#endif
if (utimensat(dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) == -1)
return -1;
return 0;
}
/*
* copy_file - copy a file
*
* Copy a file from src to dst.
*
* statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set
* the access and modification and the access rights.
*
* Return 0 on success, -1 on error.
*/
static int copy_file (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;
int ifd;
int ofd;
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->full_path, S_IFREG) != 0) {
(void) close (ifd);
return -1;
}
#endif /* WITH_SELINUX */
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)
|| (fchmod (ofd, statp->st_mode & 07777) != 0)
#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
* except those that define Access Control Lists are copied.
* ACLs are excluded by default because copying them between
* file systems with and without ACL support needs some
* additional logic so that no unexpected permissions result.
*/
|| ( !reset_selinux
&& (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 (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);
if (close (ofd) != 0 && errno != EINTR) {
return -1;
}
if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) {
return -1;
}
return err;
}
#define def_chown_if_needed(chown_function, type_dst) \
static int chown_function ## _if_needed (type_dst 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 chown_function (dst, tmpuid, tmpgid); \
}
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);
}
-150
View File
@@ -1,150 +0,0 @@
/*
* 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 csrand32(void);
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;
}
static uint32_t
csrand32(void)
{
return csrand();
}
/*
* 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 csrand32();
bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`
do {
r = csrand32();
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;
}
-216
View File
@@ -1,216 +0,0 @@
/* $Id$ */
/* some useful defines */
#ifndef _DEFINES_H_
#define _DEFINES_H_
#include "config.h"
#include <stdbool.h>
#include <locale.h>
#define gettext_noop(String) (String)
/* #define gettext_def(String) "#define String" */
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
#else
# undef bindtextdomain
# define bindtextdomain(Domain, Directory) (NULL)
# undef textdomain
# define textdomain(Domain) (NULL)
# define _(Text) Text
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#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
#include <sys/time.h>
#include <time.h>
#include <dirent.h>
/*
* Possible cases:
* - /usr/include/shadow.h exists and includes the shadow group stuff.
* - /usr/include/shadow.h exists, but we use our own gshadow.h.
*/
#include <shadow.h>
#if defined(SHADOWGRP) && !defined(GSHADOW)
#include "gshadow_.h"
#endif
#include <limits.h>
#ifndef NGROUPS_MAX
#ifdef NGROUPS
#define NGROUPS_MAX NGROUPS
#else
#define NGROUPS_MAX 64
#endif
#endif
#include <syslog.h>
#ifndef LOG_WARN
#define LOG_WARN LOG_WARNING
#endif
/* LOG_NOWAIT is deprecated */
#ifndef LOG_NOWAIT
#define LOG_NOWAIT 0
#endif
/* LOG_AUTH is deprecated, use LOG_AUTHPRIV instead */
#ifndef LOG_AUTHPRIV
#define LOG_AUTHPRIV LOG_AUTH
#endif
/* cleaner than lots of #ifdefs everywhere - use this as follows:
SYSLOG((LOG_CRIT, "user %s cracked root", user)); */
#ifdef ENABLE_NLS
/* Temporarily set LC_TIME to "C" to avoid strange dates in syslog.
This is a workaround for a more general syslog(d) design problem -
syslogd should log the current system time for each event, and not
trust the formatted time received from the unix domain (or worse,
UDP) socket. -MM */
/* Avoid translated PAM error messages: Set LC_ALL to "C".
* --Nekral */
#define SYSLOG(x) \
do { \
char *old_locale = setlocale (LC_ALL, NULL); \
char *saved_locale = NULL; \
if (NULL != old_locale) { \
saved_locale = strdup (old_locale); \
} \
if (NULL != saved_locale) { \
(void) setlocale (LC_ALL, "C"); \
} \
syslog x ; \
if (NULL != saved_locale) { \
(void) setlocale (LC_ALL, saved_locale); \
free (saved_locale); \
} \
} while (false)
#else /* !ENABLE_NLS */
#define SYSLOG(x) syslog x
#endif /* !ENABLE_NLS */
/* The default syslog settings can now be changed here,
in just one place. */
#ifndef SYSLOG_OPTIONS
/* #define SYSLOG_OPTIONS (LOG_PID | LOG_CONS | LOG_NOWAIT) */
#define SYSLOG_OPTIONS (LOG_PID)
#endif
#ifndef SYSLOG_FACILITY
#define SYSLOG_FACILITY LOG_AUTHPRIV
#endif
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
#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
*/
/* Solaris defines this in shadow.h */
#ifndef DAY
#define DAY ((time_t) 24 * 3600)
#endif
#define WEEK (7*DAY)
#ifndef PASSWD_FILE
#define PASSWD_FILE "/etc/passwd"
#endif
#ifndef GROUP_FILE
#define GROUP_FILE "/etc/group"
#endif
#ifndef SHADOW_FILE
#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
/*
* string to use for the pw_passwd field in /etc/passwd when using
* shadow passwords - most systems use "x" but there are a few
* exceptions, so it can be changed here if necessary. --marekm
*/
#ifndef SHADOW_PASSWD_STRING
#define SHADOW_PASSWD_STRING "x"
#endif
#define SHADOW_SP_FLAG_UNSET ((unsigned long)-1)
#ifdef WITH_AUDIT
/* in case we use pam < 0.80 */
#undef __u8
#undef __u32
#include <libaudit.h>
#endif
/* Maximum length of passwd entry */
#define PASSWD_ENTRY_MAX_LENGTH 32768
#ifdef HAVE_SECURE_GETENV
# define shadow_getenv(name) secure_getenv(name)
# else
# 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_ */
-79
View File
@@ -1,79 +0,0 @@
/*
* 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
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
#ident "$Id$"
#include <unistd.h>
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
#include "shadowlog_internal.h"
/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt)
{
static char cipher[128];
char *cp;
cp = crypt (clear, salt);
if (NULL == cp) {
/*
* Single Unix Spec: crypt() may return a null pointer,
* and set errno to indicate an error. In this case return
* the NULL so the caller can handle appropriately.
*/
return NULL;
}
/* Some crypt() do not return NULL if the algorithm is not
* supported, and return a DES encrypted password. */
if ((NULL != salt) && (salt[0] == '$') && (strlen (cp) <= 13))
{
/*@observer@*/const char *method;
switch (salt[1])
{
case '1':
method = "MD5";
break;
case '2':
method = "BCRYPT";
break;
case '5':
method = "SHA256";
break;
case '6':
method = "SHA512";
break;
case 'y':
method = "YESCRYPT";
break;
default:
{
static char nummethod[4] = "$x$";
nummethod[1] = salt[1];
method = &nummethod[0];
}
}
(void) fprintf (shadow_logfd,
_("crypt method not supported by libcrypt? (%s)\n"),
method);
exit (EXIT_FAILURE);
}
if (strlen (cp) != 13) {
return cp; /* nonstandard crypt() in libc, better bail out */
}
strcpy (cipher, cp);
return cipher;
}

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