Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
e7a7f8bd36 |
@ -9,11 +9,9 @@ packages:
|
|||||||
- gettext
|
- gettext
|
||||||
- gettext-dev
|
- gettext-dev
|
||||||
- gettext-lang
|
- gettext-lang
|
||||||
- libbsd-dev
|
|
||||||
- libcap-dev
|
- libcap-dev
|
||||||
- libtool
|
- libtool
|
||||||
- linux-pam-dev
|
- linux-pam-dev
|
||||||
- pkgconf
|
|
||||||
- sed
|
- sed
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/shadow-maint/shadow
|
- https://github.com/shadow-maint/shadow
|
||||||
|
@ -8,12 +8,10 @@ packages:
|
|||||||
- gettext
|
- gettext
|
||||||
- gettext-devel
|
- gettext-devel
|
||||||
- git
|
- git
|
||||||
- libbsd-devel
|
|
||||||
- libselinux-devel
|
- libselinux-devel
|
||||||
- libsemanage-devel
|
- libsemanage-devel
|
||||||
- libtool
|
- libtool
|
||||||
- libxslt
|
- libxslt
|
||||||
- pkgconf
|
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/shadow-maint/shadow
|
- https://github.com/shadow-maint/shadow
|
||||||
tasks:
|
tasks:
|
||||||
|
@ -3,13 +3,11 @@ packages:
|
|||||||
- automake
|
- automake
|
||||||
- autopoint
|
- autopoint
|
||||||
- xsltproc
|
- xsltproc
|
||||||
- libbsd-dev
|
|
||||||
- libselinux1-dev
|
- libselinux1-dev
|
||||||
- gettext
|
- gettext
|
||||||
- expect
|
- expect
|
||||||
- byacc
|
- byacc
|
||||||
- libtool
|
- libtool
|
||||||
- pkgconf
|
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/shadow-maint/shadow
|
- https://github.com/shadow-maint/shadow
|
||||||
tasks:
|
tasks:
|
||||||
|
@ -3,13 +3,11 @@ packages:
|
|||||||
- automake
|
- automake
|
||||||
- autopoint
|
- autopoint
|
||||||
- xsltproc
|
- xsltproc
|
||||||
- libbsd-dev
|
|
||||||
- libselinux1-dev
|
- libselinux1-dev
|
||||||
- gettext
|
- gettext
|
||||||
- expect
|
- expect
|
||||||
- byacc
|
- byacc
|
||||||
- libtool
|
- libtool
|
||||||
- pkgconf
|
|
||||||
sources:
|
sources:
|
||||||
- https://github.com/shadow-maint/shadow
|
- https://github.com/shadow-maint/shadow
|
||||||
tasks:
|
tasks:
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*.{c,h}]
|
|
||||||
indent_style = tab
|
|
@ -6,7 +6,7 @@ runs:
|
|||||||
- shell: bash
|
- shell: bash
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update -y
|
sudo apt-get update -y
|
||||||
sudo apt-get install -y ubuntu-dev-tools libbsd-dev
|
sudo apt-get install -y ubuntu-dev-tools
|
||||||
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
|
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
|
||||||
sudo apt-get update -y
|
sudo apt-get update -y
|
||||||
sudo apt-get -y build-dep shadow
|
sudo apt-get -y build-dep shadow
|
||||||
|
76
.github/workflows/runner.yml
vendored
76
.github/workflows/runner.yml
vendored
@ -1,76 +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
|
|
||||||
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
|
|
||||||
sudo ./run_some
|
|
||||||
cat testsuite.log
|
|
||||||
|
|
||||||
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
|
|
9
.github/workflows/static-code-analysis.yml
vendored
9
.github/workflows/static-code-analysis.yml
vendored
@ -14,7 +14,7 @@ jobs:
|
|||||||
security-events: write
|
security-events: write
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
id: dependencies
|
id: dependencies
|
||||||
@ -32,20 +32,19 @@ jobs:
|
|||||||
- name: Build shadow-utils
|
- name: Build shadow-utils
|
||||||
run: |
|
run: |
|
||||||
PROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
|
PROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
|
||||||
make -kj$PROCESSORS || true
|
make -j$PROCESSORS
|
||||||
|
|
||||||
- name: Check build errors
|
|
||||||
run: make
|
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v2
|
||||||
|
|
||||||
differential-shellcheck:
|
differential-shellcheck:
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
security-events: write
|
security-events: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
|
@ -36,7 +36,7 @@ addons:
|
|||||||
notification_email: christian.brauner@ubuntu.com,serge@hallyn.com
|
notification_email: christian.brauner@ubuntu.com,serge@hallyn.com
|
||||||
|
|
||||||
build_command_prepend: "./autogen.sh --without-selinux --disable-man"
|
build_command_prepend: "./autogen.sh --without-selinux --disable-man"
|
||||||
build_command: "make -kj4 || make"
|
build_command: "make -j4"
|
||||||
branch_pattern: master
|
branch_pattern: master
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
@ -3,7 +3,6 @@ reports and various comments. This list may be incomplete, I received
|
|||||||
a lot of mail...
|
a lot of mail...
|
||||||
|
|
||||||
# Maintainers
|
# Maintainers
|
||||||
* Marek Michałkiewicz <marekm72@gmail.com> (1995-2000)
|
|
||||||
* Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
|
* Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
|
||||||
* Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
|
* Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
|
||||||
* Serge E. Hallyn <serge@hallyn.com> (2014-now)
|
* Serge E. Hallyn <serge@hallyn.com> (2014-now)
|
||||||
|
14
ChangeLog
14
ChangeLog
@ -9558,7 +9558,7 @@
|
|||||||
* NEWS: release date corrected.
|
* NEWS: release date corrected.
|
||||||
|
|
||||||
* NEWS, src/su.c:
|
* NEWS, src/su.c:
|
||||||
fixed set environment too early when using PAM, so move it to !USE_PAM
|
fixed set enviroment too early when using PAM, so move it to !USE_PAM
|
||||||
(patch submitted by Mike Frysinger <vapier@gentoo.org>).
|
(patch submitted by Mike Frysinger <vapier@gentoo.org>).
|
||||||
|
|
||||||
2006-07-30 Tomasz Kłoczko <kloczek@pld.org.pl>
|
2006-07-30 Tomasz Kłoczko <kloczek@pld.org.pl>
|
||||||
@ -10245,7 +10245,7 @@
|
|||||||
* NEWS: cleanups.
|
* NEWS: cleanups.
|
||||||
|
|
||||||
* autogen.sh:
|
* autogen.sh:
|
||||||
by default in development environment use CFLAGS="-O2 -Wall".
|
by default in development enviroment use CFLAGS="-O2 -Wall".
|
||||||
|
|
||||||
* src/chgpasswd.c (main): remove two unused variables (newgr and now).
|
* src/chgpasswd.c (main): remove two unused variables (newgr and now).
|
||||||
|
|
||||||
@ -11654,7 +11654,7 @@
|
|||||||
in OPTIONS section). Describe -a and -k options.
|
in OPTIONS section). Describe -a and -k options.
|
||||||
|
|
||||||
* NEWS, src/su.c:
|
* NEWS, src/su.c:
|
||||||
fixed twice copy environment which causes auth problems (bug was introduced in 4.0.12;
|
fixed twice copy enviroment which causes auth problems (bug was introduced in 4.0.12;
|
||||||
fix by Nicolas François <nicolas.francois@centraliens.net>).
|
fix by Nicolas François <nicolas.francois@centraliens.net>).
|
||||||
|
|
||||||
* src/passwd.c, po/ja.po, po/ko.po, po/nb.po, po/nl.po, po/nn.po, po/pl.po, po/pt.po, po/pt_BR.po, po/ro.po, po/ru.po, po/sk.po, po/sq.po, po/sv.po, po/tl.po, po/tr.po, po/uk.po, po/vi.po, po/zh_CN.po, po/zh_TW.po, po/bs.po, po/ca.po, po/cs.po, po/da.po, po/de.po, po/el.po, po/es.po, po/eu.po, po/fi.po, po/fr.po, po/he.po, po/id.po, po/it.po:
|
* src/passwd.c, po/ja.po, po/ko.po, po/nb.po, po/nl.po, po/nn.po, po/pl.po, po/pt.po, po/pt_BR.po, po/ro.po, po/ru.po, po/sk.po, po/sq.po, po/sv.po, po/tl.po, po/tr.po, po/uk.po, po/vi.po, po/zh_CN.po, po/zh_TW.po, po/bs.po, po/ca.po, po/cs.po, po/da.po, po/de.po, po/el.po, po/es.po, po/eu.po, po/fi.po, po/fr.po, po/he.po, po/id.po, po/it.po:
|
||||||
@ -12584,7 +12584,7 @@
|
|||||||
http://bugs.debian.org/48002
|
http://bugs.debian.org/48002
|
||||||
|
|
||||||
* src/login.c, NEWS:
|
* src/login.c, NEWS:
|
||||||
fixed loggin of username on successful login (was using the normal username,
|
fixed loggin of username on succesful login (was using the normal username,
|
||||||
when it should have used pam_user) http://bugs.debian.org/47819
|
when it should have used pam_user) http://bugs.debian.org/47819
|
||||||
|
|
||||||
2005-06-02 Tomasz Kłoczko <kloczek@pld.org.pl>
|
2005-06-02 Tomasz Kłoczko <kloczek@pld.org.pl>
|
||||||
@ -13029,7 +13029,7 @@
|
|||||||
* man/pl/usermod.8: finish sync with english version.
|
* man/pl/usermod.8: finish sync with english version.
|
||||||
|
|
||||||
* man/hu/login.1, man/pl/login.1, NEWS, man/Attic/login.1, man/de/login.1:
|
* man/hu/login.1, man/pl/login.1, NEWS, man/Attic/login.1, man/de/login.1:
|
||||||
removed fragment about abilities pass environment variables in login prompt.
|
removed fragment about abilities pass enviroment variables in login prompt.
|
||||||
|
|
||||||
* man/Attic/gpasswd.1, man/Attic/newgrp.1:
|
* man/Attic/gpasswd.1, man/Attic/newgrp.1:
|
||||||
fixes by Nicolas Nicolas François <nicolas.francois@centraliens.net> (not all
|
fixes by Nicolas Nicolas François <nicolas.francois@centraliens.net> (not all
|
||||||
@ -13508,7 +13508,7 @@
|
|||||||
removed not used translations.
|
removed not used translations.
|
||||||
|
|
||||||
* NEWS, src/su.c:
|
* NEWS, src/su.c:
|
||||||
fix adding of pam_env env variables to environment (Martin Schlemmer <azarah@nosferatu.za.org>).
|
fix adding of pam_env env variables to enviroment (Martin Schlemmer <azarah@nosferatu.za.org>).
|
||||||
|
|
||||||
* NEWS, configure.in:
|
* NEWS, configure.in:
|
||||||
fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables which was allways
|
fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables which was allways
|
||||||
@ -13605,7 +13605,7 @@
|
|||||||
|
|
||||||
* NEWS, src/su.c:
|
* NEWS, src/su.c:
|
||||||
add pam_open_session() support. If builded without PAM support
|
add pam_open_session() support. If builded without PAM support
|
||||||
propagate $DISPLAY and $XAUTHORITY environment variables.
|
propagate $DISPLAY and $XAUTHORITY enviroment variables.
|
||||||
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
|
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
|
||||||
|
|
||||||
2004-10-23 Tomasz Kłoczko <kloczek@pld.org.pl>
|
2004-10-23 Tomasz Kłoczko <kloczek@pld.org.pl>
|
||||||
|
14
NEWS
14
NEWS
@ -696,7 +696,7 @@ shadow-4.0.18 -> shadow-4.0.18.1 03-08-2006
|
|||||||
shadow-4.0.17 -> shadow-4.0.18 01-08-2006
|
shadow-4.0.17 -> shadow-4.0.18 01-08-2006
|
||||||
|
|
||||||
*** general:
|
*** general:
|
||||||
- su: fixed set environment too early when using PAM, so move it to !USE_PAM
|
- su: fixed set enviroment too early when using PAM, so move it to !USE_PAM
|
||||||
(patch submitted by Mike Frysinger <vapier@gentoo.org>),
|
(patch submitted by Mike Frysinger <vapier@gentoo.org>),
|
||||||
- groupadd, groupmod, useradd, usermod: fixed UID/GID overflow (fixed
|
- groupadd, groupmod, useradd, usermod: fixed UID/GID overflow (fixed
|
||||||
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=198920)
|
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=198920)
|
||||||
@ -855,7 +855,7 @@ shadow-4.0.14 -> shadow-4.0.15 13-03-2006
|
|||||||
- su: move exit() outside libmisc/shell.c::shell() for handle shell() errors
|
- su: move exit() outside libmisc/shell.c::shell() for handle shell() errors
|
||||||
on higher level (now is better visable where some programs exit with 126
|
on higher level (now is better visable where some programs exit with 126
|
||||||
and 127 exit codes); added new shell() parameter (char *const envp[])
|
and 127 exit codes); added new shell() parameter (char *const envp[])
|
||||||
which allow fix preserving environment in su on using -p, (patch by
|
which allow fix preserving enviroment in su on using -p, (patch by
|
||||||
Alexander Gattin <xrgtn@yandex.ru>),
|
Alexander Gattin <xrgtn@yandex.ru>),
|
||||||
- su: added handle -c,--command option for GNU su compliance (merge
|
- su: added handle -c,--command option for GNU su compliance (merge
|
||||||
437_su_-c_option Debian patch),
|
437_su_-c_option Debian patch),
|
||||||
@ -966,7 +966,7 @@ shadow-4.0.12 -> shadow-4.0.13 10-10-2005
|
|||||||
to example described in ident(1) man page (modern compilers like latest GCC
|
to example described in ident(1) man page (modern compilers like latest GCC
|
||||||
removes not used functions by global optimization).
|
removes not used functions by global optimization).
|
||||||
So "ident /usr/bin/passwd" will show again some useable informations
|
So "ident /usr/bin/passwd" will show again some useable informations
|
||||||
- su: fixed twice copy environment which causes auth problems
|
- su: fixed twice copy enviroment which causes auth problems
|
||||||
(bug was introduced in 4.0.12; fix by Nicolas François <nicolas.francois@centraliens.net>),
|
(bug was introduced in 4.0.12; fix by Nicolas François <nicolas.francois@centraliens.net>),
|
||||||
- chage: differentiate the different failure causes by the exit value
|
- chage: differentiate the different failure causes by the exit value
|
||||||
This will permit to adduser Debian script to detect if chage failed because the
|
This will permit to adduser Debian script to detect if chage failed because the
|
||||||
@ -1133,7 +1133,7 @@ shadow-4.0.9 -> shadow-4.0.10 28-06-2005
|
|||||||
http://bugs.debian.org/53702
|
http://bugs.debian.org/53702
|
||||||
- login: check for hushed login and pass PAM_SILENT if true,
|
- login: check for hushed login and pass PAM_SILENT if true,
|
||||||
http://bugs.debian.org/48002
|
http://bugs.debian.org/48002
|
||||||
- login: fixed username on successful login (was using the normal username,
|
- login: fixed username on succesful login (was using the normal username,
|
||||||
when it should have used pam_user) http://bugs.debian.org/47819
|
when it should have used pam_user) http://bugs.debian.org/47819
|
||||||
- remove using SHADOWPWD #define so now shadow is always built with shadow
|
- remove using SHADOWPWD #define so now shadow is always built with shadow
|
||||||
password support,
|
password support,
|
||||||
@ -1212,7 +1212,7 @@ shadow-4.0.7 -> shadow-4.0.8 26-04-2005
|
|||||||
(without gshadow) doesn't permit to use newgrp,
|
(without gshadow) doesn't permit to use newgrp,
|
||||||
- newgrp(1): newgrp uses /bin/sh (not bash),
|
- newgrp(1): newgrp uses /bin/sh (not bash),
|
||||||
- faillog(8): updated after rewritten faillog command for use getopt_long(),
|
- faillog(8): updated after rewritten faillog command for use getopt_long(),
|
||||||
- login(1): removed fragment about abilities pass environment variables in login prompt,
|
- login(1): removed fragment about abilities pass enviroment variables in login prompt,
|
||||||
- gshadow(5): new file (by Nicolas Nicolas François <nicolas.francois@centraliens.net>),
|
- gshadow(5): new file (by Nicolas Nicolas François <nicolas.francois@centraliens.net>),
|
||||||
- usermod(8): fixed #302388 Debian bug: added separated -o option description,
|
- usermod(8): fixed #302388 Debian bug: added separated -o option description,
|
||||||
|
|
||||||
@ -1242,7 +1242,7 @@ shadow-4.0.6 -> shadow-4.0.7 26-01-2005
|
|||||||
|
|
||||||
shadow-4.0.5 -> shadow-4.0.6 08-11-2004
|
shadow-4.0.5 -> shadow-4.0.6 08-11-2004
|
||||||
|
|
||||||
- su: fixed adding of pam_env env variables to environment
|
- su: fixed adding of pam_env env variables to enviroment
|
||||||
(Martin Schlemmer <azarah@nosferatu.za.org>),
|
(Martin Schlemmer <azarah@nosferatu.za.org>),
|
||||||
- autoconf: fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables
|
- autoconf: fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables
|
||||||
which was always empty (Gregorio Guidi <g.guidi@sns.it>),
|
which was always empty (Gregorio Guidi <g.guidi@sns.it>),
|
||||||
@ -1275,7 +1275,7 @@ shadow-4.0.4.1 -> shadow-4.0.5 27-10-2004
|
|||||||
including symlinks placed into /etc/skel/public_html for example.
|
including symlinks placed into /etc/skel/public_html for example.
|
||||||
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=66819
|
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=66819
|
||||||
- su: add pam_open_session() support. If built without PAM support
|
- su: add pam_open_session() support. If built without PAM support
|
||||||
propagate $DISPLAY and $XAUTHORITY environment variables.
|
propagate $DISPLAY and $XAUTHORITY enviroment variables.
|
||||||
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
|
Based on http://www.gentoo.org/cgi-bin/viewcvs.cgi/sys-apps/shadow/files/shadow-4.0.4.1-su-pam_open_session.patch?rev=1.1
|
||||||
- applied 036_pam_access_with_preauth.patch Debian patch submited by Bjorn
|
- applied 036_pam_access_with_preauth.patch Debian patch submited by Bjorn
|
||||||
Torkelsson <Bjorn.Torkelsson@hpc2n.umu.se>: add support for PAM account
|
Torkelsson <Bjorn.Torkelsson@hpc2n.umu.se>: add support for PAM account
|
||||||
|
@ -31,11 +31,6 @@ There are several ways to contact us:
|
|||||||
https://alioth-lists-archive.debian.net/pipermail/pkg-shadow-commits/),
|
https://alioth-lists-archive.debian.net/pipermail/pkg-shadow-commits/),
|
||||||
only used for historical purposes
|
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
|
||||||
Authors and maintainers are listed in [AUTHORS.md](
|
Authors and maintainers are listed in [AUTHORS.md](
|
||||||
https://github.com/shadow-maint/shadow/blob/master/AUTHORS.md).
|
https://github.com/shadow-maint/shadow/blob/master/AUTHORS.md).
|
||||||
|
@ -9,4 +9,3 @@ At the moment only the latest release is supported.
|
|||||||
Security vulnerabilities may be reported to
|
Security vulnerabilities may be reported to
|
||||||
* Serge Hallyn <serge@hallyn.com> (B175CFA98F192AF2)
|
* Serge Hallyn <serge@hallyn.com> (B175CFA98F192AF2)
|
||||||
* Christian Brauner <christian@brauner.io> (4880B8C9BD0E5106FC070F4F7B3C391EFEA93624)
|
* Christian Brauner <christian@brauner.io> (4880B8C9BD0E5106FC070F4F7B3C391EFEA93624)
|
||||||
* Iker Pedrosa <ipedrosa@redhat.com> (4E80EF49C7987B6DE2F81F5005079C6C3A653E57)
|
|
||||||
|
86
configure.ac
86
configure.ac
@ -36,25 +36,31 @@ LT_INIT
|
|||||||
dnl Checks for libraries.
|
dnl Checks for libraries.
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
AC_CHECK_HEADERS(crypt.h utmp.h \
|
AC_HEADER_STDBOOL
|
||||||
termio.h sgtty.h sys/ioctl.h paths.h \
|
|
||||||
sys/capability.h sys/random.h \
|
AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
|
||||||
gshadow.h lastlog.h rpc/key_prot.h acl/libacl.h \
|
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
|
||||||
|
utime.h ulimit.h sys/capability.h sys/random.h sys/resource.h \
|
||||||
|
gshadow.h lastlog.h locale.h rpc/key_prot.h netdb.h acl/libacl.h \
|
||||||
attr/libattr.h attr/error_context.h)
|
attr/libattr.h attr/error_context.h)
|
||||||
|
|
||||||
dnl shadow now uses the libc's shadow implementation
|
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_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
|
||||||
|
|
||||||
AC_CHECK_FUNCS(arc4random_buf futimes \
|
AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes \
|
||||||
getentropy getrandom getspnam getusershell \
|
getentropy getrandom getspnam getusershell \
|
||||||
initgroups lckpwdf lutimes mempcpy \
|
getutent initgroups lckpwdf lutimes \
|
||||||
setgroups updwtmp updwtmpx innetgr \
|
setgroups updwtmp updwtmpx innetgr getpwnam_r \
|
||||||
getspnam_r \
|
getpwuid_r getgrnam_r getgrgid_r getspnam_r \
|
||||||
rpmatch \
|
memset_s explicit_bzero)
|
||||||
memset_explicit explicit_bzero stpecpy stpeprintf)
|
|
||||||
AC_SYS_LARGEFILE
|
AC_SYS_LARGEFILE
|
||||||
|
|
||||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_atim])
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_atimensec])
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_mtim])
|
||||||
|
AC_CHECK_MEMBERS([struct stat.st_mtimensec])
|
||||||
|
AC_STRUCT_TM
|
||||||
|
|
||||||
AC_CHECK_MEMBERS([struct utmp.ut_type,
|
AC_CHECK_MEMBERS([struct utmp.ut_type,
|
||||||
struct utmp.ut_id,
|
struct utmp.ut_id,
|
||||||
@ -68,6 +74,14 @@ AC_CHECK_MEMBERS([struct utmp.ut_type,
|
|||||||
struct utmp.ut_xtime,
|
struct utmp.ut_xtime,
|
||||||
struct utmp.ut_tv],,,[[#include <utmp.h>]])
|
struct utmp.ut_tv],,,[[#include <utmp.h>]])
|
||||||
|
|
||||||
|
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>]])
|
||||||
|
|
||||||
if test "$ac_cv_header_lastlog_h" = "yes"; then
|
if test "$ac_cv_header_lastlog_h" = "yes"; then
|
||||||
AC_CACHE_CHECK(for ll_host in struct lastlog,
|
AC_CACHE_CHECK(for ll_host in struct lastlog,
|
||||||
ac_cv_struct_lastlog_ll_host,
|
ac_cv_struct_lastlog_ll_host,
|
||||||
@ -88,8 +102,9 @@ fi
|
|||||||
dnl Checks for library functions.
|
dnl Checks for library functions.
|
||||||
AC_TYPE_GETGROUPS
|
AC_TYPE_GETGROUPS
|
||||||
AC_FUNC_UTIME_NULL
|
AC_FUNC_UTIME_NULL
|
||||||
AC_REPLACE_FUNCS(putgrent putpwent putspent)
|
AC_REPLACE_FUNCS(mkdir putgrent putpwent putspent rename rmdir)
|
||||||
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
|
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
|
||||||
|
AC_REPLACE_FUNCS(snprintf strcasecmp strdup strerror strstr)
|
||||||
|
|
||||||
AC_CHECK_FUNC(setpgrp)
|
AC_CHECK_FUNC(setpgrp)
|
||||||
AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
|
AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
|
||||||
@ -101,10 +116,6 @@ if test "$ac_cv_header_shadow_h" = "yes"; then
|
|||||||
ac_cv_libc_shadowgrp,
|
ac_cv_libc_shadowgrp,
|
||||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||||
#include <shadow.h>
|
#include <shadow.h>
|
||||||
#ifdef HAVE_GSHADOW_H
|
|
||||||
#include <gshadow.h>
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
struct sgrp *sg = sgetsgent("test:x::");
|
struct sgrp *sg = sgetsgent("test:x::");
|
||||||
@ -180,7 +191,7 @@ AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
|
|||||||
[Path to passwd program.])
|
[Path to passwd program.])
|
||||||
|
|
||||||
dnl XXX - quick hack, should disappear before anyone notices :).
|
dnl XXX - quick hack, should disappear before anyone notices :).
|
||||||
dnl XXX - I just read the above message :).
|
AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog().])
|
||||||
if test "$ac_cv_func_ruserok" = "yes"; then
|
if test "$ac_cv_func_ruserok" = "yes"; then
|
||||||
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
|
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).])
|
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
|
||||||
@ -215,6 +226,17 @@ AC_ARG_ENABLE(account-tools-setuid,
|
|||||||
[enable_acct_tools_setuid="no"]
|
[enable_acct_tools_setuid="no"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(utmpx,
|
||||||
|
[AS_HELP_STRING([--enable-utmpx],
|
||||||
|
[enable loggin in utmpx / wtmpx @<:@default=no@:>@])],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) enable_utmpx="yes" ;;
|
||||||
|
no) enable_utmpx="no" ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-utmpx) ;;
|
||||||
|
esac],
|
||||||
|
[enable_utmpx="no"]
|
||||||
|
)
|
||||||
|
|
||||||
AC_ARG_ENABLE(subordinate-ids,
|
AC_ARG_ENABLE(subordinate-ids,
|
||||||
[AS_HELP_STRING([--enable-subordinate-ids],
|
[AS_HELP_STRING([--enable-subordinate-ids],
|
||||||
[support subordinate ids @<:@default=yes@:>@])],
|
[support subordinate ids @<:@default=yes@:>@])],
|
||||||
@ -314,12 +336,12 @@ 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 other libraries. This should prevent linking libnsl if not really
|
||||||
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
|
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
|
||||||
|
|
||||||
|
AC_SEARCH_LIBS(inet_ntoa, inet)
|
||||||
|
AC_SEARCH_LIBS(socket, socket)
|
||||||
AC_SEARCH_LIBS(gethostbyname, nsl)
|
AC_SEARCH_LIBS(gethostbyname, nsl)
|
||||||
|
|
||||||
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
|
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
|
||||||
if test -n "$LIBECONF"; then
|
if test -n "$LIBECONF"; then
|
||||||
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
|
|
||||||
[Directory for distribution provided configuration files])
|
|
||||||
ECONF_CPPFLAGS="-DUSE_ECONF=1"
|
ECONF_CPPFLAGS="-DUSE_ECONF=1"
|
||||||
AC_ARG_ENABLE([vendordir],
|
AC_ARG_ENABLE([vendordir],
|
||||||
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
|
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
|
||||||
@ -327,9 +349,6 @@ fi
|
|||||||
AC_SUBST(ECONF_CPPFLAGS)
|
AC_SUBST(ECONF_CPPFLAGS)
|
||||||
AC_SUBST(LIBECONF)
|
AC_SUBST(LIBECONF)
|
||||||
AC_SUBST([VENDORDIR], [$enable_vendordir])
|
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])
|
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
|
||||||
|
|
||||||
if test "$enable_shadowgrp" = "yes"; then
|
if test "$enable_shadowgrp" = "yes"; then
|
||||||
@ -382,21 +401,6 @@ AC_SUBST(LIYESCRYPT)
|
|||||||
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
|
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
|
||||||
[AC_MSG_ERROR([crypt() not found])])
|
[AC_MSG_ERROR([crypt() not found])])
|
||||||
|
|
||||||
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_SUBST(LIBACL)
|
AC_SUBST(LIBACL)
|
||||||
if test "$with_acl" != "no"; then
|
if test "$with_acl" != "no"; then
|
||||||
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
|
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
|
||||||
@ -678,6 +682,15 @@ if test "$with_skey" = "yes"; then
|
|||||||
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
|
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$enable_utmpx" = "yes"; then
|
||||||
|
if test "$ac_cv_header_utmpx_h" != "yes"; then
|
||||||
|
AC_MSG_ERROR([The utmpx.h header file is required for utmpx support.])
|
||||||
|
fi
|
||||||
|
AC_DEFINE(USE_UTMPX,
|
||||||
|
1,
|
||||||
|
[Define if utmpx should be used])
|
||||||
|
fi
|
||||||
|
|
||||||
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
|
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
|
||||||
|
|
||||||
AM_GNU_GETTEXT_VERSION([0.19])
|
AM_GNU_GETTEXT_VERSION([0.19])
|
||||||
@ -746,5 +759,4 @@ echo " sssd support: $with_sssd"
|
|||||||
echo " subordinate IDs support: $enable_subids"
|
echo " subordinate IDs support: $enable_subids"
|
||||||
echo " use file caps: $with_fcaps"
|
echo " use file caps: $with_fcaps"
|
||||||
echo " install su: $with_su"
|
echo " install su: $with_su"
|
||||||
echo " enabled vendor dir: $enable_vendordir"
|
|
||||||
echo
|
echo
|
||||||
|
@ -2,5 +2,5 @@
|
|||||||
# and also cooperate to make a distribution for `make dist'
|
# and also cooperate to make a distribution for `make dist'
|
||||||
|
|
||||||
EXTRA_DIST = README adduser.c adduser.sh adduser2.sh \
|
EXTRA_DIST = README adduser.c adduser.sh adduser2.sh \
|
||||||
atudel groupmems.shar shadow-anonftp.patch \
|
atudel groupmems.shar pwdauth.c shadow-anonftp.patch \
|
||||||
udbachk.tgz
|
udbachk.tgz
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
** Added in the password date field, which should always reflect the last
|
** Added in the password date field, which should always reflect the last
|
||||||
** date the password was changed, for expiry purposes. "passwd" always
|
** date the password was changed, for expiry purposes. "passwd" always
|
||||||
** updates this field, so the adduser program should set it up right
|
** updates this field, so the adduser program should set it up right
|
||||||
** initially (or a user could keep their initial password forever ;)
|
** initially (or a user could keep thier initial password forever ;)
|
||||||
** The number is in days since Jan 1st, 1970.
|
** The number is in days since Jan 1st, 1970.
|
||||||
**
|
**
|
||||||
** Have fun with it, and someone please make
|
** Have fun with it, and someone please make
|
||||||
@ -489,7 +489,7 @@ safeget (char *buf, int maxlen)
|
|||||||
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
|
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
|
||||||
{
|
{
|
||||||
bad = (!isalnum (c) && (c != '_') && (c != ' '));
|
bad = (!isalnum (c) && (c != '_') && (c != ' '));
|
||||||
*(buf++) = c;
|
*(buf++) = (char) c;
|
||||||
}
|
}
|
||||||
*buf = '\0';
|
*buf = '\0';
|
||||||
|
|
||||||
|
308
contrib/pwdauth.c
Normal file
308
contrib/pwdauth.c
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
* pwdauth.c - program to verify a given username/password pair.
|
||||||
|
*
|
||||||
|
* Run it with username in argv[1] (may be omitted - default is the
|
||||||
|
* current user), and send it the password over a pipe on stdin.
|
||||||
|
* Exit status: 0 - correct password, 1 - wrong password, >1 - other
|
||||||
|
* errors. For use with shadow passwords, this program should be
|
||||||
|
* installed setuid root.
|
||||||
|
*
|
||||||
|
* This can be used, for example, by xlock - you don't have to install
|
||||||
|
* this large and complex (== possibly insecure) program setuid root,
|
||||||
|
* just modify it to run this simple program to do the authentication.
|
||||||
|
*
|
||||||
|
* Recent versions (xlockmore-3.9) are cleaner, and drop privileges as
|
||||||
|
* soon as possible after getting the user's encrypted password.
|
||||||
|
* Using this program probably doesn't make it more secure, and has one
|
||||||
|
* disadvantage: since we don't get the encrypted user's password at
|
||||||
|
* startup (but at the time the user is authenticated), it is not clear
|
||||||
|
* how we should handle errors (like getpwnam() returning NULL).
|
||||||
|
* - fail the authentication? Problem: no way to unlock (other than kill
|
||||||
|
* the process from somewhere else) if the NIS server stops responding.
|
||||||
|
* - succeed and unlock? Problem: it's too easy to unlock by unplugging
|
||||||
|
* the box from the network and waiting until NIS times out...
|
||||||
|
*
|
||||||
|
* This program is Copyright (C) 1996 Marek Michalkiewicz
|
||||||
|
* <marekm@i17linuxb.ists.pwr.wroc.pl>.
|
||||||
|
*
|
||||||
|
* It may be used and distributed freely for any purposes. There is no
|
||||||
|
* warranty - use at your own risk. I am not liable for any damages etc.
|
||||||
|
* If you improve it, please send me your changes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static char rcsid[] = "$Id$";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define USE_SYSLOG to use syslog() to log successful and failed
|
||||||
|
* authentication. This should be safe even if your system has
|
||||||
|
* the infamous syslog buffer overrun security problem...
|
||||||
|
*/
|
||||||
|
#define USE_SYSLOG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define HAVE_GETSPNAM to get shadow passwords using getspnam().
|
||||||
|
* Some systems don't have getspnam(), but getpwnam() returns
|
||||||
|
* encrypted passwords only if running as root.
|
||||||
|
*
|
||||||
|
* According to the xlock source (not tested, except Linux) -
|
||||||
|
* define: Linux, Solaris 2.x, SVR4, ...
|
||||||
|
* undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX.
|
||||||
|
* Known not supported (yet): Ultrix, OSF/1, SCO.
|
||||||
|
*/
|
||||||
|
#define HAVE_GETSPNAM
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt().
|
||||||
|
* pw_encrypt() is like the standard crypt(), except that it may
|
||||||
|
* support better password hashing algorithms.
|
||||||
|
*
|
||||||
|
* Define if linking with libshadow.a from the shadow password
|
||||||
|
* suite (Linux, SunOS 4.x?).
|
||||||
|
*/
|
||||||
|
#undef HAVE_PW_ENCRYPT
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define HAVE_AUTH_METHODS to support the shadow suite specific
|
||||||
|
* extension: the encrypted password field contains a list of
|
||||||
|
* administrator defined authentication methods, separated by
|
||||||
|
* semicolons. This program only supports the standard password
|
||||||
|
* authentication method (a string that doesn't start with '@').
|
||||||
|
*/
|
||||||
|
#undef HAVE_AUTH_METHODS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* FAIL_DELAY - number of seconds to sleep before exiting if the
|
||||||
|
* password was wrong, to slow down password guessing attempts.
|
||||||
|
*/
|
||||||
|
#define FAIL_DELAY 2
|
||||||
|
|
||||||
|
/* No user-serviceable parts below :-). */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
|
#include <syslog.h>
|
||||||
|
#ifndef LOG_AUTHPRIV
|
||||||
|
#define LOG_AUTHPRIV LOG_AUTH
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_GETSPNAM
|
||||||
|
#include <shadow.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_PW_ENCRYPT
|
||||||
|
extern char *pw_encrypt();
|
||||||
|
#define crypt pw_encrypt
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read the password (one line) from fp. We don't turn off echo
|
||||||
|
* because we expect input from a pipe.
|
||||||
|
*/
|
||||||
|
static char *
|
||||||
|
get_line(fp)
|
||||||
|
FILE *fp;
|
||||||
|
{
|
||||||
|
static char buf[128];
|
||||||
|
char *cp;
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
cp = buf;
|
||||||
|
while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') {
|
||||||
|
if (cp >= buf + sizeof buf - 1)
|
||||||
|
break;
|
||||||
|
*cp++ = ch;
|
||||||
|
}
|
||||||
|
*cp = '\0';
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the password file entry for the current user. If the name
|
||||||
|
* returned by getlogin() is correct (matches the current real uid),
|
||||||
|
* return the entry for that user. Otherwise, return the entry (if
|
||||||
|
* any) matching the current real uid. Return NULL on failure.
|
||||||
|
*/
|
||||||
|
static struct passwd *
|
||||||
|
get_my_pwent()
|
||||||
|
{
|
||||||
|
uid_t uid = getuid();
|
||||||
|
char *name = getlogin();
|
||||||
|
|
||||||
|
if (name && *name) {
|
||||||
|
struct passwd *pw = getpwnam(name);
|
||||||
|
|
||||||
|
if (pw && pw->pw_uid == uid)
|
||||||
|
return pw;
|
||||||
|
}
|
||||||
|
return getpwuid(uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify the password. The system-dependent shadow support is here.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
password_auth_ok(pw, pass)
|
||||||
|
const struct passwd *pw;
|
||||||
|
const char *pass;
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
char *cp;
|
||||||
|
#ifdef HAVE_AUTH_METHODS
|
||||||
|
char *buf;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GETSPNAM
|
||||||
|
struct spwd *sp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pw) {
|
||||||
|
#ifdef HAVE_GETSPNAM
|
||||||
|
sp = getspnam(pw->pw_name);
|
||||||
|
if (sp)
|
||||||
|
cp = sp->sp_pwdp;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
cp = pw->pw_passwd;
|
||||||
|
} else
|
||||||
|
cp = "xx";
|
||||||
|
|
||||||
|
#ifdef HAVE_AUTH_METHODS
|
||||||
|
buf = strdup(cp); /* will be modified by strtok() */
|
||||||
|
if (!buf) {
|
||||||
|
fprintf(stderr, "Out of memory.\n");
|
||||||
|
exit(13);
|
||||||
|
}
|
||||||
|
cp = strtok(buf, ";");
|
||||||
|
while (cp && *cp == '@')
|
||||||
|
cp = strtok(NULL, ";");
|
||||||
|
|
||||||
|
/* fail if no password authentication for this user */
|
||||||
|
if (!cp)
|
||||||
|
cp = "xx";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (*pass || *cp)
|
||||||
|
result = (strcmp(crypt(pass, cp), cp) == 0);
|
||||||
|
else
|
||||||
|
result = 1; /* user with no password */
|
||||||
|
|
||||||
|
#ifdef HAVE_AUTH_METHODS
|
||||||
|
free(buf);
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Main program.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
main(argc, argv)
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
{
|
||||||
|
struct passwd *pw;
|
||||||
|
char *pass, *name;
|
||||||
|
char myname[32];
|
||||||
|
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
|
openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
|
||||||
|
#endif
|
||||||
|
pw = get_my_pwent();
|
||||||
|
if (!pw) {
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
|
syslog(LOG_ERR, "can't get login name for uid %d.\n",
|
||||||
|
(int) getuid());
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "Who are you?\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
strncpy(myname, pw->pw_name, sizeof myname - 1);
|
||||||
|
myname[sizeof myname - 1] = '\0';
|
||||||
|
name = myname;
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
name = argv[1];
|
||||||
|
pw = getpwnam(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
pass = get_line(stdin);
|
||||||
|
if (password_auth_ok(pw, pass)) {
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
|
syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE,
|
||||||
|
"user `%s' entered correct password for `%.32s'.\n",
|
||||||
|
myname, name);
|
||||||
|
#endif
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
|
/* be careful not to overrun the syslog buffer */
|
||||||
|
syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING,
|
||||||
|
"user `%s' entered incorrect password for `%.32s'.\n",
|
||||||
|
myname, name);
|
||||||
|
#endif
|
||||||
|
#ifdef FAIL_DELAY
|
||||||
|
sleep(FAIL_DELAY);
|
||||||
|
#endif
|
||||||
|
fprintf(stderr, "Wrong password.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/*
|
||||||
|
* You can use code similar to the following to run this program.
|
||||||
|
* Return values: >=0 - program exit status (use the <sys/wait.h>
|
||||||
|
* macros to get the exit code, it is shifted left by 8 bits),
|
||||||
|
* -1 - check errno.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
verify_password(const char *username, const char *password)
|
||||||
|
{
|
||||||
|
int pipe_fd[2];
|
||||||
|
int pid, wpid, status;
|
||||||
|
|
||||||
|
if (pipe(pipe_fd))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if ((pid = fork()) == 0) {
|
||||||
|
char *arg[3];
|
||||||
|
char *env[1];
|
||||||
|
|
||||||
|
/* child */
|
||||||
|
close(pipe_fd[1]);
|
||||||
|
if (pipe_fd[0] != 0) {
|
||||||
|
if (dup2(pipe_fd[0], 0) != 0)
|
||||||
|
_exit(127);
|
||||||
|
close(pipe_fd[0]);
|
||||||
|
}
|
||||||
|
arg[0] = "/usr/bin/pwdauth";
|
||||||
|
arg[1] = username;
|
||||||
|
arg[2] = NULL;
|
||||||
|
env[0] = NULL;
|
||||||
|
execve(arg[0], arg, env);
|
||||||
|
_exit(127);
|
||||||
|
} else if (pid == -1) {
|
||||||
|
/* error */
|
||||||
|
close(pipe_fd[0]);
|
||||||
|
close(pipe_fd[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* parent */
|
||||||
|
close(pipe_fd[0]);
|
||||||
|
write(pipe_fd[1], password, strlen(password));
|
||||||
|
write(pipe_fd[1], "\n", 1);
|
||||||
|
close(pipe_fd[1]);
|
||||||
|
|
||||||
|
while ((wpid = wait(&status)) != pid) {
|
||||||
|
if (wpid == -1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#endif
|
@ -26,6 +26,7 @@ New ideas to add to this list are welcome, too. --marekm
|
|||||||
- vipw: check password files for errors after editing
|
- vipw: check password files for errors after editing
|
||||||
- add "maximum time users allowed to stay logged in" limit option to logoutd
|
- add "maximum time users allowed to stay logged in" limit option to logoutd
|
||||||
- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
|
- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
|
||||||
|
- better utmpx support (logoutd, ...)
|
||||||
- better OPIE support (report number of logins left, etc.)
|
- better OPIE support (report number of logins left, etc.)
|
||||||
- new option for /etc/suauth: don't load user's environment (force "su -")
|
- new option for /etc/suauth: don't load user's environment (force "su -")
|
||||||
suggested by Ulisses Alonso Camaro
|
suggested by Ulisses Alonso Camaro
|
||||||
|
@ -1,68 +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
|
|
||||||
```
|
|
||||||
|
|
||||||
### 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
|
|
||||||
```
|
|
@ -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.
|
|
@ -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.
|
|
@ -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)
|
|
@ -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.
|
|
@ -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).
|
|
@ -1,18 +0,0 @@
|
|||||||
# Tests
|
|
||||||
|
|
||||||
Currently, shadow only provides system tests.
|
|
||||||
|
|
||||||
## 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`.
|
|
||||||
```
|
|
@ -159,7 +159,7 @@ ENV_HZ HZ=100
|
|||||||
#
|
#
|
||||||
# (they are minimal, add the rest in the shell startup files)
|
# (they are minimal, add the rest in the shell startup files)
|
||||||
ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin
|
||||||
ENV_PATH PATH=/usr/bin:/usr/local/bin
|
ENV_PATH PATH=/usr/bin:/usr/sbin
|
||||||
|
|
||||||
#
|
#
|
||||||
# Terminal permissions
|
# Terminal permissions
|
||||||
|
@ -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
|
|
||||||
|
|
@ -11,7 +11,6 @@ libshadow_la_CPPFLAGS += -DVENDORDIR=\"$(VENDORDIR)\"
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
libshadow_la_CPPFLAGS += -I$(top_srcdir)
|
libshadow_la_CPPFLAGS += -I$(top_srcdir)
|
||||||
libshadow_la_CFLAGS = $(LIBBSD_CFLAGS)
|
|
||||||
|
|
||||||
libshadow_la_SOURCES = \
|
libshadow_la_SOURCES = \
|
||||||
commonio.c \
|
commonio.c \
|
||||||
@ -66,7 +65,8 @@ libshadow_la_SOURCES = \
|
|||||||
shadowio.c \
|
shadowio.c \
|
||||||
shadowio.h \
|
shadowio.h \
|
||||||
shadowmem.c \
|
shadowmem.c \
|
||||||
spawn.c
|
spawn.c \
|
||||||
|
utent.c
|
||||||
|
|
||||||
if WITH_TCB
|
if WITH_TCB
|
||||||
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h
|
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h
|
||||||
|
122
lib/alloc.h
122
lib/alloc.h
@ -1,122 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023, 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 "defines.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define ALLOCARRAY(n, type) ((type *) alloca(sizeof(type) * (n)))
|
|
||||||
#define CALLOC(n, type) ((type *) calloc(n, sizeof(type)))
|
|
||||||
#define XCALLOC(n, type) ((type *) xcalloc(n, sizeof(type)))
|
|
||||||
#define MALLOCARRAY(n, type) ((type *) mallocarray(n, sizeof(type)))
|
|
||||||
#define XMALLOCARRAY(n, type) ((type *) xmallocarray(n, sizeof(type)))
|
|
||||||
|
|
||||||
#define ALLOCA(type) ALLOCARRAY(1, type)
|
|
||||||
#define MALLOC(type) MALLOCARRAY(1, type)
|
|
||||||
#define XMALLOC(type) XMALLOCARRAY(1, type)
|
|
||||||
#define REALLOC(ptr, type) REALLOCARRAY(ptr, 1, type)
|
|
||||||
#define REALLOCF(ptr, type) REALLOCARRAYF(ptr, 1, type)
|
|
||||||
|
|
||||||
#define REALLOCARRAY(ptr, n, type) \
|
|
||||||
({ \
|
|
||||||
__auto_type p_ = (ptr); \
|
|
||||||
\
|
|
||||||
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
|
|
||||||
\
|
|
||||||
(type *) reallocarray(p_, n, sizeof(type)); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define REALLOCARRAYF(ptr, n, type) \
|
|
||||||
({ \
|
|
||||||
__auto_type p_ = (ptr); \
|
|
||||||
\
|
|
||||||
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
|
|
||||||
\
|
|
||||||
(type *) reallocarrayf(p_, n, sizeof(type)); \
|
|
||||||
})
|
|
||||||
|
|
||||||
#define XREALLOCARRAY(ptr, n, type) \
|
|
||||||
({ \
|
|
||||||
__auto_type p_ = (ptr); \
|
|
||||||
\
|
|
||||||
static_assert(__builtin_types_compatible_p(typeof(p_), type *), ""); \
|
|
||||||
\
|
|
||||||
(type *) xreallocarray(p_, 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(XMALLOCARRAY(strlen(str) + 1, char), str);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // include guard
|
|
53
lib/bit.h
53
lib/bit.h
@ -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
|
|
@ -21,8 +21,6 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "nscd.h"
|
#include "nscd.h"
|
||||||
#include "sssd.h"
|
#include "sssd.h"
|
||||||
#ifdef WITH_TCB
|
#ifdef WITH_TCB
|
||||||
@ -253,13 +251,25 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_FCHOWN
|
||||||
if (fchown (fileno (fp), sb->st_uid, sb->st_gid) != 0) {
|
if (fchown (fileno (fp), sb->st_uid, sb->st_gid) != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#else /* !HAVE_FCHOWN */
|
||||||
|
if (chown (name, sb->st_mode) != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_FCHOWN */
|
||||||
|
|
||||||
|
#ifdef HAVE_FCHMOD
|
||||||
if (fchmod (fileno (fp), sb->st_mode & 0664) != 0) {
|
if (fchmod (fileno (fp), sb->st_mode & 0664) != 0) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
#else /* !HAVE_FCHMOD */
|
||||||
|
if (chmod (name, sb->st_mode & 0664) != 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
#endif /* !HAVE_FCHMOD */
|
||||||
return fp;
|
return fp;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@ -364,11 +374,11 @@ int commonio_lock_nowait (struct commonio_db *db, bool log)
|
|||||||
}
|
}
|
||||||
file_len = strlen(db->filename) + 11;/* %lu max size */
|
file_len = strlen(db->filename) + 11;/* %lu max size */
|
||||||
lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */
|
lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */
|
||||||
file = MALLOCARRAY(file_len, char);
|
file = (char*)malloc(file_len);
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
goto cleanup_ENOMEM;
|
goto cleanup_ENOMEM;
|
||||||
}
|
}
|
||||||
lock = MALLOCARRAY(lock_file_len, char);
|
lock = (char*)malloc(lock_file_len);
|
||||||
if (lock == NULL) {
|
if (lock == NULL) {
|
||||||
goto cleanup_ENOMEM;
|
goto cleanup_ENOMEM;
|
||||||
}
|
}
|
||||||
@ -608,7 +618,7 @@ int commonio_open (struct commonio_db *db, int mode)
|
|||||||
|
|
||||||
fd = open (db->filename,
|
fd = open (db->filename,
|
||||||
(db->readonly ? O_RDONLY : O_RDWR)
|
(db->readonly ? O_RDONLY : O_RDWR)
|
||||||
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW | O_CLOEXEC);
|
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
|
||||||
saved_errno = errno;
|
saved_errno = errno;
|
||||||
db->fp = NULL;
|
db->fp = NULL;
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
@ -639,19 +649,22 @@ int commonio_open (struct commonio_db *db, int mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do not inherit fd in spawned processes (e.g. nscd) */
|
||||||
|
fcntl (fileno (db->fp), F_SETFD, FD_CLOEXEC);
|
||||||
|
|
||||||
buflen = BUFLEN;
|
buflen = BUFLEN;
|
||||||
buf = MALLOCARRAY (buflen, char);
|
buf = (char *) malloc (buflen);
|
||||||
if (NULL == buf) {
|
if (NULL == buf) {
|
||||||
goto cleanup_ENOMEM;
|
goto cleanup_ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (db->ops->fgets (buf, buflen, db->fp) == buf) {
|
while (db->ops->fgets (buf, (int) buflen, db->fp) == buf) {
|
||||||
while ( ((cp = strrchr (buf, '\n')) == NULL)
|
while ( ((cp = strrchr (buf, '\n')) == NULL)
|
||||||
&& (feof (db->fp) == 0)) {
|
&& (feof (db->fp) == 0)) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
buflen += BUFLEN;
|
buflen += BUFLEN;
|
||||||
cp = REALLOCARRAY (buf, buflen, char);
|
cp = (char *) realloc (buf, buflen);
|
||||||
if (NULL == cp) {
|
if (NULL == cp) {
|
||||||
goto cleanup_buf;
|
goto cleanup_buf;
|
||||||
}
|
}
|
||||||
@ -685,7 +698,7 @@ int commonio_open (struct commonio_db *db, int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = MALLOC (struct commonio_entry);
|
p = (struct commonio_entry *) malloc (sizeof *p);
|
||||||
if (NULL == p) {
|
if (NULL == p) {
|
||||||
goto cleanup_entry;
|
goto cleanup_entry;
|
||||||
}
|
}
|
||||||
@ -762,7 +775,7 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
entries = MALLOCARRAY (n, struct commonio_entry *);
|
entries = malloc (n * sizeof (struct commonio_entry *));
|
||||||
if (entries == NULL) {
|
if (entries == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -985,11 +998,13 @@ int commonio_close (struct commonio_db *db)
|
|||||||
if (fflush (db->fp) != 0) {
|
if (fflush (db->fp) != 0) {
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
|
#ifdef HAVE_FSYNC
|
||||||
if (fsync (fileno (db->fp)) != 0) {
|
if (fsync (fileno (db->fp)) != 0) {
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
|
#else /* !HAVE_FSYNC */
|
||||||
|
sync ();
|
||||||
|
#endif /* !HAVE_FSYNC */
|
||||||
if (fclose (db->fp) != 0) {
|
if (fclose (db->fp) != 0) {
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
@ -1081,7 +1096,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* not found, new entry */
|
/* not found, new entry */
|
||||||
p = MALLOC (struct commonio_entry);
|
p = (struct commonio_entry *) malloc (sizeof *p);
|
||||||
if (NULL == p) {
|
if (NULL == p) {
|
||||||
db->ops->free (nentry);
|
db->ops->free (nentry);
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
@ -1118,7 +1133,7 @@ int commonio_append (struct commonio_db *db, const void *eptr)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* new entry */
|
/* new entry */
|
||||||
p = MALLOC (struct commonio_entry);
|
p = (struct commonio_entry *) malloc (sizeof *p);
|
||||||
if (NULL == p) {
|
if (NULL == p) {
|
||||||
db->ops->free (nentry);
|
db->ops->free (nentry);
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
@ -1185,8 +1200,6 @@ int commonio_remove (struct commonio_db *db, const char *name)
|
|||||||
db->ops->free (p->eptr);
|
db->ops->free (p->eptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(p);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,6 @@ extern int commonio_setname (struct commonio_db *, const char *);
|
|||||||
extern bool commonio_present (const struct commonio_db *db);
|
extern bool commonio_present (const struct commonio_db *db);
|
||||||
extern int commonio_lock (struct commonio_db *);
|
extern int commonio_lock (struct commonio_db *);
|
||||||
extern int commonio_lock_nowait (struct commonio_db *, bool log);
|
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 int commonio_open (struct commonio_db *, int);
|
||||||
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
|
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
|
||||||
extern int commonio_update (struct commonio_db *, const void *);
|
extern int commonio_update (struct commonio_db *, const void *);
|
||||||
|
139
lib/defines.h
139
lib/defines.h
@ -6,8 +6,41 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#if HAVE_STDBOOL_H
|
||||||
#include <locale.h>
|
# include <stdbool.h>
|
||||||
|
#else
|
||||||
|
# if ! HAVE__BOOL
|
||||||
|
# ifdef __cplusplus
|
||||||
|
typedef bool _Bool;
|
||||||
|
# else
|
||||||
|
typedef unsigned char _Bool;
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# define bool _Bool
|
||||||
|
# define false (0)
|
||||||
|
# define true (1)
|
||||||
|
# define __bool_true_false_are_defined 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Take care of NLS matters. */
|
||||||
|
#ifdef S_SPLINT_S
|
||||||
|
extern char *setlocale(int categories, const char *locale);
|
||||||
|
# define LC_ALL (6)
|
||||||
|
extern char * bindtextdomain (const char * domainname, const char * dirname);
|
||||||
|
extern char * textdomain (const char * domainname);
|
||||||
|
# define _(Text) Text
|
||||||
|
# define ngettext(Msgid1, Msgid2, N) \
|
||||||
|
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||||
|
#else
|
||||||
|
#ifdef HAVE_LOCALE_H
|
||||||
|
# include <locale.h>
|
||||||
|
#else
|
||||||
|
# undef setlocale
|
||||||
|
# define setlocale(category, locale) (NULL)
|
||||||
|
# ifndef LC_ALL
|
||||||
|
# define LC_ALL 6
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define gettext_noop(String) (String)
|
#define gettext_noop(String) (String)
|
||||||
/* #define gettext_def(String) "#define String" */
|
/* #define gettext_def(String) "#define String" */
|
||||||
@ -24,17 +57,22 @@
|
|||||||
# define ngettext(Msgid1, Msgid2, N) \
|
# define ngettext(Msgid1, Msgid2, N) \
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <errno.h>
|
#if HAVE_ERRNO_H
|
||||||
|
# include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#if HAVE_UNISTD_H
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* crypt(3), crypt_gensalt(3), and their
|
* crypt(3), crypt_gensalt(3), and their
|
||||||
@ -47,15 +85,17 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef HAVE_MEMSET_EXPLICIT
|
#ifdef HAVE_MEMSET_S
|
||||||
# define memzero(ptr, size) memset_explicit((ptr), 0, (size))
|
# define memzero(ptr, size) memset_s((ptr), 0, (size))
|
||||||
#elif defined HAVE_EXPLICIT_BZERO /* !HAVE_MEMSET_S */
|
#elif defined HAVE_EXPLICIT_BZERO /* !HAVE_MEMSET_S */
|
||||||
# define memzero(ptr, size) explicit_bzero((ptr), (size))
|
# define memzero(ptr, size) explicit_bzero((ptr), (size))
|
||||||
#else /* !HAVE_MEMSET_S && HAVE_EXPLICIT_BZERO */
|
#else /* !HAVE_MEMSET_S && HAVE_EXPLICIT_BZERO */
|
||||||
static inline void memzero(void *ptr, size_t size)
|
static inline void memzero(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
ptr = memset(ptr, '\0', size);
|
volatile unsigned char * volatile p = ptr;
|
||||||
__asm__ __volatile__ ("" : : "r"(ptr) : "memory");
|
while (size--) {
|
||||||
|
*p++ = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* !HAVE_MEMSET_S && !HAVE_EXPLICIT_BZERO */
|
#endif /* !HAVE_MEMSET_S && !HAVE_EXPLICIT_BZERO */
|
||||||
|
|
||||||
@ -83,6 +123,7 @@ static inline void memzero(void *ptr, size_t size)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
#ifndef LOG_WARN
|
#ifndef LOG_WARN
|
||||||
@ -129,6 +170,14 @@ static inline void memzero(void *ptr, size_t size)
|
|||||||
#define SYSLOG(x) syslog x
|
#define SYSLOG(x) syslog x
|
||||||
#endif /* !ENABLE_NLS */
|
#endif /* !ENABLE_NLS */
|
||||||
|
|
||||||
|
#else /* !USE_SYSLOG */
|
||||||
|
|
||||||
|
#define SYSLOG(x) /* empty */
|
||||||
|
#define openlog(a,b,c) /* empty */
|
||||||
|
#define closelog() /* empty */
|
||||||
|
|
||||||
|
#endif /* !USE_SYSLOG */
|
||||||
|
|
||||||
/* The default syslog settings can now be changed here,
|
/* The default syslog settings can now be changed here,
|
||||||
in just one place. */
|
in just one place. */
|
||||||
|
|
||||||
@ -143,10 +192,33 @@ static inline void memzero(void *ptr, size_t size)
|
|||||||
|
|
||||||
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
|
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
|
||||||
|
|
||||||
#include <termios.h>
|
#ifndef F_OK
|
||||||
#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
|
# define F_OK 0
|
||||||
#define GTTY(fd, termio) tcgetattr(fd, termio)
|
# define X_OK 1
|
||||||
#define TERMIO struct termios
|
# define W_OK 2
|
||||||
|
# define R_OK 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SEEK_SET
|
||||||
|
# define SEEK_SET 0
|
||||||
|
# define SEEK_CUR 1
|
||||||
|
# define SEEK_END 2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TERMIOS_H
|
||||||
|
# include <termios.h>
|
||||||
|
# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
|
||||||
|
# define GTTY(fd, termio) tcgetattr(fd, termio)
|
||||||
|
# define TERMIO struct termios
|
||||||
|
# define USE_TERMIOS
|
||||||
|
#else /* assumed HAVE_TERMIO_H */
|
||||||
|
# include <sys/ioctl.h>
|
||||||
|
# include <termio.h>
|
||||||
|
# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
|
||||||
|
# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
|
||||||
|
# define TEMRIO struct termio
|
||||||
|
# define USE_TERMIO
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Password aging constants
|
* Password aging constants
|
||||||
@ -169,10 +241,6 @@ static inline void memzero(void *ptr, size_t size)
|
|||||||
#define SCALE DAY
|
#define SCALE DAY
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WIDTHOF(x) (sizeof(x) * CHAR_BIT)
|
|
||||||
#define NITEMS(arr) (sizeof((arr)) / sizeof((arr)[0]))
|
|
||||||
#define STRLEN(s) (NITEMS(s) - 1)
|
|
||||||
|
|
||||||
/* Copy string pointed by B to array A with size checking. It was originally
|
/* Copy string pointed by B to array A with size checking. It was originally
|
||||||
in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
|
in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
|
||||||
very sloppy coding used to assume that BUFSIZ will always be enough... */
|
very sloppy coding used to assume that BUFSIZ will always be enough... */
|
||||||
@ -199,6 +267,18 @@ static inline void memzero(void *ptr, size_t size)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *) 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef sun /* hacks for compiling on SunOS */
|
||||||
|
# ifndef SOLARIS
|
||||||
|
extern int fputs ();
|
||||||
|
extern char *strdup ();
|
||||||
|
extern char *strerror ();
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* string to use for the pw_passwd field in /etc/passwd when using
|
* string to use for the pw_passwd field in /etc/passwd when using
|
||||||
* shadow passwords - most systems use "x" but there are a few
|
* shadow passwords - most systems use "x" but there are a few
|
||||||
@ -223,28 +303,33 @@ static inline void memzero(void *ptr, size_t size)
|
|||||||
|
|
||||||
/* To be used for verified unused parameters */
|
/* To be used for verified unused parameters */
|
||||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||||
# define unused __attribute__((unused))
|
# define unused __attribute__((unused))
|
||||||
# define NORETURN __attribute__((__noreturn__))
|
|
||||||
# define format_attr(type, index, check) __attribute__((format (type, index, check)))
|
# define format_attr(type, index, check) __attribute__((format (type, index, check)))
|
||||||
#else
|
#else
|
||||||
# define unused
|
# define unused
|
||||||
# define NORETURN
|
|
||||||
# define format_attr(type, index, check)
|
# define format_attr(type, index, check)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Maximum length of usernames */
|
/* Maximum length of usernames */
|
||||||
#include <utmp.h>
|
#ifdef HAVE_UTMPX_H
|
||||||
#define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
|
# include <utmpx.h>
|
||||||
|
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmpx *)NULL)->ut_user))
|
||||||
|
#else
|
||||||
|
# include <utmp.h>
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_USER
|
||||||
|
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
|
||||||
|
# else
|
||||||
|
# ifdef HAVE_STRUCT_UTMP_UT_NAME
|
||||||
|
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_name))
|
||||||
|
# else
|
||||||
|
# define USER_NAME_MAX_LENGTH 32
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Maximum length of passwd entry */
|
/* Maximum length of passwd entry */
|
||||||
#define PASSWD_ENTRY_MAX_LENGTH 32768
|
#define PASSWD_ENTRY_MAX_LENGTH 32768
|
||||||
|
|
||||||
#if (__GNUC__ >= 11) && !defined(__clang__)
|
|
||||||
# define ATTR_MALLOC(deallocator) [[gnu::malloc(deallocator)]]
|
|
||||||
#else
|
|
||||||
# define ATTR_MALLOC(deallocator)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SECURE_GETENV
|
#ifdef HAVE_SECURE_GETENV
|
||||||
# define shadow_getenv(name) secure_getenv(name)
|
# define shadow_getenv(name) secure_getenv(name)
|
||||||
# else
|
# else
|
||||||
|
40
lib/fields.c
40
lib/fields.c
@ -21,9 +21,9 @@
|
|||||||
*
|
*
|
||||||
* The supplied field is scanned for non-printable and other illegal
|
* The supplied field is scanned for non-printable and other illegal
|
||||||
* characters.
|
* characters.
|
||||||
* + -1 is returned if an illegal or control character is present.
|
* + -1 is returned if an illegal character is present.
|
||||||
* + 1 is returned if no illegal or control characters are present,
|
* + 1 is returned if no illegal characters are present, but the field
|
||||||
* but the field contains a non-printable character.
|
* contains a non-printable character.
|
||||||
* + 0 is returned otherwise.
|
* + 0 is returned otherwise.
|
||||||
*/
|
*/
|
||||||
int valid_field (const char *field, const char *illegal)
|
int valid_field (const char *field, const char *illegal)
|
||||||
@ -37,22 +37,23 @@ int valid_field (const char *field, const char *illegal)
|
|||||||
|
|
||||||
/* For each character of field, search if it appears in the list
|
/* For each character of field, search if it appears in the list
|
||||||
* of illegal characters. */
|
* of illegal characters. */
|
||||||
if (illegal && NULL != strpbrk (field, illegal)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search if there are non-printable or control characters */
|
|
||||||
for (cp = field; '\0' != *cp; cp++) {
|
for (cp = field; '\0' != *cp; cp++) {
|
||||||
unsigned char c = *cp;
|
if (strchr (illegal, *cp) != NULL) {
|
||||||
if (!isprint (c)) {
|
|
||||||
err = 1;
|
|
||||||
}
|
|
||||||
if (iscntrl (c)) {
|
|
||||||
err = -1;
|
err = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (0 == err) {
|
||||||
|
/* Search if there are some non-printable characters */
|
||||||
|
for (cp = field; '\0' != *cp; cp++) {
|
||||||
|
if (!isprint (*cp)) {
|
||||||
|
err = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
|
|||||||
|
|
||||||
printf ("\t%s [%s]: ", prompt, buf);
|
printf ("\t%s [%s]: ", prompt, buf);
|
||||||
(void) fflush (stdout);
|
(void) fflush (stdout);
|
||||||
if (fgets (newf, maxsize, stdin) != newf) {
|
if (fgets (newf, (int) maxsize, stdin) != newf) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,16 +91,17 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
|
|||||||
* entering a space. --marekm
|
* entering a space. --marekm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (newf < cp && isspace (cp[-1])) {
|
while (--cp >= newf && isspace (*cp));
|
||||||
cp--;
|
cp++;
|
||||||
}
|
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
cp = newf;
|
cp = newf;
|
||||||
while (isspace (*cp)) {
|
while (('\0' != *cp) && isspace (*cp)) {
|
||||||
cp++;
|
cp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy (buf, cp);
|
strncpy (buf, cp, maxsize - 1);
|
||||||
|
buf[maxsize - 1] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ int get_gid (const char *gidstr, gid_t *gid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*gid = val;
|
*gid = (gid_t)val;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,9 +10,6 @@
|
|||||||
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
int get_pid (const char *pidstr, pid_t *pid)
|
int get_pid (const char *pidstr, pid_t *pid)
|
||||||
{
|
{
|
||||||
@ -24,79 +21,11 @@ int get_pid (const char *pidstr, pid_t *pid)
|
|||||||
if ( ('\0' == *pidstr)
|
if ( ('\0' == *pidstr)
|
||||||
|| ('\0' != *endptr)
|
|| ('\0' != *endptr)
|
||||||
|| (ERANGE == errno)
|
|| (ERANGE == errno)
|
||||||
|| (val < 1)
|
|
||||||
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
|
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*pid = val;
|
*pid = (pid_t)val;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If use passed in fd:4 as an argument, then return the
|
|
||||||
* value '4', the fd to use.
|
|
||||||
* On error, return -1.
|
|
||||||
*/
|
|
||||||
int get_pidfd_from_fd(const char *pidfdstr)
|
|
||||||
{
|
|
||||||
long long int val;
|
|
||||||
char *endptr;
|
|
||||||
struct stat st;
|
|
||||||
dev_t proc_st_dev, proc_st_rdev;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
val = strtoll (pidfdstr, &endptr, 10);
|
|
||||||
if ( ('\0' == *pidfdstr)
|
|
||||||
|| ('\0' != *endptr)
|
|
||||||
|| (ERANGE == errno)
|
|
||||||
|| (val < 0)
|
|
||||||
|| (/*@+longintegral@*/val != (int)val)/*@=longintegral@*/) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stat("/proc/self/uid_map", &st) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
proc_st_dev = st.st_dev;
|
|
||||||
proc_st_rdev = st.st_rdev;
|
|
||||||
|
|
||||||
if (fstat(val, &st) < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (st.st_dev != proc_st_dev || st.st_rdev != proc_st_rdev) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)val;
|
|
||||||
}
|
|
||||||
|
|
||||||
int open_pidfd(const char *pidstr)
|
|
||||||
{
|
|
||||||
int proc_dir_fd;
|
|
||||||
int written;
|
|
||||||
char proc_dir_name[32];
|
|
||||||
pid_t target;
|
|
||||||
|
|
||||||
if (get_pid(pidstr, &target) == 0)
|
|
||||||
return -ENOENT;
|
|
||||||
|
|
||||||
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
|
|
||||||
written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
|
|
||||||
target);
|
|
||||||
if ((written <= 0) || ((size_t)written >= sizeof(proc_dir_name))) {
|
|
||||||
fprintf(stderr, "snprintf of proc path failed for %u: %s\n",
|
|
||||||
target, strerror(errno));
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
|
|
||||||
if (proc_dir_fd < 0) {
|
|
||||||
fprintf(stderr, _("Could not open proc directory for target %u: %s\n"),
|
|
||||||
target, strerror(errno));
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
return proc_dir_fd;
|
|
||||||
}
|
|
||||||
|
@ -25,7 +25,7 @@ int get_uid (const char *uidstr, uid_t *uid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*uid = val;
|
*uid = (uid_t)val;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
lib/getdef.c
57
lib/getdef.c
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -21,11 +20,8 @@
|
|||||||
#ifdef USE_ECONF
|
#ifdef USE_ECONF
|
||||||
#include <libeconf.h>
|
#include <libeconf.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
#include "shadowlog_internal.h"
|
#include "shadowlog_internal.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A configuration item definition.
|
* A configuration item definition.
|
||||||
*/
|
*/
|
||||||
@ -136,8 +132,10 @@ static struct itemdef def_table[] = {
|
|||||||
#ifndef USE_PAM
|
#ifndef USE_PAM
|
||||||
PAMDEFS
|
PAMDEFS
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_SYSLOG
|
||||||
{"SYSLOG_SG_ENAB", NULL},
|
{"SYSLOG_SG_ENAB", NULL},
|
||||||
{"SYSLOG_SU_ENAB", NULL},
|
{"SYSLOG_SU_ENAB", NULL},
|
||||||
|
#endif
|
||||||
#ifdef WITH_TCB
|
#ifdef WITH_TCB
|
||||||
{"TCB_AUTH_GROUP", NULL},
|
{"TCB_AUTH_GROUP", NULL},
|
||||||
{"TCB_SYMLINKS", NULL},
|
{"TCB_SYMLINKS", NULL},
|
||||||
@ -195,7 +193,7 @@ static void def_load (void);
|
|||||||
}
|
}
|
||||||
|
|
||||||
d = def_find (item);
|
d = def_find (item);
|
||||||
return (NULL == d) ? NULL : d->value;
|
return ((NULL == d)? (const char *) NULL : d->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -253,7 +251,7 @@ int getdef_num (const char *item, int dflt)
|
|||||||
return dflt;
|
return dflt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return (int) val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -288,7 +286,7 @@ unsigned int getdef_unum (const char *item, unsigned int dflt)
|
|||||||
return dflt;
|
return dflt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return (unsigned int) val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -432,7 +430,7 @@ static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
|
|||||||
SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name));
|
SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name));
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return NULL;
|
return (struct itemdef *) NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -448,14 +446,14 @@ void setdef_config_file (const char* file)
|
|||||||
char* cp;
|
char* cp;
|
||||||
|
|
||||||
len = strlen(file) + strlen(sysconfdir) + 2;
|
len = strlen(file) + strlen(sysconfdir) + 2;
|
||||||
cp = MALLOCARRAY(len, char);
|
cp = malloc(len);
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
exit (13);
|
exit (13);
|
||||||
snprintf(cp, len, "%s/%s", file, sysconfdir);
|
snprintf(cp, len, "%s/%s", file, sysconfdir);
|
||||||
sysconfdir = cp;
|
sysconfdir = cp;
|
||||||
#ifdef VENDORDIR
|
#ifdef VENDORDIR
|
||||||
len = strlen(file) + strlen(vendordir) + 2;
|
len = strlen(file) + strlen(vendordir) + 2;
|
||||||
cp = MALLOCARRAY(len, char);
|
cp = malloc(len);
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
exit (13);
|
exit (13);
|
||||||
snprintf(cp, len, "%s/%s", file, vendordir);
|
snprintf(cp, len, "%s/%s", file, vendordir);
|
||||||
@ -472,13 +470,18 @@ void setdef_config_file (const char* file)
|
|||||||
* Loads the user-configured options from the default configuration file
|
* Loads the user-configured options from the default configuration file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef USE_ECONF
|
|
||||||
static void def_load (void)
|
static void def_load (void)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_ECONF
|
||||||
econf_file *defs_file = NULL;
|
econf_file *defs_file = NULL;
|
||||||
econf_err error;
|
econf_err error;
|
||||||
char **keys;
|
char **keys;
|
||||||
size_t key_number;
|
size_t key_number;
|
||||||
|
#else
|
||||||
|
int i;
|
||||||
|
FILE *fp;
|
||||||
|
char buf[1024], *name, *value, *s;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the initialized flag.
|
* Set the initialized flag.
|
||||||
@ -486,6 +489,8 @@ static void def_load (void)
|
|||||||
*/
|
*/
|
||||||
def_loaded = true;
|
def_loaded = true;
|
||||||
|
|
||||||
|
#ifdef USE_ECONF
|
||||||
|
|
||||||
error = econf_readDirs (&defs_file, vendordir, sysconfdir, "login", "defs", " \t", "#");
|
error = econf_readDirs (&defs_file, vendordir, sysconfdir, "login", "defs", " \t", "#");
|
||||||
if (error) {
|
if (error) {
|
||||||
if (error == ECONF_NOFILE)
|
if (error == ECONF_NOFILE)
|
||||||
@ -505,12 +510,7 @@ static void def_load (void)
|
|||||||
for (size_t i = 0; i < key_number; i++) {
|
for (size_t i = 0; i < key_number; i++) {
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
error = econf_getStringValue(defs_file, NULL, keys[i], &value);
|
econf_getStringValue(defs_file, NULL, keys[i], &value);
|
||||||
if (error) {
|
|
||||||
SYSLOG ((LOG_CRIT, "failed reading key %zu from econf [%s]",
|
|
||||||
i, econf_errString(error)));
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Store the value in def_table.
|
* Store the value in def_table.
|
||||||
@ -520,26 +520,11 @@ static void def_load (void)
|
|||||||
* syslog. The tools will just use their default values.
|
* syslog. The tools will just use their default values.
|
||||||
*/
|
*/
|
||||||
(void)putdef_str (keys[i], value);
|
(void)putdef_str (keys[i], value);
|
||||||
|
|
||||||
free(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
econf_free (keys);
|
econf_free (keys);
|
||||||
econf_free (defs_file);
|
econf_free (defs_file);
|
||||||
}
|
#else
|
||||||
#else /* USE_ECONF */
|
|
||||||
static void def_load (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
FILE *fp;
|
|
||||||
char buf[1024], *name, *value, *s;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set the initialized flag.
|
|
||||||
* (do it early to prevent recursion in putdef_str())
|
|
||||||
*/
|
|
||||||
def_loaded = true;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the configuration definitions file.
|
* Open the configuration definitions file.
|
||||||
*/
|
*/
|
||||||
@ -557,12 +542,12 @@ static void def_load (void)
|
|||||||
/*
|
/*
|
||||||
* Go through all of the lines in the file.
|
* Go through all of the lines in the file.
|
||||||
*/
|
*/
|
||||||
while (fgets (buf, sizeof (buf), fp) != NULL) {
|
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trim trailing whitespace.
|
* Trim trailing whitespace.
|
||||||
*/
|
*/
|
||||||
for (i = (ptrdiff_t) strlen (buf) - 1; i >= 0; --i) {
|
for (i = (int) strlen (buf) - 1; i >= 0; --i) {
|
||||||
if (!isspace (buf[i])) {
|
if (!isspace (buf[i])) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -603,8 +588,8 @@ static void def_load (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
(void) fclose (fp);
|
(void) fclose (fp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* USE_ECONF */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CKDEFS
|
#ifdef CKDEFS
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "commonio.h"
|
#include "commonio.h"
|
||||||
@ -51,7 +50,7 @@ static const char *group_getname (const void *ent)
|
|||||||
|
|
||||||
static void *group_parse (const char *line)
|
static void *group_parse (const char *line)
|
||||||
{
|
{
|
||||||
return sgetgrent (line);
|
return (void *) sgetgrent (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int group_put (const void *ent, FILE * file)
|
static int group_put (const void *ent, FILE * file)
|
||||||
@ -160,7 +159,7 @@ int gr_open (int mode)
|
|||||||
|
|
||||||
int gr_update (const struct group *gr)
|
int gr_update (const struct group *gr)
|
||||||
{
|
{
|
||||||
return commonio_update (&group_db, gr);
|
return commonio_update (&group_db, (const void *) gr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int gr_remove (const char *name)
|
int gr_remove (const char *name)
|
||||||
@ -248,8 +247,8 @@ static int group_open_hook (void)
|
|||||||
|
|
||||||
for (gr1 = group_db.head; NULL != gr1; gr1 = gr1->next) {
|
for (gr1 = group_db.head; NULL != gr1; gr1 = gr1->next) {
|
||||||
for (gr2 = gr1->next; NULL != gr2; gr2 = gr2->next) {
|
for (gr2 = gr1->next; NULL != gr2; gr2 = gr2->next) {
|
||||||
struct group *g1 = gr1->eptr;
|
struct group *g1 = (struct group *)gr1->eptr;
|
||||||
struct group *g2 = gr2->eptr;
|
struct group *g2 = (struct group *)gr2->eptr;
|
||||||
if (NULL != g1 &&
|
if (NULL != g1 &&
|
||||||
NULL != g2 &&
|
NULL != g2 &&
|
||||||
0 == strcmp (g1->gr_name, g2->gr_name) &&
|
0 == strcmp (g1->gr_name, g2->gr_name) &&
|
||||||
@ -303,8 +302,8 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gptr1 = gr1->eptr;
|
gptr1 = (struct group *)gr1->eptr;
|
||||||
gptr2 = gr2->eptr;
|
gptr2 = (struct group *)gr2->eptr;
|
||||||
if (NULL == gptr2 || NULL == gptr1) {
|
if (NULL == gptr2 || NULL == gptr1) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -312,8 +311,9 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
|
|||||||
|
|
||||||
/* Concatenate the 2 lines */
|
/* Concatenate the 2 lines */
|
||||||
new_line_len = strlen (gr1->line) + strlen (gr2->line) +1;
|
new_line_len = strlen (gr1->line) + strlen (gr2->line) +1;
|
||||||
new_line = MALLOCARRAY (new_line_len + 1, char);
|
new_line = (char *)malloc (new_line_len + 1);
|
||||||
if (NULL == new_line) {
|
if (NULL == new_line) {
|
||||||
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
snprintf(new_line, new_line_len + 1, "%s\n%s", gr1->line, gr2->line);
|
snprintf(new_line, new_line_len + 1, "%s\n%s", gr1->line, gr2->line);
|
||||||
@ -333,9 +333,10 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
|
|||||||
members++;
|
members++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_members = CALLOC (members + 1, char *);
|
new_members = (char **)calloc ( (members+1), sizeof(char*) );
|
||||||
if (NULL == new_members) {
|
if (NULL == new_members) {
|
||||||
free (new_line);
|
free (new_line);
|
||||||
|
errno = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i=0; NULL != gptr1->gr_mem[i]; i++) {
|
for (i=0; NULL != gptr1->gr_mem[i]; i++) {
|
||||||
@ -376,7 +377,7 @@ static int split_groups (unsigned int max_members)
|
|||||||
struct commonio_entry *gr;
|
struct commonio_entry *gr;
|
||||||
|
|
||||||
for (gr = group_db.head; NULL != gr; gr = gr->next) {
|
for (gr = group_db.head; NULL != gr; gr = gr->next) {
|
||||||
struct group *gptr = gr->eptr;
|
struct group *gptr = (struct group *)gr->eptr;
|
||||||
struct commonio_entry *new;
|
struct commonio_entry *new;
|
||||||
struct group *new_gptr;
|
struct group *new_gptr;
|
||||||
unsigned int members = 0;
|
unsigned int members = 0;
|
||||||
@ -394,8 +395,9 @@ static int split_groups (unsigned int max_members)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
new = MALLOC (struct commonio_entry);
|
new = (struct commonio_entry *) malloc (sizeof *new);
|
||||||
if (NULL == new) {
|
if (NULL == new) {
|
||||||
|
errno = ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
new->eptr = group_dup(gr->eptr);
|
new->eptr = group_dup(gr->eptr);
|
||||||
@ -404,7 +406,7 @@ static int split_groups (unsigned int max_members)
|
|||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
new_gptr = new->eptr;
|
new_gptr = (struct group *)new->eptr;
|
||||||
new->line = NULL;
|
new->line = NULL;
|
||||||
new->changed = true;
|
new->changed = true;
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "groupio.h"
|
#include "groupio.h"
|
||||||
@ -22,7 +21,7 @@
|
|||||||
struct group *gr;
|
struct group *gr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
gr = MALLOC (struct group);
|
gr = (struct group *) malloc (sizeof *gr);
|
||||||
if (NULL == gr) {
|
if (NULL == gr) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -47,7 +46,7 @@
|
|||||||
for (i = 0; grent->gr_mem[i]; i++);
|
for (i = 0; grent->gr_mem[i]; i++);
|
||||||
|
|
||||||
/*@-mustfreeonly@*/
|
/*@-mustfreeonly@*/
|
||||||
gr->gr_mem = MALLOCARRAY (i + 1, char *);
|
gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
|
||||||
/*@=mustfreeonly@*/
|
/*@=mustfreeonly@*/
|
||||||
if (NULL == gr->gr_mem) {
|
if (NULL == gr->gr_mem) {
|
||||||
gr_free(gr);
|
gr_free(gr);
|
||||||
@ -87,3 +86,33 @@ void gr_free (/*@out@*/ /*@only@*/struct group *grent)
|
|||||||
gr_free_members(grent);
|
gr_free_members(grent);
|
||||||
free (grent);
|
free (grent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gr_append_member(struct group *grp, char *member)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (NULL == grp->gr_mem || grp->gr_mem[0] == NULL) {
|
||||||
|
grp->gr_mem = (char **)malloc(2 * sizeof(char *));
|
||||||
|
if (!grp->gr_mem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
grp->gr_mem[0] = strdup(member);
|
||||||
|
if (!grp->gr_mem[0]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
grp->gr_mem[1] = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; grp->gr_mem[i]; i++) ;
|
||||||
|
grp->gr_mem = realloc(grp->gr_mem, (i + 2) * sizeof(char *));
|
||||||
|
if (NULL == grp->gr_mem) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
grp->gr_mem[i] = strdup(member);
|
||||||
|
if (NULL == grp->gr_mem[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
grp->gr_mem[i + 1] = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -15,12 +15,8 @@
|
|||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
static /*@null@*/FILE *shadow;
|
static /*@null@*/FILE *shadow;
|
||||||
static /*@null@*//*@only@*/char **members = NULL;
|
static /*@null@*//*@only@*/char **members = NULL;
|
||||||
static size_t nmembers = 0;
|
static size_t nmembers = 0;
|
||||||
@ -66,7 +62,7 @@ static /*@null@*/char **build_list (char *s, char **list[], size_t * nlist)
|
|||||||
|
|
||||||
while (s != NULL && *s != '\0') {
|
while (s != NULL && *s != '\0') {
|
||||||
size = (nelem + 1) * sizeof (ptr);
|
size = (nelem + 1) * sizeof (ptr);
|
||||||
ptr = REALLOCARRAY (*list, size, char *);
|
ptr = realloc (*list, size);
|
||||||
if (NULL != ptr) {
|
if (NULL != ptr) {
|
||||||
ptr[nelem] = s;
|
ptr[nelem] = s;
|
||||||
nelem++;
|
nelem++;
|
||||||
@ -80,7 +76,7 @@ static /*@null@*/char **build_list (char *s, char **list[], size_t * nlist)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
size = (nelem + 1) * sizeof (ptr);
|
size = (nelem + 1) * sizeof (ptr);
|
||||||
ptr = REALLOCARRAY (*list, size, char *);
|
ptr = realloc (*list, size);
|
||||||
if (NULL != ptr) {
|
if (NULL != ptr) {
|
||||||
ptr[nelem] = NULL;
|
ptr[nelem] = NULL;
|
||||||
*list = ptr;
|
*list = ptr;
|
||||||
@ -106,7 +102,7 @@ void endsgent (void)
|
|||||||
(void) fclose (shadow);
|
(void) fclose (shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow = NULL;
|
shadow = (FILE *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *string)
|
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *string)
|
||||||
@ -120,7 +116,7 @@ void endsgent (void)
|
|||||||
size_t len = strlen (string) + 1;
|
size_t len = strlen (string) + 1;
|
||||||
|
|
||||||
if (len > sgrbuflen) {
|
if (len > sgrbuflen) {
|
||||||
char *buf = REALLOCARRAY (sgrbuf, len, char);
|
char *buf = (char *) realloc (sgrbuf, sizeof (char) * len);
|
||||||
if (NULL == buf) {
|
if (NULL == buf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -128,7 +124,8 @@ void endsgent (void)
|
|||||||
sgrbuflen = len;
|
sgrbuflen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy (sgrbuf, string);
|
strncpy (sgrbuf, string, len);
|
||||||
|
sgrbuf[len-1] = '\0';
|
||||||
|
|
||||||
cp = strrchr (sgrbuf, '\n');
|
cp = strrchr (sgrbuf, '\n');
|
||||||
if (NULL != cp) {
|
if (NULL != cp) {
|
||||||
@ -198,7 +195,7 @@ void endsgent (void)
|
|||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
if (0 == buflen) {
|
if (0 == buflen) {
|
||||||
buf = MALLOCARRAY (BUFSIZ, char);
|
buf = (char *) malloc (BUFSIZ);
|
||||||
if (NULL == buf) {
|
if (NULL == buf) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -210,16 +207,16 @@ void endsgent (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_NIS
|
#ifdef USE_NIS
|
||||||
while (fgetsx (buf, buflen, fp) == buf)
|
while (fgetsx (buf, (int) buflen, fp) == buf)
|
||||||
#else
|
#else
|
||||||
if (fgetsx (buf, buflen, fp) == buf)
|
if (fgetsx (buf, (int) buflen, fp) == buf)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
while ( ((cp = strrchr (buf, '\n')) == NULL)
|
while ( ((cp = strrchr (buf, '\n')) == NULL)
|
||||||
&& (feof (fp) == 0)) {
|
&& (feof (fp) == 0)) {
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
cp = REALLOCARRAY (buf, buflen * 2, char);
|
cp = (char *) realloc (buf, buflen*2);
|
||||||
if (NULL == cp) {
|
if (NULL == cp) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -402,7 +399,7 @@ void endsgent (void)
|
|||||||
nis_disabled = true;
|
nis_disabled = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
while ((sgrp = getsgent ()) != NULL) {
|
while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
|
||||||
if (strcmp (name, sgrp->sg_name) == 0) {
|
if (strcmp (name, sgrp->sg_name) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -440,7 +437,7 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
|
|||||||
size += strlen (sgrp->sg_mem[i]) + 1;
|
size += strlen (sgrp->sg_mem[i]) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf = MALLOCARRAY (size, char);
|
buf = malloc (size);
|
||||||
if (NULL == buf) {
|
if (NULL == buf) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -505,5 +502,5 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /*} SHADOWGRP */
|
#endif /*} SHADOWGRP */
|
||||||
|
@ -81,5 +81,5 @@ int ulckpwdf (void)
|
|||||||
return (pw_unlock () && spw_unlock ())? 0 : -1;
|
return (pw_unlock () && spw_unlock ())? 0 : -1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SHADOW_INCLUDE_LIB_MEMPCPY_H_
|
|
||||||
#define SHADOW_INCLUDE_LIB_MEMPCPY_H_
|
|
||||||
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#if !defined(HAVE_MEMPCPY)
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
inline void *mempcpy(void *restrict dst, const void *restrict src, size_t n);
|
|
||||||
|
|
||||||
|
|
||||||
inline void *
|
|
||||||
mempcpy(void *restrict dst, const void *restrict src, size_t n)
|
|
||||||
{
|
|
||||||
return memcpy(dst, src, n) + n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !HAVE_MEMPCPY
|
|
||||||
#endif // include guard
|
|
@ -53,6 +53,6 @@ int nscd_flush_cache (const char *service)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* USE_NSCD */
|
#else /* USE_NSCD */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* USE_NSCD */
|
#endif /* USE_NSCD */
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "../libsubid/subid.h"
|
#include "../libsubid/subid.h"
|
||||||
#include "shadowlog_internal.h"
|
#include "shadowlog_internal.h"
|
||||||
@ -61,9 +59,6 @@ void nss_init(const char *nsswitch_path) {
|
|||||||
// subid: files
|
// subid: files
|
||||||
nssfp = fopen(nsswitch_path, "r");
|
nssfp = fopen(nsswitch_path, "r");
|
||||||
if (!nssfp) {
|
if (!nssfp) {
|
||||||
if (errno != ENOENT)
|
|
||||||
fprintf(shadow_logfd, "Failed opening %s: %m\n", nsswitch_path);
|
|
||||||
|
|
||||||
atomic_store(&nss_init_completed, true);
|
atomic_store(&nss_init_completed, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -102,7 +97,7 @@ void nss_init(const char *nsswitch_path) {
|
|||||||
subid_nss = NULL;
|
subid_nss = NULL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
subid_nss = MALLOC(struct subid_nss_ops);
|
subid_nss = malloc(sizeof(*subid_nss));
|
||||||
if (!subid_nss) {
|
if (!subid_nss) {
|
||||||
dlclose(h);
|
dlclose(h);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static const struct pam_conv conv = {
|
static struct pam_conv conv = {
|
||||||
SHADOW_PAM_CONVERSATION,
|
SHADOW_PAM_CONVERSATION,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
14
lib/port.c
14
lib/port.c
@ -79,7 +79,7 @@ static void endportent (void)
|
|||||||
(void) fclose (ports);
|
(void) fclose (ports);
|
||||||
}
|
}
|
||||||
|
|
||||||
ports = NULL;
|
ports = (FILE *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -130,11 +130,11 @@ static struct port *getportent (void)
|
|||||||
again:
|
again:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the next line and remove optional trailing '\n'.
|
* Get the next line and remove the last character, which
|
||||||
* Lines which begin with '#' are all ignored.
|
* is a '\n'. Lines which begin with '#' are all ignored.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (fgets (buf, sizeof buf, ports) == 0) {
|
if (fgets (buf, (int) sizeof buf, ports) == 0) {
|
||||||
errno = saveerr;
|
errno = saveerr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ static struct port *getportent (void)
|
|||||||
* TTY devices.
|
* TTY devices.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
buf[strcspn (buf, "\n")] = 0;
|
buf[strlen (buf) - 1] = 0;
|
||||||
|
|
||||||
port.pt_names = ttys;
|
port.pt_names = ttys;
|
||||||
for (cp = buf, j = 0; j < PORT_TTY; j++) {
|
for (cp = buf, j = 0; j < PORT_TTY; j++) {
|
||||||
@ -172,13 +172,13 @@ static struct port *getportent (void)
|
|||||||
}
|
}
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
cp++;
|
cp++;
|
||||||
port.pt_names[j + 1] = NULL;
|
port.pt_names[j + 1] = (char *) 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the list of user names. It is the second colon
|
* Get the list of user names. It is the second colon
|
||||||
* separated field, and is a comma separated list of user
|
* separated field, and is a comma separated list of user
|
||||||
* names. The entry '*' is used to specify all usernames.
|
* names. The entry '*' is used to specify all usernames.
|
||||||
* The last entry in the list is a NULL pointer.
|
* The last entry in the list is a (char *) 0 pointer.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (':' != *cp) {
|
if (':' != *cp) {
|
||||||
|
@ -21,9 +21,12 @@
|
|||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
#include <utmpx.h>
|
||||||
|
#else
|
||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
|
#endif
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
@ -41,12 +44,6 @@ extern int add_groups (const char *);
|
|||||||
/* age.c */
|
/* age.c */
|
||||||
extern void agecheck (/*@null@*/const struct spwd *);
|
extern void agecheck (/*@null@*/const struct spwd *);
|
||||||
extern int expire (const struct passwd *, /*@null@*/const struct spwd *);
|
extern int expire (const struct passwd *, /*@null@*/const struct spwd *);
|
||||||
|
|
||||||
/* agetpass.c */
|
|
||||||
extern void erase_pass(char *pass);
|
|
||||||
ATTR_MALLOC(erase_pass)
|
|
||||||
extern char *agetpass(const char *prompt);
|
|
||||||
|
|
||||||
/* isexpired.c */
|
/* isexpired.c */
|
||||||
extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *);
|
extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *);
|
||||||
|
|
||||||
@ -160,8 +157,6 @@ extern int getlong (const char *numstr, /*@out@*/long int *result);
|
|||||||
|
|
||||||
/* get_pid.c */
|
/* get_pid.c */
|
||||||
extern int get_pid (const char *pidstr, pid_t *pid);
|
extern int get_pid (const char *pidstr, pid_t *pid);
|
||||||
extern int get_pidfd_from_fd(const char *pidfdstr);
|
|
||||||
extern int open_pidfd(const char *pidstr);
|
|
||||||
|
|
||||||
/* getrange */
|
/* getrange */
|
||||||
extern int getrange (const char *range,
|
extern int getrange (const char *range,
|
||||||
@ -191,6 +186,7 @@ extern void __gr_set_changed (void);
|
|||||||
extern /*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent);
|
extern /*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent);
|
||||||
extern void gr_free_members (struct group *grent);
|
extern void gr_free_members (struct group *grent);
|
||||||
extern void gr_free (/*@out@*/ /*@only@*/struct group *grent);
|
extern void gr_free (/*@out@*/ /*@only@*/struct group *grent);
|
||||||
|
extern bool gr_append_member (struct group *grp, char *member);
|
||||||
|
|
||||||
/* hushed.c */
|
/* hushed.c */
|
||||||
extern bool hushed (const char *username);
|
extern bool hushed (const char *username);
|
||||||
@ -233,7 +229,7 @@ extern void dolastlog (
|
|||||||
extern int login_access (const char *user, const char *from);
|
extern int login_access (const char *user, const char *from);
|
||||||
|
|
||||||
/* loginprompt.c */
|
/* loginprompt.c */
|
||||||
extern void login_prompt (char *, int);
|
extern void login_prompt (const char *, char *, int);
|
||||||
|
|
||||||
/* mail.c */
|
/* mail.c */
|
||||||
extern void mailcheck (void);
|
extern void mailcheck (void);
|
||||||
@ -357,11 +353,6 @@ extern /*@dependent@*/ /*@null@*/struct commonio_entry *__pw_get_head (void);
|
|||||||
extern /*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent);
|
extern /*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent);
|
||||||
extern void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent);
|
extern void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent);
|
||||||
|
|
||||||
/* csrand.c */
|
|
||||||
unsigned long csrand (void);
|
|
||||||
unsigned long csrand_uniform (unsigned long n);
|
|
||||||
unsigned long csrand_interval (unsigned long min, unsigned long max);
|
|
||||||
|
|
||||||
/* remove_tree.c */
|
/* remove_tree.c */
|
||||||
extern int remove_tree (const char *root, bool remove_root);
|
extern int remove_tree (const char *root, bool remove_root);
|
||||||
|
|
||||||
@ -385,7 +376,7 @@ extern int check_selinux_permit (const char *perm_name);
|
|||||||
|
|
||||||
/* semanage.c */
|
/* semanage.c */
|
||||||
#ifdef WITH_SELINUX
|
#ifdef WITH_SELINUX
|
||||||
extern int set_seuser(const char *login_name, const char *seuser_name, const char *serange);
|
extern int set_seuser(const char *login_name, const char *seuser_name);
|
||||||
extern int del_seuser(const char *login_name);
|
extern int del_seuser(const char *login_name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -469,16 +460,30 @@ extern int set_filesize_limit (int blocks);
|
|||||||
extern int user_busy (const char *name, uid_t uid);
|
extern int user_busy (const char *name, uid_t uid);
|
||||||
|
|
||||||
/* utmp.c */
|
/* utmp.c */
|
||||||
|
#ifndef USE_UTMPX
|
||||||
extern /*@null@*/struct utmp *get_current_utmp (void);
|
extern /*@null@*/struct utmp *get_current_utmp (void);
|
||||||
extern struct utmp *prepare_utmp (const char *name,
|
extern struct utmp *prepare_utmp (const char *name,
|
||||||
const char *line,
|
const char *line,
|
||||||
const char *host,
|
const char *host,
|
||||||
/*@null@*/const struct utmp *ut);
|
/*@null@*/const struct utmp *ut);
|
||||||
extern int setutmp (struct utmp *ut);
|
extern int setutmp (struct utmp *ut);
|
||||||
|
#else
|
||||||
|
extern /*@null@*/struct utmpx *get_current_utmp (void);
|
||||||
|
extern struct utmpx *prepare_utmpx (const char *name,
|
||||||
|
const char *line,
|
||||||
|
const char *host,
|
||||||
|
/*@null@*/const struct utmpx *ut);
|
||||||
|
extern int setutmpx (struct utmpx *utx);
|
||||||
|
#endif /* USE_UTMPX */
|
||||||
|
|
||||||
/* valid.c */
|
/* valid.c */
|
||||||
extern bool valid (const char *, const struct passwd *);
|
extern bool valid (const char *, const struct passwd *);
|
||||||
|
|
||||||
|
/* xmalloc.c */
|
||||||
|
extern /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size)
|
||||||
|
/*@ensures MaxSet(result) == (size - 1); @*/;
|
||||||
|
extern /*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *);
|
||||||
|
|
||||||
/* xgetpwnam.c */
|
/* xgetpwnam.c */
|
||||||
extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
|
extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
|
||||||
/* xgetpwuid.c */
|
/* xgetpwuid.c */
|
||||||
|
@ -207,5 +207,5 @@ int pw_auth (const char *cipher,
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
#else /* !USE_PAM */
|
#else /* !USE_PAM */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
|
@ -42,7 +42,7 @@ static const char *passwd_getname (const void *ent)
|
|||||||
|
|
||||||
static void *passwd_parse (const char *line)
|
static void *passwd_parse (const char *line)
|
||||||
{
|
{
|
||||||
return sgetpwent (line);
|
return (void *) sgetpwent (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int passwd_put (const void *ent, FILE * file)
|
static int passwd_put (const void *ent, FILE * file)
|
||||||
@ -137,7 +137,7 @@ int pw_open (int mode)
|
|||||||
|
|
||||||
int pw_update (const struct passwd *pw)
|
int pw_update (const struct passwd *pw)
|
||||||
{
|
{
|
||||||
return commonio_update (&passwd_db, pw);
|
return commonio_update (&passwd_db, (const void *) pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pw_remove (const char *name)
|
int pw_remove (const char *name)
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "pwio.h"
|
#include "pwio.h"
|
||||||
@ -23,11 +21,12 @@
|
|||||||
{
|
{
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
|
|
||||||
pw = CALLOC (1, struct passwd);
|
pw = (struct passwd *) malloc (sizeof *pw);
|
||||||
if (NULL == pw) {
|
if (NULL == pw) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* The libc might define other fields. They won't be copied. */
|
/* The libc might define other fields. They won't be copied. */
|
||||||
|
memset (pw, 0, sizeof *pw);
|
||||||
pw->pw_uid = pwent->pw_uid;
|
pw->pw_uid = pwent->pw_uid;
|
||||||
pw->pw_gid = pwent->pw_gid;
|
pw->pw_gid = pwent->pw_gid;
|
||||||
/*@-mustfreeonly@*/
|
/*@-mustfreeonly@*/
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <lib/prototypes.h>
|
#include <lib/prototypes.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "run_part.h"
|
#include "run_part.h"
|
||||||
#include "shadowlog_internal.h"
|
#include "shadowlog_internal.h"
|
||||||
|
|
||||||
@ -59,7 +57,7 @@ int run_parts (const char *directory, const char *name, const char *action)
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
path_length=strlen(directory) + strlen(namelist[n]->d_name) + 2;
|
path_length=strlen(directory) + strlen(namelist[n]->d_name) + 2;
|
||||||
char *s = MALLOCARRAY(path_length, char);
|
char *s = (char*)malloc(path_length);
|
||||||
if (!s) {
|
if (!s) {
|
||||||
printf ("could not allocate memory\n");
|
printf ("could not allocate memory\n");
|
||||||
for (; n<scanlist; n++) {
|
for (; n<scanlist; n++) {
|
||||||
|
@ -188,7 +188,7 @@ int check_selinux_permit (const char *perm_name)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) { .func_log = selinux_log_cb });
|
selinux_set_callback (SELINUX_CB_LOG, (union selinux_callback) selinux_log_cb);
|
||||||
|
|
||||||
if (getprevcon_raw (&user_context_raw) != 0) {
|
if (getprevcon_raw (&user_context_raw) != 0) {
|
||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
@ -206,5 +206,5 @@ int check_selinux_permit (const char *perm_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else /* !WITH_SELINUX */
|
#else /* !WITH_SELINUX */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !WITH_SELINUX */
|
#endif /* !WITH_SELINUX */
|
||||||
|
@ -22,6 +22,10 @@
|
|||||||
|
|
||||||
#include "shadowlog_internal.h"
|
#include "shadowlog_internal.h"
|
||||||
|
|
||||||
|
#ifndef DEFAULT_SERANGE
|
||||||
|
#define DEFAULT_SERANGE "s0"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
format_attr(printf, 3, 4)
|
format_attr(printf, 3, 4)
|
||||||
static void semanage_error_callback (unused void *varg,
|
static void semanage_error_callback (unused void *varg,
|
||||||
@ -97,8 +101,6 @@ static semanage_handle_t *semanage_init (void)
|
|||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (handle)
|
|
||||||
semanage_disconnect (handle);
|
|
||||||
semanage_handle_destroy (handle);
|
semanage_handle_destroy (handle);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -107,8 +109,7 @@ fail:
|
|||||||
static int semanage_user_mod (semanage_handle_t *handle,
|
static int semanage_user_mod (semanage_handle_t *handle,
|
||||||
semanage_seuser_key_t *key,
|
semanage_seuser_key_t *key,
|
||||||
const char *login_name,
|
const char *login_name,
|
||||||
const char *seuser_name,
|
const char *seuser_name)
|
||||||
const char *serange)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
semanage_seuser_t *seuser = NULL;
|
semanage_seuser_t *seuser = NULL;
|
||||||
@ -121,12 +122,11 @@ static int semanage_user_mod (semanage_handle_t *handle,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serange && semanage_mls_enabled(handle)) {
|
if (semanage_mls_enabled(handle)) {
|
||||||
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
|
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
_("Could not set serange for %s to %s\n"),
|
_("Could not set serange for %s\n"), login_name);
|
||||||
login_name, serange);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -158,10 +158,9 @@ done:
|
|||||||
|
|
||||||
|
|
||||||
static int semanage_user_add (semanage_handle_t *handle,
|
static int semanage_user_add (semanage_handle_t *handle,
|
||||||
const semanage_seuser_key_t *key,
|
semanage_seuser_key_t *key,
|
||||||
const char *login_name,
|
const char *login_name,
|
||||||
const char *seuser_name,
|
const char *seuser_name)
|
||||||
const char *serange)
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
semanage_seuser_t *seuser = NULL;
|
semanage_seuser_t *seuser = NULL;
|
||||||
@ -182,12 +181,11 @@ static int semanage_user_add (semanage_handle_t *handle,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serange && semanage_mls_enabled(handle)) {
|
if (semanage_mls_enabled(handle)) {
|
||||||
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
|
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
_("Could not set serange for %s to %s\n"),
|
_("Could not set serange for %s\n"), login_name);
|
||||||
login_name, serange);
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -218,7 +216,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int set_seuser (const char *login_name, const char *seuser_name, const char *serange)
|
int set_seuser (const char *login_name, const char *seuser_name)
|
||||||
{
|
{
|
||||||
semanage_handle_t *handle = NULL;
|
semanage_handle_t *handle = NULL;
|
||||||
semanage_seuser_key_t *key = NULL;
|
semanage_seuser_key_t *key = NULL;
|
||||||
@ -252,7 +250,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (0 != seuser_exists) {
|
if (0 != seuser_exists) {
|
||||||
ret = semanage_user_mod (handle, key, login_name, seuser_name, serange);
|
ret = semanage_user_mod (handle, key, login_name, seuser_name);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
_("Cannot modify SELinux user mapping\n"));
|
_("Cannot modify SELinux user mapping\n"));
|
||||||
@ -260,7 +258,7 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = semanage_user_add (handle, key, login_name, seuser_name, serange);
|
ret = semanage_user_add (handle, key, login_name, seuser_name);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
_("Cannot add SELinux user mapping\n"));
|
_("Cannot add SELinux user mapping\n"));
|
||||||
@ -281,8 +279,6 @@ int set_seuser (const char *login_name, const char *seuser_name, const char *ser
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
semanage_seuser_key_free (key);
|
semanage_seuser_key_free (key);
|
||||||
if (handle)
|
|
||||||
semanage_disconnect (handle);
|
|
||||||
semanage_handle_destroy (handle);
|
semanage_handle_destroy (handle);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -357,12 +353,9 @@ int del_seuser (const char *login_name)
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
done:
|
done:
|
||||||
semanage_seuser_key_free (key);
|
|
||||||
if (handle)
|
|
||||||
semanage_disconnect (handle);
|
|
||||||
semanage_handle_destroy (handle);
|
semanage_handle_destroy (handle);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else /* !WITH_SELINUX */
|
#else /* !WITH_SELINUX */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !WITH_SELINUX */
|
#endif /* !WITH_SELINUX */
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
|
||||||
@ -36,9 +34,10 @@
|
|||||||
*/
|
*/
|
||||||
static char **list (char *s)
|
static char **list (char *s)
|
||||||
{
|
{
|
||||||
static char **members = NULL;
|
static char **members = 0;
|
||||||
static int size = 0; /* max members + 1 */
|
static int size = 0; /* max members + 1 */
|
||||||
int i;
|
int i;
|
||||||
|
char **rbuf;
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -46,9 +45,21 @@ static char **list (char *s)
|
|||||||
member name, or terminating NULL). */
|
member name, or terminating NULL). */
|
||||||
if (i >= size) {
|
if (i >= size) {
|
||||||
size = i + 100; /* at least: i + 1 */
|
size = i + 100; /* at least: i + 1 */
|
||||||
members = REALLOCARRAYF(members, size, char *);
|
if (members) {
|
||||||
if (!members)
|
rbuf =
|
||||||
return NULL;
|
realloc (members, size * sizeof (char *));
|
||||||
|
} else {
|
||||||
|
/* for old (before ANSI C) implementations of
|
||||||
|
realloc() that don't handle NULL properly */
|
||||||
|
rbuf = malloc (size * sizeof (char *));
|
||||||
|
}
|
||||||
|
if (!rbuf) {
|
||||||
|
free (members);
|
||||||
|
members = 0;
|
||||||
|
size = 0;
|
||||||
|
return (char **) 0;
|
||||||
|
}
|
||||||
|
members = rbuf;
|
||||||
}
|
}
|
||||||
if (!s || s[0] == '\0')
|
if (!s || s[0] == '\0')
|
||||||
break;
|
break;
|
||||||
@ -60,14 +71,14 @@ static char **list (char *s)
|
|||||||
*s++ = '\0';
|
*s++ = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
members[i] = NULL;
|
members[i] = (char *) 0;
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct group *sgetgrent (const char *buf)
|
struct group *sgetgrent (const char *buf)
|
||||||
{
|
{
|
||||||
static char *grpbuf = NULL;
|
static char *grpbuf = 0;
|
||||||
static size_t size = 0;
|
static size_t size = 0;
|
||||||
static char *grpfields[NFIELDS];
|
static char *grpfields[NFIELDS];
|
||||||
static struct group grent;
|
static struct group grent;
|
||||||
@ -79,10 +90,10 @@ struct group *sgetgrent (const char *buf)
|
|||||||
allocate a larger block */
|
allocate a larger block */
|
||||||
free (grpbuf);
|
free (grpbuf);
|
||||||
size = strlen (buf) + 1000; /* at least: strlen(buf) + 1 */
|
size = strlen (buf) + 1000; /* at least: strlen(buf) + 1 */
|
||||||
grpbuf = MALLOCARRAY (size, char);
|
grpbuf = malloc (size);
|
||||||
if (grpbuf == NULL) {
|
if (!grpbuf) {
|
||||||
size = 0;
|
size = 0;
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strcpy (grpbuf, buf);
|
strcpy (grpbuf, buf);
|
||||||
@ -101,16 +112,16 @@ struct group *sgetgrent (const char *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i < (NFIELDS - 1) || *grpfields[2] == '\0' || cp != NULL) {
|
if (i < (NFIELDS - 1) || *grpfields[2] == '\0' || cp != NULL) {
|
||||||
return NULL;
|
return (struct group *) 0;
|
||||||
}
|
}
|
||||||
grent.gr_name = grpfields[0];
|
grent.gr_name = grpfields[0];
|
||||||
grent.gr_passwd = grpfields[1];
|
grent.gr_passwd = grpfields[1];
|
||||||
if (get_gid (grpfields[2], &grent.gr_gid) == 0) {
|
if (get_gid (grpfields[2], &grent.gr_gid) == 0) {
|
||||||
return NULL;
|
return (struct group *) 0;
|
||||||
}
|
}
|
||||||
grent.gr_mem = list (grpfields[3]);
|
grent.gr_mem = list (grpfields[3]);
|
||||||
if (NULL == grent.gr_mem) {
|
if (NULL == grent.gr_mem) {
|
||||||
return NULL; /* out of memory */
|
return (struct group *) 0; /* out of memory */
|
||||||
}
|
}
|
||||||
|
|
||||||
return &grent;
|
return &grent;
|
||||||
|
@ -182,6 +182,6 @@ struct spwd *sgetspent (const char *string)
|
|||||||
return (&spwd);
|
return (&spwd);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "commonio.h"
|
#include "commonio.h"
|
||||||
@ -26,12 +25,13 @@
|
|||||||
struct sgrp *sg;
|
struct sgrp *sg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
sg = CALLOC (1, struct sgrp);
|
sg = (struct sgrp *) malloc (sizeof *sg);
|
||||||
if (NULL == sg) {
|
if (NULL == sg) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Do the same as the other _dup function, even if we know the
|
/* Do the same as the other _dup function, even if we know the
|
||||||
* structure. */
|
* structure. */
|
||||||
|
memset (sg, 0, sizeof *sg);
|
||||||
/*@-mustfreeonly@*/
|
/*@-mustfreeonly@*/
|
||||||
sg->sg_name = strdup (sgent->sg_name);
|
sg->sg_name = strdup (sgent->sg_name);
|
||||||
/*@=mustfreeonly@*/
|
/*@=mustfreeonly@*/
|
||||||
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
for (i = 0; NULL != sgent->sg_adm[i]; i++);
|
for (i = 0; NULL != sgent->sg_adm[i]; i++);
|
||||||
/*@-mustfreeonly@*/
|
/*@-mustfreeonly@*/
|
||||||
sg->sg_adm = MALLOCARRAY (i + 1, char *);
|
sg->sg_adm = (char **) malloc ((i + 1) * sizeof (char *));
|
||||||
/*@=mustfreeonly@*/
|
/*@=mustfreeonly@*/
|
||||||
if (NULL == sg->sg_adm) {
|
if (NULL == sg->sg_adm) {
|
||||||
free (sg->sg_passwd);
|
free (sg->sg_passwd);
|
||||||
@ -75,7 +75,7 @@
|
|||||||
|
|
||||||
for (i = 0; NULL != sgent->sg_mem[i]; i++);
|
for (i = 0; NULL != sgent->sg_mem[i]; i++);
|
||||||
/*@-mustfreeonly@*/
|
/*@-mustfreeonly@*/
|
||||||
sg->sg_mem = MALLOCARRAY (i + 1, char *);
|
sg->sg_mem = (char **) malloc ((i + 1) * sizeof (char *));
|
||||||
/*@=mustfreeonly@*/
|
/*@=mustfreeonly@*/
|
||||||
if (NULL == sg->sg_mem) {
|
if (NULL == sg->sg_mem) {
|
||||||
for (i = 0; NULL != sg->sg_adm[i]; i++) {
|
for (i = 0; NULL != sg->sg_adm[i]; i++) {
|
||||||
@ -151,7 +151,7 @@ static const char *gshadow_getname (const void *ent)
|
|||||||
|
|
||||||
static void *gshadow_parse (const char *line)
|
static void *gshadow_parse (const char *line)
|
||||||
{
|
{
|
||||||
return sgetsgent (line);
|
return (void *) sgetsgent (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gshadow_put (const void *ent, FILE * file)
|
static int gshadow_put (const void *ent, FILE * file)
|
||||||
@ -253,7 +253,7 @@ int sgr_open (int mode)
|
|||||||
|
|
||||||
int sgr_update (const struct sgrp *sg)
|
int sgr_update (const struct sgrp *sg)
|
||||||
{
|
{
|
||||||
return commonio_update (&gshadow_db, sg);
|
return commonio_update (&gshadow_db, (const void *) sg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sgr_remove (const char *name)
|
int sgr_remove (const char *name)
|
||||||
@ -302,5 +302,5 @@ int sgr_sort ()
|
|||||||
return commonio_sort_wrt (&gshadow_db, __gr_get_db ());
|
return commonio_sort_wrt (&gshadow_db, __gr_get_db ());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif
|
#endif
|
||||||
|
10
lib/shadow.c
10
lib/shadow.c
@ -94,7 +94,7 @@ void endspent (void)
|
|||||||
(void) fclose (shadow);
|
(void) fclose (shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
shadow = NULL;
|
shadow = (FILE *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -336,9 +336,9 @@ struct spwd *fgetspent (FILE * fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_NIS
|
#ifdef USE_NIS
|
||||||
while (fgets (buf, sizeof buf, fp) != NULL)
|
while (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
|
||||||
#else
|
#else
|
||||||
if (fgets (buf, sizeof buf, fp) != NULL)
|
if (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
cp = strchr (buf, '\n');
|
cp = strchr (buf, '\n');
|
||||||
@ -511,7 +511,7 @@ struct spwd *getspnam (const char *name)
|
|||||||
nis_disabled = true;
|
nis_disabled = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
while ((sp = getspent ()) != NULL) {
|
while ((sp = getspent ()) != (struct spwd *) 0) {
|
||||||
if (strcmp (name, sp->sp_namp) == 0) {
|
if (strcmp (name, sp->sp_namp) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -525,6 +525,6 @@ struct spwd *getspnam (const char *name)
|
|||||||
return (sp);
|
return (sp);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ static const char *shadow_getname (const void *ent)
|
|||||||
|
|
||||||
static void *shadow_parse (const char *line)
|
static void *shadow_parse (const char *line)
|
||||||
{
|
{
|
||||||
return sgetspent (line);
|
return (void *) sgetspent (line);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shadow_put (const void *ent, FILE * file)
|
static int shadow_put (const void *ent, FILE * file)
|
||||||
@ -164,7 +164,7 @@ int spw_open (int mode)
|
|||||||
|
|
||||||
int spw_update (const struct spwd *sp)
|
int spw_update (const struct spwd *sp)
|
||||||
{
|
{
|
||||||
return commonio_update (&shadow_db, sp);
|
return commonio_update (&shadow_db, (const void *) sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int spw_remove (const char *name)
|
int spw_remove (const char *name)
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
#define _SHADOWLOG_INTERNAL_H
|
#define _SHADOWLOG_INTERNAL_H
|
||||||
|
|
||||||
extern const char *shadow_progname; /* Program name showed in error messages */
|
extern const char *shadow_progname; /* Program name showed in error messages */
|
||||||
extern FILE *shadow_logfd; /* file descriptor to which error messages are printed */
|
extern FILE *shadow_logfd; /* file descripter to which error messages are printed */
|
||||||
|
|
||||||
#endif /* _SHADOWLOG_INTERNAL_H */
|
#endif /* _SHADOWLOG_INTERNAL_H */
|
||||||
|
@ -16,19 +16,18 @@
|
|||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include <shadow.h>
|
#include <shadow.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "shadowio.h"
|
#include "shadowio.h"
|
||||||
|
|
||||||
/*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent)
|
/*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent)
|
||||||
{
|
{
|
||||||
struct spwd *sp;
|
struct spwd *sp;
|
||||||
|
|
||||||
sp = CALLOC (1, struct spwd);
|
sp = (struct spwd *) malloc (sizeof *sp);
|
||||||
if (NULL == sp) {
|
if (NULL == sp) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* The libc might define other fields. They won't be copied. */
|
/* The libc might define other fields. They won't be copied. */
|
||||||
|
memset (sp, 0, sizeof *sp);
|
||||||
sp->sp_lstchg = spent->sp_lstchg;
|
sp->sp_lstchg = spent->sp_lstchg;
|
||||||
sp->sp_min = spent->sp_min;
|
sp->sp_min = spent->sp_min;
|
||||||
sp->sp_max = spent->sp_max;
|
sp->sp_max = spent->sp_max;
|
||||||
|
12
lib/sssd.c
12
lib/sssd.c
@ -4,11 +4,8 @@
|
|||||||
#ifdef USE_SSSD
|
#ifdef USE_SSSD
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "exitcodes.h"
|
#include "exitcodes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
@ -22,17 +19,12 @@ int sssd_flush_cache (int dbflags)
|
|||||||
{
|
{
|
||||||
int status, code, rv;
|
int status, code, rv;
|
||||||
const char *cmd = "/usr/sbin/sss_cache";
|
const char *cmd = "/usr/sbin/sss_cache";
|
||||||
struct stat sb;
|
|
||||||
char *sss_cache_args = NULL;
|
char *sss_cache_args = NULL;
|
||||||
const char *spawnedArgs[] = {"sss_cache", NULL, NULL};
|
const char *spawnedArgs[] = {"sss_cache", NULL, NULL};
|
||||||
const char *spawnedEnv[] = {NULL};
|
const char *spawnedEnv[] = {NULL};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
rv = stat(cmd, &sb);
|
sss_cache_args = malloc(4);
|
||||||
if (rv == -1 && errno == ENOENT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
sss_cache_args = MALLOCARRAY(4, char);
|
|
||||||
if (sss_cache_args == NULL) {
|
if (sss_cache_args == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -78,6 +70,6 @@ int sssd_flush_cache (int dbflags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* USE_SSSD */
|
#else /* USE_SSSD */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* USE_SSSD */
|
#endif /* USE_SSSD */
|
||||||
|
|
||||||
|
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SHADOW_INCLUDE_LIB_STPECPY_H_
|
|
||||||
#define SHADOW_INCLUDE_LIB_STPECPY_H_
|
|
||||||
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#if !defined(HAVE_STPECPY)
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
|
|
||||||
inline char *stpecpy(char *dst, char *end, const char *restrict src);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SYNOPSIS
|
|
||||||
* char *_Nullable stpecpy(char *_Nullable dst, char end[0],
|
|
||||||
* const char *restrict src);
|
|
||||||
*
|
|
||||||
* ARGUMENTS
|
|
||||||
* dst Destination buffer where to copy a string.
|
|
||||||
*
|
|
||||||
* end Pointer to one after the last element of the buffer
|
|
||||||
* pointed to by `dst`. Usually, it should be calculated
|
|
||||||
* as `dst + NITEMS(dst)`.
|
|
||||||
*
|
|
||||||
* src Source string to be copied into dst.
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
* This function copies the string pointed to by src, into a string
|
|
||||||
* at the buffer pointed to by dst. If the destination buffer,
|
|
||||||
* limited by a pointer to its end --one after its last element--,
|
|
||||||
* isn't large enough to hold the copy, the resulting string is
|
|
||||||
* truncated.
|
|
||||||
*
|
|
||||||
* This function can be chained with calls to [v]stpeprintf().
|
|
||||||
*
|
|
||||||
* RETURN VALUE
|
|
||||||
* dst + strlen(dst)
|
|
||||||
* • On success, this function returns a pointer to the
|
|
||||||
* terminating NUL byte.
|
|
||||||
*
|
|
||||||
* end
|
|
||||||
* • If this call truncated the resulting string.
|
|
||||||
* • If `dst == end` (a previous chained call to these
|
|
||||||
* functions truncated).
|
|
||||||
* NULL
|
|
||||||
* • If `dst == NULL` (a previous chained call to
|
|
||||||
* [v]stpeprintf() failed).
|
|
||||||
*
|
|
||||||
* ERRORS
|
|
||||||
* This function doesn't set errno.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
inline char *
|
|
||||||
stpecpy(char *dst, char *end, const char *restrict src)
|
|
||||||
{
|
|
||||||
bool trunc;
|
|
||||||
char *p;
|
|
||||||
size_t dsize, dlen, slen;
|
|
||||||
|
|
||||||
if (dst == end)
|
|
||||||
return end;
|
|
||||||
if (dst == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
dsize = end - dst;
|
|
||||||
slen = strnlen(src, dsize);
|
|
||||||
trunc = (slen == dsize);
|
|
||||||
dlen = slen - trunc;
|
|
||||||
|
|
||||||
p = mempcpy(dst, src, dlen);
|
|
||||||
*p = '\0';
|
|
||||||
|
|
||||||
return p + trunc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !HAVE_STPECPY
|
|
||||||
#endif // include guard
|
|
119
lib/stpeprintf.h
119
lib/stpeprintf.h
@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2022 - 2023, Alejandro Colomar <alx@kernel.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SHADOW_INCLUDE_LIB_STPEPRINTF_H_
|
|
||||||
#define SHADOW_INCLUDE_LIB_STPEPRINTF_H_
|
|
||||||
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#if !defined(HAVE_STPEPRINTF)
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
|
|
||||||
format_attr(printf, 3, 4)
|
|
||||||
inline char *stpeprintf(char *dst, char *end, const char *restrict fmt, ...);
|
|
||||||
|
|
||||||
format_attr(printf, 3, 0)
|
|
||||||
inline char *vstpeprintf(char *dst, char *end, const char *restrict fmt,
|
|
||||||
va_list ap);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SYNOPSIS
|
|
||||||
* [[gnu::format(printf, 3, 4)]]
|
|
||||||
* char *_Nullable stpeprintf(char *_Nullable dst, char end[0],
|
|
||||||
* const char *restrict fmt, ...);
|
|
||||||
*
|
|
||||||
* [[gnu::format(printf, 3, 0)]]
|
|
||||||
* char *_Nullable vstpeprintf(char *_Nullable dst, char end[0],
|
|
||||||
* const char *restrict fmt, va_list ap);
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* ARGUMENTS
|
|
||||||
* dst Destination buffer where to write a string.
|
|
||||||
*
|
|
||||||
* end Pointer to one after the last element of the buffer
|
|
||||||
* pointed to by `dst`. Usually, it should be calculated
|
|
||||||
* as `dst + NITEMS(dst)`.
|
|
||||||
*
|
|
||||||
* fmt Format string
|
|
||||||
*
|
|
||||||
* ...
|
|
||||||
* ap Variadic argument list
|
|
||||||
*
|
|
||||||
* DESCRIPTION
|
|
||||||
* These functions are very similar to [v]snprintf(3).
|
|
||||||
*
|
|
||||||
* The destination buffer is limited by a pointer to its end --one
|
|
||||||
* after its last element-- instead of a size. This allows
|
|
||||||
* chaining calls to it safely, unlike [v]snprintf(3), which is
|
|
||||||
* difficult to chain without invoking Undefined Behavior.
|
|
||||||
*
|
|
||||||
* RETURN VALUE
|
|
||||||
* dst + strlen(dst)
|
|
||||||
* • On success, these functions return a pointer to the
|
|
||||||
* terminating NUL byte.
|
|
||||||
*
|
|
||||||
* end
|
|
||||||
* • If this call truncated the resulting string.
|
|
||||||
* • If `dst == end` (a previous chained call to these
|
|
||||||
* functions truncated).
|
|
||||||
* NULL
|
|
||||||
* • If this function failed (see ERRORS).
|
|
||||||
* • If `dst == NULL` (a previous chained call to these
|
|
||||||
* functions failed).
|
|
||||||
*
|
|
||||||
* ERRORS
|
|
||||||
* These functions may fail for the same reasons as vsnprintf(3).
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
inline char *
|
|
||||||
stpeprintf(char *dst, char *end, const char *restrict fmt, ...)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
va_list ap;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
p = vstpeprintf(dst, end, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline char *
|
|
||||||
vstpeprintf(char *dst, char *end, const char *restrict fmt, va_list ap)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
ptrdiff_t size;
|
|
||||||
|
|
||||||
if (dst == end)
|
|
||||||
return end;
|
|
||||||
if (dst == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
size = end - dst;
|
|
||||||
len = vsnprintf(dst, size, fmt, ap);
|
|
||||||
|
|
||||||
if (len == -1)
|
|
||||||
return NULL;
|
|
||||||
if (len >= size)
|
|
||||||
return end;
|
|
||||||
|
|
||||||
return dst + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !HAVE_STPEPRINTF
|
|
||||||
#endif // include guard
|
|
@ -17,8 +17,6 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
|
|
||||||
#define ID_SIZE 31
|
#define ID_SIZE 31
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -34,7 +32,7 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
|
|||||||
const struct subordinate_range *rangeent = ent;
|
const struct subordinate_range *rangeent = ent;
|
||||||
struct subordinate_range *range;
|
struct subordinate_range *range;
|
||||||
|
|
||||||
range = MALLOC (struct subordinate_range);
|
range = (struct subordinate_range *) malloc (sizeof *range);
|
||||||
if (NULL == range) {
|
if (NULL == range) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -316,12 +314,12 @@ static bool have_range(struct commonio_db *db,
|
|||||||
static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n)
|
static bool append_range(struct subid_range **ranges, const struct subordinate_range *new, int n)
|
||||||
{
|
{
|
||||||
if (!*ranges) {
|
if (!*ranges) {
|
||||||
*ranges = MALLOC(struct subid_range);
|
*ranges = malloc(sizeof(struct subid_range));
|
||||||
if (!*ranges)
|
if (!*ranges)
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
struct subid_range *alloced;
|
struct subid_range *alloced;
|
||||||
alloced = REALLOCARRAY(*ranges, n + 1, struct subid_range);
|
alloced = realloc(*ranges, (n + 1) * (sizeof(struct subid_range)));
|
||||||
if (!alloced)
|
if (!alloced)
|
||||||
return false;
|
return false;
|
||||||
*ranges = alloced;
|
*ranges = alloced;
|
||||||
@ -357,15 +355,14 @@ static int subordinate_range_cmp (const void *p1, const void *p2)
|
|||||||
{
|
{
|
||||||
struct subordinate_range *range1, *range2;
|
struct subordinate_range *range1, *range2;
|
||||||
|
|
||||||
|
if ((*(struct commonio_entry **) p1)->eptr == NULL)
|
||||||
range1 = (*(struct commonio_entry **) p1)->eptr;
|
|
||||||
if (range1 == NULL)
|
|
||||||
return 1;
|
return 1;
|
||||||
|
if ((*(struct commonio_entry **) p2)->eptr == NULL)
|
||||||
range2 = (*(struct commonio_entry **) p2)->eptr;
|
|
||||||
if (range2 == NULL)
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
range1 = ((struct subordinate_range *) (*(struct commonio_entry **) p1)->eptr);
|
||||||
|
range2 = ((struct subordinate_range *) (*(struct commonio_entry **) p2)->eptr);
|
||||||
|
|
||||||
if (range1->start < range2->start)
|
if (range1->start < range2->start)
|
||||||
return -1;
|
return -1;
|
||||||
else if (range1->start > range2->start)
|
else if (range1->start > range2->start)
|
||||||
@ -623,28 +620,17 @@ bool have_sub_uids(const char *owner, uid_t start, unsigned long count)
|
|||||||
return have_range (&subordinate_uid_db, owner, start, count);
|
return have_range (&subordinate_uid_db, owner, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sub_uid_add: add a subuid range, perhaps through nss.
|
|
||||||
*
|
|
||||||
* Return 1 if the range is already present or on success. On error
|
|
||||||
* return 0 and set errno appropriately.
|
|
||||||
*/
|
|
||||||
int sub_uid_add (const char *owner, uid_t start, unsigned long count)
|
int sub_uid_add (const char *owner, uid_t start, unsigned long count)
|
||||||
{
|
{
|
||||||
if (get_subid_nss_handle()) {
|
if (get_subid_nss_handle())
|
||||||
errno = EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return add_range (&subordinate_uid_db, owner, start, count);
|
return add_range (&subordinate_uid_db, owner, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 on success. on failure, return 0 and set errno appropriately */
|
|
||||||
int sub_uid_remove (const char *owner, uid_t start, unsigned long count)
|
int sub_uid_remove (const char *owner, uid_t start, unsigned long count)
|
||||||
{
|
{
|
||||||
if (get_subid_nss_handle()) {
|
if (get_subid_nss_handle())
|
||||||
errno = EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return remove_range (&subordinate_uid_db, owner, start, count);
|
return remove_range (&subordinate_uid_db, owner, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,28 +716,17 @@ bool local_sub_gid_assigned(const char *owner)
|
|||||||
return range_exists (&subordinate_gid_db, owner);
|
return range_exists (&subordinate_gid_db, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sub_gid_add: add a subgid range, perhaps through nss.
|
|
||||||
*
|
|
||||||
* Return 1 if the range is already present or on success. On error
|
|
||||||
* return 0 and set errno appropriately.
|
|
||||||
*/
|
|
||||||
int sub_gid_add (const char *owner, gid_t start, unsigned long count)
|
int sub_gid_add (const char *owner, gid_t start, unsigned long count)
|
||||||
{
|
{
|
||||||
if (get_subid_nss_handle()) {
|
if (get_subid_nss_handle())
|
||||||
errno = EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return add_range (&subordinate_gid_db, owner, start, count);
|
return add_range (&subordinate_gid_db, owner, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 on success. on failure, return 0 and set errno appropriately */
|
|
||||||
int sub_gid_remove (const char *owner, gid_t start, unsigned long count)
|
int sub_gid_remove (const char *owner, gid_t start, unsigned long count)
|
||||||
{
|
{
|
||||||
if (get_subid_nss_handle()) {
|
if (get_subid_nss_handle())
|
||||||
errno = EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return remove_range (&subordinate_gid_db, owner, start, count);
|
return remove_range (&subordinate_gid_db, owner, start, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -935,7 +910,7 @@ static int append_uids(uid_t **uids, const char *owner, int n)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = REALLOCARRAY(*uids, n + 1, uid_t);
|
ret = realloc(*uids, (n + 1) * sizeof(uid_t));
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
free(*uids);
|
free(*uids);
|
||||||
return -1;
|
return -1;
|
||||||
@ -1010,7 +985,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b
|
|||||||
switch (id_type) {
|
switch (id_type) {
|
||||||
case ID_TYPE_UID:
|
case ID_TYPE_UID:
|
||||||
if (!sub_uid_lock()) {
|
if (!sub_uid_lock()) {
|
||||||
printf("Failed locking subuids (errno %d)\n", errno);
|
printf("Failed loging subuids (errno %d)\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sub_uid_open(O_CREAT | O_RDWR)) {
|
if (!sub_uid_open(O_CREAT | O_RDWR)) {
|
||||||
@ -1022,7 +997,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b
|
|||||||
break;
|
break;
|
||||||
case ID_TYPE_GID:
|
case ID_TYPE_GID:
|
||||||
if (!sub_gid_lock()) {
|
if (!sub_gid_lock()) {
|
||||||
printf("Failed locking subgids (errno %d)\n", errno);
|
printf("Failed loging subgids (errno %d)\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sub_gid_open(O_CREAT | O_RDWR)) {
|
if (!sub_gid_open(O_CREAT | O_RDWR)) {
|
||||||
@ -1082,7 +1057,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
|
|||||||
switch (id_type) {
|
switch (id_type) {
|
||||||
case ID_TYPE_UID:
|
case ID_TYPE_UID:
|
||||||
if (!sub_uid_lock()) {
|
if (!sub_uid_lock()) {
|
||||||
printf("Failed locking subuids (errno %d)\n", errno);
|
printf("Failed loging subuids (errno %d)\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sub_uid_open(O_CREAT | O_RDWR)) {
|
if (!sub_uid_open(O_CREAT | O_RDWR)) {
|
||||||
@ -1094,7 +1069,7 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
|
|||||||
break;
|
break;
|
||||||
case ID_TYPE_GID:
|
case ID_TYPE_GID:
|
||||||
if (!sub_gid_lock()) {
|
if (!sub_gid_lock()) {
|
||||||
printf("Failed locking subgids (errno %d)\n", errno);
|
printf("Failed loging subgids (errno %d)\n", errno);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sub_gid_open(O_CREAT | O_RDWR)) {
|
if (!sub_gid_open(O_CREAT | O_RDWR)) {
|
||||||
@ -1122,6 +1097,6 @@ bool release_subid_range(struct subordinate_range *range, enum subid_type id_typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else /* !ENABLE_SUBIDS */
|
#else /* !ENABLE_SUBIDS */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !ENABLE_SUBIDS */
|
#endif /* !ENABLE_SUBIDS */
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
|
|||||||
shadow_progname, link);
|
shadow_progname, link);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
link[ret] = '\0';
|
link[(size_t)ret] = '\0';
|
||||||
rval = strdup (link);
|
rval = strdup (link);
|
||||||
if (NULL == rval) {
|
if (NULL == rval) {
|
||||||
OUT_OF_MEMORY;
|
OUT_OF_MEMORY;
|
||||||
|
70
lib/utent.c
Normal file
70
lib/utent.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 1993 - 1994, Julianne Frances Haugh
|
||||||
|
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||||
|
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifndef HAVE_GETUTENT
|
||||||
|
|
||||||
|
#include "defines.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <utmp.h>
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char rcsid[] = "$Id$";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int utmp_fd = -1;
|
||||||
|
static struct utmp utmp_buf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setutent - open or rewind the utmp file
|
||||||
|
*/
|
||||||
|
|
||||||
|
void setutent (void)
|
||||||
|
{
|
||||||
|
if (utmp_fd == -1)
|
||||||
|
if ((utmp_fd = open (_UTMP_FILE, O_RDWR)) == -1)
|
||||||
|
utmp_fd = open (_UTMP_FILE, O_RDONLY);
|
||||||
|
|
||||||
|
if (utmp_fd != -1)
|
||||||
|
lseek (utmp_fd, (off_t) 0L, SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* endutent - close the utmp file
|
||||||
|
*/
|
||||||
|
|
||||||
|
void endutent (void)
|
||||||
|
{
|
||||||
|
if (utmp_fd != -1)
|
||||||
|
close (utmp_fd);
|
||||||
|
|
||||||
|
utmp_fd = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getutent - get the next record from the utmp file
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct utmp *getutent (void)
|
||||||
|
{
|
||||||
|
if (utmp_fd == -1)
|
||||||
|
setutent ();
|
||||||
|
|
||||||
|
if (utmp_fd == -1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (read (utmp_fd, &utmp_buf, sizeof utmp_buf) != sizeof utmp_buf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return &utmp_buf;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
|
#endif
|
@ -5,15 +5,11 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) $(ECONF_CPPFLAGS)
|
|||||||
|
|
||||||
noinst_LTLIBRARIES = libmisc.la
|
noinst_LTLIBRARIES = libmisc.la
|
||||||
|
|
||||||
libmisc_la_CFLAGS = $(LIBBSD_CFLAGS)
|
|
||||||
libmisc_la_SOURCES = \
|
libmisc_la_SOURCES = \
|
||||||
addgrps.c \
|
addgrps.c \
|
||||||
age.c \
|
age.c \
|
||||||
agetpass.c \
|
|
||||||
alloc.c \
|
|
||||||
audit_help.c \
|
audit_help.c \
|
||||||
basename.c \
|
basename.c \
|
||||||
bit.c \
|
|
||||||
chkname.c \
|
chkname.c \
|
||||||
chkname.h \
|
chkname.h \
|
||||||
chowndir.c \
|
chowndir.c \
|
||||||
@ -45,7 +41,6 @@ libmisc_la_SOURCES = \
|
|||||||
list.c log.c \
|
list.c log.c \
|
||||||
loginprompt.c \
|
loginprompt.c \
|
||||||
mail.c \
|
mail.c \
|
||||||
mempcpy.c \
|
|
||||||
motd.c \
|
motd.c \
|
||||||
myname.c \
|
myname.c \
|
||||||
obscure.c \
|
obscure.c \
|
||||||
@ -55,7 +50,6 @@ libmisc_la_SOURCES = \
|
|||||||
pwd2spwd.c \
|
pwd2spwd.c \
|
||||||
pwdcheck.c \
|
pwdcheck.c \
|
||||||
pwd_init.c \
|
pwd_init.c \
|
||||||
csrand.c \
|
|
||||||
remove_tree.c \
|
remove_tree.c \
|
||||||
rlogin.c \
|
rlogin.c \
|
||||||
root_flag.c \
|
root_flag.c \
|
||||||
@ -63,8 +57,6 @@ libmisc_la_SOURCES = \
|
|||||||
setugid.c \
|
setugid.c \
|
||||||
setupenv.c \
|
setupenv.c \
|
||||||
shell.c \
|
shell.c \
|
||||||
stpecpy.c \
|
|
||||||
stpeprintf.c \
|
|
||||||
strtoday.c \
|
strtoday.c \
|
||||||
sub.c \
|
sub.c \
|
||||||
sulog.c \
|
sulog.c \
|
||||||
@ -79,6 +71,7 @@ libmisc_la_SOURCES = \
|
|||||||
xgetgrnam.c \
|
xgetgrnam.c \
|
||||||
xgetgrgid.c \
|
xgetgrgid.c \
|
||||||
xgetspnam.c \
|
xgetspnam.c \
|
||||||
|
xmalloc.c \
|
||||||
yesno.c
|
yesno.c
|
||||||
|
|
||||||
if WITH_BTRFS
|
if WITH_BTRFS
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "shadowlog.h"
|
#include "shadowlog.h"
|
||||||
|
|
||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
@ -31,7 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
int add_groups (const char *list)
|
int add_groups (const char *list)
|
||||||
{
|
{
|
||||||
GETGROUPS_T *grouplist;
|
GETGROUPS_T *grouplist, *tmp;
|
||||||
size_t i;
|
size_t i;
|
||||||
int ngroups;
|
int ngroups;
|
||||||
bool added;
|
bool added;
|
||||||
@ -48,7 +46,7 @@ int add_groups (const char *list)
|
|||||||
|
|
||||||
i = 16;
|
i = 16;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
grouplist = MALLOCARRAY (i, GETGROUPS_T);
|
grouplist = (gid_t *) malloc (i * sizeof (GETGROUPS_T));
|
||||||
if (NULL == grouplist) {
|
if (NULL == grouplist) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -90,17 +88,19 @@ int add_groups (const char *list)
|
|||||||
fputs (_("Warning: too many groups\n"), shadow_logfd);
|
fputs (_("Warning: too many groups\n"), shadow_logfd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
grouplist = REALLOCARRAYF(grouplist, (size_t) ngroups + 1, GETGROUPS_T);
|
tmp = (gid_t *) realloc (grouplist, (size_t)(ngroups + 1) * sizeof (GETGROUPS_T));
|
||||||
if (grouplist == NULL) {
|
if (NULL == tmp) {
|
||||||
|
free (grouplist);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
grouplist[ngroups] = grp->gr_gid;
|
tmp[ngroups] = grp->gr_gid;
|
||||||
ngroups++;
|
ngroups++;
|
||||||
|
grouplist = tmp;
|
||||||
added = true;
|
added = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (added) {
|
if (added) {
|
||||||
ret = setgroups (ngroups, grouplist);
|
ret = setgroups ((size_t)ngroups, grouplist);
|
||||||
free (grouplist);
|
free (grouplist);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -109,6 +109,6 @@ int add_groups (const char *list)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* HAVE_SETGROUPS && !USE_PAM */
|
#else /* HAVE_SETGROUPS && !USE_PAM */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* HAVE_SETGROUPS && !USE_PAM */
|
#endif /* HAVE_SETGROUPS && !USE_PAM */
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
|
|||||||
_exit (126);
|
_exit (126);
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) NULL);
|
(void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0);
|
||||||
err = errno;
|
err = errno;
|
||||||
perror ("Can't execute " PASSWD_PROGRAM);
|
perror ("Can't execute " PASSWD_PROGRAM);
|
||||||
_exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
_exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
|
||||||
@ -139,7 +139,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
|
|||||||
|
|
||||||
void agecheck (/*@null@*/const struct spwd *sp)
|
void agecheck (/*@null@*/const struct spwd *sp)
|
||||||
{
|
{
|
||||||
long now = time(NULL) / SCALE;
|
long now = (long) time ((time_t *) 0) / SCALE;
|
||||||
long remain;
|
long remain;
|
||||||
|
|
||||||
if (NULL == sp) {
|
if (NULL == sp) {
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2022, Alejandro Colomar <alx@kernel.org>
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <readpassphrase.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ident "$Id$"
|
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(PASS_MAX)
|
|
||||||
#define PASS_MAX BUFSIZ - 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SYNOPSIS
|
|
||||||
* [[gnu::malloc(erase_pass)]]
|
|
||||||
* char *agetpass(const char *prompt);
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
char *
|
|
||||||
agetpass(const char *prompt)
|
|
||||||
{
|
|
||||||
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 = MALLOCARRAY(PASS_MAX + 2, char);
|
|
||||||
if (pass == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (readpassphrase(prompt, pass, PASS_MAX + 2, RPP_REQUIRE_TTY) == 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
erase_pass(char *pass)
|
|
||||||
{
|
|
||||||
freezero(pass, PASS_MAX + 2);
|
|
||||||
}
|
|
@ -62,7 +62,7 @@ void audit_logger (int type, unused const char *pgname, const char *op,
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
audit_log_acct_message (audit_fd, type, NULL, op, name, id,
|
audit_log_acct_message (audit_fd, type, NULL, op, name, id,
|
||||||
NULL, NULL, NULL, result);
|
NULL, NULL, NULL, (int) result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,11 +77,11 @@ void audit_logger_message (const char *message, shadow_audit_result result)
|
|||||||
NULL, /* hostname */
|
NULL, /* hostname */
|
||||||
NULL, /* addr */
|
NULL, /* addr */
|
||||||
NULL, /* tty */
|
NULL, /* tty */
|
||||||
result);
|
(int) result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* WITH_AUDIT */
|
#else /* WITH_AUDIT */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* WITH_AUDIT */
|
#endif /* WITH_AUDIT */
|
||||||
|
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
/*@observer@*/const char *Basename (const char *str)
|
/*@observer@*/const char *Basename (const char *str)
|
||||||
{
|
{
|
||||||
if (str == NULL) {
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
char *cp = strrchr (str, '/');
|
char *cp = strrchr (str, '/');
|
||||||
|
|
||||||
return (NULL != cp) ? cp + 1 : str;
|
return (NULL != cp) ? cp + 1 : str;
|
||||||
|
@ -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);
|
|
@ -51,7 +51,7 @@ void chown_tty (const struct passwd *info)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|
if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0)
|
||||||
|| (fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600)) != 0)) {
|
|| (fchmod (STDIN_FILENO, (mode_t)getdef_num ("TTYPERM", 0600)) != 0)) {
|
||||||
int err = errno;
|
int err = errno;
|
||||||
FILE *shadow_logfd = log_get_logfd();
|
FILE *shadow_logfd = log_get_logfd();
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
void cleanup_report_add_group (void *group_name)
|
void cleanup_report_add_group (void *group_name)
|
||||||
{
|
{
|
||||||
const char *name = group_name;
|
const char *name = (const char *)group_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to add group %s", name));
|
SYSLOG ((LOG_ERR, "failed to add group %s", name));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -40,7 +40,7 @@ void cleanup_report_add_group (void *group_name)
|
|||||||
*/
|
*/
|
||||||
void cleanup_report_del_group (void *group_name)
|
void cleanup_report_del_group (void *group_name)
|
||||||
{
|
{
|
||||||
const char *name = group_name;
|
const char *name = (const char *)group_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
|
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -95,7 +95,7 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
|
|||||||
*/
|
*/
|
||||||
void cleanup_report_add_group_group (void *group_name)
|
void cleanup_report_add_group_group (void *group_name)
|
||||||
{
|
{
|
||||||
const char *name = group_name;
|
const char *name = (const char *)group_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
|
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -115,7 +115,7 @@ void cleanup_report_add_group_group (void *group_name)
|
|||||||
*/
|
*/
|
||||||
void cleanup_report_add_group_gshadow (void *group_name)
|
void cleanup_report_add_group_gshadow (void *group_name)
|
||||||
{
|
{
|
||||||
const char *name = group_name;
|
const char *name = (const char *)group_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
|
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -136,7 +136,7 @@ void cleanup_report_add_group_gshadow (void *group_name)
|
|||||||
*/
|
*/
|
||||||
void cleanup_report_del_group_group (void *group_name)
|
void cleanup_report_del_group_group (void *group_name)
|
||||||
{
|
{
|
||||||
const char *name = group_name;
|
const char *name = (const char *)group_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR,
|
SYSLOG ((LOG_ERR,
|
||||||
"failed to remove group %s from %s",
|
"failed to remove group %s from %s",
|
||||||
@ -159,7 +159,7 @@ void cleanup_report_del_group_group (void *group_name)
|
|||||||
*/
|
*/
|
||||||
void cleanup_report_del_group_gshadow (void *group_name)
|
void cleanup_report_del_group_gshadow (void *group_name)
|
||||||
{
|
{
|
||||||
const char *name = group_name;
|
const char *name = (const char *)group_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR,
|
SYSLOG ((LOG_ERR,
|
||||||
"failed to remove group %s from %s",
|
"failed to remove group %s from %s",
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
#include "shadowlog.h"
|
#include "shadowlog.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cleanup_report_add_user - Report failure to add a user to the system
|
* cleanup_report_add_user - Report failure to add an user to the system
|
||||||
*
|
*
|
||||||
* It should be registered when it is decided to add a user to the system.
|
* It should be registered when it is decided to add an user to the system.
|
||||||
*/
|
*/
|
||||||
void cleanup_report_add_user (void *user_name)
|
void cleanup_report_add_user (void *user_name)
|
||||||
{
|
{
|
||||||
const char *name = user_name;
|
const char *name = (const char *)user_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to add user %s", name));
|
SYSLOG ((LOG_ERR, "failed to add user %s", name));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -51,15 +51,15 @@ void cleanup_report_mod_passwd (void *cleanup_info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cleanup_report_add_user_passwd - Report failure to add a user to
|
* cleanup_report_add_user_passwd - Report failure to add an user to
|
||||||
* /etc/passwd
|
* /etc/passwd
|
||||||
*
|
*
|
||||||
* It should be registered when it is decided to add a user to the
|
* It should be registered when it is decided to add an user to the
|
||||||
* /etc/passwd database.
|
* /etc/passwd database.
|
||||||
*/
|
*/
|
||||||
void cleanup_report_add_user_passwd (void *user_name)
|
void cleanup_report_add_user_passwd (void *user_name)
|
||||||
{
|
{
|
||||||
const char *name = user_name;
|
const char *name = (const char *)user_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
|
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -71,15 +71,15 @@ void cleanup_report_add_user_passwd (void *user_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cleanup_report_add_user_shadow - Report failure to add a user to
|
* cleanup_report_add_user_shadow - Report failure to add an user to
|
||||||
* /etc/shadow
|
* /etc/shadow
|
||||||
*
|
*
|
||||||
* It should be registered when it is decided to add a user to the
|
* It should be registered when it is decided to add an user to the
|
||||||
* /etc/shadow database.
|
* /etc/shadow database.
|
||||||
*/
|
*/
|
||||||
void cleanup_report_add_user_shadow (void *user_name)
|
void cleanup_report_add_user_shadow (void *user_name)
|
||||||
{
|
{
|
||||||
const char *name = user_name;
|
const char *name = (const char *)user_name;
|
||||||
|
|
||||||
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
|
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
|
@ -44,7 +44,8 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
|
|||||||
|
|
||||||
if (*cons != '/') {
|
if (*cons != '/') {
|
||||||
char *pbuf;
|
char *pbuf;
|
||||||
strlcpy (buf, cons, sizeof (buf));
|
strncpy (buf, cons, sizeof (buf));
|
||||||
|
buf[sizeof (buf) - 1] = '\0';
|
||||||
pbuf = &buf[0];
|
pbuf = &buf[0];
|
||||||
while ((s = strtok (pbuf, ":")) != NULL) {
|
while ((s = strtok (pbuf, ":")) != NULL) {
|
||||||
if (strcmp (s, tty) == 0) {
|
if (strcmp (s, tty) == 0) {
|
||||||
@ -70,9 +71,8 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
|
|||||||
* See if this tty is listed in the console file.
|
* See if this tty is listed in the console file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while (fgets (buf, sizeof (buf), fp) != NULL) {
|
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
|
||||||
/* Remove optional trailing '\n'. */
|
buf[strlen (buf) - 1] = '\0';
|
||||||
buf[strcspn (buf, "\n")] = '\0';
|
|
||||||
if (strcmp (buf, tty) == 0) {
|
if (strcmp (buf, tty) == 0) {
|
||||||
(void) fclose (fp);
|
(void) fclose (fp);
|
||||||
return true;
|
return true;
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#ifdef WITH_SELINUX
|
#ifdef WITH_SELINUX
|
||||||
@ -228,7 +226,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
lp = XMALLOC (struct link_name);
|
lp = (struct link_name *) xmalloc (sizeof *lp);
|
||||||
src_len = strlen (src_orig);
|
src_len = strlen (src_orig);
|
||||||
dst_len = strlen (dst_orig);
|
dst_len = strlen (dst_orig);
|
||||||
name_len = strlen (name);
|
name_len = strlen (name);
|
||||||
@ -236,7 +234,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
|||||||
lp->ln_ino = sb->st_ino;
|
lp->ln_ino = sb->st_ino;
|
||||||
lp->ln_count = sb->st_nlink;
|
lp->ln_count = sb->st_nlink;
|
||||||
len = name_len - src_len + dst_len + 1;
|
len = name_len - src_len + dst_len + 1;
|
||||||
lp->ln_name = XMALLOCARRAY (len, char);
|
lp->ln_name = (char *) xmalloc (len);
|
||||||
(void) snprintf (lp->ln_name, len, "%s%s", dst_orig, name + src_len);
|
(void) snprintf (lp->ln_name, len, "%s%s", dst_orig, name + src_len);
|
||||||
lp->ln_next = links;
|
lp->ln_next = links;
|
||||||
links = lp;
|
links = lp;
|
||||||
@ -326,8 +324,8 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
|
|||||||
src_len += strlen (src->full_path);
|
src_len += strlen (src->full_path);
|
||||||
dst_len += strlen (dst->full_path);
|
dst_len += strlen (dst->full_path);
|
||||||
|
|
||||||
src_name = MALLOCARRAY (src_len, char);
|
src_name = (char *) malloc (src_len);
|
||||||
dst_name = MALLOCARRAY (dst_len, char);
|
dst_name = (char *) malloc (dst_len);
|
||||||
|
|
||||||
if ((NULL == src_name) || (NULL == dst_name)) {
|
if ((NULL == src_name) || (NULL == dst_name)) {
|
||||||
err = -1;
|
err = -1;
|
||||||
@ -421,25 +419,35 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
|||||||
if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
|
if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) {
|
||||||
/* If we cannot stat the file, do not care. */
|
/* If we cannot stat the file, do not care. */
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef HAVE_STRUCT_STAT_ST_ATIM
|
||||||
mt[0].tv_sec = sb.st_atim.tv_sec;
|
mt[0].tv_sec = sb.st_atim.tv_sec;
|
||||||
mt[0].tv_nsec = sb.st_atim.tv_nsec;
|
mt[0].tv_nsec = sb.st_atim.tv_nsec;
|
||||||
|
#else /* !HAVE_STRUCT_STAT_ST_ATIM */
|
||||||
|
mt[0].tv_sec = sb.st_atime;
|
||||||
|
# ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC
|
||||||
|
mt[0].tv_nsec = sb.st_atimensec;
|
||||||
|
# else /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||||
|
mt[0].tv_nsec = 0;
|
||||||
|
# endif /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */
|
||||||
|
#endif /* !HAVE_STRUCT_STAT_ST_ATIM */
|
||||||
|
|
||||||
|
#ifdef HAVE_STRUCT_STAT_ST_MTIM
|
||||||
mt[1].tv_sec = sb.st_mtim.tv_sec;
|
mt[1].tv_sec = sb.st_mtim.tv_sec;
|
||||||
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
|
mt[1].tv_nsec = sb.st_mtim.tv_nsec;
|
||||||
|
#else /* !HAVE_STRUCT_STAT_ST_MTIM */
|
||||||
|
mt[1].tv_sec = sb.st_mtime;
|
||||||
|
# ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||||
|
mt[1].tv_nsec = sb.st_mtimensec;
|
||||||
|
# else /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
|
||||||
|
mt[1].tv_nsec = 0;
|
||||||
|
# endif /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */
|
||||||
|
#endif /* !HAVE_STRUCT_STAT_ST_MTIM */
|
||||||
|
|
||||||
if (S_ISDIR (sb.st_mode)) {
|
if (S_ISDIR (sb.st_mode)) {
|
||||||
err = copy_dir (src, dst, reset_selinux, &sb, mt,
|
err = copy_dir (src, dst, reset_selinux, &sb, mt,
|
||||||
old_uid, new_uid, old_gid, new_gid);
|
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, &sb, AT_SYMLINK_NOFOLLOW) != -1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy any symbolic links
|
* Copy any symbolic links
|
||||||
*/
|
*/
|
||||||
@ -499,7 +507,6 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
|||||||
gid_t old_gid, gid_t new_gid)
|
gid_t old_gid, gid_t new_gid)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct stat dst_sb;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a new target directory, make it owned by
|
* Create a new target directory, make it owned by
|
||||||
@ -511,15 +518,6 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* WITH_SELINUX */
|
#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)
|
if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0)
|
||||||
|| (chownat_if_needed (dst, statp,
|
|| (chownat_if_needed (dst, statp,
|
||||||
old_uid, new_uid, old_gid, new_gid) != 0)
|
old_uid, new_uid, old_gid, new_gid) != 0)
|
||||||
@ -561,7 +559,7 @@ static /*@null@*/char *readlink_malloc (const char *filename)
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t nchars;
|
ssize_t nchars;
|
||||||
char *buffer = MALLOCARRAY (size, char);
|
char *buffer = (char *) malloc (size);
|
||||||
if (NULL == buffer) {
|
if (NULL == buffer) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -626,7 +624,7 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
|
|||||||
*/
|
*/
|
||||||
if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) {
|
if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) {
|
||||||
size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1;
|
size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1;
|
||||||
char *dummy = XMALLOCARRAY (len, char);
|
char *dummy = (char *) xmalloc (len);
|
||||||
(void) snprintf (dummy, len, "%s%s",
|
(void) snprintf (dummy, len, "%s%s",
|
||||||
dst_orig,
|
dst_orig,
|
||||||
oldlink + strlen (src_orig));
|
oldlink + strlen (src_orig));
|
||||||
@ -770,7 +768,7 @@ static ssize_t full_write(int fd, const void *buf, size_t count) {
|
|||||||
|
|
||||||
written += res;
|
written += res;
|
||||||
buf = (const unsigned char*)buf + res;
|
buf = (const unsigned char*)buf + res;
|
||||||
count -= res;
|
count -= (size_t)res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
@ -852,7 +850,7 @@ static int copy_file (const struct path_info *src, const struct path_info *dst,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full_write (ofd, buf, cnt) < 0) {
|
if (full_write (ofd, buf, (size_t)cnt) < 0) {
|
||||||
(void) close (ofd);
|
(void) close (ofd);
|
||||||
(void) close (ifd);
|
(void) close (ifd);
|
||||||
return -1;
|
return -1;
|
||||||
|
141
libmisc/csrand.c
141
libmisc/csrand.c
@ -1,141 +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"
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t csrand_uniform32(uint32_t n);
|
|
||||||
static unsigned long csrand_uniform_slow(unsigned long n);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a uniformly-distributed CS random u_long value.
|
|
||||||
*/
|
|
||||||
unsigned long
|
|
||||||
csrand(void)
|
|
||||||
{
|
|
||||||
FILE *fp;
|
|
||||||
unsigned long r;
|
|
||||||
|
|
||||||
#ifdef HAVE_GETENTROPY
|
|
||||||
/* getentropy may exist but lack kernel support. */
|
|
||||||
if (getentropy(&r, sizeof(r)) == 0)
|
|
||||||
return r;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_GETRANDOM
|
|
||||||
/* Likewise getrandom. */
|
|
||||||
if (getrandom(&r, sizeof(r), 0) == sizeof(r))
|
|
||||||
return r;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_ARC4RANDOM_BUF
|
|
||||||
/* arc4random_buf can never fail. */
|
|
||||||
arc4random_buf(&r, sizeof(r));
|
|
||||||
return r;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Use /dev/urandom as a last resort. */
|
|
||||||
fp = fopen("/dev/urandom", "r");
|
|
||||||
if (NULL == fp) {
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fread(&r, sizeof(r), 1, fp) != 1) {
|
|
||||||
fclose(fp);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
return r;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
fprintf(log_get_logfd(), _("Unable to obtain random bytes.\n"));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a uniformly-distributed CS random value in the interval [0, n-1].
|
|
||||||
*/
|
|
||||||
unsigned long
|
|
||||||
csrand_uniform(unsigned long n)
|
|
||||||
{
|
|
||||||
if (n == 0 || n > UINT32_MAX)
|
|
||||||
return csrand_uniform_slow(n);
|
|
||||||
|
|
||||||
return csrand_uniform32(n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return a uniformly-distributed CS random value in the interval [min, max].
|
|
||||||
*/
|
|
||||||
unsigned long
|
|
||||||
csrand_interval(unsigned long min, unsigned long max)
|
|
||||||
{
|
|
||||||
return csrand_uniform(max - min + 1) + min;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Fast Random Integer Generation in an Interval
|
|
||||||
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
|
|
||||||
* <https://arxiv.org/abs/1805.10941>
|
|
||||||
*/
|
|
||||||
static uint32_t
|
|
||||||
csrand_uniform32(uint32_t n)
|
|
||||||
{
|
|
||||||
uint32_t bound, rem;
|
|
||||||
uint64_t r, mult;
|
|
||||||
|
|
||||||
if (n == 0)
|
|
||||||
return csrand();
|
|
||||||
|
|
||||||
bound = -n % n; // analogous to `2^64 % n`, since `x % y == (x-y) % y`
|
|
||||||
|
|
||||||
do {
|
|
||||||
r = csrand();
|
|
||||||
mult = r * n;
|
|
||||||
rem = mult; // analogous to `mult % 2^64`
|
|
||||||
} while (rem < bound); // p = (2^64 % n) / 2^64; W.C.: n=2^63+1, p=0.5
|
|
||||||
|
|
||||||
r = mult >> WIDTHOF(n); // analogous to `mult / 2^64`
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
@ -33,24 +33,14 @@
|
|||||||
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
|
|
||||||
void
|
void date_to_str (size_t size, char buf[size], long date)
|
||||||
date_to_str(size_t size, char buf[size], long date)
|
|
||||||
{
|
{
|
||||||
time_t t;
|
time_t t;
|
||||||
const struct tm *tm;
|
|
||||||
|
|
||||||
t = date;
|
t = date;
|
||||||
if (date < 0) {
|
if (date < 0)
|
||||||
(void) strlcpy(buf, "never", size);
|
(void) strncpy (buf, "never", size);
|
||||||
return;
|
else
|
||||||
}
|
(void) strftime (buf, size, "%Y-%m-%d", gmtime (&t));
|
||||||
|
|
||||||
tm = gmtime(&t);
|
|
||||||
if (tm == NULL) {
|
|
||||||
(void) strlcpy(buf, "future", size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void) strftime(buf, size, "%Y-%m-%d", tm);
|
|
||||||
buf[size - 1] = '\0';
|
buf[size - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,6 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@ -26,7 +24,7 @@ void pw_entry (const char *name, struct passwd *pwent)
|
|||||||
struct spwd *spwd;
|
struct spwd *spwd;
|
||||||
|
|
||||||
if (!(passwd = getpwnam (name))) { /* local, no need for xgetpwnam */
|
if (!(passwd = getpwnam (name))) { /* local, no need for xgetpwnam */
|
||||||
pwent->pw_name = NULL;
|
pwent->pw_name = (char *) 0;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
pwent->pw_name = xstrdup (passwd->pw_name);
|
pwent->pw_name = xstrdup (passwd->pw_name);
|
||||||
|
@ -15,8 +15,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "shadowlog.h"
|
#include "shadowlog.h"
|
||||||
@ -28,6 +26,7 @@
|
|||||||
#define NEWENVP_STEP 16
|
#define NEWENVP_STEP 16
|
||||||
size_t newenvc = 0;
|
size_t newenvc = 0;
|
||||||
/*@null@*/char **newenvp = NULL;
|
/*@null@*/char **newenvp = NULL;
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
static const char *const forbid[] = {
|
static const char *const forbid[] = {
|
||||||
"_RLD_=",
|
"_RLD_=",
|
||||||
@ -43,7 +42,7 @@ static const char *const forbid[] = {
|
|||||||
"PATH=",
|
"PATH=",
|
||||||
"SHELL=",
|
"SHELL=",
|
||||||
"SHLIB_PATH=",
|
"SHLIB_PATH=",
|
||||||
NULL
|
(char *) 0
|
||||||
};
|
};
|
||||||
|
|
||||||
/* these are allowed, but with no slashes inside
|
/* these are allowed, but with no slashes inside
|
||||||
@ -52,7 +51,7 @@ static const char *const noslash[] = {
|
|||||||
"LANG=",
|
"LANG=",
|
||||||
"LANGUAGE=",
|
"LANGUAGE=",
|
||||||
"LC_", /* anything with the LC_ prefix */
|
"LC_", /* anything with the LC_ prefix */
|
||||||
NULL
|
(char *) 0
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -60,7 +59,7 @@ static const char *const noslash[] = {
|
|||||||
*/
|
*/
|
||||||
void initenv (void)
|
void initenv (void)
|
||||||
{
|
{
|
||||||
newenvp = XMALLOCARRAY (NEWENVP_STEP, char *);
|
newenvp = (char **) xmalloc (NEWENVP_STEP * sizeof (char *));
|
||||||
*newenvp = NULL;
|
*newenvp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ void addenv (const char *string, /*@null@*/const char *value)
|
|||||||
if (NULL != value) {
|
if (NULL != value) {
|
||||||
size_t len = strlen (string) + strlen (value) + 2;
|
size_t len = strlen (string) + strlen (value) + 2;
|
||||||
int wlen;
|
int wlen;
|
||||||
newstring = XMALLOCARRAY (len, char);
|
newstring = xmalloc (len);
|
||||||
wlen = snprintf (newstring, len, "%s=%s", string, value);
|
wlen = snprintf (newstring, len, "%s=%s", string, value);
|
||||||
assert (wlen == (int) len -1);
|
assert (wlen == (int) len -1);
|
||||||
} else {
|
} else {
|
||||||
@ -128,16 +127,16 @@ void addenv (const char *string, /*@null@*/const char *value)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
|
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
|
||||||
bool update_environ;
|
char **__newenvp;
|
||||||
char **__newenvp;
|
size_t newsize;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the resize operation succeeds we can
|
* If the resize operation succeeds we can
|
||||||
* happily go on, else print a message.
|
* happily go on, else print a message.
|
||||||
*/
|
*/
|
||||||
update_environ = (environ == newenvp);
|
|
||||||
|
|
||||||
__newenvp = REALLOCARRAY(newenvp, newenvc + NEWENVP_STEP, char *);
|
newsize = (newenvc + NEWENVP_STEP) * sizeof (char *);
|
||||||
|
__newenvp = (char **) realloc (newenvp, newsize);
|
||||||
|
|
||||||
if (NULL != __newenvp) {
|
if (NULL != __newenvp) {
|
||||||
/*
|
/*
|
||||||
@ -145,8 +144,9 @@ void addenv (const char *string, /*@null@*/const char *value)
|
|||||||
* environ so that it doesn't point to some
|
* environ so that it doesn't point to some
|
||||||
* free memory area (realloc() could move it).
|
* free memory area (realloc() could move it).
|
||||||
*/
|
*/
|
||||||
if (update_environ)
|
if (environ == newenvp) {
|
||||||
environ = __newenvp;
|
environ = __newenvp;
|
||||||
|
}
|
||||||
newenvp = __newenvp;
|
newenvp = __newenvp;
|
||||||
} else {
|
} else {
|
||||||
(void) fputs (_("Environment overflow\n"), log_get_logfd());
|
(void) fputs (_("Environment overflow\n"), log_get_logfd());
|
||||||
|
@ -53,7 +53,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||||
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||||
/* This is not necessarily a failure. The file is
|
/* This is not necessarily a failure. The file is
|
||||||
* initially zero length.
|
* initially zero length.
|
||||||
*
|
*
|
||||||
@ -86,7 +86,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||||
|| (write (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)
|
|| (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
|
||||||
|| (close (fd) != 0)) {
|
|| (close (fd) != 0)) {
|
||||||
SYSLOG ((LOG_WARN,
|
SYSLOG ((LOG_WARN,
|
||||||
"Can't write faillog entry for UID %lu in %s.",
|
"Can't write faillog entry for UID %lu in %s.",
|
||||||
@ -163,7 +163,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||||
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
|| (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||||
(void) close (fd);
|
(void) close (fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -185,7 +185,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
|||||||
fail.fail_cnt = 0;
|
fail.fail_cnt = 0;
|
||||||
|
|
||||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||||
|| (write (fd, &fail, sizeof fail) != (ssize_t) sizeof fail)
|
|| (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
|
||||||
|| (close (fd) != 0)) {
|
|| (close (fd) != 0)) {
|
||||||
SYSLOG ((LOG_WARN,
|
SYSLOG ((LOG_WARN,
|
||||||
"Can't reset faillog entry for UID %lu in %s.",
|
"Can't reset faillog entry for UID %lu in %s.",
|
||||||
@ -242,7 +242,13 @@ void failprint (const struct faillog *fail)
|
|||||||
* maintains a record of all login failures.
|
* maintains a record of all login failures.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void failtmp (const char *username, const struct utmp *failent)
|
void failtmp (const char *username,
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
const struct utmpx *failent
|
||||||
|
#else /* !USE_UTMPX */
|
||||||
|
const struct utmp *failent
|
||||||
|
#endif /* !USE_UTMPX */
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const char *ftmp;
|
const char *ftmp;
|
||||||
int fd;
|
int fd;
|
||||||
@ -278,7 +284,7 @@ void failtmp (const char *username, const struct utmp *failent)
|
|||||||
* Append the new failure record and close the log file.
|
* Append the new failure record and close the log file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( (write (fd, failent, sizeof *failent) != (ssize_t) sizeof *failent)
|
if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent)
|
||||||
|| (close (fd) != 0)) {
|
|| (close (fd) != 0)) {
|
||||||
SYSLOG ((LOG_WARN,
|
SYSLOG ((LOG_WARN,
|
||||||
"Can't append failure of user %s to %s.",
|
"Can't append failure of user %s to %s.",
|
||||||
|
@ -13,7 +13,11 @@
|
|||||||
|
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "faillog.h"
|
#include "faillog.h"
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
#include <utmpx.h>
|
||||||
|
#else /* !USE_UTMPX */
|
||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
|
#endif /* !USE_UTMPX */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* failure - make failure entry
|
* failure - make failure entry
|
||||||
@ -47,7 +51,11 @@ extern void failprint (const struct faillog *);
|
|||||||
* failtmp updates the (struct utmp) formatted failure log which
|
* failtmp updates the (struct utmp) formatted failure log which
|
||||||
* maintains a record of all login failures.
|
* maintains a record of all login failures.
|
||||||
*/
|
*/
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
extern void failtmp (const char *username, const struct utmpx *);
|
||||||
|
#else /* !USE_UTMPX */
|
||||||
extern void failtmp (const char *username, const struct utmp *);
|
extern void failtmp (const char *username, const struct utmp *);
|
||||||
|
#endif /* !USE_UTMPX */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "groupio.h"
|
#include "groupio.h"
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
@ -41,14 +40,15 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
|||||||
*preferred_min = (gid_t) 1;
|
*preferred_min = (gid_t) 1;
|
||||||
|
|
||||||
/* Get the minimum ID range from login.defs or default to 101 */
|
/* Get the minimum ID range from login.defs or default to 101 */
|
||||||
*min_id = getdef_ulong ("SYS_GID_MIN", 101UL);
|
*min_id = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If SYS_GID_MAX is unspecified, we should assume it to be one
|
* If SYS_GID_MAX is unspecified, we should assume it to be one
|
||||||
* less than the GID_MIN (which is reserved for non-system accounts)
|
* less than the GID_MIN (which is reserved for non-system accounts)
|
||||||
*/
|
*/
|
||||||
gid_def_max = getdef_ulong ("GID_MIN", 1000UL) - 1;
|
gid_def_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1;
|
||||||
*max_id = getdef_ulong ("SYS_GID_MAX", gid_def_max);
|
*max_id = (gid_t) getdef_ulong ("SYS_GID_MAX",
|
||||||
|
(unsigned long) gid_def_max);
|
||||||
|
|
||||||
/* Check that the ranges make sense */
|
/* Check that the ranges make sense */
|
||||||
if (*max_id < *min_id) {
|
if (*max_id < *min_id) {
|
||||||
@ -71,8 +71,8 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
|||||||
/* Non-system groups */
|
/* Non-system groups */
|
||||||
|
|
||||||
/* Get the values from login.defs or use reasonable defaults */
|
/* Get the values from login.defs or use reasonable defaults */
|
||||||
*min_id = getdef_ulong ("GID_MIN", 1000UL);
|
*min_id = (gid_t) getdef_ulong ("GID_MIN", 1000UL);
|
||||||
*max_id = getdef_ulong ("GID_MAX", 60000UL);
|
*max_id = (gid_t) getdef_ulong ("GID_MAX", 60000UL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The preferred minimum should match the standard ID minimum
|
* The preferred minimum should match the standard ID minimum
|
||||||
@ -99,7 +99,6 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
|||||||
*
|
*
|
||||||
* On success, return 0
|
* On success, return 0
|
||||||
* If the ID is in use, return EEXIST
|
* If the ID is in use, return EEXIST
|
||||||
* If the ID might clash with -1, return EINVAL
|
|
||||||
* If the ID is outside the range, return ERANGE
|
* If the ID is outside the range, return ERANGE
|
||||||
* In other cases, return errno from getgrgid()
|
* In other cases, return errno from getgrgid()
|
||||||
*/
|
*/
|
||||||
@ -113,11 +112,6 @@ static int check_gid (const gid_t gid,
|
|||||||
return ERANGE;
|
return ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for compatibility with 16b and 32b gid_t error codes */
|
|
||||||
if (gid == UINT16_MAX || gid == UINT32_MAX) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether we already detected this GID
|
* Check whether we already detected this GID
|
||||||
* using the gr_next() loop
|
* using the gr_next() loop
|
||||||
@ -189,10 +183,10 @@ int find_new_gid (bool sys_group,
|
|||||||
* gr_locate_gid() found the GID in an as-yet uncommitted
|
* gr_locate_gid() found the GID in an as-yet uncommitted
|
||||||
* entry. We'll proceed below and auto-set a GID.
|
* entry. We'll proceed below and auto-set a GID.
|
||||||
*/
|
*/
|
||||||
} else if (result == EEXIST || result == ERANGE || result == EINVAL) {
|
} else if (result == EEXIST || result == ERANGE) {
|
||||||
/*
|
/*
|
||||||
* Continue on below. At this time, we won't
|
* Continue on below. At this time, we won't
|
||||||
* treat these three cases differently.
|
* treat these two cases differently.
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -232,13 +226,14 @@ int find_new_gid (bool sys_group,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Create an array to hold all of the discovered GIDs */
|
/* Create an array to hold all of the discovered GIDs */
|
||||||
used_gids = CALLOC (gid_max + 1, bool);
|
used_gids = malloc (sizeof (bool) * (gid_max +1));
|
||||||
if (NULL == used_gids) {
|
if (NULL == used_gids) {
|
||||||
fprintf (log_get_logfd(),
|
fprintf (log_get_logfd(),
|
||||||
_("%s: failed to allocate memory: %s\n"),
|
_("%s: failed to allocate memory: %s\n"),
|
||||||
log_get_progname(), strerror (errno));
|
log_get_progname(), strerror (errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
memset (used_gids, false, sizeof (bool) * (gid_max + 1));
|
||||||
|
|
||||||
/* First look for the lowest and highest value in the local database */
|
/* First look for the lowest and highest value in the local database */
|
||||||
(void) gr_rewind ();
|
(void) gr_rewind ();
|
||||||
@ -302,11 +297,8 @@ int find_new_gid (bool sys_group,
|
|||||||
*gid = id;
|
*gid = id;
|
||||||
free (used_gids);
|
free (used_gids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This GID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
@ -348,11 +340,8 @@ int find_new_gid (bool sys_group,
|
|||||||
*gid = id;
|
*gid = id;
|
||||||
free (used_gids);
|
free (used_gids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This GID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
@ -411,11 +400,8 @@ int find_new_gid (bool sys_group,
|
|||||||
*gid = id;
|
*gid = id;
|
||||||
free (used_gids);
|
free (used_gids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This GID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
@ -457,11 +443,8 @@ int find_new_gid (bool sys_group,
|
|||||||
*gid = id;
|
*gid = id;
|
||||||
free (used_gids);
|
free (used_gids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This GID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
|
@ -59,6 +59,6 @@ int find_new_sub_gids (gid_t *range_start, unsigned long *range_count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* !ENABLE_SUBIDS */
|
#else /* !ENABLE_SUBIDS */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !ENABLE_SUBIDS */
|
#endif /* !ENABLE_SUBIDS */
|
||||||
|
|
||||||
|
@ -59,6 +59,6 @@ int find_new_sub_uids (uid_t *range_start, unsigned long *range_count)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* !ENABLE_SUBIDS */
|
#else /* !ENABLE_SUBIDS */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !ENABLE_SUBIDS */
|
#endif /* !ENABLE_SUBIDS */
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "pwio.h"
|
#include "pwio.h"
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
@ -41,14 +40,15 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
|||||||
*preferred_min = (uid_t) 1;
|
*preferred_min = (uid_t) 1;
|
||||||
|
|
||||||
/* Get the minimum ID range from login.defs or default to 101 */
|
/* Get the minimum ID range from login.defs or default to 101 */
|
||||||
*min_id = getdef_ulong ("SYS_UID_MIN", 101UL);
|
*min_id = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If SYS_UID_MAX is unspecified, we should assume it to be one
|
* If SYS_UID_MAX is unspecified, we should assume it to be one
|
||||||
* less than the UID_MIN (which is reserved for non-system accounts)
|
* less than the UID_MIN (which is reserved for non-system accounts)
|
||||||
*/
|
*/
|
||||||
uid_def_max = getdef_ulong ("UID_MIN", 1000UL) - 1;
|
uid_def_max = (uid_t) getdef_ulong ("UID_MIN", 1000UL) - 1;
|
||||||
*max_id = getdef_ulong ("SYS_UID_MAX", uid_def_max);
|
*max_id = (uid_t) getdef_ulong ("SYS_UID_MAX",
|
||||||
|
(unsigned long) uid_def_max);
|
||||||
|
|
||||||
/* Check that the ranges make sense */
|
/* Check that the ranges make sense */
|
||||||
if (*max_id < *min_id) {
|
if (*max_id < *min_id) {
|
||||||
@ -71,8 +71,8 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
|||||||
/* Non-system users */
|
/* Non-system users */
|
||||||
|
|
||||||
/* Get the values from login.defs or use reasonable defaults */
|
/* Get the values from login.defs or use reasonable defaults */
|
||||||
*min_id = getdef_ulong ("UID_MIN", 1000UL);
|
*min_id = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
|
||||||
*max_id = getdef_ulong ("UID_MAX", 60000UL);
|
*max_id = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The preferred minimum should match the standard ID minimum
|
* The preferred minimum should match the standard ID minimum
|
||||||
@ -99,7 +99,6 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
|||||||
*
|
*
|
||||||
* On success, return 0
|
* On success, return 0
|
||||||
* If the ID is in use, return EEXIST
|
* If the ID is in use, return EEXIST
|
||||||
* If the ID might clash with -1, return EINVAL
|
|
||||||
* If the ID is outside the range, return ERANGE
|
* If the ID is outside the range, return ERANGE
|
||||||
* In other cases, return errno from getpwuid()
|
* In other cases, return errno from getpwuid()
|
||||||
*/
|
*/
|
||||||
@ -113,11 +112,6 @@ static int check_uid(const uid_t uid,
|
|||||||
return ERANGE;
|
return ERANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for compatibility with 16b and 32b uid_t error codes */
|
|
||||||
if (uid == UINT16_MAX || uid == UINT32_MAX) {
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check whether we already detected this UID
|
* Check whether we already detected this UID
|
||||||
* using the pw_next() loop
|
* using the pw_next() loop
|
||||||
@ -189,10 +183,10 @@ int find_new_uid(bool sys_user,
|
|||||||
* pw_locate_uid() found the UID in an as-yet uncommitted
|
* pw_locate_uid() found the UID in an as-yet uncommitted
|
||||||
* entry. We'll proceed below and auto-set an UID.
|
* entry. We'll proceed below and auto-set an UID.
|
||||||
*/
|
*/
|
||||||
} else if (result == EEXIST || result == ERANGE || result == EINVAL) {
|
} else if (result == EEXIST || result == ERANGE) {
|
||||||
/*
|
/*
|
||||||
* Continue on below. At this time, we won't
|
* Continue on below. At this time, we won't
|
||||||
* treat these three cases differently.
|
* treat these two cases differently.
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
@ -232,7 +226,7 @@ int find_new_uid(bool sys_user,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Create an array to hold all of the discovered UIDs */
|
/* Create an array to hold all of the discovered UIDs */
|
||||||
used_uids = MALLOCARRAY (uid_max + 1, bool);
|
used_uids = malloc (sizeof (bool) * (uid_max +1));
|
||||||
if (NULL == used_uids) {
|
if (NULL == used_uids) {
|
||||||
fprintf (log_get_logfd(),
|
fprintf (log_get_logfd(),
|
||||||
_("%s: failed to allocate memory: %s\n"),
|
_("%s: failed to allocate memory: %s\n"),
|
||||||
@ -303,11 +297,8 @@ int find_new_uid(bool sys_user,
|
|||||||
*uid = id;
|
*uid = id;
|
||||||
free (used_uids);
|
free (used_uids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This UID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
@ -349,11 +340,8 @@ int find_new_uid(bool sys_user,
|
|||||||
*uid = id;
|
*uid = id;
|
||||||
free (used_uids);
|
free (used_uids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This UID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
@ -412,11 +400,8 @@ int find_new_uid(bool sys_user,
|
|||||||
*uid = id;
|
*uid = id;
|
||||||
free (used_uids);
|
free (used_uids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This UID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
@ -458,11 +443,8 @@ int find_new_uid(bool sys_user,
|
|||||||
*uid = id;
|
*uid = id;
|
||||||
free (used_uids);
|
free (used_uids);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (result == EEXIST || result == EINVAL) {
|
} else if (result == EEXIST) {
|
||||||
/*
|
/* This UID is in use, we'll continue to the next */
|
||||||
* This GID is in use or unusable, we'll
|
|
||||||
* continue to the next.
|
|
||||||
*/
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* An unexpected error occurred.
|
* An unexpected error occurred.
|
||||||
|
@ -36,7 +36,7 @@ extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *gr
|
|||||||
&& ('\0' == *endptr)
|
&& ('\0' == *endptr)
|
||||||
&& (ERANGE != errno)
|
&& (ERANGE != errno)
|
||||||
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
|
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
|
||||||
return xgetgrgid (gid);
|
return xgetgrgid ((gid_t) gid);
|
||||||
}
|
}
|
||||||
return xgetgrnam (grname);
|
return xgetgrnam (grname);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
* Epoch, 1970-01-01 00:00:00 +0000 (UTC), except that if the SOURCE_DATE_EPOCH
|
* Epoch, 1970-01-01 00:00:00 +0000 (UTC), except that if the SOURCE_DATE_EPOCH
|
||||||
* environment variable is exported it will use that instead.
|
* environment variable is exported it will use that instead.
|
||||||
*/
|
*/
|
||||||
/*@observer@*/time_t gettime (void)
|
/*@observer@*/time_t gettime ()
|
||||||
{
|
{
|
||||||
char *endptr;
|
char *endptr;
|
||||||
char *source_date_epoch;
|
char *source_date_epoch;
|
||||||
@ -55,13 +55,13 @@
|
|||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"),
|
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"),
|
||||||
ULONG_MAX, epoch);
|
ULONG_MAX, epoch);
|
||||||
} else if ((time_t)epoch > fallback) {
|
} else if (epoch > fallback) {
|
||||||
fprintf (shadow_logfd,
|
fprintf (shadow_logfd,
|
||||||
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"),
|
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"),
|
||||||
fallback, epoch);
|
fallback, epoch);
|
||||||
} else {
|
} else {
|
||||||
/* Valid */
|
/* Valid */
|
||||||
return epoch;
|
return (time_t)epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fallback;
|
return fallback;
|
||||||
|
@ -66,7 +66,7 @@ bool hushed (const char *username)
|
|||||||
if (NULL == fp) {
|
if (NULL == fp) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (found = false; !found && (fgets (buf, sizeof buf, fp) == buf);) {
|
for (found = false; !found && (fgets (buf, (int) sizeof buf, fp) == buf);) {
|
||||||
buf[strcspn (buf, "\n")] = '\0';
|
buf[strcspn (buf, "\n")] = '\0';
|
||||||
found = (strcmp (buf, pw->pw_shell) == 0) ||
|
found = (strcmp (buf, pw->pw_shell) == 0) ||
|
||||||
(strcmp (buf, pw->pw_name) == 0);
|
(strcmp (buf, pw->pw_name) == 0);
|
||||||
|
@ -11,10 +11,7 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "stpeprintf.h"
|
|
||||||
#include "idmapping.h"
|
#include "idmapping.h"
|
||||||
#if HAVE_SYS_CAPABILITY_H
|
#if HAVE_SYS_CAPABILITY_H
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
@ -46,7 +43,7 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mappings = CALLOC(ranges, struct map_range);
|
mappings = calloc(ranges, sizeof(*mappings));
|
||||||
if (!mappings) {
|
if (!mappings) {
|
||||||
fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"),
|
fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"),
|
||||||
log_get_progname());
|
log_get_progname());
|
||||||
@ -102,7 +99,7 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
|
|||||||
* 8bytes --> 21 ascii estimated -> 18446744073709551616 (20 real)
|
* 8bytes --> 21 ascii estimated -> 18446744073709551616 (20 real)
|
||||||
* 16bytes --> 39 ascii estimated -> 340282366920938463463374607431768211456 (39 real)
|
* 16bytes --> 39 ascii estimated -> 340282366920938463463374607431768211456 (39 real)
|
||||||
*/
|
*/
|
||||||
#define ULONG_DIGITS (((WIDTHOF(unsigned long) + 9)/10)*3)
|
#define ULONG_DIGITS ((((sizeof(unsigned long) * CHAR_BIT) + 9)/10)*3)
|
||||||
|
|
||||||
#if HAVE_SYS_CAPABILITY_H
|
#if HAVE_SYS_CAPABILITY_H
|
||||||
static inline bool maps_lower_root(int cap, int ranges, const struct map_range *mappings)
|
static inline bool maps_lower_root(int cap, int ranges, const struct map_range *mappings)
|
||||||
@ -144,7 +141,7 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings
|
|||||||
int idx;
|
int idx;
|
||||||
const struct map_range *mapping;
|
const struct map_range *mapping;
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
char *buf, *pos, *end;
|
char *buf, *pos;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
#if HAVE_SYS_CAPABILITY_H
|
#if HAVE_SYS_CAPABILITY_H
|
||||||
@ -191,21 +188,22 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bufsize = ranges * ((ULONG_DIGITS + 1) * 3);
|
bufsize = ranges * ((ULONG_DIGITS + 1) * 3);
|
||||||
pos = buf = XMALLOCARRAY(bufsize, char);
|
pos = buf = xmalloc(bufsize);
|
||||||
end = buf + bufsize;
|
|
||||||
|
|
||||||
/* Build the mapping command */
|
/* Build the mapping command */
|
||||||
mapping = mappings;
|
mapping = mappings;
|
||||||
for (idx = 0; idx < ranges; idx++, mapping++) {
|
for (idx = 0; idx < ranges; idx++, mapping++) {
|
||||||
/* Append this range to the string that will be written */
|
/* Append this range to the string that will be written */
|
||||||
pos = stpeprintf(pos, end, "%lu %lu %lu\n",
|
int written = snprintf(pos, bufsize - (pos - buf),
|
||||||
mapping->upper,
|
"%lu %lu %lu\n",
|
||||||
mapping->lower,
|
mapping->upper,
|
||||||
mapping->count);
|
mapping->lower,
|
||||||
}
|
mapping->count);
|
||||||
if (pos == end || pos == NULL) {
|
if ((written <= 0) || (written >= (bufsize - (pos - buf)))) {
|
||||||
fprintf(log_get_logfd(), _("%s: stpeprintf failed!\n"), log_get_progname());
|
fprintf(log_get_logfd(), _("%s: snprintf failed!\n"), log_get_progname());
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
pos += written;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write the mapping to the mapping file */
|
/* Write the mapping to the mapping file */
|
||||||
|
@ -40,7 +40,7 @@ int isexpired (const struct passwd *pw, /*@null@*/const struct spwd *sp)
|
|||||||
{
|
{
|
||||||
long now;
|
long now;
|
||||||
|
|
||||||
now = time(NULL) / SCALE;
|
now = (long) time ((time_t *) 0) / SCALE;
|
||||||
|
|
||||||
if (NULL == sp) {
|
if (NULL == sp) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -28,7 +28,11 @@
|
|||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
#include "shadowlog.h"
|
#include "shadowlog.h"
|
||||||
|
#ifdef HAVE_SYS_RESOURCE_H
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
|
#define LIMITS
|
||||||
|
#endif
|
||||||
|
#ifdef LIMITS
|
||||||
#ifndef LIMITS_FILE
|
#ifndef LIMITS_FILE
|
||||||
#define LIMITS_FILE "/etc/limits"
|
#define LIMITS_FILE "/etc/limits"
|
||||||
#endif
|
#endif
|
||||||
@ -68,7 +72,7 @@ static int setrlimit_value (unsigned int resource,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
longlimit *= multiplier;
|
longlimit *= multiplier;
|
||||||
limit = longlimit;
|
limit = (rlim_t)longlimit;
|
||||||
if (longlimit != limit)
|
if (longlimit != limit)
|
||||||
{
|
{
|
||||||
/* FIXME: Again, silent error handling...
|
/* FIXME: Again, silent error handling...
|
||||||
@ -95,7 +99,7 @@ static int set_prio (const char *value)
|
|||||||
|| (prio != (int) prio)) {
|
|| (prio != (int) prio)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (setpriority (PRIO_PROCESS, 0, prio) != 0) {
|
if (setpriority (PRIO_PROCESS, 0, (int) prio) != 0) {
|
||||||
return LOGIN_ERROR_RLIMIT;
|
return LOGIN_ERROR_RLIMIT;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -111,7 +115,7 @@ static int set_umask (const char *value)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) umask (mask);
|
(void) umask ((mode_t) mask);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +123,11 @@ static int set_umask (const char *value)
|
|||||||
/* Counts the number of user logins and check against the limit */
|
/* Counts the number of user logins and check against the limit */
|
||||||
static int check_logins (const char *name, const char *maxlogins)
|
static int check_logins (const char *name, const char *maxlogins)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
struct utmpx *ut;
|
||||||
|
#else /* !USE_UTMPX */
|
||||||
struct utmp *ut;
|
struct utmp *ut;
|
||||||
|
#endif /* !USE_UTMPX */
|
||||||
unsigned long limit, count;
|
unsigned long limit, count;
|
||||||
|
|
||||||
if (getulong (maxlogins, &limit) == 0) {
|
if (getulong (maxlogins, &limit) == 0) {
|
||||||
@ -132,8 +140,13 @@ static int check_logins (const char *name, const char *maxlogins)
|
|||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
setutxent ();
|
||||||
|
while ((ut = getutxent ()))
|
||||||
|
#else /* !USE_UTMPX */
|
||||||
setutent ();
|
setutent ();
|
||||||
while ((ut = getutent ()))
|
while ((ut = getutent ()))
|
||||||
|
#endif /* !USE_UTMPX */
|
||||||
{
|
{
|
||||||
if (USER_PROCESS != ut->ut_type) {
|
if (USER_PROCESS != ut->ut_type) {
|
||||||
continue;
|
continue;
|
||||||
@ -149,7 +162,11 @@ static int check_logins (const char *name, const char *maxlogins)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef USE_UTMPX
|
||||||
|
endutxent ();
|
||||||
|
#else /* !USE_UTMPX */
|
||||||
endutent ();
|
endutent ();
|
||||||
|
#endif /* !USE_UTMPX */
|
||||||
/*
|
/*
|
||||||
* This is called after setutmp(), so the number of logins counted
|
* This is called after setutmp(), so the number of logins counted
|
||||||
* includes the user who is currently trying to log in.
|
* includes the user who is currently trying to log in.
|
||||||
@ -226,26 +243,34 @@ static int do_user_limits (const char *buf, const char *name)
|
|||||||
|
|
||||||
while ('\0' != *pp) {
|
while ('\0' != *pp) {
|
||||||
switch (*pp++) {
|
switch (*pp++) {
|
||||||
|
#ifdef RLIMIT_AS
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A':
|
case 'A':
|
||||||
/* RLIMIT_AS - max address space (KB) */
|
/* RLIMIT_AS - max address space (KB) */
|
||||||
retval |= setrlimit_value (RLIMIT_AS, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_AS, pp, 1024);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef RLIMIT_CORE
|
||||||
case 'c':
|
case 'c':
|
||||||
case 'C':
|
case 'C':
|
||||||
/* RLIMIT_CORE - max core file size (KB) */
|
/* RLIMIT_CORE - max core file size (KB) */
|
||||||
retval |= setrlimit_value (RLIMIT_CORE, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_CORE, pp, 1024);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef RLIMIT_DATA
|
||||||
case 'd':
|
case 'd':
|
||||||
case 'D':
|
case 'D':
|
||||||
/* RLIMIT_DATA - max data size (KB) */
|
/* RLIMIT_DATA - max data size (KB) */
|
||||||
retval |= setrlimit_value (RLIMIT_DATA, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_DATA, pp, 1024);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef RLIMIT_FSIZE
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'F':
|
case 'F':
|
||||||
/* RLIMIT_FSIZE - Maximum filesize (KB) */
|
/* RLIMIT_FSIZE - Maximum filesize (KB) */
|
||||||
retval |= setrlimit_value (RLIMIT_FSIZE, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_FSIZE, pp, 1024);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#ifdef RLIMIT_NICE
|
#ifdef RLIMIT_NICE
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'I':
|
case 'I':
|
||||||
@ -269,11 +294,13 @@ static int do_user_limits (const char *buf, const char *name)
|
|||||||
retval |= setrlimit_value (RLIMIT_MEMLOCK, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_MEMLOCK, pp, 1024);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RLIMIT_NOFILE
|
||||||
case 'n':
|
case 'n':
|
||||||
case 'N':
|
case 'N':
|
||||||
/* RLIMIT_NOFILE - max number of open files */
|
/* RLIMIT_NOFILE - max number of open files */
|
||||||
retval |= setrlimit_value (RLIMIT_NOFILE, pp, 1);
|
retval |= setrlimit_value (RLIMIT_NOFILE, pp, 1);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#ifdef RLIMIT_RTPRIO
|
#ifdef RLIMIT_RTPRIO
|
||||||
case 'o':
|
case 'o':
|
||||||
case 'O':
|
case 'O':
|
||||||
@ -292,16 +319,20 @@ static int do_user_limits (const char *buf, const char *name)
|
|||||||
retval |= setrlimit_value (RLIMIT_RSS, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_RSS, pp, 1024);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef RLIMIT_STACK
|
||||||
case 's':
|
case 's':
|
||||||
case 'S':
|
case 'S':
|
||||||
/* RLIMIT_STACK - max stack size (KB) */
|
/* RLIMIT_STACK - max stack size (KB) */
|
||||||
retval |= setrlimit_value (RLIMIT_STACK, pp, 1024);
|
retval |= setrlimit_value (RLIMIT_STACK, pp, 1024);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef RLIMIT_CPU
|
||||||
case 't':
|
case 't':
|
||||||
case 'T':
|
case 'T':
|
||||||
/* RLIMIT_CPU - max CPU time (MIN) */
|
/* RLIMIT_CPU - max CPU time (MIN) */
|
||||||
retval |= setrlimit_value (RLIMIT_CPU, pp, 60);
|
retval |= setrlimit_value (RLIMIT_CPU, pp, 60);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#ifdef RLIMIT_NPROC
|
#ifdef RLIMIT_NPROC
|
||||||
case 'u':
|
case 'u':
|
||||||
case 'U':
|
case 'U':
|
||||||
@ -448,6 +479,7 @@ static int setup_user_limits (const char *uname)
|
|||||||
}
|
}
|
||||||
return do_user_limits (limits, uname);
|
return do_user_limits (limits, uname);
|
||||||
}
|
}
|
||||||
|
#endif /* LIMITS */
|
||||||
|
|
||||||
|
|
||||||
static void setup_usergroups (const struct passwd *info)
|
static void setup_usergroups (const struct passwd *info)
|
||||||
@ -491,6 +523,7 @@ void setup_limits (const struct passwd *info)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (getdef_bool ("QUOTAS_ENAB")) {
|
if (getdef_bool ("QUOTAS_ENAB")) {
|
||||||
|
#ifdef LIMITS
|
||||||
if (info->pw_uid != 0) {
|
if (info->pw_uid != 0) {
|
||||||
if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) {
|
if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) {
|
||||||
(void) fputs (_("Too many logins.\n"), log_get_logfd());
|
(void) fputs (_("Too many logins.\n"), log_get_logfd());
|
||||||
@ -498,6 +531,7 @@ void setup_limits (const struct passwd *info)
|
|||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
|
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
|
||||||
if (',' == *cp) {
|
if (',' == *cp) {
|
||||||
cp++;
|
cp++;
|
||||||
@ -508,7 +542,7 @@ void setup_limits (const struct passwd *info)
|
|||||||
if ( (getlong (cp + 4, &inc) == 1)
|
if ( (getlong (cp + 4, &inc) == 1)
|
||||||
&& (inc >= -20) && (inc <= 20)) {
|
&& (inc >= -20) && (inc <= 20)) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if ( (nice (inc) != -1)
|
if ( (nice ((int) inc) != -1)
|
||||||
|| (0 != errno)) {
|
|| (0 != errno)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -525,7 +559,7 @@ void setup_limits (const struct passwd *info)
|
|||||||
long int blocks;
|
long int blocks;
|
||||||
if ( (getlong (cp + 7, &blocks) == 0)
|
if ( (getlong (cp + 7, &blocks) == 0)
|
||||||
|| (blocks != (int) blocks)
|
|| (blocks != (int) blocks)
|
||||||
|| (set_filesize_limit (blocks) != 0)) {
|
|| (set_filesize_limit ((int) blocks) != 0)) {
|
||||||
SYSLOG ((LOG_WARN,
|
SYSLOG ((LOG_WARN,
|
||||||
"Can't set the ulimit for user %s",
|
"Can't set the ulimit for user %s",
|
||||||
info->pw_name));
|
info->pw_name));
|
||||||
@ -540,7 +574,7 @@ void setup_limits (const struct passwd *info)
|
|||||||
"Can't set umask value for user %s",
|
"Can't set umask value for user %s",
|
||||||
info->pw_name));
|
info->pw_name));
|
||||||
} else {
|
} else {
|
||||||
(void) umask (mask);
|
(void) umask ((mode_t) mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
@ -550,6 +584,6 @@ void setup_limits (const struct passwd *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#else /* !USE_PAM */
|
#else /* !USE_PAM */
|
||||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||||
#endif /* !USE_PAM */
|
#endif /* !USE_PAM */
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
/*
|
/*
|
||||||
@ -35,7 +33,7 @@
|
|||||||
* pointer if it is present.
|
* pointer if it is present.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; list[i] != NULL; i++) {
|
for (i = 0; list[i] != (char *) 0; i++) {
|
||||||
if (strcmp (list[i], member) == 0) {
|
if (strcmp (list[i], member) == 0) {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
@ -46,7 +44,7 @@
|
|||||||
* old entries, and the new entries as well.
|
* old entries, and the new entries as well.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp = XMALLOCARRAY (i + 2, char *);
|
tmp = (char **) xmalloc ((i + 2) * sizeof member);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the original list to the new list, then append the
|
* Copy the original list to the new list, then append the
|
||||||
@ -54,12 +52,12 @@
|
|||||||
* is returned to the invoker.
|
* is returned to the invoker.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; list[i] != NULL; i++) {
|
for (i = 0; list[i] != (char *) 0; i++) {
|
||||||
tmp[i] = list[i];
|
tmp[i] = list[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp[i] = xstrdup (member);
|
tmp[i] = xstrdup (member);
|
||||||
tmp[i+1] = NULL;
|
tmp[i+1] = (char *) 0;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
@ -85,7 +83,7 @@
|
|||||||
* pointer if it is not present.
|
* pointer if it is not present.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = j = 0; list[i] != NULL; i++) {
|
for (i = j = 0; list[i] != (char *) 0; i++) {
|
||||||
if (strcmp (list[i], member) != 0) {
|
if (strcmp (list[i], member) != 0) {
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
@ -100,7 +98,7 @@
|
|||||||
* old entries.
|
* old entries.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
tmp = XMALLOCARRAY (j + 1, char *);
|
tmp = (char **) xmalloc ((j + 1) * sizeof member);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the original list except the deleted members to the
|
* Copy the original list except the deleted members to the
|
||||||
@ -108,14 +106,14 @@
|
|||||||
* is returned to the invoker.
|
* is returned to the invoker.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = j = 0; list[i] != NULL; i++) {
|
for (i = j = 0; list[i] != (char *) 0; i++) {
|
||||||
if (strcmp (list[i], member) != 0) {
|
if (strcmp (list[i], member) != 0) {
|
||||||
tmp[j] = list[i];
|
tmp[j] = list[i];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp[j] = NULL;
|
tmp[j] = (char *) 0;
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
@ -135,7 +133,7 @@
|
|||||||
|
|
||||||
for (i = 0; NULL != list[i]; i++);
|
for (i = 0; NULL != list[i]; i++);
|
||||||
|
|
||||||
tmp = XMALLOCARRAY (i + 1, char *);
|
tmp = (char **) xmalloc ((i + 1) * sizeof (char *));
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (NULL != *list) {
|
while (NULL != *list) {
|
||||||
@ -144,7 +142,7 @@
|
|||||||
list++;
|
list++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp[i] = NULL;
|
tmp[i] = (char *) 0;
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,14 +210,14 @@ bool is_on_list (char *const *list, const char *member)
|
|||||||
* Allocate the array we're going to store the pointers into.
|
* Allocate the array we're going to store the pointers into.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
array = XMALLOCARRAY (i, char *);
|
array = (char **) xmalloc (sizeof (char *) * i);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Empty list is special - 0 members, not 1 empty member. --marekm
|
* Empty list is special - 0 members, not 1 empty member. --marekm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ('\0' == *members) {
|
if ('\0' == *members) {
|
||||||
*array = NULL;
|
*array = (char *) 0;
|
||||||
free (members);
|
free (members);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
@ -237,7 +235,7 @@ bool is_on_list (char *const *list, const char *member)
|
|||||||
cp2++;
|
cp2++;
|
||||||
cp = cp2;
|
cp = cp2;
|
||||||
} else {
|
} else {
|
||||||
array[i + 1] = NULL;
|
array[i + 1] = (char *) 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ void dolastlog (
|
|||||||
* the way we read the old one in.
|
* the way we read the old one in.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (read (fd, &newlog, sizeof newlog) != (ssize_t) sizeof newlog) {
|
if (read (fd, (void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) {
|
||||||
memzero (&newlog, sizeof newlog);
|
memzero (&newlog, sizeof newlog);
|
||||||
}
|
}
|
||||||
if (NULL != ll) {
|
if (NULL != ll) {
|
||||||
@ -82,7 +82,7 @@ void dolastlog (
|
|||||||
strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1);
|
strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1);
|
||||||
#endif
|
#endif
|
||||||
if ( (lseek (fd, offset, SEEK_SET) != offset)
|
if ( (lseek (fd, offset, SEEK_SET) != offset)
|
||||||
|| (write (fd, &newlog, sizeof newlog) != (ssize_t) sizeof newlog)
|
|| (write (fd, (const void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog)
|
||||||
|| (close (fd) != 0)) {
|
|| (close (fd) != 0)) {
|
||||||
SYSLOG ((LOG_WARN,
|
SYSLOG ((LOG_WARN,
|
||||||
"Can't write lastlog entry for UID %lu in %s.",
|
"Can't write lastlog entry for UID %lu in %s.",
|
||||||
|
@ -14,15 +14,14 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "alloc.h"
|
|
||||||
#include "prototypes.h"
|
#include "prototypes.h"
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
|
|
||||||
static void login_exit (unused int sig)
|
static void login_exit (unused int sig)
|
||||||
{
|
{
|
||||||
_exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -32,7 +31,7 @@ static void login_exit (unused int sig)
|
|||||||
* is set in login.defs, this file is displayed before the prompt.
|
* is set in login.defs, this file is displayed before the prompt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void login_prompt (char *name, int namesize)
|
void login_prompt (const char *prompt, char *name, int namesize)
|
||||||
{
|
{
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
@ -41,38 +40,45 @@ void login_prompt (char *name, int namesize)
|
|||||||
char *cp;
|
char *cp;
|
||||||
int i;
|
int i;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
const char *fname = getdef_str ("ISSUE_FILE");
|
|
||||||
|
|
||||||
sighandler_t sigquit;
|
sighandler_t sigquit;
|
||||||
|
#ifdef SIGTSTP
|
||||||
sighandler_t sigtstp;
|
sighandler_t sigtstp;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is a small chance that a QUIT character will be part of
|
* There is a small chance that a QUIT character will be part of
|
||||||
* some random noise during a prompt. Deal with this by exiting
|
* some random noise during a prompt. Deal with this by exiting
|
||||||
* instead of core dumping. Do the same thing for SIGTSTP.
|
* instead of core dumping. If SIGTSTP is defined, do the same
|
||||||
|
* thing for that signal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sigquit = signal (SIGQUIT, login_exit);
|
sigquit = signal (SIGQUIT, login_exit);
|
||||||
|
#ifdef SIGTSTP
|
||||||
sigtstp = signal (SIGTSTP, login_exit);
|
sigtstp = signal (SIGTSTP, login_exit);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* See if the user has configured the issue file to
|
* See if the user has configured the issue file to
|
||||||
* be displayed and display it before the prompt.
|
* be displayed and display it before the prompt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (NULL != fname) {
|
if (NULL != prompt) {
|
||||||
fp = fopen (fname, "r");
|
const char *fname = getdef_str ("ISSUE_FILE");
|
||||||
if (NULL != fp) {
|
if (NULL != fname) {
|
||||||
while ((i = getc (fp)) != EOF) {
|
fp = fopen (fname, "r");
|
||||||
(void) putc (i, stdout);
|
if (NULL != fp) {
|
||||||
}
|
while ((i = getc (fp)) != EOF) {
|
||||||
|
(void) putc (i, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
(void) fclose (fp);
|
(void) fclose (fp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
(void) gethostname (buf, sizeof buf);
|
||||||
|
printf (prompt, buf);
|
||||||
|
(void) fflush (stdout);
|
||||||
}
|
}
|
||||||
(void) gethostname (buf, sizeof buf);
|
|
||||||
printf (_("\n%s login: "), buf);
|
|
||||||
(void) fflush (stdout);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the user's response. The trailing newline will be
|
* Read the user's response. The trailing newline will be
|
||||||
@ -80,7 +86,7 @@ void login_prompt (char *name, int namesize)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
memzero (buf, sizeof buf);
|
memzero (buf, sizeof buf);
|
||||||
if (fgets (buf, sizeof buf, stdin) != buf) {
|
if (fgets (buf, (int) sizeof buf, stdin) != buf) {
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,20 +98,58 @@ void login_prompt (char *name, int namesize)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Skip leading whitespace. This makes " username" work right.
|
* Skip leading whitespace. This makes " username" work right.
|
||||||
* Then copy the rest (up to the end) into the username.
|
* Then copy the rest (up to the end or the first "non-graphic"
|
||||||
|
* character into the username.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (cp = buf; *cp == ' ' || *cp == '\t'; cp++);
|
for (cp = buf; *cp == ' ' || *cp == '\t'; cp++);
|
||||||
|
|
||||||
for (i = 0; i < namesize - 1 && *cp != '\0'; name[i++] = *cp++);
|
for (i = 0; i < namesize - 1 && isgraph (*cp); name[i++] = *cp++);
|
||||||
|
while (isgraph (*cp)) {
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('\0' != *cp) {
|
||||||
|
cp++;
|
||||||
|
}
|
||||||
|
|
||||||
name[i] = '\0';
|
name[i] = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a disaster, at best. The user may have entered extra
|
||||||
|
* environmental variables at the prompt. There are several ways
|
||||||
|
* to do this, and I just take the easy way out.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ('\0' != *cp) { /* process new variables */
|
||||||
|
char *nvar;
|
||||||
|
int count = 1;
|
||||||
|
int envc;
|
||||||
|
|
||||||
|
for (envc = 0; envc < MAX_ENV; envc++) {
|
||||||
|
nvar = strtok ((0 != envc) ? (char *) 0 : cp, " \t,");
|
||||||
|
if (NULL == nvar) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strchr (nvar, '=') != NULL) {
|
||||||
|
envp[envc] = nvar;
|
||||||
|
} else {
|
||||||
|
size_t len = strlen (nvar) + 32;
|
||||||
|
envp[envc] = xmalloc (len);
|
||||||
|
(void) snprintf (envp[envc], len,
|
||||||
|
"L%d=%s", count++, nvar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_env (envc, envp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the SIGQUIT handler back to its original value
|
* Set the SIGQUIT handler back to its original value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void) signal (SIGQUIT, sigquit);
|
(void) signal (SIGQUIT, sigquit);
|
||||||
|
#ifdef SIGTSTP
|
||||||
(void) signal (SIGTSTP, sigtstp);
|
(void) signal (SIGTSTP, sigtstp);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "alloc.h"
|
|
||||||
#include "getdef.h"
|
#include "getdef.h"
|
||||||
|
|
||||||
#ident "$Id$"
|
#ident "$Id$"
|
||||||
@ -39,7 +38,7 @@ void mailcheck (void)
|
|||||||
size_t len = strlen (mailbox) + 5;
|
size_t len = strlen (mailbox) + 5;
|
||||||
int wlen;
|
int wlen;
|
||||||
|
|
||||||
newmail = XMALLOCARRAY (len, char);
|
newmail = xmalloc (len);
|
||||||
wlen = snprintf (newmail, len, "%s/new", mailbox);
|
wlen = snprintf (newmail, len, "%s/new", mailbox);
|
||||||
assert (wlen == (int) len - 1);
|
assert (wlen == (int) len - 1);
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user