Compare commits

1 Commits

Author SHA1 Message Date
e7a7f8bd36 :( 2023-03-10 22:22:31 +00:00
449 changed files with 10471 additions and 8689 deletions

View File

@ -9,11 +9,9 @@ packages:
- gettext
- gettext-dev
- gettext-lang
- libbsd-dev
- libcap-dev
- libtool
- linux-pam-dev
- pkgconf
- sed
sources:
- https://github.com/shadow-maint/shadow

View File

@ -8,12 +8,10 @@ packages:
- gettext
- gettext-devel
- git
- libbsd-devel
- libselinux-devel
- libsemanage-devel
- libtool
- libxslt
- pkgconf
sources:
- https://github.com/shadow-maint/shadow
tasks:

View File

@ -3,13 +3,11 @@ packages:
- automake
- autopoint
- xsltproc
- libbsd-dev
- libselinux1-dev
- gettext
- expect
- byacc
- libtool
- pkgconf
sources:
- https://github.com/shadow-maint/shadow
tasks:

View File

@ -3,13 +3,11 @@ packages:
- automake
- autopoint
- xsltproc
- libbsd-dev
- libselinux1-dev
- gettext
- expect
- byacc
- libtool
- pkgconf
sources:
- https://github.com/shadow-maint/shadow
tasks:

View File

@ -1,4 +0,0 @@
root = true
[*.{c,h}]
indent_style = tab

View File

@ -6,7 +6,7 @@ runs:
- shell: bash
run: |
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 apt-get update -y
sudo apt-get -y build-dep shadow

View File

@ -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

View File

@ -14,7 +14,7 @@ jobs:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v3
uses: actions/checkout@v2
- name: Install dependencies
id: dependencies
@ -32,20 +32,19 @@ jobs:
- name: Build shadow-utils
run: |
PROCESSORS=$(/usr/bin/getconf _NPROCESSORS_ONLN)
make -kj$PROCESSORS || true
- name: Check build errors
run: make
make -j$PROCESSORS
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
differential-shellcheck:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
pull-requests: write
steps:
- name: Checkout repository

View File

@ -36,7 +36,7 @@ addons:
notification_email: christian.brauner@ubuntu.com,serge@hallyn.com
build_command_prepend: "./autogen.sh --without-selinux --disable-man"
build_command: "make -kj4 || make"
build_command: "make -j4"
branch_pattern: master
script:

View File

@ -3,7 +3,6 @@ reports and various comments. This list may be incomplete, I received
a lot of mail...
# Maintainers
* Marek Michałkiewicz <marekm72@gmail.com> (1995-2000)
* Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
* Nicolas François <nicolas.francois@centraliens.net> (2007-2014)
* Serge E. Hallyn <serge@hallyn.com> (2014-now)

View File

@ -9558,7 +9558,7 @@
* NEWS: release date corrected.
* 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>).
2006-07-30 Tomasz Kłoczko <kloczek@pld.org.pl>
@ -10245,7 +10245,7 @@
* NEWS: cleanups.
* 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).
@ -11654,7 +11654,7 @@
in OPTIONS section). Describe -a and -k options.
* 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>).
* 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
* 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
2005-06-02 Tomasz Kłoczko <kloczek@pld.org.pl>
@ -13029,7 +13029,7 @@
* man/pl/usermod.8: finish sync with english version.
* man/hu/login.1, man/pl/login.1, NEWS, man/Attic/login.1, man/de/login.1:
removed fragment about abilities pass environment variables in login prompt.
removed fragment about abilities pass enviroment variables in login prompt.
* man/Attic/gpasswd.1, man/Attic/newgrp.1:
fixes by Nicolas Nicolas François <nicolas.francois@centraliens.net> (not all
@ -13508,7 +13508,7 @@
removed not used translations.
* 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:
fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables which was allways
@ -13605,7 +13605,7 @@
* NEWS, src/su.c:
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
2004-10-23 Tomasz Kłoczko <kloczek@pld.org.pl>

14
NEWS
View File

@ -696,7 +696,7 @@ shadow-4.0.18 -> shadow-4.0.18.1 03-08-2006
shadow-4.0.17 -> shadow-4.0.18 01-08-2006
*** general:
- su: fixed set 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>),
- groupadd, groupmod, useradd, usermod: fixed UID/GID overflow (fixed
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=198920)
@ -855,7 +855,7 @@ shadow-4.0.14 -> shadow-4.0.15 13-03-2006
- su: move exit() outside libmisc/shell.c::shell() for handle shell() errors
on higher level (now is better visable where some programs exit with 126
and 127 exit codes); added new shell() parameter (char *const envp[])
which allow fix preserving 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>),
- su: added handle -c,--command option for GNU su compliance (merge
437_su_-c_option Debian patch),
@ -966,7 +966,7 @@ shadow-4.0.12 -> shadow-4.0.13 10-10-2005
to example described in ident(1) man page (modern compilers like latest GCC
removes not used functions by global optimization).
So "ident /usr/bin/passwd" will show again some useable informations
- su: fixed twice copy 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>),
- chage: differentiate the different failure causes by the exit value
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
- login: check for hushed login and pass PAM_SILENT if true,
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
- remove using SHADOWPWD #define so now shadow is always built with shadow
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,
- newgrp(1): newgrp uses /bin/sh (not bash),
- faillog(8): updated after rewritten faillog command for use getopt_long(),
- login(1): removed fragment about abilities pass 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>),
- 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
- 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>),
- autoconf: fixed filling MAIL_SPOOL_DIR and MAIL_SPOOL_FILE variables
which was always empty (Gregorio Guidi <g.guidi@sns.it>),
@ -1275,7 +1275,7 @@ shadow-4.0.4.1 -> shadow-4.0.5 27-10-2004
including symlinks placed into /etc/skel/public_html for example.
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=66819
- su: add pam_open_session() support. If built without PAM support
propagate $DISPLAY and $XAUTHORITY 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
- applied 036_pam_access_with_preauth.patch Debian patch submited by Bjorn
Torkelsson <Bjorn.Torkelsson@hpc2n.umu.se>: add support for PAM account

View File

@ -31,11 +31,6 @@ There are several ways to contact us:
https://alioth-lists-archive.debian.net/pipermail/pkg-shadow-commits/),
only used for historical purposes
## Contributions
Contributions are welcome. Follow the
[guidelines](doc/contributions/introduction.md) before posting any patches.
## Authors and maintainers
Authors and maintainers are listed in [AUTHORS.md](
https://github.com/shadow-maint/shadow/blob/master/AUTHORS.md).

View File

@ -9,4 +9,3 @@ At the moment only the latest release is supported.
Security vulnerabilities may be reported to
* Serge Hallyn <serge@hallyn.com> (B175CFA98F192AF2)
* Christian Brauner <christian@brauner.io> (4880B8C9BD0E5106FC070F4F7B3C391EFEA93624)
* Iker Pedrosa <ipedrosa@redhat.com> (4E80EF49C7987B6DE2F81F5005079C6C3A653E57)

View File

@ -36,25 +36,31 @@ LT_INIT
dnl Checks for libraries.
dnl Checks for header files.
AC_CHECK_HEADERS(crypt.h utmp.h \
termio.h sgtty.h sys/ioctl.h paths.h \
sys/capability.h sys/random.h \
gshadow.h lastlog.h rpc/key_prot.h acl/libacl.h \
AC_HEADER_STDBOOL
AC_CHECK_HEADERS(crypt.h errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
utime.h ulimit.h sys/capability.h sys/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)
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
AC_CHECK_FUNCS(arc4random_buf futimes \
AC_CHECK_FUNCS(arc4random_buf l64a fchmod fchown fsync futimes \
getentropy getrandom getspnam getusershell \
initgroups lckpwdf lutimes mempcpy \
setgroups updwtmp updwtmpx innetgr \
getspnam_r \
rpmatch \
memset_explicit explicit_bzero stpecpy stpeprintf)
getutent initgroups lckpwdf lutimes \
setgroups updwtmp updwtmpx innetgr getpwnam_r \
getpwuid_r getgrnam_r getgrgid_r getspnam_r \
memset_s explicit_bzero)
AC_SYS_LARGEFILE
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,
struct utmp.ut_id,
@ -68,6 +74,14 @@ AC_CHECK_MEMBERS([struct utmp.ut_type,
struct utmp.ut_xtime,
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
AC_CACHE_CHECK(for ll_host in struct lastlog,
ac_cv_struct_lastlog_ll_host,
@ -88,8 +102,9 @@ fi
dnl Checks for library functions.
AC_TYPE_GETGROUPS
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(snprintf strcasecmp strdup strerror strstr)
AC_CHECK_FUNC(setpgrp)
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_RUN_IFELSE([AC_LANG_SOURCE([
#include <shadow.h>
#ifdef HAVE_GSHADOW_H
#include <gshadow.h>
#endif
int
main()
{
struct sgrp *sg = sgetsgent("test:x::");
@ -180,7 +191,7 @@ AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
[Path to passwd program.])
dnl XXX - quick hack, should disappear before anyone notices :).
dnl XXX - I just read the above message :).
AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog().])
if test "$ac_cv_func_ruserok" = "yes"; then
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
@ -215,6 +226,17 @@ AC_ARG_ENABLE(account-tools-setuid,
[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,
[AS_HELP_STRING([--enable-subordinate-ids],
[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 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_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
if test -n "$LIBECONF"; then
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
[Directory for distribution provided configuration files])
ECONF_CPPFLAGS="-DUSE_ECONF=1"
AC_ARG_ENABLE([vendordir],
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
@ -327,9 +349,6 @@ fi
AC_SUBST(ECONF_CPPFLAGS)
AC_SUBST(LIBECONF)
AC_SUBST([VENDORDIR], [$enable_vendordir])
if test "x$enable_vendordir" != x; then
AC_DEFINE(HAVE_VENDORDIR, 1, [Define to support vendor settings.])
fi
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
if test "$enable_shadowgrp" = "yes"; then
@ -382,21 +401,6 @@ AC_SUBST(LIYESCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
[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)
if test "$with_acl" != "no"; then
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])],[])
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.])
AM_GNU_GETTEXT_VERSION([0.19])
@ -746,5 +759,4 @@ echo " sssd support: $with_sssd"
echo " subordinate IDs support: $enable_subids"
echo " use file caps: $with_fcaps"
echo " install su: $with_su"
echo " enabled vendor dir: $enable_vendordir"
echo

View File

@ -2,5 +2,5 @@
# and also cooperate to make a distribution for `make dist'
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

View File

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

308
contrib/pwdauth.c Normal file
View 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

View File

@ -26,6 +26,7 @@ New ideas to add to this list are welcome, too. --marekm
- vipw: check password files for errors after editing
- add "maximum time users allowed to stay logged in" limit option to logoutd
- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
- better utmpx support (logoutd, ...)
- better OPIE support (report number of logins left, etc.)
- new option for /etc/suauth: don't load user's environment (force "su -")
suggested by Ulisses Alonso Camaro

View File

@ -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
```

View File

@ -1,25 +0,0 @@
# Continuous Integration (CI)
Shadow runs a CI workflow every time a pull-request (PR) is updated. This
workflow contains several checks to assure the quality of the project, and
only pull-requests with green results are merged.
## Build & install
The project is built & installed on Ubuntu, Alpine, Debian and Fedora. The last
three distributions are built & installed on containers, and the workflow can
be triggered locally by following the instructions specified in the
[Build & install](build_install.md#containers) page.
## System tests
The project is tested on Ubuntu. For that purpose it is built & installed in
this distribution in a VM. You can run this step locally by following the
instructions provided in the [Tests](tests.md#system-tests) page.
## Static code analysis
C and shell static code analysis is also executed. For that purpose
[CodeQL](https://codeql.github.com/) and
[Differential ShellCheck](https://github.com/marketplace/actions/differential-shellcheck)
are used.

View File

@ -1,12 +0,0 @@
# Coding style
* For a general guidance refer to the
[Linux kernel coding style](https://www.kernel.org/doc/html/latest/process/coding-style.html)
* Patches that change the existing coding style are not welcome, as they make
downstream porting harder for the distributions
## Indentation
Tabs are preferred over spaces for indentation. Loading the `.editorconfig`
file in your preferred IDE may help you configure it.

View File

@ -1,77 +0,0 @@
# Introduction
## Git and Github
We recommend you to get familiar with the
[git](https://guides.github.com/introduction/git-handbook) and
[Github](https://guides.github.com) workflows before posting any changes.
### Set up in a nut shell
The following steps describe the process in a nut shell to provide you a basic
template:
* Create an account on [GitHub](https://github.com)
* Fork the [shadow repository](https://github.com/shadow-maint/shadow)
* Clone the shadow repository
```
git clone https://github.com/shadow-maint/shadow.git
```
* Add your fork as an extra remote
```
git remote add $ghusername git@github.com:$ghusername/shadow.git
```
* Setup your name contact e-mail that you want to use for the development
```
git config user.name "John Smith"
git config user.email "john.smith@home.com"
```
**Note**: this will setup the user information only for this repository. You
can also add `--global` switch to the `git config` command to setup these
options globally and thus making them available in every git repository.
* Create a working branch
```
git checkout -b my-changes
```
* Commit changes
```
vim change-what-you-need
git commit -s
```
Check
[the kernel patches guide](https://www.kernel.org/doc/html/v4.14/process/submitting-patches.html#describe-your-changes)
to get an idea on how to write a good commit message.
* Push your changes to your GitHub repository
```
git push $ghusername my-changes --force
```
* Open a Pull Request against shadow project by clicking on the link provided
in the output of the previous step
* Make sure that all Continuous Integration checks are green and wait review
## Internal guidelines
Additionally, you should also check the following internal guidelines to
understand the project's development model:
* [Build & install](build_install.md)
* [Coding style](coding_style.md)
* [Tests](tests.md)
* [Continuous Integration](CI.md)
* [Releases](releases.md)
* [License](license.md)

View File

@ -1,10 +0,0 @@
# License
All new source code committed to the shadow project is assumed to be made
available under the [BSD-3-Clause](../../COPYING) license unless the submitter
specifies another license at that time. The shadow maintainers reserve the
right to refuse a submission if the license is deemed incompatible with the
goals of the project.
**Note**: old code may be made available under another license, check the
license tag for each file to get additional information.

View File

@ -1,7 +0,0 @@
# Releases
The shadow project doesn't follow any specific timeline to release new software
versions. Usually, they are released when a major milestone is finished.
Released source code, alongside the release notes, are provided in the
[release Github page](https://github.com/shadow-maint/shadow/releases).

View File

@ -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`.
```

View File

@ -159,7 +159,7 @@ ENV_HZ HZ=100
#
# (they are minimal, add the rest in the shell startup files)
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

View File

@ -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

View File

@ -11,7 +11,6 @@ libshadow_la_CPPFLAGS += -DVENDORDIR=\"$(VENDORDIR)\"
endif
libshadow_la_CPPFLAGS += -I$(top_srcdir)
libshadow_la_CFLAGS = $(LIBBSD_CFLAGS)
libshadow_la_SOURCES = \
commonio.c \
@ -66,7 +65,8 @@ libshadow_la_SOURCES = \
shadowio.c \
shadowio.h \
shadowmem.c \
spawn.c
spawn.c \
utent.c
if WITH_TCB
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h

View File

@ -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

View File

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

View File

@ -21,8 +21,6 @@
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include "alloc.h"
#include "nscd.h"
#include "sssd.h"
#ifdef WITH_TCB
@ -253,13 +251,25 @@ static /*@null@*/ /*@dependent@*/FILE *fopen_set_perms (
return NULL;
}
#ifdef HAVE_FCHOWN
if (fchown (fileno (fp), sb->st_uid, sb->st_gid) != 0) {
goto fail;
}
#else /* !HAVE_FCHOWN */
if (chown (name, sb->st_mode) != 0) {
goto fail;
}
#endif /* !HAVE_FCHOWN */
#ifdef HAVE_FCHMOD
if (fchmod (fileno (fp), sb->st_mode & 0664) != 0) {
goto fail;
}
#else /* !HAVE_FCHMOD */
if (chmod (name, sb->st_mode & 0664) != 0) {
goto fail;
}
#endif /* !HAVE_FCHMOD */
return fp;
fail:
@ -364,11 +374,11 @@ int commonio_lock_nowait (struct commonio_db *db, bool log)
}
file_len = strlen(db->filename) + 11;/* %lu max size */
lock_file_len = strlen(db->filename) + 6; /* sizeof ".lock" */
file = MALLOCARRAY(file_len, char);
file = (char*)malloc(file_len);
if (file == NULL) {
goto cleanup_ENOMEM;
}
lock = MALLOCARRAY(lock_file_len, char);
lock = (char*)malloc(lock_file_len);
if (lock == NULL) {
goto cleanup_ENOMEM;
}
@ -608,7 +618,7 @@ int commonio_open (struct commonio_db *db, int mode)
fd = open (db->filename,
(db->readonly ? O_RDONLY : O_RDWR)
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW | O_CLOEXEC);
| O_NOCTTY | O_NONBLOCK | O_NOFOLLOW);
saved_errno = errno;
db->fp = NULL;
if (fd >= 0) {
@ -639,19 +649,22 @@ int commonio_open (struct commonio_db *db, int mode)
return 0;
}
/* Do not inherit fd in spawned processes (e.g. nscd) */
fcntl (fileno (db->fp), F_SETFD, FD_CLOEXEC);
buflen = BUFLEN;
buf = MALLOCARRAY (buflen, char);
buf = (char *) malloc (buflen);
if (NULL == buf) {
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)
&& (feof (db->fp) == 0)) {
size_t len;
buflen += BUFLEN;
cp = REALLOCARRAY (buf, buflen, char);
cp = (char *) realloc (buf, buflen);
if (NULL == cp) {
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) {
goto cleanup_entry;
}
@ -762,7 +775,7 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
return 0;
}
entries = MALLOCARRAY (n, struct commonio_entry *);
entries = malloc (n * sizeof (struct commonio_entry *));
if (entries == NULL) {
return -1;
}
@ -985,11 +998,13 @@ int commonio_close (struct commonio_db *db)
if (fflush (db->fp) != 0) {
errors++;
}
#ifdef HAVE_FSYNC
if (fsync (fileno (db->fp)) != 0) {
errors++;
}
#else /* !HAVE_FSYNC */
sync ();
#endif /* !HAVE_FSYNC */
if (fclose (db->fp) != 0) {
errors++;
}
@ -1081,7 +1096,7 @@ int commonio_update (struct commonio_db *db, const void *eptr)
return 1;
}
/* not found, new entry */
p = MALLOC (struct commonio_entry);
p = (struct commonio_entry *) malloc (sizeof *p);
if (NULL == p) {
db->ops->free (nentry);
errno = ENOMEM;
@ -1118,7 +1133,7 @@ int commonio_append (struct commonio_db *db, const void *eptr)
return 0;
}
/* new entry */
p = MALLOC (struct commonio_entry);
p = (struct commonio_entry *) malloc (sizeof *p);
if (NULL == p) {
db->ops->free (nentry);
errno = ENOMEM;
@ -1185,8 +1200,6 @@ int commonio_remove (struct commonio_db *db, const char *name)
db->ops->free (p->eptr);
}
free(p);
return 1;
}

View File

@ -123,7 +123,6 @@ extern int commonio_setname (struct commonio_db *, const char *);
extern bool commonio_present (const struct commonio_db *db);
extern int commonio_lock (struct commonio_db *);
extern int commonio_lock_nowait (struct commonio_db *, bool log);
extern int do_fcntl_lock (const char *file, bool log, short type);
extern int commonio_open (struct commonio_db *, int);
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
extern int commonio_update (struct commonio_db *, const void *);

View File

@ -6,8 +6,41 @@
#include "config.h"
#include <stdbool.h>
#include <locale.h>
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if ! HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# endif
# endif
# define bool _Bool
# define false (0)
# define true (1)
# define __bool_true_false_are_defined 1
#endif
/* 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_def(String) "#define String" */
@ -24,17 +57,22 @@
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#endif
#endif
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#if HAVE_ERRNO_H
# include <errno.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
/*
* crypt(3), crypt_gensalt(3), and their
@ -47,15 +85,17 @@
#include <sys/time.h>
#include <time.h>
#ifdef HAVE_MEMSET_EXPLICIT
# define memzero(ptr, size) memset_explicit((ptr), 0, (size))
#ifdef HAVE_MEMSET_S
# define memzero(ptr, size) memset_s((ptr), 0, (size))
#elif defined HAVE_EXPLICIT_BZERO /* !HAVE_MEMSET_S */
# define memzero(ptr, size) explicit_bzero((ptr), (size))
#else /* !HAVE_MEMSET_S && HAVE_EXPLICIT_BZERO */
static inline void memzero(void *ptr, size_t size)
{
ptr = memset(ptr, '\0', size);
__asm__ __volatile__ ("" : : "r"(ptr) : "memory");
volatile unsigned char * volatile p = ptr;
while (size--) {
*p++ = '\0';
}
}
#endif /* !HAVE_MEMSET_S && !HAVE_EXPLICIT_BZERO */
@ -83,6 +123,7 @@ static inline void memzero(void *ptr, size_t size)
#endif
#endif
#ifdef USE_SYSLOG
#include <syslog.h>
#ifndef LOG_WARN
@ -129,6 +170,14 @@ static inline void memzero(void *ptr, size_t size)
#define SYSLOG(x) syslog x
#endif /* !ENABLE_NLS */
#else /* !USE_SYSLOG */
#define SYSLOG(x) /* empty */
#define openlog(a,b,c) /* empty */
#define closelog() /* empty */
#endif /* !USE_SYSLOG */
/* The default syslog settings can now be changed here,
in just one place. */
@ -143,10 +192,33 @@ static inline void memzero(void *ptr, size_t size)
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
#include <termios.h>
#define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
#define GTTY(fd, termio) tcgetattr(fd, termio)
#define TERMIO struct termios
#ifndef F_OK
# define F_OK 0
# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#ifndef SEEK_SET
# define SEEK_SET 0
# define SEEK_CUR 1
# define SEEK_END 2
#endif
#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
@ -169,10 +241,6 @@ static inline void memzero(void *ptr, size_t size)
#define SCALE DAY
#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
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... */
@ -199,6 +267,18 @@ static inline void memzero(void *ptr, size_t size)
#endif
#endif
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifdef sun /* hacks for compiling on SunOS */
# ifndef SOLARIS
extern int fputs ();
extern char *strdup ();
extern char *strerror ();
# endif
#endif
/*
* string to use for the pw_passwd field in /etc/passwd when using
* shadow passwords - most systems use "x" but there are a few
@ -223,28 +303,33 @@ static inline void memzero(void *ptr, size_t size)
/* To be used for verified unused parameters */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define unused __attribute__((unused))
# define NORETURN __attribute__((__noreturn__))
# define unused __attribute__((unused))
# define format_attr(type, index, check) __attribute__((format (type, index, check)))
#else
# define unused
# define NORETURN
# define format_attr(type, index, check)
#endif
/* Maximum length of usernames */
#include <utmp.h>
#define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmpx *)NULL)->ut_user))
#else
# include <utmp.h>
# ifdef HAVE_STRUCT_UTMP_UT_USER
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
# else
# ifdef HAVE_STRUCT_UTMP_UT_NAME
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_name))
# else
# define USER_NAME_MAX_LENGTH 32
# endif
# endif
#endif
/* Maximum length of passwd entry */
#define PASSWD_ENTRY_MAX_LENGTH 32768
#if (__GNUC__ >= 11) && !defined(__clang__)
# define ATTR_MALLOC(deallocator) [[gnu::malloc(deallocator)]]
#else
# define ATTR_MALLOC(deallocator)
#endif
#ifdef HAVE_SECURE_GETENV
# define shadow_getenv(name) secure_getenv(name)
# else

View File

@ -21,9 +21,9 @@
*
* The supplied field is scanned for non-printable and other illegal
* characters.
* + -1 is returned if an illegal or control character is present.
* + 1 is returned if no illegal or control characters are present,
* but the field contains a non-printable character.
* + -1 is returned if an illegal character is present.
* + 1 is returned if no illegal characters are present, but the field
* contains a non-printable character.
* + 0 is returned otherwise.
*/
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
* 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++) {
unsigned char c = *cp;
if (!isprint (c)) {
err = 1;
}
if (iscntrl (c)) {
if (strchr (illegal, *cp) != NULL) {
err = -1;
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;
}
@ -73,7 +74,7 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
printf ("\t%s [%s]: ", prompt, buf);
(void) fflush (stdout);
if (fgets (newf, maxsize, stdin) != newf) {
if (fgets (newf, (int) maxsize, stdin) != newf) {
return;
}
@ -90,16 +91,17 @@ void change_field (char *buf, size_t maxsize, const char *prompt)
* entering a space. --marekm
*/
while (newf < cp && isspace (cp[-1])) {
cp--;
}
while (--cp >= newf && isspace (*cp));
cp++;
*cp = '\0';
cp = newf;
while (isspace (*cp)) {
while (('\0' != *cp) && isspace (*cp)) {
cp++;
}
strcpy (buf, cp);
strncpy (buf, cp, maxsize - 1);
buf[maxsize - 1] = '\0';
}
}

View File

@ -25,7 +25,7 @@ int get_gid (const char *gidstr, gid_t *gid)
return 0;
}
*gid = val;
*gid = (gid_t)val;
return 1;
}

View File

@ -10,9 +10,6 @@
#include "prototypes.h"
#include "defines.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
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)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (val < 1)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
return 0;
}
*pid = val;
*pid = (pid_t)val;
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;
}

View File

@ -25,7 +25,7 @@ int get_uid (const char *uidstr, uid_t *uid)
return 0;
}
*uid = val;
*uid = (uid_t)val;
return 1;
}

View File

@ -13,7 +13,6 @@
#include "prototypes.h"
#include "defines.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
@ -21,11 +20,8 @@
#ifdef USE_ECONF
#include <libeconf.h>
#endif
#include "alloc.h"
#include "getdef.h"
#include "shadowlog_internal.h"
/*
* A configuration item definition.
*/
@ -136,8 +132,10 @@ static struct itemdef def_table[] = {
#ifndef USE_PAM
PAMDEFS
#endif
#ifdef USE_SYSLOG
{"SYSLOG_SG_ENAB", NULL},
{"SYSLOG_SU_ENAB", NULL},
#endif
#ifdef WITH_TCB
{"TCB_AUTH_GROUP", NULL},
{"TCB_SYMLINKS", NULL},
@ -195,7 +193,7 @@ static void def_load (void);
}
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 val;
return (int) val;
}
@ -288,7 +286,7 @@ unsigned int getdef_unum (const char *item, unsigned int 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));
out:
return NULL;
return (struct itemdef *) NULL;
}
/*
@ -448,14 +446,14 @@ void setdef_config_file (const char* file)
char* cp;
len = strlen(file) + strlen(sysconfdir) + 2;
cp = MALLOCARRAY(len, char);
cp = malloc(len);
if (cp == NULL)
exit (13);
snprintf(cp, len, "%s/%s", file, sysconfdir);
sysconfdir = cp;
#ifdef VENDORDIR
len = strlen(file) + strlen(vendordir) + 2;
cp = MALLOCARRAY(len, char);
cp = malloc(len);
if (cp == NULL)
exit (13);
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
*/
#ifdef USE_ECONF
static void def_load (void)
{
#ifdef USE_ECONF
econf_file *defs_file = NULL;
econf_err error;
char **keys;
size_t key_number;
#else
int i;
FILE *fp;
char buf[1024], *name, *value, *s;
#endif
/*
* Set the initialized flag.
@ -486,6 +489,8 @@ static void def_load (void)
*/
def_loaded = true;
#ifdef USE_ECONF
error = econf_readDirs (&defs_file, vendordir, sysconfdir, "login", "defs", " \t", "#");
if (error) {
if (error == ECONF_NOFILE)
@ -505,12 +510,7 @@ static void def_load (void)
for (size_t i = 0; i < key_number; i++) {
char *value;
error = 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);
}
econf_getStringValue(defs_file, NULL, keys[i], &value);
/*
* Store the value in def_table.
@ -520,26 +520,11 @@ static void def_load (void)
* syslog. The tools will just use their default values.
*/
(void)putdef_str (keys[i], value);
free(value);
}
econf_free (keys);
econf_free (defs_file);
}
#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;
#else
/*
* Open the configuration definitions file.
*/
@ -557,12 +542,12 @@ static void def_load (void)
/*
* 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.
*/
for (i = (ptrdiff_t) strlen (buf) - 1; i >= 0; --i) {
for (i = (int) strlen (buf) - 1; i >= 0; --i) {
if (!isspace (buf[i])) {
break;
}
@ -603,8 +588,8 @@ static void def_load (void)
}
(void) fclose (fp);
#endif
}
#endif /* USE_ECONF */
#ifdef CKDEFS

View File

@ -15,7 +15,6 @@
#include <assert.h>
#include <stdio.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
@ -51,7 +50,7 @@ static const char *group_getname (const void *ent)
static void *group_parse (const char *line)
{
return sgetgrent (line);
return (void *) sgetgrent (line);
}
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)
{
return commonio_update (&group_db, gr);
return commonio_update (&group_db, (const void *) gr);
}
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 (gr2 = gr1->next; NULL != gr2; gr2 = gr2->next) {
struct group *g1 = gr1->eptr;
struct group *g2 = gr2->eptr;
struct group *g1 = (struct group *)gr1->eptr;
struct group *g2 = (struct group *)gr2->eptr;
if (NULL != g1 &&
NULL != g2 &&
0 == strcmp (g1->gr_name, g2->gr_name) &&
@ -303,8 +302,8 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
return NULL;
}
gptr1 = gr1->eptr;
gptr2 = gr2->eptr;
gptr1 = (struct group *)gr1->eptr;
gptr2 = (struct group *)gr2->eptr;
if (NULL == gptr2 || NULL == gptr1) {
errno = EINVAL;
return NULL;
@ -312,8 +311,9 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
/* Concatenate the 2 lines */
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) {
errno = ENOMEM;
return NULL;
}
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++;
}
}
new_members = CALLOC (members + 1, char *);
new_members = (char **)calloc ( (members+1), sizeof(char*) );
if (NULL == new_members) {
free (new_line);
errno = ENOMEM;
return NULL;
}
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;
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 group *new_gptr;
unsigned int members = 0;
@ -394,8 +395,9 @@ static int split_groups (unsigned int max_members)
continue;
}
new = MALLOC (struct commonio_entry);
new = (struct commonio_entry *) malloc (sizeof *new);
if (NULL == new) {
errno = ENOMEM;
return 0;
}
new->eptr = group_dup(gr->eptr);
@ -404,7 +406,7 @@ static int split_groups (unsigned int max_members)
errno = ENOMEM;
return 0;
}
new_gptr = new->eptr;
new_gptr = (struct group *)new->eptr;
new->line = NULL;
new->changed = true;

View File

@ -12,7 +12,6 @@
#ident "$Id$"
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include "groupio.h"
@ -22,7 +21,7 @@
struct group *gr;
int i;
gr = MALLOC (struct group);
gr = (struct group *) malloc (sizeof *gr);
if (NULL == gr) {
return NULL;
}
@ -47,7 +46,7 @@
for (i = 0; grent->gr_mem[i]; i++);
/*@-mustfreeonly@*/
gr->gr_mem = MALLOCARRAY (i + 1, char *);
gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
/*@=mustfreeonly@*/
if (NULL == gr->gr_mem) {
gr_free(gr);
@ -87,3 +86,33 @@ void gr_free (/*@out@*/ /*@only@*/struct group *grent)
gr_free_members(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;
}

View File

@ -15,12 +15,8 @@
#ident "$Id$"
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
static /*@null@*/FILE *shadow;
static /*@null@*//*@only@*/char **members = NULL;
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') {
size = (nelem + 1) * sizeof (ptr);
ptr = REALLOCARRAY (*list, size, char *);
ptr = realloc (*list, size);
if (NULL != ptr) {
ptr[nelem] = s;
nelem++;
@ -80,7 +76,7 @@ static /*@null@*/char **build_list (char *s, char **list[], size_t * nlist)
}
}
size = (nelem + 1) * sizeof (ptr);
ptr = REALLOCARRAY (*list, size, char *);
ptr = realloc (*list, size);
if (NULL != ptr) {
ptr[nelem] = NULL;
*list = ptr;
@ -106,7 +102,7 @@ void endsgent (void)
(void) fclose (shadow);
}
shadow = NULL;
shadow = (FILE *) 0;
}
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *string)
@ -120,7 +116,7 @@ void endsgent (void)
size_t len = strlen (string) + 1;
if (len > sgrbuflen) {
char *buf = REALLOCARRAY (sgrbuf, len, char);
char *buf = (char *) realloc (sgrbuf, sizeof (char) * len);
if (NULL == buf) {
return NULL;
}
@ -128,7 +124,8 @@ void endsgent (void)
sgrbuflen = len;
}
strcpy (sgrbuf, string);
strncpy (sgrbuf, string, len);
sgrbuf[len-1] = '\0';
cp = strrchr (sgrbuf, '\n');
if (NULL != cp) {
@ -198,7 +195,7 @@ void endsgent (void)
char *cp;
if (0 == buflen) {
buf = MALLOCARRAY (BUFSIZ, char);
buf = (char *) malloc (BUFSIZ);
if (NULL == buf) {
return NULL;
}
@ -210,16 +207,16 @@ void endsgent (void)
}
#ifdef USE_NIS
while (fgetsx (buf, buflen, fp) == buf)
while (fgetsx (buf, (int) buflen, fp) == buf)
#else
if (fgetsx (buf, buflen, fp) == buf)
if (fgetsx (buf, (int) buflen, fp) == buf)
#endif
{
while ( ((cp = strrchr (buf, '\n')) == NULL)
&& (feof (fp) == 0)) {
size_t len;
cp = REALLOCARRAY (buf, buflen * 2, char);
cp = (char *) realloc (buf, buflen*2);
if (NULL == cp) {
return NULL;
}
@ -402,7 +399,7 @@ void endsgent (void)
nis_disabled = true;
}
#endif
while ((sgrp = getsgent ()) != NULL) {
while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
if (strcmp (name, sgrp->sg_name) == 0) {
break;
}
@ -440,7 +437,7 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
size += strlen (sgrp->sg_mem[i]) + 1;
}
buf = MALLOCARRAY (size, char);
buf = malloc (size);
if (NULL == buf) {
return -1;
}
@ -505,5 +502,5 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
return 0;
}
#else
extern int ISO_C_forbids_an_empty_translation_unit;
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /*} SHADOWGRP */

View File

@ -81,5 +81,5 @@ int ulckpwdf (void)
return (pw_unlock () && spw_unlock ())? 0 : -1;
}
#else
extern int ISO_C_forbids_an_empty_translation_unit;
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

View File

@ -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

View File

@ -53,6 +53,6 @@ int nscd_flush_cache (const char *service)
return 0;
}
#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 */

View File

@ -6,8 +6,6 @@
#include <strings.h>
#include <ctype.h>
#include <stdatomic.h>
#include "alloc.h"
#include "prototypes.h"
#include "../libsubid/subid.h"
#include "shadowlog_internal.h"
@ -61,9 +59,6 @@ void nss_init(const char *nsswitch_path) {
// subid: files
nssfp = fopen(nsswitch_path, "r");
if (!nssfp) {
if (errno != ENOENT)
fprintf(shadow_logfd, "Failed opening %s: %m\n", nsswitch_path);
atomic_store(&nss_init_completed, true);
return;
}
@ -102,7 +97,7 @@ void nss_init(const char *nsswitch_path) {
subid_nss = NULL;
goto done;
}
subid_nss = MALLOC(struct subid_nss_ops);
subid_nss = malloc(sizeof(*subid_nss));
if (!subid_nss) {
dlclose(h);
goto done;

View File

@ -15,7 +15,7 @@
#endif
static const struct pam_conv conv = {
static struct pam_conv conv = {
SHADOW_PAM_CONVERSATION,
NULL
};

View File

@ -79,7 +79,7 @@ static void endportent (void)
(void) fclose (ports);
}
ports = NULL;
ports = (FILE *) 0;
}
/*
@ -130,11 +130,11 @@ static struct port *getportent (void)
again:
/*
* Get the next line and remove optional trailing '\n'.
* Lines which begin with '#' are all ignored.
* Get the next line and remove the last character, which
* 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;
return 0;
}
@ -149,7 +149,7 @@ static struct port *getportent (void)
* TTY devices.
*/
buf[strcspn (buf, "\n")] = 0;
buf[strlen (buf) - 1] = 0;
port.pt_names = ttys;
for (cp = buf, j = 0; j < PORT_TTY; j++) {
@ -172,13 +172,13 @@ static struct port *getportent (void)
}
*cp = '\0';
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
* separated field, and is a comma separated list of user
* 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) {

View File

@ -21,9 +21,12 @@
#include <config.h>
#include <sys/socket.h>
#include <sys/stat.h>
#ifdef USE_UTMPX
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
@ -41,12 +44,6 @@ extern int add_groups (const char *);
/* age.c */
extern void agecheck (/*@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 */
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 */
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 */
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 void gr_free_members (struct group *grent);
extern void gr_free (/*@out@*/ /*@only@*/struct group *grent);
extern bool gr_append_member (struct group *grp, char *member);
/* hushed.c */
extern bool hushed (const char *username);
@ -233,7 +229,7 @@ extern void dolastlog (
extern int login_access (const char *user, const char *from);
/* loginprompt.c */
extern void login_prompt (char *, int);
extern void login_prompt (const char *, char *, int);
/* mail.c */
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 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 */
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 */
#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);
#endif
@ -469,16 +460,30 @@ extern int set_filesize_limit (int blocks);
extern int user_busy (const char *name, uid_t uid);
/* utmp.c */
#ifndef USE_UTMPX
extern /*@null@*/struct utmp *get_current_utmp (void);
extern struct utmp *prepare_utmp (const char *name,
const char *line,
const char *host,
/*@null@*/const 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 */
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 */
extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
/* xgetpwuid.c */

View File

@ -207,5 +207,5 @@ int pw_auth (const char *cipher,
return retval;
}
#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 */

View File

@ -42,7 +42,7 @@ static const char *passwd_getname (const void *ent)
static void *passwd_parse (const char *line)
{
return sgetpwent (line);
return (void *) sgetpwent (line);
}
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)
{
return commonio_update (&passwd_db, pw);
return commonio_update (&passwd_db, (const void *) pw);
}
int pw_remove (const char *name)

View File

@ -13,8 +13,6 @@
#ident "$Id$"
#include <stdio.h>
#include "alloc.h"
#include "defines.h"
#include "prototypes.h"
#include "pwio.h"
@ -23,11 +21,12 @@
{
struct passwd *pw;
pw = CALLOC (1, struct passwd);
pw = (struct passwd *) malloc (sizeof *pw);
if (NULL == pw) {
return NULL;
}
/* The libc might define other fields. They won't be copied. */
memset (pw, 0, sizeof *pw);
pw->pw_uid = pwent->pw_uid;
pw->pw_gid = pwent->pw_gid;
/*@-mustfreeonly@*/

View File

@ -8,8 +8,6 @@
#include <sys/wait.h>
#include <unistd.h>
#include <lib/prototypes.h>
#include "alloc.h"
#include "run_part.h"
#include "shadowlog_internal.h"
@ -59,7 +57,7 @@ int run_parts (const char *directory, const char *name, const char *action)
struct stat sb;
path_length=strlen(directory) + strlen(namelist[n]->d_name) + 2;
char *s = MALLOCARRAY(path_length, char);
char *s = (char*)malloc(path_length);
if (!s) {
printf ("could not allocate memory\n");
for (; n<scanlist; n++) {

View File

@ -188,7 +188,7 @@ int check_selinux_permit (const char *perm_name)
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) {
fprintf (shadow_logfd,
@ -206,5 +206,5 @@ int check_selinux_permit (const char *perm_name)
}
#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 */

View File

@ -22,6 +22,10 @@
#include "shadowlog_internal.h"
#ifndef DEFAULT_SERANGE
#define DEFAULT_SERANGE "s0"
#endif
format_attr(printf, 3, 4)
static void semanage_error_callback (unused void *varg,
@ -97,8 +101,6 @@ static semanage_handle_t *semanage_init (void)
return handle;
fail:
if (handle)
semanage_disconnect (handle);
semanage_handle_destroy (handle);
return NULL;
}
@ -107,8 +109,7 @@ fail:
static int semanage_user_mod (semanage_handle_t *handle,
semanage_seuser_key_t *key,
const char *login_name,
const char *seuser_name,
const char *serange)
const char *seuser_name)
{
int ret;
semanage_seuser_t *seuser = NULL;
@ -121,12 +122,11 @@ static int semanage_user_mod (semanage_handle_t *handle,
goto done;
}
if (serange && semanage_mls_enabled(handle)) {
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
if (semanage_mls_enabled(handle)) {
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
if (ret != 0) {
fprintf (shadow_logfd,
_("Could not set serange for %s to %s\n"),
login_name, serange);
_("Could not set serange for %s\n"), login_name);
ret = 1;
goto done;
}
@ -158,10 +158,9 @@ done:
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 *seuser_name,
const char *serange)
const char *seuser_name)
{
int ret;
semanage_seuser_t *seuser = NULL;
@ -182,12 +181,11 @@ static int semanage_user_add (semanage_handle_t *handle,
goto done;
}
if (serange && semanage_mls_enabled(handle)) {
ret = semanage_seuser_set_mlsrange (handle, seuser, serange);
if (semanage_mls_enabled(handle)) {
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
if (ret != 0) {
fprintf (shadow_logfd,
_("Could not set serange for %s to %s\n"),
login_name, serange);
_("Could not set serange for %s\n"), login_name);
ret = 1;
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_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) {
ret = semanage_user_mod (handle, key, login_name, seuser_name, serange);
ret = semanage_user_mod (handle, key, login_name, seuser_name);
if (ret != 0) {
fprintf (shadow_logfd,
_("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;
}
} 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) {
fprintf (shadow_logfd,
_("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:
semanage_seuser_key_free (key);
if (handle)
semanage_disconnect (handle);
semanage_handle_destroy (handle);
return ret;
}
@ -357,12 +353,9 @@ int del_seuser (const char *login_name)
ret = 0;
done:
semanage_seuser_key_free (key);
if (handle)
semanage_disconnect (handle);
semanage_handle_destroy (handle);
return ret;
}
#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 */

View File

@ -14,8 +14,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
#include "alloc.h"
#include "defines.h"
#include "prototypes.h"
@ -36,9 +34,10 @@
*/
static char **list (char *s)
{
static char **members = NULL;
static char **members = 0;
static int size = 0; /* max members + 1 */
int i;
char **rbuf;
i = 0;
for (;;) {
@ -46,9 +45,21 @@ static char **list (char *s)
member name, or terminating NULL). */
if (i >= size) {
size = i + 100; /* at least: i + 1 */
members = REALLOCARRAYF(members, size, char *);
if (!members)
return NULL;
if (members) {
rbuf =
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')
break;
@ -60,14 +71,14 @@ static char **list (char *s)
*s++ = '\0';
}
}
members[i] = NULL;
members[i] = (char *) 0;
return members;
}
struct group *sgetgrent (const char *buf)
{
static char *grpbuf = NULL;
static char *grpbuf = 0;
static size_t size = 0;
static char *grpfields[NFIELDS];
static struct group grent;
@ -79,10 +90,10 @@ struct group *sgetgrent (const char *buf)
allocate a larger block */
free (grpbuf);
size = strlen (buf) + 1000; /* at least: strlen(buf) + 1 */
grpbuf = MALLOCARRAY (size, char);
if (grpbuf == NULL) {
grpbuf = malloc (size);
if (!grpbuf) {
size = 0;
return NULL;
return 0;
}
}
strcpy (grpbuf, buf);
@ -101,16 +112,16 @@ struct group *sgetgrent (const char *buf)
}
}
if (i < (NFIELDS - 1) || *grpfields[2] == '\0' || cp != NULL) {
return NULL;
return (struct group *) 0;
}
grent.gr_name = grpfields[0];
grent.gr_passwd = grpfields[1];
if (get_gid (grpfields[2], &grent.gr_gid) == 0) {
return NULL;
return (struct group *) 0;
}
grent.gr_mem = list (grpfields[3]);
if (NULL == grent.gr_mem) {
return NULL; /* out of memory */
return (struct group *) 0; /* out of memory */
}
return &grent;

View File

@ -182,6 +182,6 @@ struct spwd *sgetspent (const char *string)
return (&spwd);
}
#else
extern int ISO_C_forbids_an_empty_translation_unit;
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

View File

@ -14,7 +14,6 @@
#ident "$Id$"
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
@ -26,12 +25,13 @@
struct sgrp *sg;
int i;
sg = CALLOC (1, struct sgrp);
sg = (struct sgrp *) malloc (sizeof *sg);
if (NULL == sg) {
return NULL;
}
/* Do the same as the other _dup function, even if we know the
* structure. */
memset (sg, 0, sizeof *sg);
/*@-mustfreeonly@*/
sg->sg_name = strdup (sgent->sg_name);
/*@=mustfreeonly@*/
@ -50,7 +50,7 @@
for (i = 0; NULL != sgent->sg_adm[i]; i++);
/*@-mustfreeonly@*/
sg->sg_adm = MALLOCARRAY (i + 1, char *);
sg->sg_adm = (char **) malloc ((i + 1) * sizeof (char *));
/*@=mustfreeonly@*/
if (NULL == sg->sg_adm) {
free (sg->sg_passwd);
@ -75,7 +75,7 @@
for (i = 0; NULL != sgent->sg_mem[i]; i++);
/*@-mustfreeonly@*/
sg->sg_mem = MALLOCARRAY (i + 1, char *);
sg->sg_mem = (char **) malloc ((i + 1) * sizeof (char *));
/*@=mustfreeonly@*/
if (NULL == sg->sg_mem) {
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)
{
return sgetsgent (line);
return (void *) sgetsgent (line);
}
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)
{
return commonio_update (&gshadow_db, sg);
return commonio_update (&gshadow_db, (const void *) sg);
}
int sgr_remove (const char *name)
@ -302,5 +302,5 @@ int sgr_sort ()
return commonio_sort_wrt (&gshadow_db, __gr_get_db ());
}
#else
extern int ISO_C_forbids_an_empty_translation_unit;
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

View File

@ -94,7 +94,7 @@ void endspent (void)
(void) fclose (shadow);
}
shadow = NULL;
shadow = (FILE *) 0;
}
/*
@ -336,9 +336,9 @@ struct spwd *fgetspent (FILE * fp)
}
#ifdef USE_NIS
while (fgets (buf, sizeof buf, fp) != NULL)
while (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
#else
if (fgets (buf, sizeof buf, fp) != NULL)
if (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
#endif
{
cp = strchr (buf, '\n');
@ -511,7 +511,7 @@ struct spwd *getspnam (const char *name)
nis_disabled = true;
}
#endif
while ((sp = getspent ()) != NULL) {
while ((sp = getspent ()) != (struct spwd *) 0) {
if (strcmp (name, sp->sp_namp) == 0) {
break;
}
@ -525,6 +525,6 @@ struct spwd *getspnam (const char *name)
return (sp);
}
#else
extern int ISO_C_forbids_an_empty_translation_unit;
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

View File

@ -47,7 +47,7 @@ static const char *shadow_getname (const void *ent)
static void *shadow_parse (const char *line)
{
return sgetspent (line);
return (void *) sgetspent (line);
}
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)
{
return commonio_update (&shadow_db, sp);
return commonio_update (&shadow_db, (const void *) sp);
}
int spw_remove (const char *name)

View File

@ -2,6 +2,6 @@
#define _SHADOWLOG_INTERNAL_H
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 */

View File

@ -16,19 +16,18 @@
#include "defines.h"
#include <shadow.h>
#include <stdio.h>
#include "alloc.h"
#include "shadowio.h"
/*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent)
{
struct spwd *sp;
sp = CALLOC (1, struct spwd);
sp = (struct spwd *) malloc (sizeof *sp);
if (NULL == sp) {
return NULL;
}
/* The libc might define other fields. They won't be copied. */
memset (sp, 0, sizeof *sp);
sp->sp_lstchg = spent->sp_lstchg;
sp->sp_min = spent->sp_min;
sp->sp_max = spent->sp_max;

View File

@ -4,11 +4,8 @@
#ifdef USE_SSSD
#include <stdio.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "alloc.h"
#include "exitcodes.h"
#include "defines.h"
#include "prototypes.h"
@ -22,17 +19,12 @@ int sssd_flush_cache (int dbflags)
{
int status, code, rv;
const char *cmd = "/usr/sbin/sss_cache";
struct stat sb;
char *sss_cache_args = NULL;
const char *spawnedArgs[] = {"sss_cache", NULL, NULL};
const char *spawnedEnv[] = {NULL};
int i = 0;
rv = stat(cmd, &sb);
if (rv == -1 && errno == ENOENT)
return 0;
sss_cache_args = MALLOCARRAY(4, char);
sss_cache_args = malloc(4);
if (sss_cache_args == NULL) {
return -1;
}
@ -78,6 +70,6 @@ int sssd_flush_cache (int dbflags)
return 0;
}
#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 */

View File

@ -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

View File

@ -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

View File

@ -17,8 +17,6 @@
#include <ctype.h>
#include <fcntl.h>
#include "alloc.h"
#define ID_SIZE 31
/*
@ -34,7 +32,7 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
const struct subordinate_range *rangeent = ent;
struct subordinate_range *range;
range = MALLOC (struct subordinate_range);
range = (struct subordinate_range *) malloc (sizeof *range);
if (NULL == range) {
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)
{
if (!*ranges) {
*ranges = MALLOC(struct subid_range);
*ranges = malloc(sizeof(struct subid_range));
if (!*ranges)
return false;
} else {
struct subid_range *alloced;
alloced = REALLOCARRAY(*ranges, n + 1, struct subid_range);
alloced = realloc(*ranges, (n + 1) * (sizeof(struct subid_range)));
if (!alloced)
return false;
*ranges = alloced;
@ -357,15 +355,14 @@ static int subordinate_range_cmp (const void *p1, const void *p2)
{
struct subordinate_range *range1, *range2;
range1 = (*(struct commonio_entry **) p1)->eptr;
if (range1 == NULL)
if ((*(struct commonio_entry **) p1)->eptr == NULL)
return 1;
range2 = (*(struct commonio_entry **) p2)->eptr;
if (range2 == NULL)
if ((*(struct commonio_entry **) p2)->eptr == NULL)
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)
return -1;
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);
}
/*
* 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)
{
if (get_subid_nss_handle()) {
errno = EOPNOTSUPP;
return 0;
}
if (get_subid_nss_handle())
return -EOPNOTSUPP;
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)
{
if (get_subid_nss_handle()) {
errno = EOPNOTSUPP;
return 0;
}
if (get_subid_nss_handle())
return -EOPNOTSUPP;
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);
}
/*
* 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)
{
if (get_subid_nss_handle()) {
errno = EOPNOTSUPP;
return 0;
}
if (get_subid_nss_handle())
return -EOPNOTSUPP;
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)
{
if (get_subid_nss_handle()) {
errno = EOPNOTSUPP;
return 0;
}
if (get_subid_nss_handle())
return -EOPNOTSUPP;
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;
}
ret = REALLOCARRAY(*uids, n + 1, uid_t);
ret = realloc(*uids, (n + 1) * sizeof(uid_t));
if (!ret) {
free(*uids);
return -1;
@ -1010,7 +985,7 @@ bool new_subid_range(struct subordinate_range *range, enum subid_type id_type, b
switch (id_type) {
case ID_TYPE_UID:
if (!sub_uid_lock()) {
printf("Failed locking subuids (errno %d)\n", errno);
printf("Failed loging subuids (errno %d)\n", errno);
return false;
}
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;
case ID_TYPE_GID:
if (!sub_gid_lock()) {
printf("Failed locking subgids (errno %d)\n", errno);
printf("Failed loging subgids (errno %d)\n", errno);
return false;
}
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) {
case ID_TYPE_UID:
if (!sub_uid_lock()) {
printf("Failed locking subuids (errno %d)\n", errno);
printf("Failed loging subuids (errno %d)\n", errno);
return false;
}
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;
case ID_TYPE_GID:
if (!sub_gid_lock()) {
printf("Failed locking subgids (errno %d)\n", errno);
printf("Failed loging subgids (errno %d)\n", errno);
return false;
}
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 */
extern int ISO_C_forbids_an_empty_translation_unit;
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !ENABLE_SUBIDS */

View File

@ -141,7 +141,7 @@ static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
shadow_progname, link);
return NULL;
}
link[ret] = '\0';
link[(size_t)ret] = '\0';
rval = strdup (link);
if (NULL == rval) {
OUT_OF_MEMORY;

70
lib/utent.c Normal file
View 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

View File

@ -5,15 +5,11 @@ AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) $(ECONF_CPPFLAGS)
noinst_LTLIBRARIES = libmisc.la
libmisc_la_CFLAGS = $(LIBBSD_CFLAGS)
libmisc_la_SOURCES = \
addgrps.c \
age.c \
agetpass.c \
alloc.c \
audit_help.c \
basename.c \
bit.c \
chkname.c \
chkname.h \
chowndir.c \
@ -45,7 +41,6 @@ libmisc_la_SOURCES = \
list.c log.c \
loginprompt.c \
mail.c \
mempcpy.c \
motd.c \
myname.c \
obscure.c \
@ -55,7 +50,6 @@ libmisc_la_SOURCES = \
pwd2spwd.c \
pwdcheck.c \
pwd_init.c \
csrand.c \
remove_tree.c \
rlogin.c \
root_flag.c \
@ -63,8 +57,6 @@ libmisc_la_SOURCES = \
setugid.c \
setupenv.c \
shell.c \
stpecpy.c \
stpeprintf.c \
strtoday.c \
sub.c \
sulog.c \
@ -79,6 +71,7 @@ libmisc_la_SOURCES = \
xgetgrnam.c \
xgetgrgid.c \
xgetspnam.c \
xmalloc.c \
yesno.c
if WITH_BTRFS

View File

@ -17,8 +17,6 @@
#include <stdio.h>
#include <grp.h>
#include <errno.h>
#include "alloc.h"
#include "shadowlog.h"
#ident "$Id$"
@ -31,7 +29,7 @@
*/
int add_groups (const char *list)
{
GETGROUPS_T *grouplist;
GETGROUPS_T *grouplist, *tmp;
size_t i;
int ngroups;
bool added;
@ -48,7 +46,7 @@ int add_groups (const char *list)
i = 16;
for (;;) {
grouplist = MALLOCARRAY (i, GETGROUPS_T);
grouplist = (gid_t *) malloc (i * sizeof (GETGROUPS_T));
if (NULL == grouplist) {
return -1;
}
@ -90,17 +88,19 @@ int add_groups (const char *list)
fputs (_("Warning: too many groups\n"), shadow_logfd);
break;
}
grouplist = REALLOCARRAYF(grouplist, (size_t) ngroups + 1, GETGROUPS_T);
if (grouplist == NULL) {
tmp = (gid_t *) realloc (grouplist, (size_t)(ngroups + 1) * sizeof (GETGROUPS_T));
if (NULL == tmp) {
free (grouplist);
return -1;
}
grouplist[ngroups] = grp->gr_gid;
tmp[ngroups] = grp->gr_gid;
ngroups++;
grouplist = tmp;
added = true;
}
if (added) {
ret = setgroups (ngroups, grouplist);
ret = setgroups ((size_t)ngroups, grouplist);
free (grouplist);
return ret;
}
@ -109,6 +109,6 @@ int add_groups (const char *list)
return 0;
}
#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 */

View File

@ -112,7 +112,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
_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;
perror ("Can't execute " PASSWD_PROGRAM);
_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)
{
long now = time(NULL) / SCALE;
long now = (long) time ((time_t *) 0) / SCALE;
long remain;
if (NULL == sp) {

View File

@ -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);
}

View File

@ -62,7 +62,7 @@ void audit_logger (int type, unused const char *pgname, const char *op,
return;
} else {
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, /* addr */
NULL, /* tty */
result);
(int) result);
}
}
#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 */

View File

@ -21,10 +21,6 @@
#include "prototypes.h"
/*@observer@*/const char *Basename (const char *str)
{
if (str == NULL) {
abort ();
}
char *cp = strrchr (str, '/');
return (NULL != cp) ? cp + 1 : str;

View File

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

View File

@ -51,7 +51,7 @@ void chown_tty (const struct passwd *info)
*/
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;
FILE *shadow_logfd = log_get_logfd();

View File

@ -22,7 +22,7 @@
*/
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));
#ifdef WITH_AUDIT
@ -40,7 +40,7 @@ void cleanup_report_add_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));
#ifdef WITH_AUDIT
@ -95,7 +95,7 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
*/
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 ()));
#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)
{
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 ()));
#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)
{
const char *name = group_name;
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR,
"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)
{
const char *name = group_name;
const char *name = (const char *)group_name;
SYSLOG ((LOG_ERR,
"failed to remove group %s from %s",

View File

@ -16,13 +16,13 @@
#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)
{
const char *name = user_name;
const char *name = (const char *)user_name;
SYSLOG ((LOG_ERR, "failed to add user %s", name));
#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
*
* 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.
*/
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 ()));
#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
*
* 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.
*/
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 ()));
#ifdef WITH_AUDIT

View File

@ -44,7 +44,8 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
if (*cons != '/') {
char *pbuf;
strlcpy (buf, cons, sizeof (buf));
strncpy (buf, cons, sizeof (buf));
buf[sizeof (buf) - 1] = '\0';
pbuf = &buf[0];
while ((s = strtok (pbuf, ":")) != NULL) {
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.
*/
while (fgets (buf, sizeof (buf), fp) != NULL) {
/* Remove optional trailing '\n'. */
buf[strcspn (buf, "\n")] = '\0';
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
buf[strlen (buf) - 1] = '\0';
if (strcmp (buf, tty) == 0) {
(void) fclose (fp);
return true;

View File

@ -17,8 +17,6 @@
#include <sys/time.h>
#include <fcntl.h>
#include <stdio.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#ifdef WITH_SELINUX
@ -228,7 +226,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
return NULL;
}
lp = XMALLOC (struct link_name);
lp = (struct link_name *) xmalloc (sizeof *lp);
src_len = strlen (src_orig);
dst_len = strlen (dst_orig);
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_count = sb->st_nlink;
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);
lp->ln_next = links;
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);
dst_len += strlen (dst->full_path);
src_name = MALLOCARRAY (src_len, char);
dst_name = MALLOCARRAY (dst_len, char);
src_name = (char *) malloc (src_len);
dst_name = (char *) malloc (dst_len);
if ((NULL == src_name) || (NULL == dst_name)) {
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 we cannot stat the file, do not care. */
} else {
#ifdef HAVE_STRUCT_STAT_ST_ATIM
mt[0].tv_sec = sb.st_atim.tv_sec;
mt[0].tv_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_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)) {
err = copy_dir (src, dst, reset_selinux, &sb, mt,
old_uid, new_uid, old_gid, new_gid);
}
/*
* If the destination already exists do nothing.
* This is after the copy_dir above to still iterate into subdirectories.
*/
if (fstatat(dst->dirfd, dst->name, &sb, AT_SYMLINK_NOFOLLOW) != -1) {
return 0;
}
/*
* 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)
{
int err = 0;
struct stat dst_sb;
/*
* 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;
}
#endif /* WITH_SELINUX */
/*
* If the destination is already a directory, don't change it
* but copy into it (recursively).
*/
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
return (copy_tree_impl (src, dst, false, reset_selinux,
old_uid, new_uid, old_gid, new_gid) != 0);
}
if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0)
|| (chownat_if_needed (dst, statp,
old_uid, new_uid, old_gid, new_gid) != 0)
@ -561,7 +559,7 @@ static /*@null@*/char *readlink_malloc (const char *filename)
while (true) {
ssize_t nchars;
char *buffer = MALLOCARRAY (size, char);
char *buffer = (char *) malloc (size);
if (NULL == buffer) {
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) {
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",
dst_orig,
oldlink + strlen (src_orig));
@ -770,7 +768,7 @@ static ssize_t full_write(int fd, const void *buf, size_t count) {
written += res;
buf = (const unsigned char*)buf + res;
count -= res;
count -= (size_t)res;
}
return written;
@ -852,7 +850,7 @@ static int copy_file (const struct path_info *src, const struct path_info *dst,
break;
}
if (full_write (ofd, buf, cnt) < 0) {
if (full_write (ofd, buf, (size_t)cnt) < 0) {
(void) close (ofd);
(void) close (ifd);
return -1;

View File

@ -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;
}

View File

@ -33,24 +33,14 @@
#include "prototypes.h"
void
date_to_str(size_t size, char buf[size], long date)
void date_to_str (size_t size, char buf[size], long date)
{
time_t t;
const struct tm *tm;
time_t t;
t = date;
if (date < 0) {
(void) strlcpy(buf, "never", size);
return;
}
tm = gmtime(&t);
if (tm == NULL) {
(void) strlcpy(buf, "future", size);
return;
}
(void) strftime(buf, size, "%Y-%m-%d", tm);
if (date < 0)
(void) strncpy (buf, "never", size);
else
(void) strftime (buf, size, "%Y-%m-%d", gmtime (&t));
buf[size - 1] = '\0';
}

View File

@ -13,8 +13,6 @@
#include <sys/types.h>
#include <stdio.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
@ -26,7 +24,7 @@ void pw_entry (const char *name, struct passwd *pwent)
struct spwd *spwd;
if (!(passwd = getpwnam (name))) { /* local, no need for xgetpwnam */
pwent->pw_name = NULL;
pwent->pw_name = (char *) 0;
return;
} else {
pwent->pw_name = xstrdup (passwd->pw_name);

View File

@ -15,8 +15,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
#include "shadowlog.h"
@ -28,6 +26,7 @@
#define NEWENVP_STEP 16
size_t newenvc = 0;
/*@null@*/char **newenvp = NULL;
extern char **environ;
static const char *const forbid[] = {
"_RLD_=",
@ -43,7 +42,7 @@ static const char *const forbid[] = {
"PATH=",
"SHELL=",
"SHLIB_PATH=",
NULL
(char *) 0
};
/* these are allowed, but with no slashes inside
@ -52,7 +51,7 @@ static const char *const noslash[] = {
"LANG=",
"LANGUAGE=",
"LC_", /* anything with the LC_ prefix */
NULL
(char *) 0
};
/*
@ -60,7 +59,7 @@ static const char *const noslash[] = {
*/
void initenv (void)
{
newenvp = XMALLOCARRAY (NEWENVP_STEP, char *);
newenvp = (char **) xmalloc (NEWENVP_STEP * sizeof (char *));
*newenvp = NULL;
}
@ -74,7 +73,7 @@ void addenv (const char *string, /*@null@*/const char *value)
if (NULL != value) {
size_t len = strlen (string) + strlen (value) + 2;
int wlen;
newstring = XMALLOCARRAY (len, char);
newstring = xmalloc (len);
wlen = snprintf (newstring, len, "%s=%s", string, value);
assert (wlen == (int) len -1);
} else {
@ -128,16 +127,16 @@ void addenv (const char *string, /*@null@*/const char *value)
*/
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
bool update_environ;
char **__newenvp;
char **__newenvp;
size_t newsize;
/*
* If the resize operation succeeds we can
* 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) {
/*
@ -145,8 +144,9 @@ void addenv (const char *string, /*@null@*/const char *value)
* environ so that it doesn't point to some
* free memory area (realloc() could move it).
*/
if (update_environ)
if (environ == newenvp) {
environ = __newenvp;
}
newenvp = __newenvp;
} else {
(void) fputs (_("Environment overflow\n"), log_get_logfd());

View File

@ -53,7 +53,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
*/
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
* 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)
|| (write (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)
|| (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't write faillog entry for UID %lu in %s.",
@ -163,7 +163,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
*/
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);
return 1;
}
@ -185,7 +185,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
fail.fail_cnt = 0;
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|| (write (fd, &fail, sizeof fail) != (ssize_t) sizeof fail)
|| (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail)
|| (close (fd) != 0)) {
SYSLOG ((LOG_WARN,
"Can't reset faillog entry for UID %lu in %s.",
@ -242,7 +242,13 @@ void failprint (const struct faillog *fail)
* 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;
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.
*/
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)) {
SYSLOG ((LOG_WARN,
"Can't append failure of user %s to %s.",

View File

@ -13,7 +13,11 @@
#include "defines.h"
#include "faillog.h"
#ifdef USE_UTMPX
#include <utmpx.h>
#else /* !USE_UTMPX */
#include <utmp.h>
#endif /* !USE_UTMPX */
/*
* failure - make failure entry
@ -47,7 +51,11 @@ extern void failprint (const struct faillog *);
* failtmp updates the (struct utmp) formatted failure log which
* 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 *);
#endif /* !USE_UTMPX */
#endif

View File

@ -12,7 +12,6 @@
#include <stdio.h>
#include <errno.h>
#include "alloc.h"
#include "prototypes.h"
#include "groupio.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;
/* 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
* less than the GID_MIN (which is reserved for non-system accounts)
*/
gid_def_max = getdef_ulong ("GID_MIN", 1000UL) - 1;
*max_id = getdef_ulong ("SYS_GID_MAX", gid_def_max);
gid_def_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1;
*max_id = (gid_t) getdef_ulong ("SYS_GID_MAX",
(unsigned long) gid_def_max);
/* Check that the ranges make sense */
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 */
/* Get the values from login.defs or use reasonable defaults */
*min_id = getdef_ulong ("GID_MIN", 1000UL);
*max_id = getdef_ulong ("GID_MAX", 60000UL);
*min_id = (gid_t) getdef_ulong ("GID_MIN", 1000UL);
*max_id = (gid_t) getdef_ulong ("GID_MAX", 60000UL);
/*
* 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
* If the ID is in use, return EEXIST
* If the ID might clash with -1, return EINVAL
* If the ID is outside the range, return ERANGE
* In other cases, return errno from getgrgid()
*/
@ -113,11 +112,6 @@ static int check_gid (const gid_t gid,
return ERANGE;
}
/* Check for compatibility with 16b and 32b gid_t error codes */
if (gid == UINT16_MAX || gid == UINT32_MAX) {
return EINVAL;
}
/*
* Check whether we already detected this GID
* using the gr_next() loop
@ -189,10 +183,10 @@ int find_new_gid (bool sys_group,
* gr_locate_gid() found the GID in an as-yet uncommitted
* entry. We'll proceed below and auto-set a GID.
*/
} else if (result == EEXIST || result == ERANGE || result == EINVAL) {
} else if (result == EEXIST || result == ERANGE) {
/*
* Continue on below. At this time, we won't
* treat these three cases differently.
* treat these two cases differently.
*/
} else {
/*
@ -232,13 +226,14 @@ int find_new_gid (bool sys_group,
*/
/* 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) {
fprintf (log_get_logfd(),
_("%s: failed to allocate memory: %s\n"),
log_get_progname(), strerror (errno));
return -1;
}
memset (used_gids, false, sizeof (bool) * (gid_max + 1));
/* First look for the lowest and highest value in the local database */
(void) gr_rewind ();
@ -302,11 +297,8 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.
@ -348,11 +340,8 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.
@ -411,11 +400,8 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.
@ -457,11 +443,8 @@ int find_new_gid (bool sys_group,
*gid = id;
free (used_gids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This GID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.

View File

@ -59,6 +59,6 @@ int find_new_sub_gids (gid_t *range_start, unsigned long *range_count)
return 0;
}
#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 */

View File

@ -59,6 +59,6 @@ int find_new_sub_uids (uid_t *range_start, unsigned long *range_count)
return 0;
}
#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 */

View File

@ -12,7 +12,6 @@
#include <stdio.h>
#include <errno.h>
#include "alloc.h"
#include "prototypes.h"
#include "pwio.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;
/* 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
* less than the UID_MIN (which is reserved for non-system accounts)
*/
uid_def_max = getdef_ulong ("UID_MIN", 1000UL) - 1;
*max_id = getdef_ulong ("SYS_UID_MAX", uid_def_max);
uid_def_max = (uid_t) getdef_ulong ("UID_MIN", 1000UL) - 1;
*max_id = (uid_t) getdef_ulong ("SYS_UID_MAX",
(unsigned long) uid_def_max);
/* Check that the ranges make sense */
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 */
/* Get the values from login.defs or use reasonable defaults */
*min_id = getdef_ulong ("UID_MIN", 1000UL);
*max_id = getdef_ulong ("UID_MAX", 60000UL);
*min_id = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
*max_id = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
/*
* 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
* If the ID is in use, return EEXIST
* If the ID might clash with -1, return EINVAL
* If the ID is outside the range, return ERANGE
* In other cases, return errno from getpwuid()
*/
@ -113,11 +112,6 @@ static int check_uid(const uid_t uid,
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
* 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
* 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
* treat these three cases differently.
* treat these two cases differently.
*/
} else {
/*
@ -232,7 +226,7 @@ int find_new_uid(bool sys_user,
*/
/* 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) {
fprintf (log_get_logfd(),
_("%s: failed to allocate memory: %s\n"),
@ -303,11 +297,8 @@ int find_new_uid(bool sys_user,
*uid = id;
free (used_uids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This UID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.
@ -349,11 +340,8 @@ int find_new_uid(bool sys_user,
*uid = id;
free (used_uids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This UID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.
@ -412,11 +400,8 @@ int find_new_uid(bool sys_user,
*uid = id;
free (used_uids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This UID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.
@ -458,11 +443,8 @@ int find_new_uid(bool sys_user,
*uid = id;
free (used_uids);
return 0;
} else if (result == EEXIST || result == EINVAL) {
/*
* This GID is in use or unusable, we'll
* continue to the next.
*/
} else if (result == EEXIST) {
/* This UID is in use, we'll continue to the next */
} else {
/*
* An unexpected error occurred.

View File

@ -36,7 +36,7 @@ extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *gr
&& ('\0' == *endptr)
&& (ERANGE != errno)
&& (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) {
return xgetgrgid (gid);
return xgetgrgid ((gid_t) gid);
}
return xgetgrnam (grname);
}

View File

@ -22,7 +22,7 @@
* 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.
*/
/*@observer@*/time_t gettime (void)
/*@observer@*/time_t gettime ()
{
char *endptr;
char *source_date_epoch;
@ -55,13 +55,13 @@
fprintf (shadow_logfd,
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"),
ULONG_MAX, epoch);
} else if ((time_t)epoch > fallback) {
} else if (epoch > fallback) {
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"),
fallback, epoch);
} else {
/* Valid */
return epoch;
return (time_t)epoch;
}
return fallback;

View File

@ -66,7 +66,7 @@ bool hushed (const char *username)
if (NULL == fp) {
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';
found = (strcmp (buf, pw->pw_shell) == 0) ||
(strcmp (buf, pw->pw_name) == 0);

View File

@ -11,10 +11,7 @@
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "alloc.h"
#include "prototypes.h"
#include "stpeprintf.h"
#include "idmapping.h"
#if HAVE_SYS_CAPABILITY_H
#include <sys/prctl.h>
@ -46,7 +43,7 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
return NULL;
}
mappings = CALLOC(ranges, struct map_range);
mappings = calloc(ranges, sizeof(*mappings));
if (!mappings) {
fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"),
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)
* 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
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;
const struct map_range *mapping;
size_t bufsize;
char *buf, *pos, *end;
char *buf, *pos;
int fd;
#if HAVE_SYS_CAPABILITY_H
@ -191,21 +188,22 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings
#endif
bufsize = ranges * ((ULONG_DIGITS + 1) * 3);
pos = buf = XMALLOCARRAY(bufsize, char);
end = buf + bufsize;
pos = buf = xmalloc(bufsize);
/* Build the mapping command */
mapping = mappings;
for (idx = 0; idx < ranges; idx++, mapping++) {
/* Append this range to the string that will be written */
pos = stpeprintf(pos, end, "%lu %lu %lu\n",
mapping->upper,
mapping->lower,
mapping->count);
}
if (pos == end || pos == NULL) {
fprintf(log_get_logfd(), _("%s: stpeprintf failed!\n"), log_get_progname());
exit(EXIT_FAILURE);
int written = snprintf(pos, bufsize - (pos - buf),
"%lu %lu %lu\n",
mapping->upper,
mapping->lower,
mapping->count);
if ((written <= 0) || (written >= (bufsize - (pos - buf)))) {
fprintf(log_get_logfd(), _("%s: snprintf failed!\n"), log_get_progname());
exit(EXIT_FAILURE);
}
pos += written;
}
/* Write the mapping to the mapping file */

View File

@ -40,7 +40,7 @@ int isexpired (const struct passwd *pw, /*@null@*/const struct spwd *sp)
{
long now;
now = time(NULL) / SCALE;
now = (long) time ((time_t *) 0) / SCALE;
if (NULL == sp) {
return 0;

View File

@ -28,7 +28,11 @@
#include <pwd.h>
#include "getdef.h"
#include "shadowlog.h"
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#define LIMITS
#endif
#ifdef LIMITS
#ifndef LIMITS_FILE
#define LIMITS_FILE "/etc/limits"
#endif
@ -68,7 +72,7 @@ static int setrlimit_value (unsigned int resource,
return 0;
}
longlimit *= multiplier;
limit = longlimit;
limit = (rlim_t)longlimit;
if (longlimit != limit)
{
/* FIXME: Again, silent error handling...
@ -95,7 +99,7 @@ static int set_prio (const char *value)
|| (prio != (int) prio)) {
return 0;
}
if (setpriority (PRIO_PROCESS, 0, prio) != 0) {
if (setpriority (PRIO_PROCESS, 0, (int) prio) != 0) {
return LOGIN_ERROR_RLIMIT;
}
return 0;
@ -111,7 +115,7 @@ static int set_umask (const char *value)
return 0;
}
(void) umask (mask);
(void) umask ((mode_t) mask);
return 0;
}
@ -119,7 +123,11 @@ static int set_umask (const char *value)
/* Counts the number of user logins and check against the limit */
static int check_logins (const char *name, const char *maxlogins)
{
#ifdef USE_UTMPX
struct utmpx *ut;
#else /* !USE_UTMPX */
struct utmp *ut;
#endif /* !USE_UTMPX */
unsigned long limit, count;
if (getulong (maxlogins, &limit) == 0) {
@ -132,8 +140,13 @@ static int check_logins (const char *name, const char *maxlogins)
}
count = 0;
#ifdef USE_UTMPX
setutxent ();
while ((ut = getutxent ()))
#else /* !USE_UTMPX */
setutent ();
while ((ut = getutent ()))
#endif /* !USE_UTMPX */
{
if (USER_PROCESS != ut->ut_type) {
continue;
@ -149,7 +162,11 @@ static int check_logins (const char *name, const char *maxlogins)
break;
}
}
#ifdef USE_UTMPX
endutxent ();
#else /* !USE_UTMPX */
endutent ();
#endif /* !USE_UTMPX */
/*
* This is called after setutmp(), so the number of logins counted
* 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) {
switch (*pp++) {
#ifdef RLIMIT_AS
case 'a':
case 'A':
/* RLIMIT_AS - max address space (KB) */
retval |= setrlimit_value (RLIMIT_AS, pp, 1024);
break;
#endif
#ifdef RLIMIT_CORE
case 'c':
case 'C':
/* RLIMIT_CORE - max core file size (KB) */
retval |= setrlimit_value (RLIMIT_CORE, pp, 1024);
break;
#endif
#ifdef RLIMIT_DATA
case 'd':
case 'D':
/* RLIMIT_DATA - max data size (KB) */
retval |= setrlimit_value (RLIMIT_DATA, pp, 1024);
break;
#endif
#ifdef RLIMIT_FSIZE
case 'f':
case 'F':
/* RLIMIT_FSIZE - Maximum filesize (KB) */
retval |= setrlimit_value (RLIMIT_FSIZE, pp, 1024);
break;
#endif
#ifdef RLIMIT_NICE
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);
break;
#endif
#ifdef RLIMIT_NOFILE
case 'n':
case 'N':
/* RLIMIT_NOFILE - max number of open files */
retval |= setrlimit_value (RLIMIT_NOFILE, pp, 1);
break;
#endif
#ifdef RLIMIT_RTPRIO
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);
break;
#endif
#ifdef RLIMIT_STACK
case 's':
case 'S':
/* RLIMIT_STACK - max stack size (KB) */
retval |= setrlimit_value (RLIMIT_STACK, pp, 1024);
break;
#endif
#ifdef RLIMIT_CPU
case 't':
case 'T':
/* RLIMIT_CPU - max CPU time (MIN) */
retval |= setrlimit_value (RLIMIT_CPU, pp, 60);
break;
#endif
#ifdef RLIMIT_NPROC
case 'u':
case 'U':
@ -448,6 +479,7 @@ static int setup_user_limits (const char *uname)
}
return do_user_limits (limits, uname);
}
#endif /* LIMITS */
static void setup_usergroups (const struct passwd *info)
@ -491,6 +523,7 @@ void setup_limits (const struct passwd *info)
*/
if (getdef_bool ("QUOTAS_ENAB")) {
#ifdef LIMITS
if (info->pw_uid != 0) {
if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) {
(void) fputs (_("Too many logins.\n"), log_get_logfd());
@ -498,6 +531,7 @@ void setup_limits (const struct passwd *info)
exit (EXIT_FAILURE);
}
}
#endif
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
if (',' == *cp) {
cp++;
@ -508,7 +542,7 @@ void setup_limits (const struct passwd *info)
if ( (getlong (cp + 4, &inc) == 1)
&& (inc >= -20) && (inc <= 20)) {
errno = 0;
if ( (nice (inc) != -1)
if ( (nice ((int) inc) != -1)
|| (0 != errno)) {
continue;
}
@ -525,7 +559,7 @@ void setup_limits (const struct passwd *info)
long int blocks;
if ( (getlong (cp + 7, &blocks) == 0)
|| (blocks != (int) blocks)
|| (set_filesize_limit (blocks) != 0)) {
|| (set_filesize_limit ((int) blocks) != 0)) {
SYSLOG ((LOG_WARN,
"Can't set the ulimit for user %s",
info->pw_name));
@ -540,7 +574,7 @@ void setup_limits (const struct passwd *info)
"Can't set umask value for user %s",
info->pw_name));
} else {
(void) umask (mask);
(void) umask ((mode_t) mask);
}
continue;
@ -550,6 +584,6 @@ void setup_limits (const struct passwd *info)
}
#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 */

View File

@ -11,8 +11,6 @@
#ident "$Id$"
#include <assert.h>
#include "alloc.h"
#include "prototypes.h"
#include "defines.h"
/*
@ -35,7 +33,7 @@
* 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) {
return list;
}
@ -46,7 +44,7 @@
* 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
@ -54,12 +52,12 @@
* 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] = xstrdup (member);
tmp[i+1] = NULL;
tmp[i+1] = (char *) 0;
return tmp;
}
@ -85,7 +83,7 @@
* 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) {
j++;
}
@ -100,7 +98,7 @@
* old entries.
*/
tmp = XMALLOCARRAY (j + 1, char *);
tmp = (char **) xmalloc ((j + 1) * sizeof member);
/*
* Copy the original list except the deleted members to the
@ -108,14 +106,14 @@
* 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) {
tmp[j] = list[i];
j++;
}
}
tmp[j] = NULL;
tmp[j] = (char *) 0;
return tmp;
}
@ -135,7 +133,7 @@
for (i = 0; NULL != list[i]; i++);
tmp = XMALLOCARRAY (i + 1, char *);
tmp = (char **) xmalloc ((i + 1) * sizeof (char *));
i = 0;
while (NULL != *list) {
@ -144,7 +142,7 @@
list++;
}
tmp[i] = NULL;
tmp[i] = (char *) 0;
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.
*/
array = XMALLOCARRAY (i, char *);
array = (char **) xmalloc (sizeof (char *) * i);
/*
* Empty list is special - 0 members, not 1 empty member. --marekm
*/
if ('\0' == *members) {
*array = NULL;
*array = (char *) 0;
free (members);
return array;
}
@ -237,7 +235,7 @@ bool is_on_list (char *const *list, const char *member)
cp2++;
cp = cp2;
} else {
array[i + 1] = NULL;
array[i + 1] = (char *) 0;
break;
}
}

View File

@ -67,7 +67,7 @@ void dolastlog (
* 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);
}
if (NULL != ll) {
@ -82,7 +82,7 @@ void dolastlog (
strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1);
#endif
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)) {
SYSLOG ((LOG_WARN,
"Can't write lastlog entry for UID %lu in %s.",

View File

@ -14,15 +14,14 @@
#include <assert.h>
#include <stdio.h>
#include <signal.h>
#include "alloc.h"
#include <ctype.h>
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
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.
*/
void login_prompt (char *name, int namesize)
void login_prompt (const char *prompt, char *name, int namesize)
{
char buf[1024];
@ -41,38 +40,45 @@ void login_prompt (char *name, int namesize)
char *cp;
int i;
FILE *fp;
const char *fname = getdef_str ("ISSUE_FILE");
sighandler_t sigquit;
#ifdef SIGTSTP
sighandler_t sigtstp;
#endif
/*
* There is a small chance that a QUIT character will be part of
* 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);
#ifdef SIGTSTP
sigtstp = signal (SIGTSTP, login_exit);
#endif
/*
* See if the user has configured the issue file to
* be displayed and display it before the prompt.
*/
if (NULL != fname) {
fp = fopen (fname, "r");
if (NULL != fp) {
while ((i = getc (fp)) != EOF) {
(void) putc (i, stdout);
}
if (NULL != prompt) {
const char *fname = getdef_str ("ISSUE_FILE");
if (NULL != fname) {
fp = fopen (fname, "r");
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
@ -80,7 +86,7 @@ void login_prompt (char *name, int namesize)
*/
memzero (buf, sizeof buf);
if (fgets (buf, sizeof buf, stdin) != buf) {
if (fgets (buf, (int) sizeof buf, stdin) != buf) {
exit (EXIT_FAILURE);
}
@ -92,20 +98,58 @@ void login_prompt (char *name, int namesize)
/*
* 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 (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';
/*
* 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
*/
(void) signal (SIGQUIT, sigquit);
#ifdef SIGTSTP
(void) signal (SIGTSTP, sigtstp);
#endif
}

View File

@ -15,7 +15,6 @@
#include <stdio.h>
#include <string.h>
#include "alloc.h"
#include "getdef.h"
#ident "$Id$"
@ -39,7 +38,7 @@ void mailcheck (void)
size_t len = strlen (mailbox) + 5;
int wlen;
newmail = XMALLOCARRAY (len, char);
newmail = xmalloc (len);
wlen = snprintf (newmail, len, "%s/new", mailbox);
assert (wlen == (int) len - 1);

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