Compare commits

..

2 Commits

Author SHA1 Message Date
Chris Hofstaedtler
9d5ab87d61 New upstream version 4.18.0 2025-08-26 22:55:14 +02:00
Chris Hofstaedtler
a9c3448878 New upstream version 4.17.4 2025-03-29 13:24:20 +01:00
587 changed files with 26075 additions and 20457 deletions

View File

@@ -6,7 +6,7 @@ if ENABLE_SUBIDS
SUBDIRS += libsubid
endif
SUBDIRS += src po contrib doc etc tests/unit
SUBDIRS += src po doc etc tests/unit
if ENABLE_REGENERATE_MAN
SUBDIRS += man

View File

@@ -163,7 +163,7 @@ am__define_uniq_tagged_files = \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
DIST_SUBDIRS = lib libsubid src po contrib doc etc tests/unit man
DIST_SUBDIRS = lib libsubid src po doc etc tests/unit man
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(top_srcdir)/man/po/Makefile.in ABOUT-NLS AUTHORS.md COPYING \
ChangeLog NEWS README compile config.guess config.rpath \
@@ -243,6 +243,7 @@ EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -333,8 +334,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -389,7 +388,7 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
SUBDIRS = lib $(am__append_1) src po contrib doc etc tests/unit \
SUBDIRS = lib $(am__append_1) src po doc etc tests/unit \
$(am__append_2)
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
EXTRA_DIST = NEWS README tests/

43
aclocal.m4 vendored
View File

@@ -22,14 +22,15 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*-
#
# Copyright (C) 1999-2008, 2011-2015 Free Software Foundation, Inc.
# Copyright (C) 1999-2008, 2011-2019, 2021-2022 Free Software
# Foundation, Inc.
# Written by Thomas Tanner, 1999
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 20 LTDL_INIT
# serial 21 LTDL_INIT
# LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE])
# ------------------------------------------
@@ -357,7 +358,7 @@ AC_CONFIG_COMMANDS_PRE([
if test -n "$_LT_LIBOBJS"; then
# Remove the extension.
_lt_sed_drop_objext='s/\.o$//;s/\.obj$//'
for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do
for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | $SED "$_lt_sed_drop_objext" | sort -u`; do
_ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext"
_ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo"
done
@@ -495,7 +496,7 @@ AC_CACHE_CHECK([whether deplibs are loaded by dlopen],
# If you are looking for one http://www.opendarwin.org/projects/dlcompat
lt_cv_sys_dlopen_deplibs=yes
;;
freebsd* | dragonfly*)
freebsd* | dragonfly* | midnightbsd*)
lt_cv_sys_dlopen_deplibs=yes
;;
gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu)
@@ -930,8 +931,8 @@ AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], [])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 11 (pkg-config-0.29.1)
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
# serial 12 (pkg-config-0.29.2)
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
@@ -973,7 +974,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require.
m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29.1])
[m4_define([PKG_MACROS_VERSION], [0.29.2])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ
@@ -1018,7 +1019,7 @@ dnl Check to see whether a particular set of modules exists. Similar to
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
dnl
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
dnl only at the first occurence in configure.ac, so if the first place
dnl only at the first occurrence in configure.ac, so if the first place
dnl it's called might be skipped (such as if it is within an "if", you
dnl have to call PKG_CHECK_EXISTS manually
AC_DEFUN([PKG_CHECK_EXISTS],
@@ -1074,7 +1075,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
pkg_failed=no
AC_MSG_CHECKING([for $1])
AC_MSG_CHECKING([for $2])
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
@@ -1084,17 +1085,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
m4_default([$4], [AC_MSG_ERROR(
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
@@ -1105,8 +1106,8 @@ installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
@@ -1116,10 +1117,10 @@ _PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
$3
fi[]dnl
])dnl PKG_CHECK_MODULES

View File

@@ -91,27 +91,18 @@
/* Defined to 1 if you have the declaration of 'fgetpwent_r' */
#undef HAVE_FGETPWENT_R
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
/* Define to 1 if you have the `getentropy' function. */
#undef HAVE_GETENTROPY
/* Define to 1 if you have the `getrandom' function. */
#undef HAVE_GETRANDOM
/* Define to 1 if you have the `getspnam' function. */
#undef HAVE_GETSPNAM
/* Define to 1 if you have the `getspnam_r' function. */
#undef HAVE_GETSPNAM_R
/* Define if the GNU gettext() function is already present or preinstalled. */
#undef HAVE_GETTEXT
/* Define to 1 if you have the `getusershell' function. */
#undef HAVE_GETUSERSHELL
/* Define if you have the iconv() function and it works. */
#undef HAVE_ICONV
@@ -466,8 +457,5 @@
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Path for utmp file. */
#undef _UTMP_FILE
/* Path for wtmp file. */
#undef _WTMP_FILE

510
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@ m4_define([libsubid_abi_major], 5)
m4_define([libsubid_abi_minor], 0)
m4_define([libsubid_abi_micro], 0)
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
AC_INIT([shadow], [4.17.3], [pkg-shadow-devel@lists.alioth.debian.org], [],
AC_INIT([shadow], [4.18.0], [pkg-shadow-devel@lists.alioth.debian.org], [],
[https://github.com/shadow-maint/shadow])
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
AC_CONFIG_MACRO_DIRS([m4])
@@ -30,7 +30,6 @@ AM_MAINTAINER_MODE
dnl Checks for programs.
AC_PROG_CC
AC_PROG_LN_S
AC_PROG_YACC
LT_INIT
LT_LIB_DLLOAD
@@ -39,8 +38,8 @@ dnl Checks for libraries.
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
AC_CHECK_FUNCS(arc4random_buf futimes \
getentropy getrandom getspnam getusershell \
AC_CHECK_FUNCS(arc4random_buf \
getentropy getrandom \
lckpwdf lutimes \
updwtmpx innetgr \
getspnam_r \
@@ -90,18 +89,6 @@ if test $shadow_cv_mailfile != none; then
[Name of user's mail spool file if stored in user's home directory.])
fi
AC_CACHE_CHECK([location of utmp], shadow_cv_utmpdir,
[for shadow_cv_utmpdir in /var/run /var/adm /usr/adm /etc none; do
if test -f $shadow_cv_utmpdir/utmp; then
break
fi
done])
if test "$shadow_cv_utmpdir" = "none"; then
AC_MSG_WARN(utmp file not found)
fi
AC_DEFINE_UNQUOTED(_UTMP_FILE, "$shadow_cv_utmpdir/utmp",
[Path for utmp file.])
AC_CACHE_CHECK([location of faillog/lastlog/wtmp], shadow_cv_logdir,
[for shadow_cv_logdir in /var/log /var/adm /usr/adm /etc; do
if test -d $shadow_cv_logdir; then
@@ -115,13 +102,7 @@ AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$shadow_cv_logdir/lastlog",
AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$shadow_cv_logdir/faillog",
[Path for faillog file.])
AC_CACHE_CHECK([location of the passwd program], shadow_cv_passwd_dir,
[if test -f /usr/bin/passwd; then
shadow_cv_passwd_dir=/usr/bin
else
shadow_cv_passwd_dir=/bin
fi])
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$exec_prefix/bin/passwd",
[Path to passwd program.])
AC_ARG_ENABLE(shadowgrp,
@@ -349,7 +330,7 @@ if test "$enable_lastlog" = "yes" && test "$ac_cv_header_lastlog_h" = "yes"; the
enable_lastlog="yes"
else
AC_MSG_ERROR([Cannot enable support for lastlog on systems where the data structures aren't available])
enable_subids="no"
enable_lastlog="no"
fi
fi
AM_CONDITIONAL(ENABLE_LASTLOG, test "x$enable_lastlog" != "xno")
@@ -702,7 +683,6 @@ AC_CONFIG_FILES([
libsubid/Makefile
libsubid/subid.h
src/Makefile
contrib/Makefile
etc/Makefile
etc/pam.d/Makefile
etc/shadow-maint/Makefile

View File

@@ -1,4 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
EXTRA_DIST = README adduser.c adduser.sh adduser2.sh

View File

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

View File

@@ -1,7 +0,0 @@
People keep sending various adduser programs and scripts... They are
all in this directory. I haven't tested them, use at your own risk.
Anyway, the best one I've seen so far is adduser-3.x from Debian.
udbachk.tgz is a passwd/group/shadow file integrity checker.
--marekm

View File

@@ -1,503 +0,0 @@
/****
** 04/21/96
** hacked even more, replaced gets() with something slightly harder to buffer
** overflow. Added support for setting a default quota on new account, with
** edquota -p. Other cleanups for security, I let some users run adduser suid
** root to add new accounts. (overflow checks, clobber environment, valid
** shell checks, restrictions on gid + home dir settings).
** Added max. username length. Used syslog() a bit for important events.
** Support to immediately expire account with passwd -e.
** Called it version 2.0! Because I felt like it!
** -- Chris, chris@ferret.lmh.ox.ac.uk
** 03/17/96
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
** --marekm
**
** 02/26/96
** modified to call shadow utils (useradd,chage,passwd) on shadowed
** systems - Cristian Gafton, gafton@sorosis.ro
**
** 6/27/95
** shadow-adduser 1.4:
**
** now it copies the /etc/skel dir into the person's dir,
** makes the mail folders, changed some defaults and made a 'make
** install' just for the hell of it.
**
** Greg Gallagher
** CIN.Net
**
** 1/28/95
** shadow-adduser 1.3:
**
** Basically a bug-fix on my additions in 1.2. Thanks to Terry Stewart
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
** It was such a stupid bug that I would have never seen it myself.
**
** Brandon
*****
** 01/27/95
**
** shadow-adduser 1.2:
** I took the C source from adduser-shadow (credits are below) and made
** it a little more worthwhile. Many small changes... Here's
** the ones I can remember:
**
** Removed support for non-shadowed systems (if you don't have shadow,
** use the original adduser, don't get this shadow version!)
** Added support for the correct /etc/shadow fields (Min days before
** password change, max days before password change, Warning days,
** and how many days from expiry date does the account go invalid)
** The previous version just left all of those fields blank.
** There is still one field left (expiry date for the account, period)
** which I have left blank because I do not use it and didn't want to
** spend any more time on this. I'm sure someone will put it in and
** tack another plethora of credits on here. :)
** Added in the password date field, which should always reflect the last
** date the password was changed, for expiry purposes. "passwd" always
** updates this field, so the adduser program should set it up right
** initially (or a user could keep their initial password forever ;)
** The number is in days since Jan 1st, 1970.
**
** Have fun with it, and someone please make
** a real version(this is still just a hack)
** for us all to use (and Email it to me???)
**
** Brandon
** photon@usis.com
**
*****
** adduser 1.0: add a new user account (For systems not using shadow)
** With a nice little interface and a will to do all the work for you.
**
** Craig Hagan
** hagan@opine.cs.umass.edu
**
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
** chris@slinky.cs.umass.edu
**
*****
**
** 01/19/95
**
** FURTHER modifications to enable shadow passwd support (kludged, but
** no more so than the original) by Dan Crowson - dcrowson@mo.net
**
** Search on DAN for all changes...
**
*****
**
** cc -O -o adduser adduser.c
** Use gcc if you have it... (political reasons beyond my control) (chris)
**
** I've gotten this program to work with success under Linux (without
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
** on any system that uses no shadow. (chris)
**
** If you have no crypt() then try
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
** I'm not sure how login operates with no crypt()... I guess
** the same way we're doing it here.
*/
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <syslog.h>
#include "string/strcmp/streq.h"
#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
* immediately upon next login */
#define HAVE_QUOTAS /* Obvious */
#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change
* password expiry values (if running suid root) */
#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */
#define LOGGING /* If we want to log various things to syslog */
#define MAX_USRNAME 8 /* Longer usernames seem to work on my system....
* But they're probably a poor idea */
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
#define DEFAULT_HOME "/home"
#define USERADD_PATH "/usr/sbin/useradd"
#define CHAGE_PATH "/usr/bin/chage"
#define PASSWD_PATH "/usr/bin/passwd"
#define EDQUOTA_PATH "/usr/sbin/edquota"
#define QUOTA_DEFAULT "defuser"
#define DEFAULT_GROUP 100
#define DEFAULT_MIN_PASS 0
#define DEFAULT_MAX_PASS 100
#define DEFAULT_WARN_PASS 14
#define DEFAULT_USER_DIE 366
void safeget (char *, int);
void
main (void)
{
char foo[32];
char usrname[32], person[32], dir[32], shell[32];
unsigned int group, min_pass, max_pass, warn_pass, user_die;
/* the group and uid of the new user */
int bad = 0, done = 0, correct = 0, olduid;
char cmd[255];
struct group *grp;
/* flags, in order:
* bad to see if the username is in /etc/passwd, or if strange stuff has
* been typed if the user might be put in group 0
* done allows the program to exit when a user has been added
* correct loops until a username is found that isn't in /etc/passwd
*/
/* The real program starts HERE! */
if (geteuid () != 0)
{
printf ("It seems you don't have access to add a new user. Try\n");
printf ("logging in as root or su root to gain superuser access.\n");
exit (1);
}
/* Sanity checks
*/
#ifdef LOGGING
openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
#endif
if (!(grp = getgrgid (DEFAULT_GROUP)))
{
printf ("Error: the default group %d does not exist on this system!\n",
DEFAULT_GROUP);
printf ("adduser must be recompiled.\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: failed. no such default group\n");
closelog ();
#endif
exit (1);
};
while (!correct)
{ /* loop until a "good" usrname is chosen */
while (!done)
{
printf ("\nLogin to add (^C to quit): ");
fflush (stdout);
safeget (usrname, sizeof (usrname));
if (!strlen (usrname))
{
printf ("Empty input.\n");
done = 0;
continue;
};
/* what I saw here before made me think maybe I was running DOS */
/* might this be a solution? (chris) */
if (strlen (usrname) > MAX_USRNAME)
{
printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
done = 0;
}
else if (getpwnam (usrname) != NULL)
{
printf ("That name is in use, choose another.\n");
done = 0;
}
else if (strchr (usrname, ' ') != NULL)
{
printf ("No spaces in username!!\n");
done = 0;
}
else
done = 1;
}; /* done, we have a valid new user name */
/* all set, get the rest of the stuff */
printf ("\nEditing information for new user [%s]\n", usrname);
printf ("\nFull Name [%s]: ", usrname);
fflush (stdout);
safeget (person, sizeof (person));
if (!strlen (person))
{
bzero (person, sizeof (person));
strcpy (person, usrname);
};
if (getuid () == 0)
{
do
{
bad = 0;
printf ("GID [%d]: ", DEFAULT_GROUP);
fflush (stdout);
safeget (foo, sizeof (foo));
if (!strlen (foo))
group = DEFAULT_GROUP;
else if (isdigit (*foo))
{
group = atoi (foo);
if (!(grp = getgrgid (group)))
{
printf ("unknown gid %s\n", foo);
group = DEFAULT_GROUP;
bad = 1;
};
}
else if ((grp = getgrnam (foo)))
group = grp->gr_gid;
else
{
printf ("unknown group %s\n", foo);
group = DEFAULT_GROUP;
bad = 1;
}
if (group == 0)
{ /* You're not allowed to make root group users! */
printf ("Creation of root group users not allowed (must be done by hand)\n");
group = DEFAULT_GROUP;
bad = 1;
};
}
while (bad);
}
else
{
printf ("Group will be default of: %d\n", DEFAULT_GROUP);
group = DEFAULT_GROUP;
}
if (getuid () == 0)
{
printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
fflush (stdout);
safeget (dir, sizeof (dir));
if (!strlen(dir)) /* hit return */
sprintf(dir, "%s/%s", DEFAULT_HOME, usrname);
else if (dir[strlen (dir) - 1] == '/')
strcat(dir, usrname);
}
else
{
printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
printf ("\nShell [%s]: ", DEFAULT_SHELL);
fflush (stdout);
safeget (shell, sizeof (shell));
if (!strlen (shell))
strcpy(shell, DEFAULT_SHELL);
else
{
char *sh;
int ok = 0;
#ifdef HAVE_GETUSERSHELL
setusershell ();
while ((sh = getusershell ()) != NULL)
if (streq(shell, sh))
ok = 1;
endusershell ();
#endif
if (!ok)
{
if (getuid () == 0)
printf ("Warning: root allowed non standard shell\n");
else
{
printf ("Shell NOT in /etc/shells, DEFAULT used\n");
strcpy(shell, DEFAULT_SHELL);
}
}
}
#ifdef EXPIRE_VALS_SET
if (getuid () == 0)
{
#endif
printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
if (strlen (foo) > 1)
min_pass = DEFAULT_MIN_PASS;
else
min_pass = atoi (foo);
printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
if (strlen (foo) > 1)
max_pass = atoi (foo);
else
max_pass = DEFAULT_MAX_PASS;
printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
warn_pass = atoi (foo);
if (warn_pass == 0)
warn_pass = DEFAULT_WARN_PASS;
printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
fflush (stdout);
safeget (foo, sizeof (foo));
user_die = atoi (foo);
if (user_die == 0)
user_die = DEFAULT_USER_DIE;
#ifdef EXPIRE_VALS_SET
}
else
{
printf ("\nSorry, account expiry values are set.\n");
user_die = DEFAULT_USER_DIE;
warn_pass = DEFAULT_WARN_PASS;
max_pass = DEFAULT_MAX_PASS;
min_pass = DEFAULT_MIN_PASS;
}
#endif
printf ("\nInformation for new user [%s] [%s]:\n", usrname, person);
printf ("Home directory: [%s] Shell: [%s]\n", dir, shell);
printf ("GID: [%d]\n", group);
printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
min_pass, max_pass, warn_pass, user_die);
printf ("\nIs this correct? [y/N]: ");
fflush (stdout);
safeget (foo, sizeof (foo));
done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
if (bad != 1)
printf ("\nUser [%s] not added\n", usrname);
}
/* Clobber the environment, I run this suid root sometimes to let
* non root privileged accounts add users --chris */
*environ = NULL;
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
USERADD_PATH, group, dir, shell, person, usrname);
printf ("Calling useradd to add new user:\n%s\n", cmd);
if (system (cmd))
{
printf ("User add failed!\n");
#ifdef LOGGING
syslog (LOG_ERR, "could not add new user\n");
closelog ();
#endif
exit (errno);
};
olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root
*/
setuid (0);
bzero (cmd, sizeof (cmd));
/* Chage runs suid root. => we need ruid root to run it with
* anything other than chage -l
*/
sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
min_pass, max_pass, warn_pass, user_die, usrname);
printf ("%s\n", cmd);
if (system (cmd))
{
printf ("There was an error setting password expire values\n");
#ifdef LOGGING
syslog (LOG_ERR, "password expire values could not be set\n");
#endif
};
/* I want to add a user completely with one easy command --chris */
#ifdef HAVE_QUOTAS
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
printf ("%s\n", cmd);
if (system (cmd))
{
printf ("\nWarning: error setting quota\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
#endif /* LOGGING */
}
else
printf ("\nDefault quota set.\n");
#endif /* HAVE_QUOTAS */
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
if (system (cmd))
{
printf ("\nWarning: error setting password\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: password set failed!\n");
#endif
}
#ifdef IMMEDIATE_CHANGE
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
if (system (cmd))
{
printf ("\nWarning: error expiring password\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: password expire failed!\n");
#endif /* LOGGING */
}
#endif /* IMMEDIATE_CHANGE */
setuid (olduid);
#ifdef LOGGING
closelog ();
#endif
printf ("\nDone.\n");
}
void
safeget (char *buf, int maxlen)
{
int c, i = 0, bad = 0;
char *bstart = buf;
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
{
bad = (!isalnum (c) && (c != '_') && (c != ' '));
*(buf++) = c;
}
stpcpy(buf, "");
if (bad)
{
printf ("\nString contained banned character. Please stick to alphanumerics.\n");
stpcpy(bstart, "");
}
}

View File

@@ -1,90 +0,0 @@
#!/bin/sh
# adduser script for use with shadow passwords and useradd command.
# by Hrvoje Dogan <hdogan@student.math.hr>, Dec 1995.
echo -n "Login name for new user []:"
read LOGIN
if [ -z $LOGIN ]
then echo "Come on, man, you can't leave the login field empty...";exit
fi
echo
echo -n "User id for $LOGIN [ defaults to next available]:"
read ID
GUID="-u $ID"
if [ -z $ID ]
then GUID=""
fi
echo
echo -n "Initial group for $LOGIN [users]:"
read GID
GGID="-g $GID"
if [ -z $GID ]
then GGID=""
fi
echo
echo -n "Additional groups for $LOGIN []:"
read AGID
GAGID="-G $AGID"
if [ -z $AGID ]
then GAGID=""
fi
echo
echo -n "$LOGIN's home directory [/home/$LOGIN]:"
read HME
GHME="-d $HME"
if [ -z $HME ]
then GHME=""
fi
echo
echo -n "$LOGIN's shell [/bin/bash]:"
read SHL
GSHL="-s $SHL"
if [ -z $SHL ]
then GSHL=""
fi
echo
echo -n "$LOGIN's account expiry date (MM/DD/YY) []:"
read EXP
GEXP="-e $EXP"
if [ -z $EXP ]
then GEXP=""
fi
echo
echo OK, I'm about to make a new account. Here's what you entered so far:
echo New login name: $LOGIN
if [ -z $GUID ]
then echo New UID: [Next available]
else echo New UID: $UID
fi
if [ -z $GGID ]
then echo Initial group: users
else echo Initial group: $GID
fi
if [ -z $GAGID ]
then echo Additional groups: [none]
else echo Additional groups: $AGID
fi
if [ -z $GHME ]
then echo Home directory: /home/$LOGIN
else echo Home directory: $HME
fi
if [ -z $GSHL ]
then echo Shell: /bin/bash
else echo Shell: $SHL
fi
if [ -z $GEXP ]
then echo Expiry date: [no expiration]
else echo Expiry date: $EXP
fi
echo "This is it... if you want to bail out, you'd better do it now."
read FOO
echo Making new account...
/usr/sbin/useradd $GHME -m $GEXP $GGID $GAGID $GSHL $GUID $LOGIN
/usr/bin/chfn $LOGIN
/usr/bin/passwd $LOGIN
echo "Done..."

View File

@@ -1,743 +0,0 @@
#!/bin/bash
#
# adduser Interactive user adding program.
#
# Copyright (C) 1996 Petri Mattila, Prihateam Networks
# petri@prihateam.fi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# Changes:
# 220496 v0.01 Initial version
# 230496 v0.02 More checks, embolden summary
# 240496 Even more checks
# 250496 Help with ?
# 040596 v0.03 Cleanups
# 050596 v0.04 Bug fixes, expire date checks
# 070596 v0.05 Iso-latin-1 names
#
## Defaults
# default groups
def_group="users"
def_other_groups=""
# default home directory
def_home_dir=/home/users
# default shell
def_shell=/bin/tcsh
# Default expiration date (mm/dd/yy)
def_expire=""
# default dates
def_pwd_min=0
def_pwd_max=90
def_pwd_warn=14
def_pwd_iact=14
# possible UIDs
uid_low=1000
uid_high=64000
# skel directory
skel=/etc/skel
# default mode for home directory
def_mode=711
# Regex, that the login name must meet, only ANSI characters
login_regex='^[0-9a-zA-Z_-]*$'
# Regex, that the user name must meet
# ANSI version
##name_regex='^[0-9a-zA-Z_-\ ]*$'
# ISO-LATIN-1 version
name_regex='^[0-9a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ_-\ ]*$'
# set PATH
export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
# Some special characters
case "$TERM" in
vt*|ansi*|con*|xterm*|linux*)
S='' # start embolden
E='' # end embolden
;;
*)
S=''
E=''
;;
esac
## Functions
check_root() {
if test "$EUID" -ne 0
then
echo "You must be root to run this program."
exit 1
fi
}
check_user() {
local usr pwd uid gid name home sh
cat /etc/passwd | (
while IFS=":" read usr pwd uid gid name home sh
do
if test "$1" = "${usr}"
then
return 1
fi
done
return 0
)
}
check_group() {
local read grp pwd gid members
cat /etc/group | (
while IFS=":" read grp pwd gid members
do
if test "$1" = "${grp}"
then
return 1
fi
done
return 0
)
}
check_other_groups() {
local grp check IFS
check="$1"
IFS=","
set ${check}
for grp
do
if check_group "${grp}"
then
echo "Group ${grp} does not exist."
return 1
fi
done
return 0
}
check_uid() {
local usr pwd uid gid name home sh
cat /etc/passwd | (
while IFS=":" read usr pwd uid gid name home sh
do
if test "$1" = "${uid}"
then
return 1
fi
done
return 0
)
}
read_yn() {
local ans ynd
ynd="$1"
while :
do
read ans
case "${ans}" in
"") return ${ynd} ;;
[nN]) return 1 ;;
[yY]) return 0 ;;
*) echo -n "Y or N, please ? " ;;
esac
done
}
read_login() {
echo
while :
do
echo -n "Login: ${def_login:+[${def_login}] }"
read login
if test "${login}" = '?'
then
less /etc/passwd
echo
continue
fi
if test -z "${login}" -a -n "${def_login}"
then
login="${def_login}"
echo "Using ${login}"
return
fi
if test "${#login}" -gt 8
then
echo "Login must be at most 8 characters long"
continue
fi
if test "${#login}" -lt 2
then
echo "Login must be at least 2 characters long"
continue
fi
if ! expr "${login}" : "${login_regex}" &> /dev/null
then
echo "Please use letters, numbers and special characters _-,."
continue
fi
if ! check_user "${login}"
then
echo "Username ${login} is already in use"
continue
fi
def_login="${login}"
return
done
}
read_name () {
echo
while :
do
echo -n "Real name: ${def_name:+[${def_name}] }"
read name
if test "${name}" = '?'
then
less /etc/passwd
echo
continue
fi
if test -z "${name}" -a -n "${def_name}"
then
name="${def_name}"
echo "Using ${name}"
fi
if test "${#name}" -gt 32
then
echo "Name should be at most 32 characters long"
continue
fi
if ! expr "${name}" : "${name_regex}" &> /dev/null
then
echo "Please use letters, numbers, spaces and special characters ,._-"
continue
fi
def_name="${name}"
return
done
}
read_home() {
local x
echo
while :
do
echo -n "Home Directory: [${def_home_dir}/${login}] "
read home
if test -z "${home}"
then
home="${def_home_dir}/${login}"
echo "Using ${home}"
fi
if ! expr "${home}" : '^[0-9a-zA-Z,._-\/]*$' &> /dev/null
then
echo "Please use letters, numbers, spaces and special characters ,._-/"
continue
fi
x="$(basename ${home})"
if test "${x}" != "${login}"
then
echo "Warning: you are about to use different login name and home directory."
fi
x="$(dirname ${home})"
if ! test -d "${x}"
then
echo "Directory ${x} does not exist."
echo "If you still want to use it, please make it manually."
continue
fi
def_home_dir="${x}"
return
done
}
read_shell () {
local x
echo
while :
do
echo -n "Shell: [${def_shell}] "
read shell
if test -z "${shell}"
then
shell="${def_shell}"
echo "Using ${shell}"
fi
for x in $(cat /etc/shells)
do
if test "${x}" = "${shell}"
then
def_shell="${shell}"
return
fi
done
echo "Possible shells are:"
cat /etc/shells
done
}
read_group () {
echo
while :
do
echo -n "Group: [${def_group}] "
read group
if test -z "${group}"
then
group="${def_group}"
echo "Using ${group}"
fi
if test "${group}" = '?'
then
less /etc/group
echo
continue
fi
if check_group "${group}"
then
echo "Group ${group} does not exist."
continue
fi
def_group="${group}"
return
done
}
read_other_groups () {
echo
while :
do
echo -n "Other groups: [${def_og:-none}] "
read other_groups
if test "${other_groups}" = '?'
then
less /etc/group
echo
continue
fi
if test -z "${other_groups}"
then
if test -n "${def_og}"
then
other_groups="${def_og}"
echo "Using ${other_groups}"
else
echo "No other groups"
return
fi
fi
if ! check_other_groups "${other_groups}"
then
continue
fi
def_og="${other_groups}"
return
done
}
read_uid () {
echo
while :
do
echo -n "uid: [first free] "
read uid
if test -z "${uid}"
then
echo "Using first free UID."
return
fi
if test "${uid}" = '?'
then
less /etc/passwd
echo
continue
fi
if ! expr "${uid}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${uid}" -lt "${uid_low}"
then
echo "UID must be greater than ${uid_low}"
continue
fi
if test "${uid}" -gt "${uid_high}"
then
echo "UID must be smaller than ${uid_high}"
continue
fi
if ! check_uid "${uid}"
then
echo "UID ${uid} is already in use"
continue
fi
return
done
}
read_max_valid_days() {
echo
while :
do
echo -en "Maximum days between password changes: [${def_pwd_max}] "
read max_days
if test -z "${max_days}"
then
max_days="${def_pwd_max}"
echo "Using ${max_days}"
return
fi
if ! expr "${max_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${max_days}" -lt 7
then
echo "Warning: you are using a value shorter than a week."
fi
def_pwd_max="${max_days}"
return
done
}
read_min_valid_days() {
echo
while :
do
echo -en "Minimum days between password changes: [${def_pwd_min}] "
read min_days
if test -z "${min_days}"
then
min_days="${def_pwd_min}"
echo "Using ${min_days}"
return
fi
if ! expr "${min_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${min_days}" -gt 7
then
echo "Warning: you are using a value longer than a week."
fi
def_pwd_min="${min_days}"
return
done
}
read_warning_days() {
echo
while :
do
echo -en "Number of warning days before password expires: [${def_pwd_warn}] "
read warn_days
if test -z "${warn_days}"
then
warn_days="${def_pwd_warn}"
echo "Using ${warn_days}"
fi
if ! expr "${warn_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${warn_days}" -gt 14
then
echo "Warning: you are using a value longer than two week."
fi
def_pwd_warn="${warn_days}"
return
done
}
read_inactive_days() {
echo
while :
do
echo -en "Number of usable days after expiration: [${def_pwd_iact}] "
read iact_days
if test -z "${iact_days}"
then
iact_days="${def_pwd_iact}"
echo "Using ${iact_days}"
return
fi
if ! expr "${iact_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${iact_days}" -gt 14
then
echo "Warning: you are using a value that is more than two weeks."
fi
def_pwd_iact="${iact_days}"
return
done
}
read_expire_date() {
local ans
echo
while :
do
echo -en "Expire date of this account (mm/dd/yy): [${def_expire:-never}] "
read ans
if test -z "${ans}"
then
if test -z "${def_expire}"
then
ans="never"
else
ans="${def_expire}"
echo "Using ${def_expire}"
fi
fi
if test "${ans}" = "never"
then
echo "Account will never expire."
def_expire=""
expire=""
return
fi
if ! expr "${ans}" : '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]$' &> /dev/null
then
echo "Please use format mm/dd/yy"
continue
fi
if ! expire_date="$(date -d ${ans} '+%A, %B %d %Y')"
then
continue
fi
def_expire="${expire}"
return
done
}
read_passwd_yn() {
echo -en "\nDo you want to set password [Y/n] ? "
if read_yn 0
then
set_pwd="YES"
else
set_pwd=""
fi
}
print_values() {
clear
cat << EOM
Login: ${S}${login}${E}
Group: ${S}${group}${E}
Other groups: ${S}${other_groups:-[none]}${E}
Real Name: ${S}${name}${E}
uid: ${S}${uid:-[first free]}${E}
home: ${S}${home}${E}
shell: ${S}${shell}${E}
Account expiration date: ${S}${expire_date:-never}${E}
Minimum days between password changes: ${S}${min_days}${E}
Maximum days between password changes: ${S}${max_days}${E}
Number of usable days after expiration: ${S}${iact_days}${E}
Number of warning days before expiration: ${S}${warn_days}${E}
${S}${set_pwd:+Set password for this account.}${E}
EOM
}
set_user() {
if ! useradd \
-c "${name}" \
-d "${home}" \
-g "${group}" \
-s "${shell}" \
${expire:+-e ${expire}} \
${uid:+-u ${uid}} \
${other_groups:+-G ${other_groups}} \
${login}
then
echo "Error ($?) in useradd...exiting..."
exit 1
fi
}
set_aging() {
if ! passwd \
-x ${max_days} \
-n ${min_days} \
-w ${warn_days} \
-i ${iact_days} \
${login}
then
echo "Error ($?) in setting password aging...exiting..."
exit 1
fi
}
set_password() {
if test -n "${set_pwd}"
then
echo
passwd ${login}
echo
fi
}
set_system() {
if test -d "${home}"
then
echo "Directory ${home} already exists."
echo "Skeleton files not copied."
return
fi
echo -n "Copying skeleton files..."
(
mkdir ${home}
cd ${skel} && cp -af . ${home}
chmod ${def_mode} ${home}
chown -R ${login}:${group} ${home}
)
echo "done."
## Add your own stuff here:
echo -n "Setting up other files..."
(
mailbox="/var/spool/mail/${login}"
touch ${mailbox}
chown "${login}:mail" ${mailbox}
chmod 600 ${mailbox}
)
echo "done."
}
read_values() {
clear
echo -e "\nPlease answer the following questions about the new user to be added."
while :
do
read_login
read_name
read_group
read_other_groups
read_home
read_shell
read_uid
read_expire_date
read_max_valid_days
read_min_valid_days
read_warning_days
read_inactive_days
read_passwd_yn
print_values
echo -n "Is this correct [N/y] ? "
read_yn 1 && return
done
}
main() {
check_root
read_values
set_user
set_aging
set_system
set_password
}
## Run it 8-)
main
# End.

View File

@@ -161,6 +161,7 @@ EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -251,8 +252,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@

View File

@@ -250,6 +250,7 @@ EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -340,8 +341,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@

View File

@@ -193,6 +193,7 @@ EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -283,8 +284,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@

View File

@@ -158,6 +158,7 @@ EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
@@ -248,8 +249,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
XSLTPROC = @XSLTPROC@
YACC = @YACC@
YFLAGS = @YFLAGS@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@

View File

@@ -59,12 +59,8 @@ libshadow_la_SOURCES = \
atoi/a2i/a2u_nc.h \
atoi/getnum.c \
atoi/getnum.h \
atoi/str2i/str2i.c \
atoi/str2i/str2i.h \
atoi/str2i/str2s.c \
atoi/str2i/str2s.h \
atoi/str2i/str2u.c \
atoi/str2i/str2u.h \
atoi/str2i.c \
atoi/str2i.h \
atoi/strtoi/strtoi.c \
atoi/strtoi/strtoi.h \
atoi/strtoi/strtou.c \
@@ -98,18 +94,21 @@ libshadow_la_SOURCES = \
failure.h \
fd.c \
fields.c \
fields.h \
find_new_gid.c \
find_new_uid.c \
find_new_sub_gids.c \
find_new_sub_uids.c \
fputsx.c \
fs/mkstemp/fmkomstemp.c \
fs/mkstemp/fmkomstemp.h \
fs/mkstemp/mkomstemp.c \
fs/mkstemp/mkomstemp.h \
fs/readlink/areadlink.c \
fs/readlink/areadlink.h \
fs/readlink/readlinknul.c \
fs/readlink/readlinknul.h \
get_pid.c \
getdate.h \
getdate.y \
getdef.c \
getdef.h \
getgr_nam_gid.c \
@@ -129,7 +128,6 @@ libshadow_la_SOURCES = \
loginprompt.c \
mail.c \
motd.c \
must_be.h \
myname.c \
nss.c \
nscd.c \
@@ -172,7 +170,6 @@ libshadow_la_SOURCES = \
sgetspent.c \
sgroupio.c \
sgroupio.h\
shadow.c \
shadow/grp/agetgroups.c \
shadow/grp/agetgroups.h \
shadowio.c \
@@ -186,16 +183,24 @@ libshadow_la_SOURCES = \
spawn.c \
sssd.c \
sssd.h \
string/ctype/strchrisascii/strchriscntrl.c \
string/ctype/strchrisascii/strchriscntrl.h \
string/ctype/strisascii/strisdigit.c \
string/ctype/strisascii/strisdigit.h \
string/ctype/strisascii/strisprint.c \
string/ctype/strisascii/strisprint.h \
string/ctype/strtoascii/strtolower.c \
string/ctype/strtoascii/strtolower.h \
string/memset/memzero.c \
string/memset/memzero.h \
string/sprintf/aprintf.c \
string/sprintf/aprintf.h \
string/sprintf/snprintf.c \
string/sprintf/snprintf.h \
string/sprintf/stpeprintf.c \
string/sprintf/stpeprintf.h \
string/sprintf/xasprintf.c \
string/sprintf/xasprintf.h \
string/sprintf/xaprintf.c \
string/sprintf/xaprintf.h \
string/strchr/strchrcnt.c \
string/strchr/strchrcnt.h \
string/strchr/strchrscnt.c \
@@ -204,8 +209,12 @@ libshadow_la_SOURCES = \
string/strchr/strnul.h \
string/strcmp/strcaseeq.c \
string/strcmp/strcaseeq.h \
string/strcmp/strcaseprefix.c \
string/strcmp/strcaseprefix.h \
string/strcmp/streq.c \
string/strcmp/streq.h \
string/strcmp/strprefix.c \
string/strcmp/strprefix.h \
string/strcpy/stpecpy.c \
string/strcpy/stpecpy.h \
string/strcpy/strncat.c \
@@ -234,6 +243,14 @@ libshadow_la_SOURCES = \
string/strspn/strrspn.h \
string/strtok/stpsep.c \
string/strtok/stpsep.h \
string/strtok/astrsep2ls.c \
string/strtok/astrsep2ls.h \
string/strtok/strsep2arr.c \
string/strtok/strsep2arr.h \
string/strtok/strsep2ls.c \
string/strtok/strsep2ls.h \
string/strtok/xastrsep2ls.c \
string/strtok/xastrsep2ls.h \
strtoday.c \
sub.c \
subordinateio.h \

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@
({ \
long addend_[] = {a, b, __VA_ARGS__}; \
\
addslN(NITEMS(addend_), addend_); \
addslN(countof(addend_), addend_); \
})

View File

@@ -8,49 +8,13 @@
#include <config.h>
#include "atoi/a2i/a2s_c.h"
#include "atoi/a2i/a2s_nc.h"
#include "atoi/a2i/a2i.h"
#define a2sh(n, s, ...) \
( \
_Generic(s, \
const char *: a2sh_c, \
const void *: a2sh_c, \
char *: a2sh_nc, \
void *: a2sh_nc \
)(n, s, __VA_ARGS__) \
)
#define a2si(n, s, ...) \
( \
_Generic(s, \
const char *: a2si_c, \
const void *: a2si_c, \
char *: a2si_nc, \
void *: a2si_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sl(n, s, ...) \
( \
_Generic(s, \
const char *: a2sl_c, \
const void *: a2sl_c, \
char *: a2sl_nc, \
void *: a2sl_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sll(n, s, ...) \
( \
_Generic(s, \
const char *: a2sll_c, \
const void *: a2sll_c, \
char *: a2sll_nc, \
void *: a2sll_nc \
)(n, s, __VA_ARGS__) \
)
#define a2sh(...) a2i(short, __VA_ARGS__)
#define a2si(...) a2i(int, __VA_ARGS__)
#define a2sl(...) a2i(long, __VA_ARGS__)
#define a2sll(...) a2i(long long, __VA_ARGS__)
#endif // include guard

View File

@@ -8,49 +8,13 @@
#include <config.h>
#include "atoi/a2i/a2u_c.h"
#include "atoi/a2i/a2u_nc.h"
#include "atoi/a2i/a2i.h"
#define a2uh(n, s, ...) \
( \
_Generic(s, \
const char *: a2uh_c, \
const void *: a2uh_c, \
char *: a2uh_nc, \
void *: a2uh_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ui(n, s, ...) \
( \
_Generic(s, \
const char *: a2ui_c, \
const void *: a2ui_c, \
char *: a2ui_nc, \
void *: a2ui_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ul(n, s, ...) \
( \
_Generic(s, \
const char *: a2ul_c, \
const void *: a2ul_c, \
char *: a2ul_nc, \
void *: a2ul_nc \
)(n, s, __VA_ARGS__) \
)
#define a2ull(n, s, ...) \
( \
_Generic(s, \
const char *: a2ull_c, \
const void *: a2ull_c, \
char *: a2ull_nc, \
void *: a2ull_nc \
)(n, s, __VA_ARGS__) \
)
#define a2uh(...) a2i(unsigned short, __VA_ARGS__)
#define a2ui(...) a2i(unsigned int, __VA_ARGS__)
#define a2ul(...) a2i(unsigned long, __VA_ARGS__)
#define a2ull(...) a2i(unsigned long long, __VA_ARGS__)
#endif // include guard

View File

@@ -1,8 +1,8 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "atoi/str2i/str2i.h"
#include "atoi/str2i.h"

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

@@ -0,0 +1,31 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
#include <config.h>
#include <stddef.h>
#include "atoi/a2i/a2i.h"
#include "typetraits.h"
#define str2i(T, ...) a2i(T, __VA_ARGS__, NULL, 0, type_min(T), type_max(T))
#define str2sh(...) str2i(short, __VA_ARGS__)
#define str2si(...) str2i(int, __VA_ARGS__)
#define str2sl(...) str2i(long, __VA_ARGS__)
#define str2sll(...) str2i(long long, __VA_ARGS__)
#define str2uh(...) str2i(unsigned short, __VA_ARGS__)
#define str2ui(...) str2i(unsigned int, __VA_ARGS__)
#define str2ul(...) str2i(unsigned long, __VA_ARGS__)
#define str2ull(...) str2i(unsigned long long, __VA_ARGS__)
#endif // include guard

View File

@@ -1,31 +0,0 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
#include <config.h>
#include "atoi/str2i/str2s.h"
#include "atoi/str2i/str2u.h"
#define str2i(TYPE, ...) \
( \
_Generic((TYPE) 0, \
short: str2sh, \
int: str2si, \
long: str2sl, \
long long: str2sll, \
unsigned short: str2uh, \
unsigned int: str2ui, \
unsigned long: str2ul, \
unsigned long long: str2ull \
)(__VA_ARGS__) \
)
#endif // include guard

View File

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

View File

@@ -1,57 +0,0 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include "atoi/a2i/a2s.h"
#include "attr.h"
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sh(short *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2si(int *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sl(long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2sll(long long *restrict n, const char *restrict s);
inline int
str2sh(short *restrict n, const char *restrict s)
{
return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX);
}
inline int
str2si(int *restrict n, const char *restrict s)
{
return a2si(n, s, NULL, 0, INT_MIN, INT_MAX);
}
inline int
str2sl(long *restrict n, const char *restrict s)
{
return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX);
}
inline int
str2sll(long long *restrict n, const char *restrict s)
{
return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX);
}
#endif // include guard

View File

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

View File

@@ -1,57 +0,0 @@
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
#include <config.h>
#include <limits.h>
#include <stddef.h>
#include "atoi/a2i/a2u.h"
#include "attr.h"
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2uh(unsigned short *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ui(unsigned int *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ul(unsigned long *restrict n, const char *restrict s);
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
inline int str2ull(unsigned long long *restrict n, const char *restrict s);
inline int
str2uh(unsigned short *restrict n, const char *restrict s)
{
return a2uh(n, s, NULL, 0, 0, USHRT_MAX);
}
inline int
str2ui(unsigned int *restrict n, const char *restrict s)
{
return a2ui(n, s, NULL, 0, 0, UINT_MAX);
}
inline int
str2ul(unsigned long *restrict n, const char *restrict s)
{
return a2ul(n, s, NULL, 0, 0, ULONG_MAX);
}
inline int
str2ull(unsigned long long *restrict n, const char *restrict s)
{
return a2ull(n, s, NULL, 0, 0, ULLONG_MAX);
}
#endif // include guard

View File

@@ -25,6 +25,8 @@
#include "attr.h"
#include "prototypes.h"
#include "shadowlog.h"
#include "string/sprintf/snprintf.h"
int audit_fd;
void audit_help_open (void)
@@ -46,10 +48,14 @@ void audit_help_open (void)
/*
* This function will log a message to the audit system using a predefined
* message format. Parameter usage is as follows:
* message format. For additional information on the user account lifecycle
* events check
* <https://github.com/linux-audit/audit-documentation/wiki/SPEC-User-Account-Lifecycle-Events>
*
* type - type of message: AUDIT_USER_CHAUTHTOK for changing any account
* attributes.
* Parameter usage is as follows:
*
* type - type of message. A list of possible values is available in
* "audit-records.h" file.
* pgname - program's name
* op - operation. "adding user", "changing finger info", "deleting group"
* name - user's account or group name. If not available use NULL.
@@ -68,6 +74,47 @@ void audit_logger (int type, MAYBE_UNUSED const char *pgname, const char *op,
}
}
/*
* This function will log a message to the audit system using a predefined
* message format. For additional information on the group account lifecycle
* events check
* <https://github.com/linux-audit/audit-documentation/wiki/SPEC-User-Account-Lifecycle-Events>
*
* Parameter usage is as follows:
*
* type - type of message. A list of possible values is available in
* "audit-records.h" file.
* op - operation. "adding-user", "modify-group", "deleting-user-from-group"
* name - user's account or group name. If not available use NULL.
* id - uid or gid that the operation is being performed on. This is used
* only when user is NULL.
* grp_type - type of group: "grp" or "new_group"
* grp - group name associated with event
*/
void
audit_logger_with_group(int type, const char *op, const char *name,
id_t id, const char *grp_type, const char *grp,
shadow_audit_result result)
{
int len;
char enc_group[GROUP_NAME_MAX_LENGTH * 2 + 1];
char buf[countof(enc_group) + 100];
if (audit_fd < 0)
return;
len = strnlen(grp, sizeof(enc_group)/2);
if (audit_value_needs_encoding(grp, len)) {
SNPRINTF(buf, "%s %s=%s", op, grp_type,
audit_encode_value(enc_group, grp, len));
} else {
SNPRINTF(buf, "%s %s=\"%s\"", op, grp_type, grp);
}
audit_log_acct_message(audit_fd, type, NULL, buf, name, id,
NULL, NULL, NULL, result);
}
void audit_logger_message (const char *message, shadow_audit_result result)
{
if (audit_fd < 0) {

View File

@@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cleanup_info)
gr_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -80,7 +80,7 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
sgr_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -101,7 +101,7 @@ void cleanup_report_add_group_group (void *group_name)
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"adding group to /etc/group",
"adding-group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
@@ -120,8 +120,8 @@ void cleanup_report_add_group_gshadow (void *group_name)
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"adding group to /etc/gshadow",
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
"adding-shadow-group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
@@ -143,8 +143,8 @@ void cleanup_report_del_group_group (void *group_name)
"failed to remove group %s from %s",
name, gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"removing group from /etc/group",
audit_logger (AUDIT_DEL_GROUP, log_get_progname(),
"removing-group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
@@ -166,8 +166,8 @@ void cleanup_report_del_group_gshadow (void *group_name)
"failed to remove group %s from %s",
name, sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
"removing group from /etc/gshadow",
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
"removing-shadow-group",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
@@ -187,7 +187,7 @@ void cleanup_unlock_group (MAYBE_UNUSED void *arg)
log_get_progname(), gr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking group file",
audit_logger_message ("unlocking-group",
SHADOW_AUDIT_FAILURE);
#endif
}
@@ -207,7 +207,7 @@ void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg)
log_get_progname(), sgr_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking gshadow file",
audit_logger_message ("unlocking-gshadow",
SHADOW_AUDIT_FAILURE);
#endif
}

View File

@@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cleanup_info)
pw_dbname (),
info->action));
#ifdef WITH_AUDIT
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
audit_logger (AUDIT_USER_MGMT, log_get_progname(),
info->audit_msg,
info->name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
@@ -65,7 +65,7 @@ void cleanup_report_add_user_passwd (void *user_name)
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, log_get_progname(),
"adding user to /etc/passwd",
"adding-user",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
@@ -84,8 +84,8 @@ void cleanup_report_add_user_shadow (void *user_name)
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
#ifdef WITH_AUDIT
audit_logger (AUDIT_ADD_USER, log_get_progname(),
"adding user to /etc/shadow",
audit_logger (AUDIT_USER_MGMT, log_get_progname(),
"adding-shadow-user",
name, AUDIT_NO_ID,
SHADOW_AUDIT_FAILURE);
#endif
@@ -104,7 +104,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED void *arg)
log_get_progname(), pw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking passwd file",
audit_logger_message ("unlocking-passwd",
SHADOW_AUDIT_FAILURE);
#endif
}
@@ -123,7 +123,7 @@ void cleanup_unlock_shadow (MAYBE_UNUSED void *arg)
log_get_progname(), spw_dbname ());
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
#ifdef WITH_AUDIT
audit_logger_message ("unlocking shadow file",
audit_logger_message ("unlocking-shadow",
SHADOW_AUDIT_FAILURE);
#endif
}

View File

@@ -35,8 +35,10 @@
#include "shadowlog_internal.h"
#include "sssd.h"
#include "string/memset/memzero.h"
#include "string/sprintf/aprintf.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strtok/stpsep.h"
@@ -74,17 +76,10 @@ int lrename (const char *old, const char *new)
{
int res;
char *r = NULL;
#ifndef __GLIBC__
char resolved_path[PATH_MAX];
#endif /* !__GLIBC__ */
struct stat sb;
if (lstat (new, &sb) == 0 && S_ISLNK (sb.st_mode)) {
#ifdef __GLIBC__ /* now a POSIX.1-2008 feature */
r = realpath (new, NULL);
#else /* !__GLIBC__ */
r = realpath (new, resolved_path);
#endif /* !__GLIBC__ */
if (NULL == r) {
perror ("realpath in lrename()");
} else {
@@ -94,9 +89,7 @@ int lrename (const char *old, const char *new)
res = rename (old, new);
#ifdef __GLIBC__
free (r);
#endif /* __GLIBC__ */
return res;
}
@@ -369,9 +362,12 @@ int commonio_lock_nowait (struct commonio_db *db, bool log)
return 1;
}
if (asprintf(&file, "%s.%ju", db->filename, (uintmax_t) getpid()) == -1)
file = aprintf("%s.%ju", db->filename, (uintmax_t) getpid());
if (file == NULL)
goto cleanup_ENOMEM;
if (asprintf(&lock, "%s.lock", db->filename) == -1)
lock = aprintf("%s.lock", db->filename);
if (lock == NULL)
goto cleanup_ENOMEM;
if (do_lock_file (file, lock, log) != 0) {
@@ -524,7 +520,7 @@ static void add_one_entry (struct commonio_db *db,
static bool name_is_nis (const char *name)
{
return (('+' == name[0]) || ('-' == name[0]));
return strprefix(name, "+") || strprefix(name, "-");
}

View File

@@ -17,6 +17,7 @@
#include "getdef.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strcpy/strtcpy.h"
#include "string/strtok/stpsep.h"
@@ -103,9 +104,7 @@ is_listed(const char *cfgin, const char *tty, bool def)
bool console (const char *tty)
{
if (strncmp (tty, "/dev/", 5) == 0) {
tty += 5;
}
tty = strprefix(tty, "/dev/") ?: tty;
return is_listed ("CONSOLE", tty, true);
}

View File

@@ -38,8 +38,10 @@
#include <attr/libattr.h>
#endif /* WITH_ATTR */
#include "shadowlog.h"
#include "string/sprintf/xasprintf.h"
#include "string/sprintf/aprintf.h"
#include "string/sprintf/xaprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
static /*@null@*/const char *src_orig;
@@ -232,7 +234,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
lp->ln_dev = sb->st_dev;
lp->ln_ino = sb->st_ino;
lp->ln_count = sb->st_nlink;
xasprintf(&lp->ln_name, "%s%s", dst_orig, name + strlen(src_orig));
lp->ln_name = xaprintf("%s%s", dst_orig, name + strlen(src_orig));
lp->ln_next = links;
links = lp;
@@ -321,13 +323,13 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
continue;
}
if (asprintf(&src_name, "%s/%s", src->full_path, ent->d_name) == -1)
{
src_name = aprintf("%s/%s", src->full_path, ent->d_name);
if (src_name == NULL) {
err = -1;
continue;
}
if (asprintf(&dst_name, "%s/%s", dst->full_path, ent->d_name) == -1)
{
dst_name = aprintf("%s/%s", dst->full_path, ent->d_name);
if (dst_name == NULL) {
err = -1;
goto skip;
}
@@ -576,10 +578,10 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
* create a link to the corresponding entry in the dst_orig
* directory.
*/
if (strncmp(oldlink, src_orig, strlen(src_orig)) == 0) {
if (strprefix(oldlink, src_orig)) {
char *dummy;
xasprintf(&dummy, "%s%s", dst_orig, oldlink + strlen(src_orig));
dummy = xaprintf("%s%s", dst_orig, oldlink + strlen(src_orig));
free(oldlink);
oldlink = dummy;
}

View File

@@ -65,6 +65,14 @@
#endif
#endif
#ifndef PATH_MAX
#define PATH_MAX 4096
#endif
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
#include <syslog.h>
#ifndef LOG_WARN

View File

@@ -17,6 +17,8 @@
#include "prototypes.h"
#include "defines.h"
#include "shadowlog_internal.h"
#include "string/strcmp/strprefix.h"
/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt)
{
@@ -35,7 +37,7 @@
/* Some crypt() do not return NULL if the algorithm is not
* supported, and return a DES encrypted password. */
if ((NULL != salt) && (salt[0] == '$') && (strlen (cp) <= 13))
if ((NULL != salt) && strprefix(salt, "$") && (strlen (cp) <= 13))
{
/*@observer@*/const char *method;
switch (salt[1])

View File

@@ -22,7 +22,8 @@
#include "defines.h"
#include "shadowlog.h"
#include "string/sprintf/snprintf.h"
#include "string/sprintf/xasprintf.h"
#include "string/sprintf/xaprintf.h"
#include "string/strcmp/strprefix.h"
#include "string/strdup/xstrdup.h"
@@ -77,7 +78,7 @@ void addenv (const char *string, /*@null@*/const char *value)
size_t i, n;
if (NULL != value) {
xasprintf(&newstring, "%s=%s", string, value);
newstring = xaprintf("%s=%s", string, value);
} else {
newstring = xstrdup (string);
}
@@ -175,7 +176,7 @@ void set_env (int argc, char *const *argv)
const char *const *p;
for (p = forbid; NULL != *p; p++) {
if (strncmp (*argv, *p, strlen (*p)) == 0) {
if (strprefix(*argv, *p)) {
break;
}
}
@@ -210,7 +211,7 @@ void sanitize_env (void)
for (cur = envp; NULL != *cur; cur++) {
for (bad = forbid; NULL != *bad; bad++) {
if (strncmp (*cur, *bad, strlen (*bad)) == 0) {
if (strprefix(*cur, *bad)) {
for (move = cur; NULL != *move; move++) {
*move = *(move + 1);
}
@@ -222,7 +223,7 @@ void sanitize_env (void)
for (cur = envp; NULL != *cur; cur++) {
for (bad = noslash; NULL != *bad; bad++) {
if (strncmp (*cur, *bad, strlen (*bad)) != 0) {
if (!strprefix(*cur, *bad)) {
continue;
}
if (strchr (*cur, '/') == NULL) {

View File

@@ -9,13 +9,15 @@
#include <config.h>
#ident "$Id$"
#include "fields.h"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "prototypes.h"
#include "string/ctype/strisascii/strisprint.h"
#include "string/ctype/strchrisascii/strchriscntrl.h"
#include "string/strcmp/streq.h"
#include "string/strspn/stpspn.h"
#include "string/strspn/stprspn.h"
@@ -25,41 +27,27 @@
/*
* valid_field - insure that a field contains all legal characters
*
* 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.
* + 0 is returned otherwise.
* Return:
* -1 Illegal or control characters are present.
* 1 Non-ASCII characters are present.
* 0 All chatacters are legal and ASCII.
*/
int valid_field (const char *field, const char *illegal)
int
valid_field_(const char *field, const char *illegal)
{
const char *cp;
int err = 0;
if (NULL == field) {
if (NULL == field)
return -1;
}
/* For each character of field, search if it appears in the list
* of illegal characters. */
if (illegal && NULL != strpbrk (field, illegal)) {
if (strpbrk(field, illegal))
return -1;
}
if (strchriscntrl(field))
return -1;
if (strisprint(field))
return 0;
if (streq(field, ""))
return 0;
/* Search if there are non-printable or control characters */
for (cp = field; !streq(cp, ""); cp++) {
unsigned char c = *cp;
if (!isprint (c)) {
err = 1;
}
if (iscntrl (c)) {
err = -1;
break;
}
}
return err;
return 1; // !ASCII
}
/*

20
lib/fields.h Normal file
View File

@@ -0,0 +1,20 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef _SHADOW_INCLUDE_LIB_FIELDS_H_
#define _SHADOW_INCLUDE_LIB_FIELDS_H_
#include <config.h>
#include <stddef.h>
#define valid_field(field, illegal) valid_field_(field, "" illegal "")
int valid_field_(const char *field, const char *illegal);
void change_field(char *buf, size_t maxsize, const char *prompt);
#endif // include guard

View File

@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "fs/mkstemp/fmkomstemp.h"
#include <stdio.h>
#include <sys/types.h>
extern inline FILE *fmkomstemp(char *template, unsigned int flags, mode_t m);

View File

@@ -0,0 +1,44 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_FS_MKSTEMP_FMKOMSTEMP_H_
#define SHADOW_INCLUDE_LIB_FS_MKSTEMP_FMKOMSTEMP_H_
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include "fs/mkstemp/mkomstemp.h"
inline FILE *fmkomstemp(char *template, unsigned int flags, mode_t m);
// FILE make with-open(2)-flags with-mode secure temporary
inline FILE *
fmkomstemp(char *template, unsigned int flags, mode_t m)
{
int fd;
FILE *fp;
fd = mkomstemp(template, flags, m);
if (fd == -1)
return NULL;
fp = fdopen(fd, "w");
if (fp == NULL)
goto fail;
return fp;
fail:
close(fd);
unlink(template);
return NULL;
}
#endif // include guard

View File

@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "fs/mkstemp/mkomstemp.h"
#include <sys/types.h>
extern inline int mkomstemp(char *template, unsigned int flags, mode_t m);

View File

@@ -0,0 +1,41 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_FS_MKSTEMP_MKOMSTEMP_H_
#define SHADOW_INCLUDE_LIB_FS_MKSTEMP_MKOMSTEMP_H_
#include <config.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
inline int mkomstemp(char *template, unsigned int flags, mode_t m);
// make with-open(2)-like-flags with-mode secure temporary
inline int
mkomstemp(char *template, unsigned int flags, mode_t m)
{
int fd;
fd = mkostemp(template, flags);
if (fd == -1)
return -1;
if (fchmod(fd, m) == -1)
goto fail;
return fd;
fail:
close(fd);
unlink(template);
return -1;
}
#endif // include guard

View File

@@ -9,11 +9,11 @@
#include <config.h>
#include <errno.h>
#include <limits.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "defines.h"
#include "alloc/malloc.h"
#include "attr.h"
#include "fs/readlink/readlinknul.h"

View File

@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
@@ -6,9 +6,8 @@
#include "fs/readlink/readlinknul.h"
#include <stddef.h>
#include <sys/types.h>
extern inline ssize_t readlinknul(const char *restrict link, char *restrict buf,
size_t size);
ssize_t size);

View File

@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
@@ -9,7 +9,6 @@
#include <config.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
@@ -18,35 +17,33 @@
#include "sizeof.h"
#define READLINKNUL(link, buf) readlinknul(link, buf, NITEMS(buf))
#define READLINKNUL(link, buf) readlinknul(link, buf, countof(buf))
ATTR_STRING(1)
inline ssize_t readlinknul(const char *restrict link, char *restrict buf,
size_t size);
ssize_t size);
// Similar to readlink(2), but terminate the string.
inline ssize_t
readlinknul(const char *restrict link, char *restrict buf, size_t size)
readlinknul(const char *restrict link, char *restrict buf, ssize_t size)
{
size_t ulen;
ssize_t slen;
ssize_t len;
slen = readlink(link, buf, size);
if (slen == -1)
len = readlink(link, buf, size);
if (len == -1)
return -1;
ulen = slen;
if (ulen == size) {
if (len == size) {
stpcpy(&buf[size-1], "");
errno = E2BIG;
return -1;
}
stpcpy(&buf[ulen], "");
stpcpy(&buf[len], "");
return slen;
return len;
}

View File

@@ -5,15 +5,15 @@
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <limits.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "defines.h"
#include "atoi/getnum.h"
#include "defines.h"
#include "prototypes.h"
#include "string/sprintf/snprintf.h"
@@ -52,22 +52,21 @@ int get_pidfd_from_fd(const char *pidfdstr)
int open_pidfd(const char *pidstr)
{
int proc_dir_fd;
char proc_dir_name[32];
char proc_dir_name[PATH_MAX];
pid_t target;
if (get_pid(pidstr, &target) == -1)
return -ENOENT;
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
if (SNPRINTF(proc_dir_name, "/proc/%u/", target) == -1) {
fprintf(stderr, "snprintf of proc path failed for %u: %s\n",
if (SNPRINTF(proc_dir_name, "/proc/%d/", target) == -1) {
fprintf(stderr, "snprintf of proc path failed for %d: %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"),
fprintf(stderr, _("Could not open proc directory for target %d: %s\n"),
target, strerror(errno));
return -EINVAL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +0,0 @@
/*
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _GETDATE_H_
#define _GETDATE_H_
#include <config.h>
#include "defines.h"
time_t get_date (const char *p, /*@null@*/const time_t *now);
#endif

View File

@@ -1,950 +0,0 @@
%{
/*
** Originally written by Steven M. Bellovin <smb@research.att.com> while
** at the University of North Carolina at Chapel Hill. Later tweaked by
** a couple of people on Usenet. Completely overhauled by Rich $alz
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
**
** This grammar has 13 shift/reduce conflicts.
**
** This code is in the public domain and has no copyright.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
/* Since the code of getdate.y is not included in the Emacs executable
itself, there is no need to #define static in this file. Even if
the code were included in the Emacs executable, it probably
wouldn't do any harm to #undef it here; this will only cause
problems if we try to write to a static variable, which I don't
think this code needs to do. */
#ifdef emacs
# undef static
#endif
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "attr.h"
#include "getdate.h"
#include "string/strcmp/streq.h"
#include "string/strspn/stpspn.h"
/* Some old versions of bison generate parsers that use bcopy.
That loses on systems that don't provide the function, so we have
to redefine it here. */
#if !defined (HAVE_BCOPY) && !defined (bcopy)
# define bcopy(from, to, len) memcpy ((to), (from), (len))
#endif
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
as well as gratuitously global symbol names, so we can have multiple
yacc generated parsers in the same program. Note that these are only
the variables produced by yacc. If other parser generators (bison,
byacc, etc) produce additional global names that conflict at link time,
then those parser generators need to be fixed instead of adding those
names to this list. */
#define yymaxdepth gd_maxdepth
#define yyparse gd_parse
#define yylex gd_lex
#define yyerror gd_error
#define yylval gd_lval
#define yychar gd_char
#define yydebug gd_debug
#define yypact gd_pact
#define yyr1 gd_r1
#define yyr2 gd_r2
#define yydef gd_def
#define yychk gd_chk
#define yypgo gd_pgo
#define yyact gd_act
#define yyexca gd_exca
#define yyerrflag gd_errflag
#define yynerrs gd_nerrs
#define yyps gd_ps
#define yypv gd_pv
#define yys gd_s
#define yy_yys gd_yys
#define yystate gd_state
#define yytmp gd_tmp
#define yyv gd_v
#define yy_yyv gd_yyv
#define yyval gd_val
#define yylloc gd_lloc
#define yyreds gd_reds /* With YYDEBUG defined */
#define yytoks gd_toks /* With YYDEBUG defined */
#define yylhs gd_yylhs
#define yylen gd_yylen
#define yydefred gd_yydefred
#define yydgoto gd_yydgoto
#define yysindex gd_yysindex
#define yyrindex gd_yyrindex
#define yygindex gd_yygindex
#define yytable gd_yytable
#define yycheck gd_yycheck
static int yylex (void);
static int yyerror (const char *s);
#define EPOCH 1970
#define HOUR(x) ((x) * 60)
#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */
/*
** An entry in the lexical lookup table.
*/
typedef struct _TABLE {
const char *name;
int type;
int value;
} TABLE;
/*
** Meridian: am, pm, or 24-hour style.
*/
typedef enum _MERIDIAN {
MERam, MERpm, MER24
} MERIDIAN;
/*
** Global variables. We could get rid of most of these by using a good
** union as the yacc stack. (This routine was originally written before
** yacc had the %union construct.) Maybe someday; right now we only use
** the %union very rarely.
*/
static const char *yyInput;
static int yyDayOrdinal;
static int yyDayNumber;
static int yyHaveDate;
static int yyHaveDay;
static int yyHaveRel;
static int yyHaveTime;
static int yyHaveZone;
static int yyTimezone;
static int yyDay;
static int yyHour;
static int yyMinutes;
static int yyMonth;
static int yySeconds;
static int yyYear;
static MERIDIAN yyMeridian;
static int yyRelDay;
static int yyRelHour;
static int yyRelMinutes;
static int yyRelMonth;
static int yyRelSeconds;
static int yyRelYear;
%}
%union {
int Number;
enum _MERIDIAN Meridian;
}
%token tAGO tDAY tDAY_UNIT tDAYZONE tDST tHOUR_UNIT tID
%token tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
%token tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
%type <Number> tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tMINUTE_UNIT
%type <Number> tMONTH tMONTH_UNIT
%type <Number> tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
%type <Meridian> tMERIDIAN o_merid
%%
spec : /* NULL */
| spec item
;
item : time {
yyHaveTime++;
}
| zone {
yyHaveZone++;
}
| date {
yyHaveDate++;
}
| day {
yyHaveDay++;
}
| rel {
yyHaveRel++;
}
| number
;
time : tUNUMBER tMERIDIAN {
yyHour = $1;
yyMinutes = 0;
yySeconds = 0;
yyMeridian = $2;
}
| tUNUMBER ':' tUNUMBER o_merid {
yyHour = $1;
yyMinutes = $3;
yySeconds = 0;
yyMeridian = $4;
}
| tUNUMBER ':' tUNUMBER tSNUMBER {
yyHour = $1;
yyMinutes = $3;
yyMeridian = MER24;
yyHaveZone++;
yyTimezone = ($4 < 0
? -$4 % 100 + (-$4 / 100) * 60
: - ($4 % 100 + ($4 / 100) * 60));
}
| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
yyHour = $1;
yyMinutes = $3;
yySeconds = $5;
yyMeridian = $6;
}
| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
yyHour = $1;
yyMinutes = $3;
yySeconds = $5;
yyMeridian = MER24;
yyHaveZone++;
yyTimezone = ($6 < 0
? -$6 % 100 + (-$6 / 100) * 60
: - ($6 % 100 + ($6 / 100) * 60));
}
;
zone : tZONE {
yyTimezone = $1;
}
| tDAYZONE {
yyTimezone = $1 - 60;
}
|
tZONE tDST {
yyTimezone = $1 - 60;
}
;
day : tDAY {
yyDayOrdinal = 1;
yyDayNumber = $1;
}
| tDAY ',' {
yyDayOrdinal = 1;
yyDayNumber = $1;
}
| tUNUMBER tDAY {
yyDayOrdinal = $1;
yyDayNumber = $2;
}
;
date : tUNUMBER '/' tUNUMBER {
yyMonth = $1;
yyDay = $3;
}
| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
/* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
The goal in recognizing YYYY/MM/DD is solely to support legacy
machine-generated dates like those in an RCS log listing. If
you want portability, use the ISO 8601 format. */
if ($1 >= 1000)
{
yyYear = $1;
yyMonth = $3;
yyDay = $5;
}
else
{
yyMonth = $1;
yyDay = $3;
yyYear = $5;
}
}
| tUNUMBER tSNUMBER tSNUMBER {
/* ISO 8601 format. yyyy-mm-dd. */
yyYear = $1;
yyMonth = -$2;
yyDay = -$3;
}
| tUNUMBER tMONTH tSNUMBER {
/* e.g. 17-JUN-1992. */
yyDay = $1;
yyMonth = $2;
yyYear = -$3;
}
| tMONTH tUNUMBER {
yyMonth = $1;
yyDay = $2;
}
| tMONTH tUNUMBER ',' tUNUMBER {
yyMonth = $1;
yyDay = $2;
yyYear = $4;
}
| tUNUMBER tMONTH {
yyMonth = $2;
yyDay = $1;
}
| tUNUMBER tMONTH tUNUMBER {
yyMonth = $2;
yyDay = $1;
yyYear = $3;
}
;
rel : relunit tAGO {
yyRelSeconds = -yyRelSeconds;
yyRelMinutes = -yyRelMinutes;
yyRelHour = -yyRelHour;
yyRelDay = -yyRelDay;
yyRelMonth = -yyRelMonth;
yyRelYear = -yyRelYear;
}
| relunit
;
relunit : tUNUMBER tYEAR_UNIT {
yyRelYear += $1 * $2;
}
| tSNUMBER tYEAR_UNIT {
yyRelYear += $1 * $2;
}
| tYEAR_UNIT {
yyRelYear += $1;
}
| tUNUMBER tMONTH_UNIT {
yyRelMonth += $1 * $2;
}
| tSNUMBER tMONTH_UNIT {
yyRelMonth += $1 * $2;
}
| tMONTH_UNIT {
yyRelMonth += $1;
}
| tUNUMBER tDAY_UNIT {
yyRelDay += $1 * $2;
}
| tSNUMBER tDAY_UNIT {
yyRelDay += $1 * $2;
}
| tDAY_UNIT {
yyRelDay += $1;
}
| tUNUMBER tHOUR_UNIT {
yyRelHour += $1 * $2;
}
| tSNUMBER tHOUR_UNIT {
yyRelHour += $1 * $2;
}
| tHOUR_UNIT {
yyRelHour += $1;
}
| tUNUMBER tMINUTE_UNIT {
yyRelMinutes += $1 * $2;
}
| tSNUMBER tMINUTE_UNIT {
yyRelMinutes += $1 * $2;
}
| tMINUTE_UNIT {
yyRelMinutes += $1;
}
| tUNUMBER tSEC_UNIT {
yyRelSeconds += $1 * $2;
}
| tSNUMBER tSEC_UNIT {
yyRelSeconds += $1 * $2;
}
| tSEC_UNIT {
yyRelSeconds += $1;
}
;
number : tUNUMBER
{
if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0))
yyYear = $1;
else
{
if ($1>10000)
{
yyHaveDate++;
yyDay= ($1)%100;
yyMonth= ($1/100)%100;
yyYear = $1/10000;
}
else
{
yyHaveTime++;
if ($1 < 100)
{
yyHour = $1;
yyMinutes = 0;
}
else
{
yyHour = $1 / 100;
yyMinutes = $1 % 100;
}
yySeconds = 0;
yyMeridian = MER24;
}
}
}
;
o_merid : /* NULL */
{
$$ = MER24;
}
| tMERIDIAN
{
$$ = $1;
}
;
%%
/* Month and day table. */
static TABLE const MonthDayTable[] = {
{ "january", tMONTH, 1 },
{ "february", tMONTH, 2 },
{ "march", tMONTH, 3 },
{ "april", tMONTH, 4 },
{ "may", tMONTH, 5 },
{ "june", tMONTH, 6 },
{ "july", tMONTH, 7 },
{ "august", tMONTH, 8 },
{ "september", tMONTH, 9 },
{ "sept", tMONTH, 9 },
{ "october", tMONTH, 10 },
{ "november", tMONTH, 11 },
{ "december", tMONTH, 12 },
{ "sunday", tDAY, 0 },
{ "monday", tDAY, 1 },
{ "tuesday", tDAY, 2 },
{ "tues", tDAY, 2 },
{ "wednesday", tDAY, 3 },
{ "wednes", tDAY, 3 },
{ "thursday", tDAY, 4 },
{ "thur", tDAY, 4 },
{ "thurs", tDAY, 4 },
{ "friday", tDAY, 5 },
{ "saturday", tDAY, 6 },
{ NULL, 0, 0 }
};
/* Time units table. */
static TABLE const UnitsTable[] = {
{ "year", tYEAR_UNIT, 1 },
{ "month", tMONTH_UNIT, 1 },
{ "fortnight", tDAY_UNIT, 14 },
{ "week", tDAY_UNIT, 7 },
{ "day", tDAY_UNIT, 1 },
{ "hour", tHOUR_UNIT, 1 },
{ "minute", tMINUTE_UNIT, 1 },
{ "min", tMINUTE_UNIT, 1 },
{ "second", tSEC_UNIT, 1 },
{ "sec", tSEC_UNIT, 1 },
{ NULL, 0, 0 }
};
/* Assorted relative-time words. */
static TABLE const OtherTable[] = {
{ "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
{ "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
{ "today", tMINUTE_UNIT, 0 },
{ "now", tMINUTE_UNIT, 0 },
{ "last", tUNUMBER, -1 },
{ "this", tMINUTE_UNIT, 0 },
{ "next", tUNUMBER, 2 },
{ "first", tUNUMBER, 1 },
/* { "second", tUNUMBER, 2 }, */
{ "third", tUNUMBER, 3 },
{ "fourth", tUNUMBER, 4 },
{ "fifth", tUNUMBER, 5 },
{ "sixth", tUNUMBER, 6 },
{ "seventh", tUNUMBER, 7 },
{ "eighth", tUNUMBER, 8 },
{ "ninth", tUNUMBER, 9 },
{ "tenth", tUNUMBER, 10 },
{ "eleventh", tUNUMBER, 11 },
{ "twelfth", tUNUMBER, 12 },
{ "ago", tAGO, 1 },
{ NULL, 0, 0 }
};
/* The timezone table. */
static TABLE const TimezoneTable[] = {
{ "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */
{ "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
{ "utc", tZONE, HOUR ( 0) },
{ "wet", tZONE, HOUR ( 0) }, /* Western European */
{ "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */
{ "wat", tZONE, HOUR ( 1) }, /* West Africa */
{ "at", tZONE, HOUR ( 2) }, /* Azores */
{ "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */
{ "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */
{ "est", tZONE, HOUR ( 5) }, /* Eastern Standard */
{ "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */
{ "cst", tZONE, HOUR ( 6) }, /* Central Standard */
{ "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */
{ "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */
{ "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */
{ "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */
{ "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */
{ "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */
{ "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */
{ "hst", tZONE, HOUR (10) }, /* Hawaii Standard */
{ "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */
{ "cat", tZONE, HOUR (10) }, /* Central Alaska */
{ "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */
{ "nt", tZONE, HOUR (11) }, /* Nome */
{ "idlw", tZONE, HOUR (12) }, /* International Date Line West */
{ "cet", tZONE, -HOUR (1) }, /* Central European */
{ "met", tZONE, -HOUR (1) }, /* Middle European */
{ "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */
{ "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
{ "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
{ "swt", tZONE, -HOUR (1) }, /* Swedish Winter */
{ "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */
{ "fwt", tZONE, -HOUR (1) }, /* French Winter */
{ "fst", tDAYZONE, -HOUR (1) }, /* French Summer */
{ "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */
{ "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */
{ "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */
{ "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */
{ "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */
{ "wast", tZONE, -HOUR (7) }, /* West Australian Standard */
{ "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */
{ "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */
{ "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */
{ "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */
{ "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */
{ "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */
{ "nzt", tZONE, -HOUR (12) }, /* New Zealand */
{ "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */
{ "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */
{ "idle", tZONE, -HOUR (12) }, /* International Date Line East */
{ NULL, 0, 0 }
};
/* Military timezone table. */
static TABLE const MilitaryTable[] = {
{ "a", tZONE, HOUR ( 1) },
{ "b", tZONE, HOUR ( 2) },
{ "c", tZONE, HOUR ( 3) },
{ "d", tZONE, HOUR ( 4) },
{ "e", tZONE, HOUR ( 5) },
{ "f", tZONE, HOUR ( 6) },
{ "g", tZONE, HOUR ( 7) },
{ "h", tZONE, HOUR ( 8) },
{ "i", tZONE, HOUR ( 9) },
{ "k", tZONE, HOUR ( 10) },
{ "l", tZONE, HOUR ( 11) },
{ "m", tZONE, HOUR ( 12) },
{ "n", tZONE, HOUR (- 1) },
{ "o", tZONE, HOUR (- 2) },
{ "p", tZONE, HOUR (- 3) },
{ "q", tZONE, HOUR (- 4) },
{ "r", tZONE, HOUR (- 5) },
{ "s", tZONE, HOUR (- 6) },
{ "t", tZONE, HOUR (- 7) },
{ "u", tZONE, HOUR (- 8) },
{ "v", tZONE, HOUR (- 9) },
{ "w", tZONE, HOUR (-10) },
{ "x", tZONE, HOUR (-11) },
{ "y", tZONE, HOUR (-12) },
{ "z", tZONE, HOUR ( 0) },
{ NULL, 0, 0 }
};
static int yyerror (MAYBE_UNUSED const char *s)
{
return 0;
}
static int ToHour (int Hours, MERIDIAN Meridian)
{
switch (Meridian)
{
case MER24:
if (Hours < 0 || Hours > 23)
return -1;
return Hours;
case MERam:
if (Hours < 1 || Hours > 12)
return -1;
if (Hours == 12)
Hours = 0;
return Hours;
case MERpm:
if (Hours < 1 || Hours > 12)
return -1;
if (Hours == 12)
Hours = 0;
return Hours + 12;
default:
abort ();
}
/* NOTREACHED */
}
static int ToYear (int Year)
{
if (Year < 0)
Year = -Year;
/* XPG4 suggests that years 00-68 map to 2000-2068, and
years 69-99 map to 1969-1999. */
if (Year < 69)
Year += 2000;
else if (Year < 100)
Year += 1900;
return Year;
}
static int LookupWord (char *buff)
{
register char *p;
register char *q;
register const TABLE *tp;
int i;
bool abbrev;
/* Make it lowercase. */
for (p = buff; !streq(p, ""); p++)
if (isupper (*p))
*p = tolower (*p);
if (streq(buff, "am") || streq(buff, "a.m."))
{
yylval.Meridian = MERam;
return tMERIDIAN;
}
if (streq(buff, "pm") || streq(buff, "p.m."))
{
yylval.Meridian = MERpm;
return tMERIDIAN;
}
/* See if we have an abbreviation for a month. */
if (strlen (buff) == 3)
abbrev = true;
else if (strlen (buff) == 4 && buff[3] == '.')
{
abbrev = true;
stpcpy(&buff[3], "");
}
else
abbrev = false;
for (tp = MonthDayTable; tp->name; tp++)
{
if (abbrev)
{
if (strncmp (buff, tp->name, 3) == 0)
{
yylval.Number = tp->value;
return tp->type;
}
}
else if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
}
for (tp = TimezoneTable; tp->name; tp++)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
if (streq(buff, "dst"))
return tDST;
for (tp = UnitsTable; tp->name; tp++)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
/* Strip off any plural and try the units table again. */
i = strlen (buff) - 1;
if (buff[i] == 's')
{
stpcpy(&buff[i], "");
for (tp = UnitsTable; tp->name; tp++)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
buff[i] = 's'; /* Put back for "this" in OtherTable. */
}
for (tp = OtherTable; tp->name; tp++)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
/* Military timezones. */
if (buff[1] == '\0' && isalpha (*buff))
{
for (tp = MilitaryTable; tp->name; tp++)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
}
/* Drop out any periods and try the timezone table again. */
for (i = 0, p = q = buff; !streq(q, ""); q++)
if (*q != '.')
*p++ = *q;
else
i++;
stpcpy(p, "");
if (0 != i)
for (tp = TimezoneTable; NULL != tp->name; tp++)
if (streq(buff, tp->name))
{
yylval.Number = tp->value;
return tp->type;
}
return tID;
}
static int
yylex (void)
{
register char c;
register char *p;
char buff[20];
int Count;
int sign;
for (;;)
{
yyInput = stpspn(yyInput, " \t");
if (isdigit (c = *yyInput) || c == '-' || c == '+')
{
if (c == '-' || c == '+')
{
sign = c == '-' ? -1 : 1;
if (!isdigit (*++yyInput))
/* skip the '-' sign */
continue;
}
else
sign = 0;
for (yylval.Number = 0; isdigit (c = *yyInput++);)
yylval.Number = 10 * yylval.Number + c - '0';
yyInput--;
if (sign < 0)
yylval.Number = -yylval.Number;
return (0 != sign) ? tSNUMBER : tUNUMBER;
}
if (isalpha (c))
{
for (p = buff; (c = *yyInput++, isalpha (c)) || c == '.';)
if (p < &buff[sizeof buff - 1])
*p++ = c;
stpcpy(p, "");
yyInput--;
return LookupWord (buff);
}
if (c != '(')
return *yyInput++;
Count = 0;
do
{
c = *yyInput++;
if (c == '\0')
return c;
if (c == '(')
Count++;
else if (c == ')')
Count--;
}
while (Count > 0);
}
}
#define TM_YEAR_ORIGIN 1900
/* Yield A - B, measured in seconds. */
static long difftm (struct tm *a, struct tm *b)
{
int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
long days = (
/* difference in day of year */
a->tm_yday - b->tm_yday
/* + intervening leap days */
+ ((ay >> 2) - (by >> 2))
- (ay / 100 - by / 100)
+ ((ay / 100 >> 2) - (by / 100 >> 2))
/* + difference in years * 365 */
+ (long) (ay - by) * 365
);
return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ (a->tm_min - b->tm_min))
+ (a->tm_sec - b->tm_sec));
}
time_t get_date (const char *p, const time_t *now)
{
struct tm tm, tm0, *tmp;
time_t Start;
yyInput = p;
Start = now ? *now : time(NULL);
tmp = localtime (&Start);
yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
yyMonth = tmp->tm_mon + 1;
yyDay = tmp->tm_mday;
yyHour = tmp->tm_hour;
yyMinutes = tmp->tm_min;
yySeconds = tmp->tm_sec;
yyMeridian = MER24;
yyRelSeconds = 0;
yyRelMinutes = 0;
yyRelHour = 0;
yyRelDay = 0;
yyRelMonth = 0;
yyRelYear = 0;
yyHaveDate = 0;
yyHaveDay = 0;
yyHaveRel = 0;
yyHaveTime = 0;
yyHaveZone = 0;
if (yyparse ()
|| yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
return -1;
tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
tm.tm_mon = yyMonth - 1 + yyRelMonth;
tm.tm_mday = yyDay + yyRelDay;
if ((yyHaveTime != 0) ||
( (yyHaveRel != 0) && (yyHaveDate == 0) && (yyHaveDay == 0) ))
{
tm.tm_hour = ToHour (yyHour, yyMeridian);
if (tm.tm_hour < 0)
return -1;
tm.tm_min = yyMinutes;
tm.tm_sec = yySeconds;
}
else
{
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
}
tm.tm_hour += yyRelHour;
tm.tm_min += yyRelMinutes;
tm.tm_sec += yyRelSeconds;
tm.tm_isdst = -1;
tm0 = tm;
Start = mktime (&tm);
if (Start == (time_t) -1)
{
/* Guard against falsely reporting errors near the time_t boundaries
when parsing times in other time zones. For example, if the min
time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
of UTC, then the min localtime value is 1970-01-01 08:00:00; if
we apply mktime to 1970-01-01 00:00:00 we will get an error, so
we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
zone by 24 hours to compensate. This algorithm assumes that
there is no DST transition within a day of the time_t boundaries. */
if (yyHaveZone)
{
tm = tm0;
if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
{
tm.tm_mday++;
yyTimezone -= 24 * 60;
}
else
{
tm.tm_mday--;
yyTimezone += 24 * 60;
}
Start = mktime (&tm);
}
if (Start == (time_t) -1)
return Start;
}
if (yyHaveDay && !yyHaveDate)
{
tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
+ 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
Start = mktime (&tm);
if (Start == (time_t) -1)
return Start;
}
if (yyHaveZone)
{
long delta = yyTimezone * 60L + difftm (&tm, gmtime (&Start));
if ((Start + delta < Start) != (delta < 0))
return -1; /* time_t overflow */
Start += delta;
}
return Start;
}
#if defined (TEST)
int
main(void)
{
char buff[MAX_BUFF_LEN + 1];
time_t d;
(void) printf ("Enter date, or blank line to exit.\n\t> ");
(void) fflush (stdout);
buff[MAX_BUFF_LEN] = 0;
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
{
d = get_date(buff, NULL);
if (d == -1)
(void) printf ("Bad format - couldn't convert.\n");
else
(void) printf ("%s", ctime (&d));
(void) printf ("\t> ");
(void) fflush (stdout);
}
exit (0);
/* NOTREACHED */
}
#endif /* defined (TEST) */

View File

@@ -24,14 +24,16 @@
#include "atoi/a2i/a2s.h"
#include "atoi/a2i/a2u.h"
#include "atoi/str2i/str2u.h"
#include "atoi/str2i.h"
#include "defines.h"
#include "getdef.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/sprintf/xasprintf.h"
#include "sizeof.h"
#include "string/sprintf/xaprintf.h"
#include "string/strcmp/strcaseeq.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strspn/stpspn.h"
#include "string/strspn/stprspn.h"
#include "string/strtok/stpsep.h"
@@ -76,12 +78,12 @@ struct itemdef {
#define FOREIGNDEFS \
{"ALWAYS_SET_PATH", NULL}, \
{"ENV_ROOTPATH", NULL}, \
{"LOGIN_ENV_SAFELIST", NULL}, \
{"LOGIN_KEEP_USERNAME", NULL}, \
{"LOGIN_PLAIN_PROMPT", NULL}, \
{"MOTD_FIRSTONLY", NULL}, \
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
static struct itemdef def_table[] = {
{"CHFN_RESTRICT", NULL},
{"CONSOLE_GROUPS", NULL},
@@ -454,13 +456,9 @@ out:
void setdef_config_file (const char* file)
{
#ifdef USE_ECONF
char *cp;
xasprintf(&cp, "%s/%s", file, sysconfdir);
sysconfdir = cp;
sysconfdir = xaprintf("%s/%s", file, sysconfdir);
#ifdef VENDORDIR
xasprintf(&cp, "%s/%s", file, vendordir);
vendordir = cp;
vendordir = xaprintf("%s/%s", file, vendordir);
#endif
#else
def_fname = file;
@@ -568,7 +566,7 @@ static void def_load (void)
* Break the line into two fields.
*/
name = stpspn(buf, " \t"); /* first nonwhite */
if (streq(name, "") || *name == '#')
if (streq(name, "") || strprefix(name, "#"))
continue; /* comment or empty */
s = stpsep(name, " \t"); /* next field */
@@ -609,7 +607,7 @@ int main (int argc, char **argv)
def_load ();
for (i = 0; i < NUMDEFS; ++i) {
for (i = 0; i < countof(def_table); ++i) {
d = def_find (def_table[i].name, NULL);
if (NULL == d) {
printf ("error - lookup '%s' failed\n",

View File

@@ -19,9 +19,11 @@
#include "alloc/malloc.h"
#include "commonio.h"
#include "defines.h"
#include "fields.h"
#include "getdef.h"
#include "groupio.h"
#include "prototypes.h"
#include "string/sprintf/aprintf.h"
#include "string/strcmp/streq.h"
@@ -324,7 +326,8 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
}
/* Concatenate the 2 lines */
if (asprintf(&new_line, "%s\n%s", gr1->line, gr2->line) == -1)
new_line = aprintf("%s\n%s", gr1->line, gr2->line);
if (new_line == NULL)
return NULL;
/* Concatenate the 2 list of members */

View File

@@ -15,36 +15,33 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "alloc/malloc.h"
#include "alloc/realloc.h"
#include "alloc/x/xmalloc.h"
#include "defines.h"
#include "prototypes.h"
#include "string/strchr/strchrcnt.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
#include "string/strtok/strsep2arr.h"
#include "string/strtok/xastrsep2ls.h"
static /*@null@*/FILE *shadow;
static struct sgrp sgroup = {};
#define FIELDS 4
static /*@null@*/char **
build_list(char *s)
{
char **l;
size_t i;
size_t n;
l = XMALLOC(strchrcnt(s, ',') + 2, char *);
l = xastrsep2ls(s, ",", &n);
for (i = 0; s != NULL && !streq(s, ""); i++)
l[i] = strsep(&s, ",");
l[i] = NULL;
if (streq(l[n-1], ""))
l[n-1] = NULL;
return l;
}
@@ -68,42 +65,20 @@ void endsgent (void)
}
/*@observer@*//*@null@*/struct sgrp *
sgetsgent(const char *string)
sgetsgent(const char *s)
{
static char *sgrbuf = NULL;
static size_t sgrbuflen = 0;
static char *dup = NULL;
char *fields[FIELDS];
char *cp;
int i;
size_t len = strlen (string) + 1;
char *fields[4];
if (len > sgrbuflen) {
char *buf = REALLOC(sgrbuf, len, char);
if (NULL == buf)
return NULL;
free(dup);
dup = strdup(s);
if (dup == NULL)
return NULL;
sgrbuf = buf;
sgrbuflen = len;
}
stpsep(dup, "\n");
strcpy (sgrbuf, string);
stpsep(sgrbuf, "\n");
/*
* There should be exactly 4 colon separated fields. Find
* all 4 of them and save the starting addresses in fields[].
*/
for (cp = sgrbuf, i = 0; (i < FIELDS) && (NULL != cp); i++)
fields[i] = strsep(&cp, ":");
/*
* If there was an extra field somehow, or perhaps not enough,
* the line is invalid.
*/
if (NULL != cp || i != FIELDS)
if (STRSEP2ARR(dup, ":", fields) == -1)
return NULL;
sgroup.sg_namp = fields[0];

View File

@@ -32,11 +32,10 @@
#include "atoi/a2i/a2i.h"
#include "atoi/a2i/a2s.h"
#include "atoi/str2i/str2i.h"
#include "atoi/str2i/str2s.h"
#include "atoi/str2i/str2u.h"
#include "atoi/str2i.h"
#include "string/memset/memzero.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strspn/stpspn.h"
#include "typetraits.h"
@@ -62,7 +61,7 @@ static int setrlimit_value (unsigned int resource,
/* The "-" is special, not belonging to a strange negative limit.
* It is infinity, in a controlled way.
*/
if ('-' == value[0]) {
if (strprefix(value, "-")) {
limit = RLIM_INFINITY;
} else {
@@ -370,7 +369,7 @@ static int setup_user_limits (const char *uname)
* FIXME: A better (smarter) checking should be done
*/
while (fgets (buf, 1024, fil) != NULL) {
if (('#' == buf[0]) || ('\n' == buf[0])) {
if (strprefix(buf, "#") || strprefix(buf, "\n")) {
continue;
}
MEMZERO(tempbuf);
@@ -401,7 +400,7 @@ static int setup_user_limits (const char *uname)
break;
} else if (streq(name, "*")) {
strcpy (deflimits, tempbuf);
} else if (name[0] == '@') {
} else if (strprefix(name, "@")) {
/* If the user is in the group, the group
* limits apply unless later a line for
* the specific user is found.
@@ -473,14 +472,15 @@ void setup_limits (const struct passwd *info)
}
}
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
if (',' == *cp) {
cp++;
}
char *val;
if (strncmp (cp, "pri=", 4) == 0) {
cp = strprefix(cp, ",") ?: cp;
val = strprefix(cp, "pri=");
if (val != NULL) {
int inc;
if (a2si(&inc, cp + 4, NULL, 0, -20, 20) == 0) {
if (a2si(&inc, val, NULL, 0, -20, 20) == 0) {
errno = 0;
if ( (nice (inc) != -1)
|| (0 != errno)) {
@@ -495,10 +495,12 @@ void setup_limits (const struct passwd *info)
continue;
}
if (strncmp (cp, "ulimit=", 7) == 0) {
val = strprefix(cp, "ulimit=");
if (val != NULL) {
int blocks;
if ( (str2si(&blocks, cp + 7) == -1)
if ( (str2si(&blocks, val) == -1)
|| (set_filesize_limit (blocks) != 0)) {
SYSLOG ((LOG_WARN,
"Can't set the ulimit for user %s",
@@ -506,10 +508,12 @@ void setup_limits (const struct passwd *info)
}
continue;
}
if (strncmp (cp, "umask=", 6) == 0) {
val = strprefix(cp, "umask=");
if (val != NULL) {
mode_t mask;
if (str2i(mode_t, &mask, cp + 6) == -1) {
if (str2i(mode_t, &mask, val) == -1) {
SYSLOG ((LOG_WARN,
"Can't set umask value for user %s",
info->pw_name));

View File

@@ -18,6 +18,7 @@
#include "string/strchr/strchrcnt.h"
#include "string/strcmp/streq.h"
#include "string/strdup/xstrdup.h"
#include "string/strtok/strsep2ls.h"
/*
@@ -186,9 +187,7 @@ comma_to_list(const char *comma)
{
char *members;
char **array;
int i;
char *cp;
char *cp2;
size_t n;
assert (NULL != comma);
@@ -203,7 +202,8 @@ comma_to_list(const char *comma)
* n: number of delimiters + last element + NULL
*/
array = XMALLOC(strchrcnt(members, ',') + 2, char *);
n = strchrcnt(members, ',') + 2;
array = XMALLOC(n, char *);
/*
* Empty list is special - 0 members, not 1 empty member. --marekm
@@ -215,18 +215,7 @@ comma_to_list(const char *comma)
return array;
}
/*
* Now go walk that list all over again, this time building the
* array of pointers.
*/
for (cp = members, i = 0; cp != NULL; i++)
array[i] = strsep(&cp, ",");
array[i] = NULL;
/*
* Return the new array of pointers
*/
strsep2ls(members, ",", n, array);
return array;
}

View File

@@ -16,7 +16,7 @@
#include <string.h>
#include "getdef.h"
#include "string/sprintf/xasprintf.h"
#include "string/sprintf/xaprintf.h"
#ident "$Id$"
@@ -37,7 +37,7 @@ void mailcheck (void)
if (NULL != mailbox) {
char *newmail;
xasprintf(&newmail, "%s/new", mailbox);
newmail = xaprintf("%s/new", mailbox);
if (stat (newmail, &statbuf) != -1 && statbuf.st_size != 0) {
if (statbuf.st_mtime > statbuf.st_atime) {

View File

@@ -1,117 +0,0 @@
/*
* SPDX-FileCopyrightText: 2019-2023, Alejandro Colomar <alx@kernel.org>
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef SHADOW_INCLUDE_LIBMISC_MUST_BE_H_
#define SHADOW_INCLUDE_LIBMISC_MUST_BE_H_
#include <config.h>
#include <assert.h>
/*
* SYNOPSIS
* int must_be(bool e);
*
* ARGUMENTS
* e Expression to be asserted.
*
* DESCRIPTION
* This macro fails compilation if 'e' is false. If 'e' is true,
* it returns (int) 0, so it doesn't affect the expression in which
* it is contained.
*
* This macro is similar to static_assert(3). While
* static_assert(3) can only be used where a statement is allowed,
* this must_be() macro can be used wherever an expression is
* allowed.
*
* RETURN VALUE
* 0
*
* ERRORS
* If 'e' is false, the compilation will fail, as when using
* static_assert(3).
*
* EXAMPLES
* #define must_be_array(a) must_be(is_array(a))
*
* #define NITEMS(a) (sizeof(a) / sizeof(*(a)) + must_be_array(a))
*
* int foo[42];
* int bar[NITEMS(foo)];
*/
#define must_be(e) \
( \
0 * (int) sizeof( \
struct { \
static_assert(e, ""); \
int ISO_C_forbids_a_struct_with_no_members_; \
} \
) \
)
/*
* SYNOPSIS
* int must_be_array(a);
*
* ARGUMENTS
* a Array.
*
* DESCRIPTION
* This macro fails compilation if 'a' is not an array. It is
* useful in macros that accept an array as a parameter, where this
* macro can validate the macro argument. It prevent passing a
* pointer to such macros, which would otherwise produce silent
* bugs.
*
* RETURN VALUE
* 0
*
* ERRORS
* If 'a' is not an array, the compilation will fail.
*
* EXAMPLES
* int a[10];
* int *p;
*
* must_be_array(a); // Ok
* must_be_array(p); // Compile-time error
*
* SEE ALSO
* must_be()
*/
#define is_same_type(a, b) \
( \
__builtin_types_compatible_p(a, b) \
)
#define is_same_typeof(a, b) \
( \
is_same_type(typeof(a), typeof(b)) \
)
#define is_array(a) \
( \
!is_same_typeof(a, &(a)[0]) \
)
#define must_be_array(a) \
( \
must_be(is_array(a)) \
)
#endif // include guard

View File

@@ -15,7 +15,9 @@
#include "shadowlog_internal.h"
#include "shadowlog.h"
#include "string/sprintf/snprintf.h"
#include "string/strcmp/strcaseprefix.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strspn/stpspn.h"
#include "string/strtok/stpsep.h"
@@ -79,11 +81,11 @@ nss_init(const char *nsswitch_path) {
}
p = NULL;
while (getline(&line, &len, nssfp) != -1) {
if (line[0] == '#')
if (strprefix(line, "#"))
continue;
if (strlen(line) < 8)
continue;
if (strncasecmp(line, "subid:", 6) != 0)
if (!strcaseprefix(line, "subid:"))
continue;
p = &line[6];
p = stpspn(p, " \t\n");

View File

@@ -1,11 +1,10 @@
/*
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 1989-1994, Julianne Frances Haugh
// SPDX-FileCopyrightText: 1996-1999, Marek Michałkiewicz
// SPDX-FileCopyrightText: 2003-2005, Tomasz Kłoczko
// SPDX-FileCopyrightText: 2007-2010, Nicolas François
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
@@ -19,8 +18,9 @@
#include "prototypes.h"
#include "defines.h"
#include "getdef.h"
#include "string/ctype/strtoascii/strtolower.h"
#include "string/memset/memzero.h"
#include "string/sprintf/xasprintf.h"
#include "string/sprintf/xaprintf.h"
#include "string/strcmp/streq.h"
#include "string/strdup/xstrdup.h"
@@ -78,15 +78,6 @@ static bool similar (/*@notnull@*/const char *old, /*@notnull@*/const char *new)
return true;
}
static char *str_lower (/*@returned@*/char *string)
{
char *cp;
for (cp = string; !streq(cp, ""); cp++) {
*cp = tolower (*cp);
}
return string;
}
static /*@observer@*//*@null@*/const char *password_check (
/*@notnull@*/const char *old,
@@ -100,9 +91,9 @@ static /*@observer@*//*@null@*/const char *password_check (
return _("no change");
}
newmono = str_lower (xstrdup (new));
oldmono = str_lower (xstrdup (old));
xasprintf(&wrapped, "%s%s", oldmono, oldmono);
newmono = strtolower(xstrdup(new));
oldmono = strtolower(xstrdup(old));
wrapped = xaprintf("%s%s", oldmono, oldmono);
if (palindrome (oldmono, newmono)) {
msg = _("a palindrome");

View File

@@ -10,6 +10,9 @@
#ifdef USE_PAM
/* Copied from src/passwd.c */
#define E_PAM_ERR 10 /* PAM returned an error */
#ident "$Id$"
@@ -40,7 +43,7 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
if (ret != PAM_SUCCESS) {
fprintf (shadow_logfd,
_("passwd: pam_start() failed, error %d\n"), ret);
exit (10); /* XXX */
exit (E_PAM_ERR);
}
ret = pam_chauthtok (pamh, flags);
@@ -48,7 +51,7 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret));
fputs (_("passwd: password unchanged\n"), shadow_logfd);
pam_end (pamh, ret);
exit (10); /* XXX */
exit (E_PAM_ERR);
}
fputs (_("passwd: password updated successfully\n"), shadow_logfd);

View File

@@ -20,7 +20,9 @@
#include "port.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strtok/stpsep.h"
#include "string/strtok/strsep2ls.h"
static FILE *ports;
@@ -50,7 +52,7 @@ static int portcmp (const char *pattern, const char *port)
if (streq(orig, "SU"))
return 1;
return (*pattern == '*') ? 0 : 1;
return !strprefix(pattern, "*");
}
/*
@@ -101,7 +103,8 @@ getportent(void)
int dtime;
int i, j;
int saveerr;
char *cp, *field;
char *cp;
char *fields[3];
static char buf[BUFSIZ];
static char *ttys[PORT_TTY + 1];
@@ -140,12 +143,13 @@ next:
errno = saveerr;
return NULL;
}
if ('#' == buf[0])
if (strprefix(buf, "#"))
goto next;
stpsep(buf, "\n");
field = buf;
if (STRSEP2ARR(buf, ":", fields) == -1)
goto next;
/*
* Get the name of the TTY device. It is the first colon
@@ -153,19 +157,8 @@ next:
* leading "/dev". The entry '*' is used to specify all
* TTY devices.
*/
cp = strsep(&field, ":");
if (field == NULL)
goto next;
port.pt_names = ttys;
for (j = 0; j < PORT_TTY; j++) {
port.pt_names[j] = strsep(&cp, ",");
if (cp == NULL)
break;
}
port.pt_names[j] = NULL;
if (cp != NULL)
if (STRSEP2LS(fields[0], ",", ttys) == -1)
goto next;
/*
@@ -174,19 +167,8 @@ next:
* names. The entry '*' is used to specify all usernames.
* The last entry in the list is a NULL pointer.
*/
cp = strsep(&field, ":");
if (field == NULL)
goto next;
port.pt_users = users;
for (j = 0; j < PORT_IDS; j++) {
port.pt_users[j] = strsep(&cp, ",");
if (cp == NULL)
break;
}
port.pt_users[j] = NULL;
if (cp != NULL)
if (STRSEP2LS(fields[1], ",", users) == -1)
goto next;
/*
@@ -202,7 +184,7 @@ next:
* the starting time. Days are presumed to wrap at 0000.
*/
cp = field;
cp = fields[2];
if (streq(cp, "")) {
port.pt_times = NULL;

View File

@@ -28,8 +28,9 @@
#endif /* ENABLE_SUBIDS */
#include "getdef.h"
#include "shadowlog.h"
#include "string/sprintf/xasprintf.h"
#include "string/sprintf/xaprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
static char *passwd_db_file = NULL;
@@ -53,17 +54,15 @@ static FILE* fp_grent = NULL;
*/
extern const char* process_prefix_flag (const char* short_opt, int argc, char **argv)
{
/*
* Parse the command line options.
*/
int i;
const char *prefix = NULL, *val;
const char *prefix = NULL;
for (int i = 0; i < argc; i++) {
const char *val;
val = strprefix(argv[i], "--prefix=");
for (i = 0; i < argc; i++) {
val = NULL;
if ( streq(argv[i], "--prefix")
|| ((strncmp (argv[i], "--prefix=", 9) == 0)
&& (val = argv[i] + 9))
|| val != NULL
|| streq(argv[i], short_opt))
{
if (NULL != prefix) {
@@ -109,32 +108,32 @@ extern const char* process_prefix_flag (const char* short_opt, int argc, char **
exit (E_BAD_ARG);
}
xasprintf(&passwd_db_file, "%s/%s", prefix, PASSWD_FILE);
passwd_db_file = xaprintf("%s/%s", prefix, PASSWD_FILE);
pw_setdbname(passwd_db_file);
xasprintf(&group_db_file, "%s/%s", prefix, GROUP_FILE);
group_db_file = xaprintf("%s/%s", prefix, GROUP_FILE);
gr_setdbname(group_db_file);
#ifdef SHADOWGRP
xasprintf(&sgroup_db_file, "%s/%s", prefix, SGROUP_FILE);
sgroup_db_file = xaprintf("%s/%s", prefix, SGROUP_FILE);
sgr_setdbname(sgroup_db_file);
#endif
xasprintf(&spw_db_file, "%s/%s", prefix, SHADOW_FILE);
spw_db_file = xaprintf("%s/%s", prefix, SHADOW_FILE);
spw_setdbname(spw_db_file);
#ifdef ENABLE_SUBIDS
xasprintf(&suid_db_file, "%s/%s", prefix, SUBUID_FILE);
suid_db_file = xaprintf("%s/%s", prefix, SUBUID_FILE);
sub_uid_setdbname(suid_db_file);
xasprintf(&sgid_db_file, "%s/%s", prefix, SUBGID_FILE);
sgid_db_file = xaprintf("%s/%s", prefix, SUBGID_FILE);
sub_gid_setdbname(sgid_db_file);
#endif
#ifdef USE_ECONF
setdef_config_file(prefix);
#else
xasprintf(&def_conf_file, "%s/%s", prefix, "/etc/login.defs");
def_conf_file = xaprintf("%s/%s", prefix, "/etc/login.defs");
setdef_config_file(def_conf_file);
#endif
}

View File

@@ -120,10 +120,6 @@ extern void sanitize_env (void);
/* fd.c */
extern void check_fds (void);
/* fields.c */
extern void change_field (char *, size_t, const char *);
extern int valid_field (const char *, const char *);
/* find_new_gid.c */
extern int find_new_gid (bool sys_group,
gid_t *gid,
@@ -189,6 +185,9 @@ extern void audit_logger (int type, const char *pgname, const char *op,
const char *name, unsigned int id,
shadow_audit_result result);
void audit_logger_message (const char *message, shadow_audit_result result);
void audit_logger_with_group(int type, const char *op, const char *name,
id_t id, const char *grp_type, const char *grp,
shadow_audit_result result);
#endif
/* limits.c */

View File

@@ -10,13 +10,13 @@
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
#include <stdio.h>
#include "commonio.h"
#include "defines.h"
#include "fields.h"
#include "prototypes.h"
#include "pwio.h"
static /*@null@*/ /*@only@*/void *passwd_dup (const void *ent)

View File

@@ -17,6 +17,7 @@
#include "prototypes.h"
#include "shadowlog.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include <assert.h>
@@ -34,18 +35,17 @@ static void change_root (const char* newroot);
*/
extern void process_root_flag (const char* short_opt, int argc, char **argv)
{
/*
* Parse the command line options.
*/
int i;
const char *newroot = NULL, *val;
const char *newroot = NULL;
for (int i = 0; i < argc; i++) {
const char *val;
val = strprefix(argv[i], "--root=");
for (i = 0; i < argc; i++) {
val = NULL;
if ( streq(argv[i], "--root")
|| ((strncmp (argv[i], "--root=", 7) == 0)
&& (val = argv[i] + 7))
|| streq(argv[i], short_opt)) {
|| val != NULL
|| streq(argv[i], short_opt))
{
if (NULL != newroot) {
fprintf (log_get_logfd(),
_("%s: multiple --root options\n"),

View File

@@ -13,6 +13,7 @@
#include "run_part.h"
#include "shadowlog_internal.h"
#include "string/sprintf/aprintf.h"
static int run_part(char *script_path, const char *name, const char *action)
@@ -60,8 +61,9 @@ int run_parts(const char *directory, const char *name, const char *action)
char *s;
struct stat sb;
if (asprintf(&s, "%s/%s", directory, namelist[n]->d_name) == -1) {
fprintf(shadow_logfd, "asprintf: %s\n", strerror(errno));
s = aprintf("%s/%s", directory, namelist[n]->d_name);
if (s == NULL) {
fprintf(shadow_logfd, "aprintf: %s\n", strerror(errno));
for (; n<scanlist; n++) {
free(namelist[n]);
}

View File

@@ -11,8 +11,8 @@
#include <search.h>
#include <stddef.h>
#include "must_be.h"
#include "search/cmp/cmp.h"
#include "typetraits.h"
#include <assert.h>

View File

@@ -10,8 +10,8 @@
#include <search.h>
#include "must_be.h"
#include "search/cmp/cmp.h"
#include "typetraits.h"
#include <assert.h>

View File

@@ -10,8 +10,8 @@
#include <stdlib.h>
#include "must_be.h"
#include "search/cmp/cmp.h"
#include "typetraits.h"
#define QSORT(a, n) do \

View File

@@ -13,9 +13,11 @@
#include <selinux/selinux.h>
#include <selinux/label.h>
#include "prototypes.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/sprintf/aprintf.h"
static bool selinux_checked = false;
static bool selinux_enabled;
@@ -113,18 +115,15 @@ format_attr(printf, 2, 3)
static int selinux_log_cb (int type, const char *fmt, ...) {
va_list ap;
char *buf;
int r;
#ifdef WITH_AUDIT
static int selinux_audit_fd = -2;
#endif
va_start (ap, fmt);
r = vasprintf (&buf, fmt, ap);
buf = vaprintf(fmt, ap);
va_end (ap);
if (r < 0) {
if (buf == NULL)
return 0;
}
#ifdef WITH_AUDIT
if (-2 == selinux_audit_fd) {

View File

@@ -23,8 +23,8 @@
#include "attr.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/sprintf/aprintf.h"
format_attr(printf, 3, 4)
@@ -32,18 +32,14 @@ static void semanage_error_callback (MAYBE_UNUSED void *varg,
semanage_handle_t *handle,
const char *fmt, ...)
{
int ret;
char * message = NULL;
va_list ap;
va_start (ap, fmt);
ret = vasprintf (&message, fmt, ap);
message = vaprintf(fmt, ap);
va_end (ap);
if (ret < 0) {
/* ENOMEM */
if (message == NULL)
return;
}
switch (semanage_msg_get_level (handle)) {
case SEMANAGE_MSG_ERR:

View File

@@ -26,8 +26,9 @@
#include <pwd.h>
#include "getdef.h"
#include "shadowlog.h"
#include "string/sprintf/xasprintf.h"
#include "string/sprintf/xaprintf.h"
#include "string/strcmp/streq.h"
#include "string/strcmp/strprefix.h"
#include "string/strdup/xstrdup.h"
#include "string/strspn/stpspn.h"
#include "string/strtok/stpsep.h"
@@ -39,7 +40,7 @@ addenv_path(const char *varname, const char *dirname, const char *filename)
{
char *buf;
xasprintf(&buf, "%s/%s", dirname, filename);
buf = xaprintf("%s/%s", dirname, filename);
addenv(varname, buf);
free(buf);
}
@@ -61,7 +62,7 @@ static void read_env_file (const char *filename)
cp = buf;
/* ignore whitespace and comments */
cp = stpspn(cp, " \t");
if (streq(cp, "") || ('#' == *cp)) {
if (streq(cp, "") || strprefix(cp, "#")) {
continue;
}
/*
@@ -72,7 +73,7 @@ static void read_env_file (const char *filename)
val = stpsep(cp, "=");
if (val == NULL)
continue;
if (strpbrk(name, " \t") != NULL)
if (strpbrk(name, " \t"))
continue;
#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
/*

View File

@@ -11,22 +11,22 @@
#ident "$Id$"
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "alloc/malloc.h"
#include "alloc/reallocf.h"
#include "atoi/getnum.h"
#include "defines.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
#include "string/strtok/strsep2arr.h"
#include "string/strtok/astrsep2ls.h"
#define NFIELDS 4
/*
* list - turn a comma-separated string into an array of (char *)'s
*
@@ -40,69 +40,52 @@ static char **
list(char *s)
{
static char **members = NULL;
static size_t size = 0; /* max members + 1 */
size_t i;
i = 0;
for (;;) {
/* check if there is room for another pointer (to a group
member name, or terminating NULL). */
if (i >= size) {
size = i + 100; /* at least: i + 1 */
members = REALLOCF(members, size, char *);
if (!members) {
size = 0;
return NULL;
}
}
if (!s || streq(s, ""))
break;
members[i++] = strsep(&s, ",");
}
members[i] = NULL;
size_t n;
free(members);
members = astrsep2ls(s, ",", &n);
if (members == NULL)
return NULL;
if (streq(members[n-1], ""))
members[n-1] = NULL;
return members;
}
struct group *sgetgrent (const char *buf)
struct group *
sgetgrent(const char *s)
{
static char *grpbuf = NULL;
static size_t size = 0;
static char *grpfields[NFIELDS];
static char *dup = NULL;
static struct group grent;
int i;
char *cp;
if (strlen (buf) + 1 > size) {
/* no need to use realloc() here - just free it and
allocate a larger block */
free (grpbuf);
size = strlen (buf) + 1000; /* at least: strlen(buf) + 1 */
grpbuf = MALLOC(size, char);
if (grpbuf == NULL) {
size = 0;
return NULL;
}
}
strcpy (grpbuf, buf);
stpsep(grpbuf, "\n");
char *fields[4];
for (cp = grpbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++)
grpfields[i] = strsep(&cp, ":");
free(dup);
dup = strdup(s);
if (dup == NULL)
return NULL;
if (i < NFIELDS || streq(grpfields[2], "") || cp != NULL) {
stpsep(dup, "\n");
if (STRSEP2ARR(dup, ":", fields) == -1)
return NULL;
if (streq(fields[2], ""))
return NULL;
grent.gr_name = fields[0];
grent.gr_passwd = fields[1];
if (get_gid(fields[2], &grent.gr_gid) == -1) {
return NULL;
}
grent.gr_name = grpfields[0];
grent.gr_passwd = grpfields[1];
if (get_gid(grpfields[2], &grent.gr_gid) == -1) {
return NULL;
}
grent.gr_mem = list (grpfields[3]);
grent.gr_mem = list(fields[3]);
if (NULL == grent.gr_mem) {
return NULL; /* out of memory */
}
return &grent;
}

View File

@@ -11,20 +11,21 @@
#ident "$Id$"
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "atoi/getnum.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
#include "string/strtok/strsep2arr.h"
#define NFIELDS 7
/*
* sgetpwent - convert a string to a (struct passwd)
*
@@ -38,47 +39,26 @@
* compilation glarp to improve on this in the future.
*/
struct passwd *
sgetpwent(const char *buf)
sgetpwent(const char *s)
{
static char *dup = NULL;
static struct passwd pwent;
static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH];
int i;
char *cp;
char *fields[NFIELDS];
/*
* Copy the string to a static buffer so the pointers into
* the password structure remain valid.
*/
char *fields[7];
if (strlen (buf) >= sizeof pwdbuf) {
fprintf (shadow_logfd,
"%s: Too long passwd entry encountered, file corruption?\n",
shadow_progname);
return NULL; /* fail if too long */
}
strcpy (pwdbuf, buf);
/*
* Save a pointer to the start of each colon separated
* field. The fields are converted into NUL terminated strings.
*/
for (cp = pwdbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++)
fields[i] = strsep(&cp, ":");
/* something at the end, columns over shot */
if ( cp != NULL ) {
return( NULL );
}
/*
* There must be exactly NFIELDS colon separated fields or
* the entry is invalid. Also, the UID and GID must be non-blank.
*/
if (i != NFIELDS)
free(dup);
dup = strdup(s);
if (dup == NULL)
return NULL;
stpsep(dup, "\n");
if (STRSEP2ARR(dup, ":", fields) == -1)
return NULL;
/*
* The UID and GID must be non-blank.
*/
if (streq(fields[2], ""))
return NULL;
if (streq(fields[3], ""))

View File

@@ -16,16 +16,19 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include "atoi/a2i/a2s.h"
#include "atoi/str2i/str2u.h"
#include "atoi/str2i.h"
#include "defines.h"
#include "prototypes.h"
#include "shadowlog_internal.h"
#include "sizeof.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
#include "string/strtok/strsep2arr.h"
#define FIELDS 9
@@ -36,40 +39,25 @@
* sgetspent - convert string in shadow file format to (struct spwd *)
*/
struct spwd *
sgetspent(const char *string)
sgetspent(const char *s)
{
static char spwbuf[PASSWD_ENTRY_MAX_LENGTH];
static char *dup = NULL;
static struct spwd spwd;
char *fields[FIELDS];
char *cp;
int i;
size_t i;
/*
* Copy string to local buffer. It has to be tokenized and we
* have to do that to our private copy.
*/
free(dup);
dup = strdup(s);
if (dup == NULL)
return NULL;
if (strlen (string) >= sizeof spwbuf) {
fprintf (shadow_logfd,
"%s: Too long passwd entry encountered, file corruption?\n",
shadow_progname);
return NULL; /* fail if too long */
}
strcpy (spwbuf, string);
stpsep(spwbuf, "\n");
stpsep(dup, "\n");
/*
* Tokenize the string into colon separated fields. Allow up to
* FIELDS different fields.
*/
for (cp = spwbuf, i = 0; cp != NULL && i < FIELDS; i++)
fields[i] = strsep(&cp, ":");
if (i == (FIELDS - 1))
i = strsep2arr(dup, ":", countof(fields), fields);
if (i == countof(fields) - 1)
fields[i++] = "";
if (cp != NULL || (i != FIELDS && i != OFIELDS))
if (i != countof(fields) && i != OFIELDS)
return NULL;
/*

View File

@@ -19,6 +19,7 @@
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
#include "fields.h"
#include "getdef.h"
#include "sgroupio.h"
#include "string/memset/memzero.h"

View File

@@ -1,113 +0,0 @@
/*
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
* SPDX-FileCopyrightText: 2009 , Nicolas François
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#ifndef HAVE_GETSPNAM
#ident "$Id$"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include "atoi/a2i/a2s.h"
#include "atoi/str2i/str2u.h"
#include "defines.h"
#include "prototypes.h"
#include "string/strcmp/streq.h"
#include "string/strtok/stpsep.h"
static FILE *shadow;
#define FIELDS 9
#define OFIELDS 5
/*
* setspent - initialize access to shadow text and DBM files
*/
void setspent (void)
{
if (NULL != shadow) {
rewind (shadow);
}else {
shadow = fopen (SHADOW_FILE, "re");
}
}
/*
* endspent - terminate access to shadow text and DBM files
*/
void endspent (void)
{
if (NULL != shadow) {
(void) fclose (shadow);
}
shadow = NULL;
}
/*
* fgetspent - get an entry from a /etc/shadow formatted stream
*/
struct spwd *fgetspent (FILE * fp)
{
char buf[BUFSIZ];
if (NULL == fp) {
return (0);
}
if (fgets (buf, sizeof buf, fp) != NULL)
{
stpsep(buf, "\n");
return sgetspent(buf);
}
return 0;
}
/*
* getspent - get a (struct spwd *) from the current shadow file
*/
struct spwd *getspent (void)
{
if (NULL == shadow) {
setspent ();
}
return (fgetspent (shadow));
}
/*
* getspnam - get a shadow entry by name
*/
struct spwd *getspnam (const char *name)
{
struct spwd *sp;
setspent ();
while ((sp = getspent ()) != NULL) {
if (streq(name, sp->sp_namp)) {
break;
}
}
endspent ();
return (sp);
}
#else
extern int ISO_C_forbids_an_empty_translation_unit;
#endif

View File

@@ -10,20 +10,22 @@
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <shadow.h>
#include <stdio.h>
#include "commonio.h"
#include "defines.h"
#include "fields.h"
#include "getdef.h"
#include "prototypes.h"
#include "shadowio.h"
#ifdef WITH_TCB
#include <tcb.h>
#include "tcbfuncs.h"
#endif /* WITH_TCB */
static /*@null@*/ /*@only@*/void *shadow_dup (const void *ent)
{
const struct spwd *sp = ent;

View File

@@ -1,7 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023, Alejandro Colomar <alx@kernel.org>
* SPDX-License-Identifier: BSD-3-Clause
*/
// SPDX-FileCopyrightText: 2022-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIBMISC_SIZEOF_H_
@@ -11,15 +9,22 @@
#include <config.h>
#include <limits.h>
#include "must_be.h"
#if __has_include(<stdcountof.h>)
# include <stdcountof.h>
#endif
#include <sys/types.h>
#define ssizeof(x) ((ssize_t) sizeof(x))
#define memberof(T, member) ((T){}.member)
#define WIDTHOF(x) (sizeof(x) * CHAR_BIT)
#define SIZEOF_ARRAY(a) (sizeof(a) + must_be_array(a))
#define NITEMS(a) (SIZEOF_ARRAY((a)) / sizeof((a)[0]))
#define STRLEN(s) (NITEMS(s) - 1)
#if !defined(countof)
# define countof(a) (sizeof(a) / sizeof((a)[0]))
#endif
#define SIZEOF_ARRAY(a) (countof(a) * sizeof((a)[0]))
#define STRLEN(s) (countof("" s "") - 1)
#endif // include guard

View File

@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/ctype/strchrisascii/strchriscntrl.h"
#include <stdbool.h>
extern inline bool strchriscntrl(const char *s);

View File

@@ -0,0 +1,36 @@
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRCHRISASCII_STRCHRISCNTRL_H_
#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRCHRISASCII_STRCHRISCNTRL_H_
#include <config.h>
#include <ctype.h>
#include <stdbool.h>
#include "string/strcmp/streq.h"
inline bool strchriscntrl(const char *s);
// string character is [:cntrl:]
// Return true if any iscntrl(3) character is found in the string.
inline bool
strchriscntrl(const char *s)
{
for (; !streq(s, ""); s++) {
unsigned char c = *s;
if (iscntrl(c))
return true;
}
return false;
}
#endif // include guard

View File

@@ -0,0 +1,12 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/ctype/strisascii/strisprint.h"
#include <stdbool.h>
extern inline bool strisprint(const char *s);

View File

@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_STRISPRINT_H_
#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRISASCII_STRISPRINT_H_
#include <config.h>
#include <ctype.h>
#include <stdbool.h>
#include "string/strcmp/streq.h"
inline bool strisprint(const char *s);
// string is [:print:]
// Like isprint(3), but check all characters in the string.
inline bool
strisprint(const char *s)
{
if (streq(s, ""))
return false;
for (; !streq(s, ""); s++) {
unsigned char c = *s;
if (!isprint(c))
return false;
}
return true;
}
#endif // include guard

View File

@@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/ctype/strtoascii/strtolower.h"
extern inline char *strtolower(char *str);

View File

@@ -0,0 +1,34 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_STRTOASCII_STRTOLOWER_H_
#define SHADOW_INCLUDE_LIB_STRING_CTYPE_STRTOASCII_STRTOLOWER_H_
#include <config.h>
#include <ctype.h>
#include "string/strcmp/streq.h"
inline char *strtolower(char *str);
// string convert-to lower-case
// Like tolower(3), but convert all characters in the string.
// Returns the input pointer.
inline char *
strtolower(char *str)
{
for (char *s = str; !streq(s, ""); s++) {
unsigned char c = *s;
*s = tolower(c);
}
return str;
}
#endif // include guard

View File

@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/sprintf/aprintf.h"
#include <stdarg.h>
extern inline char *aprintf(const char *restrict fmt, ...);
extern inline char *vaprintf(const char *restrict fmt, va_list ap);

View File

@@ -0,0 +1,57 @@
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_SPRINTF_APRINTF_H_
#define SHADOW_INCLUDE_LIB_STRING_SPRINTF_APRINTF_H_
#include <config.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "attr.h"
ATTR_MALLOC(free)
format_attr(printf, 1, 2)
inline char *aprintf(const char *restrict fmt, ...);
ATTR_MALLOC(free)
format_attr(printf, 1, 0)
inline char *vaprintf(const char *restrict fmt, va_list ap);
// allocate print formatted
// Like asprintf(3), but simpler; omit the length.
inline char *
aprintf(const char *restrict fmt, ...)
{
char *p;
va_list ap;
va_start(ap, fmt);
p = vaprintf(fmt, ap);
va_end(ap);
return p;
}
// Like vasprintf(3), but simpler; omit the length.
inline char *
vaprintf(const char *restrict fmt, va_list ap)
{
char *p;
if (vasprintf(&p, fmt, ap) == -1)
return NULL;
return p;
}
#endif // include guard

View File

@@ -18,7 +18,7 @@
#define SNPRINTF(s, fmt, ...) \
( \
snprintf_(s, NITEMS(s), fmt __VA_OPT__(,) __VA_ARGS__) \
snprintf_(s, countof(s), fmt __VA_OPT__(,) __VA_ARGS__) \
)

View File

@@ -40,7 +40,7 @@ inline char *vstpeprintf(char *dst, char *end, const char *restrict fmt,
*
* end Pointer to one after the last element of the buffer
* pointed to by `dst`. Usually, it should be calculated
* as `dst + NITEMS(dst)`.
* as `dst + countof(dst)`.
*
* fmt Format string
*

View File

@@ -0,0 +1,13 @@
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/sprintf/xaprintf.h"
#include <stdarg.h>
extern inline char *xaprintf(const char *restrict fmt, ...);
extern inline char *xvaprintf(const char *restrict fmt, va_list ap);

View File

@@ -0,0 +1,59 @@
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_SPRINTF_XASPRINTF_H_
#define SHADOW_INCLUDE_LIB_STRING_SPRINTF_XASPRINTF_H_
#include <config.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "attr.h"
#include "string/sprintf/aprintf.h"
ATTR_MALLOC(free)
format_attr(printf, 1, 2)
inline char *xaprintf(const char *restrict fmt, ...);
ATTR_MALLOC(free)
format_attr(printf, 1, 0)
inline char *xvaprintf(const char *restrict fmt, va_list ap);
// exit-on-error allocate print formatted
inline char *
xaprintf(const char *restrict fmt, ...)
{
char *p;
va_list ap;
va_start(ap, fmt);
p = xvaprintf(fmt, ap);
va_end(ap);
return p;
}
inline char *
xvaprintf(const char *restrict fmt, va_list ap)
{
char *p;
p = vaprintf(fmt, ap);
if (p == NULL) {
perror("vaprintf");
exit(EXIT_FAILURE);
}
return p;
}
#endif // include guard

View File

@@ -1,14 +0,0 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/sprintf/xasprintf.h"
#include <stdarg.h>
extern inline int xasprintf(char **restrict s, const char *restrict fmt, ...);
extern inline int xvasprintf(char **restrict s, const char *restrict fmt,
va_list ap);

View File

@@ -1,54 +0,0 @@
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_SPRINTF_XASPRINTF_H_
#define SHADOW_INCLUDE_LIB_STRING_SPRINTF_XASPRINTF_H_
#include <config.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "attr.h"
format_attr(printf, 2, 3)
inline int xasprintf(char **restrict s, const char *restrict fmt, ...);
format_attr(printf, 2, 0)
inline int xvasprintf(char **restrict s, const char *restrict fmt, va_list ap);
inline int
xasprintf(char **restrict s, const char *restrict fmt, ...)
{
int len;
va_list ap;
va_start(ap, fmt);
len = xvasprintf(s, fmt, ap);
va_end(ap);
return len;
}
inline int
xvasprintf(char **restrict s, const char *restrict fmt, va_list ap)
{
int len;
len = vasprintf(s, fmt, ap);
if (len == -1) {
perror("asprintf");
exit(EXIT_FAILURE);
}
return len;
}
#endif // include guard

View File

@@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/strcmp/strcaseprefix.h"
extern inline const char *strcaseprefix_(const char *s, const char *prefix);

View File

@@ -0,0 +1,49 @@
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_STRCMP_STRCASEPREFIX_H_
#define SHADOW_INCLUDE_LIB_STRING_STRCMP_STRCASEPREFIX_H_
#include <config.h>
#include <stddef.h>
#include <string.h>
#include "attr.h"
#include "cast.h"
// string case-insensitive prefix
#define strcaseprefix(s, prefix) \
({ \
const char *p_; \
\
p_ = strcaseprefix_(s, prefix); \
\
_Generic(s, \
const char *: p_, \
const void *: p_, \
char *: const_cast(char *, p_), \
void *: const_cast(char *, p_) \
); \
})
ATTR_STRING(1) ATTR_STRING(2)
inline const char *strcaseprefix_(const char *s, const char *prefix);
// strprefix_(), but case-insensitive.
inline const char *
strcaseprefix_(const char *s, const char *prefix)
{
if (strncasecmp(s, prefix, strlen(prefix)) != 0)
return NULL;
return s + strlen(prefix);
}
#endif // include guard

View File

@@ -0,0 +1,10 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#include <config.h>
#include "string/strcmp/strprefix.h"
extern inline const char *strprefix_(const char *s, const char *prefix);

View File

@@ -0,0 +1,53 @@
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_STRING_STRCMP_STRPREFIX_H_
#define SHADOW_INCLUDE_LIB_STRING_STRCMP_STRPREFIX_H_
#include <config.h>
#include <stddef.h>
#include <string.h>
#include "attr.h"
#include "cast.h"
// string prefix
#define strprefix(s, prefix) \
({ \
const char *p_; \
\
p_ = strprefix_(s, prefix); \
\
_Generic(s, \
const char *: p_, \
const void *: p_, \
char *: const_cast(char *, p_), \
void *: const_cast(char *, p_) \
); \
})
ATTR_STRING(1)
ATTR_STRING(2)
inline const char *strprefix_(const char *s, const char *prefix);
/*
* Return NULL if s does not start with prefix.
* Return `s + strlen(prefix)` if s starts with prefix.
*/
inline const char *
strprefix_(const char *s, const char *prefix)
{
if (strncmp(s, prefix, strlen(prefix)) != 0)
return NULL;
return s + strlen(prefix);
}
#endif // include guard

View File

@@ -32,7 +32,7 @@ inline char *stpecpy(char *dst, char *end, const char *restrict src);
*
* end Pointer to one after the last element of the buffer
* pointed to by `dst`. Usually, it should be calculated
* as `dst + NITEMS(dst)`.
* as `dst + countof(dst)`.
*
* src Source string to be copied into dst.
*

View File

@@ -13,7 +13,7 @@
#include "sizeof.h"
#define STRNCAT(dst, src) strncat(dst, src, NITEMS(src))
#define STRNCAT(dst, src) strncat(dst, src, countof(src))
#endif // include guard

View File

@@ -13,7 +13,7 @@
#include "sizeof.h"
#define STRNCPY(dst, src) strncpy(dst, src, NITEMS(dst))
#define STRNCPY(dst, src) strncpy(dst, src, countof(dst))
#endif // include guard

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