Compare commits
10 Commits
upstream/4
...
upstream/4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5f795a54a | ||
|
|
428fe43d86 | ||
|
|
9d5ab87d61 | ||
|
|
a9c3448878 | ||
|
|
a475f464e0 | ||
|
|
65261e28f4 | ||
|
|
bd724b34e0 | ||
|
|
c2a3ebed18 | ||
|
|
f78a468368 | ||
|
|
9f68246a01 |
18
Makefile.am
18
Makefile.am
@@ -1,6 +1,5 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
EXTRA_DIST = NEWS README
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = lib
|
||||
|
||||
@@ -8,11 +7,22 @@ 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
|
||||
endif
|
||||
|
||||
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
|
||||
EXTRA_DIST = tests/
|
||||
|
||||
EXTRA_DIST = NEWS README tests/
|
||||
|
||||
dist-hook:
|
||||
chmod -R u+w $(distdir)/tests
|
||||
chmod u+w $(distdir)
|
||||
mv $(distdir)/tests/unit $(distdir)/realunittest
|
||||
mv $(distdir)/tests/tests $(distdir)/realtests
|
||||
rm -rf $(distdir)/tests
|
||||
mv $(distdir)/realtests $(distdir)/tests
|
||||
rm -rf $(distdir)/tests/unit $(distdir)/tests/Makefile*
|
||||
mv $(distdir)/realunittest $(distdir)/tests/unit
|
||||
|
||||
40
Makefile.in
40
Makefile.in
@@ -163,11 +163,19 @@ 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)/build-aux/compile \
|
||||
$(top_srcdir)/build-aux/config.guess \
|
||||
$(top_srcdir)/build-aux/config.rpath \
|
||||
$(top_srcdir)/build-aux/config.sub \
|
||||
$(top_srcdir)/build-aux/install-sh \
|
||||
$(top_srcdir)/build-aux/ltmain.sh \
|
||||
$(top_srcdir)/build-aux/missing \
|
||||
$(top_srcdir)/man/po/Makefile.in ABOUT-NLS AUTHORS.md COPYING \
|
||||
ChangeLog NEWS README compile config.guess config.rpath \
|
||||
config.sub install-sh ltmain.sh missing
|
||||
ChangeLog NEWS README build-aux/compile build-aux/config.guess \
|
||||
build-aux/config.rpath build-aux/config.sub \
|
||||
build-aux/install-sh build-aux/ltmain.sh build-aux/missing
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
@@ -215,6 +223,7 @@ distcleancheck_listfiles = find . -type f -print
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = @AM_DISTCHECK_CONFIGURE_FLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
@@ -286,7 +295,6 @@ LIBSYSTEMD = @LIBSYSTEMD@
|
||||
LIBTCB = @LIBTCB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LIYESCRYPT = @LIYESCRYPT@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
@@ -333,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@
|
||||
@@ -389,10 +395,11 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
EXTRA_DIST = tests/
|
||||
SUBDIRS = lib $(am__append_1) src po contrib doc etc tests/unit \
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
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/
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
@@ -622,6 +629,9 @@ distdir-am: $(DISTFILES)
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
$(MAKE) $(AM_MAKEFLAGS) \
|
||||
top_distdir="$(top_distdir)" distdir="$(distdir)" \
|
||||
dist-hook
|
||||
-test -n "$(am__skip_mode_fix)" \
|
||||
|| find "$(distdir)" -type d ! -perm -755 \
|
||||
-exec chmod u+rwx,go+rx {} \; -o \
|
||||
@@ -869,8 +879,8 @@ uninstall-am:
|
||||
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
|
||||
am--refresh check check-am clean clean-cscope clean-generic \
|
||||
clean-libtool cscope cscopelist-am ctags ctags-am dist \
|
||||
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
|
||||
dist-xz dist-zip dist-zstd distcheck distclean \
|
||||
dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \
|
||||
dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
@@ -886,6 +896,16 @@ uninstall-am:
|
||||
.PRECIOUS: Makefile
|
||||
|
||||
|
||||
dist-hook:
|
||||
chmod -R u+w $(distdir)/tests
|
||||
chmod u+w $(distdir)
|
||||
mv $(distdir)/tests/unit $(distdir)/realunittest
|
||||
mv $(distdir)/tests/tests $(distdir)/realtests
|
||||
rm -rf $(distdir)/tests
|
||||
mv $(distdir)/realtests $(distdir)/tests
|
||||
rm -rf $(distdir)/tests/unit $(distdir)/tests/Makefile*
|
||||
mv $(distdir)/realunittest $(distdir)/tests/unit
|
||||
|
||||
# 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:
|
||||
|
||||
80
aclocal.m4
vendored
80
aclocal.m4
vendored
@@ -931,7 +931,7 @@ dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], [])
|
||||
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 12 (pkg-config-0.29.2)
|
||||
# serial 11 (pkg-config-0.29.1)
|
||||
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
@@ -973,7 +973,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.2])
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
||||
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
|
||||
@@ -1074,7 +1074,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 $2])
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
@@ -1084,11 +1084,11 @@ 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
|
||||
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
|
||||
@@ -1105,7 +1105,7 @@ installed software in a non-standard prefix.
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
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
|
||||
@@ -1206,6 +1206,74 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])dnl PKG_CHECK_VAR
|
||||
|
||||
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
||||
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
|
||||
dnl [DESCRIPTION], [DEFAULT])
|
||||
dnl ------------------------------------------
|
||||
dnl
|
||||
dnl Prepare a "--with-" configure option using the lowercase
|
||||
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
|
||||
dnl PKG_CHECK_MODULES in a single macro.
|
||||
AC_DEFUN([PKG_WITH_MODULES],
|
||||
[
|
||||
m4_pushdef([with_arg], m4_tolower([$1]))
|
||||
|
||||
m4_pushdef([description],
|
||||
[m4_default([$5], [build with ]with_arg[ support])])
|
||||
|
||||
m4_pushdef([def_arg], [m4_default([$6], [auto])])
|
||||
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
|
||||
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
|
||||
|
||||
m4_case(def_arg,
|
||||
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
|
||||
[m4_pushdef([with_without],[--with-]with_arg)])
|
||||
|
||||
AC_ARG_WITH(with_arg,
|
||||
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
|
||||
[AS_TR_SH([with_]with_arg)=def_arg])
|
||||
|
||||
AS_CASE([$AS_TR_SH([with_]with_arg)],
|
||||
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
|
||||
[auto],[PKG_CHECK_MODULES([$1],[$2],
|
||||
[m4_n([def_action_if_found]) $3],
|
||||
[m4_n([def_action_if_not_found]) $4])])
|
||||
|
||||
m4_popdef([with_arg])
|
||||
m4_popdef([description])
|
||||
m4_popdef([def_arg])
|
||||
|
||||
])dnl PKG_WITH_MODULES
|
||||
|
||||
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
||||
dnl [DESCRIPTION], [DEFAULT])
|
||||
dnl -----------------------------------------------
|
||||
dnl
|
||||
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
|
||||
dnl check._[VARIABLE-PREFIX] is exported as make variable.
|
||||
AC_DEFUN([PKG_HAVE_WITH_MODULES],
|
||||
[
|
||||
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
|
||||
|
||||
AM_CONDITIONAL([HAVE_][$1],
|
||||
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
|
||||
])dnl PKG_HAVE_WITH_MODULES
|
||||
|
||||
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
|
||||
dnl [DESCRIPTION], [DEFAULT])
|
||||
dnl ------------------------------------------------------
|
||||
dnl
|
||||
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
|
||||
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
|
||||
dnl and preprocessor variable.
|
||||
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
|
||||
[
|
||||
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
|
||||
|
||||
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
|
||||
])dnl PKG_HAVE_DEFINE_WITH_MODULES
|
||||
|
||||
# Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
|
||||
0
config.guess → build-aux/config.guess
vendored
0
config.guess → build-aux/config.guess
vendored
0
config.sub → build-aux/config.sub
vendored
0
config.sub → build-aux/config.sub
vendored
70
config.h.in
70
config.h.in
@@ -20,10 +20,6 @@
|
||||
/* Path for faillog file. */
|
||||
#undef FAILLOG_FILE
|
||||
|
||||
/* Define to the type of elements in the array set by `getgroups'. Usually
|
||||
this is either `int' or `gid_t'. */
|
||||
#undef GETGROUPS_T
|
||||
|
||||
/* max group name length */
|
||||
#undef GROUP_NAME_MAX_LENGTH
|
||||
|
||||
@@ -53,9 +49,6 @@
|
||||
the CoreFoundation framework. */
|
||||
#undef HAVE_CFPREFERENCESCOPYAPPVALUE
|
||||
|
||||
/* Define to 1 if you have the <crypt.h> header file. */
|
||||
#undef HAVE_CRYPT_H
|
||||
|
||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
||||
*/
|
||||
#undef HAVE_DCGETTEXT
|
||||
@@ -98,45 +91,27 @@
|
||||
/* 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 to 1 if you have the <gshadow.h> header file. */
|
||||
#undef HAVE_GSHADOW_H
|
||||
|
||||
/* Define if you have the iconv() function and it works. */
|
||||
#undef HAVE_ICONV
|
||||
|
||||
/* Define to 1 if you have the `initgroups' function. */
|
||||
#undef HAVE_INITGROUPS
|
||||
|
||||
/* Define to 1 if you have the `innetgr' function. */
|
||||
#undef HAVE_INNETGR
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <lastlog.h> header file. */
|
||||
#undef HAVE_LASTLOG_H
|
||||
|
||||
/* Define to 1 if you have the `lckpwdf' function. */
|
||||
#undef HAVE_LCKPWDF
|
||||
|
||||
@@ -164,9 +139,6 @@
|
||||
/* Define to 1 if you have the <minix/config.h> header file. */
|
||||
#undef HAVE_MINIX_CONFIG_H
|
||||
|
||||
/* Define to 1 if you have the <paths.h> header file. */
|
||||
#undef HAVE_PATHS_H
|
||||
|
||||
/* Define to 1 if you have the `putgrent' function. */
|
||||
#undef HAVE_PUTGRENT
|
||||
|
||||
@@ -179,9 +151,6 @@
|
||||
/* Define to 1 if you have the <readpassphrase.h> header file. */
|
||||
#undef HAVE_READPASSPHRASE_H
|
||||
|
||||
/* Define to 1 if you have the <rpc/key_prot.h> header file. */
|
||||
#undef HAVE_RPC_KEY_PROT_H
|
||||
|
||||
/* Define to 1 if you have the `rpmatch' function. */
|
||||
#undef HAVE_RPMATCH
|
||||
|
||||
@@ -197,9 +166,6 @@
|
||||
/* Define to 1 if you have the <semanage/semanage.h> header file. */
|
||||
#undef HAVE_SEMANAGE_SEMANAGE_H
|
||||
|
||||
/* Define to 1 if you have the `setgroups' function. */
|
||||
#undef HAVE_SETGROUPS
|
||||
|
||||
/* Define to 1 if you have the `sgetgrent' function. */
|
||||
#undef HAVE_SGETGRENT
|
||||
|
||||
@@ -209,12 +175,6 @@
|
||||
/* Define to 1 if you have the `sgetspent' function. */
|
||||
#undef HAVE_SGETSPENT
|
||||
|
||||
/* Define to 1 if you have the <sgtty.h> header file. */
|
||||
#undef HAVE_SGTTY_H
|
||||
|
||||
/* Have working shadow group support in libc */
|
||||
#undef HAVE_SHADOWGRP
|
||||
|
||||
/* Define if you have the shl_load function. */
|
||||
#undef HAVE_SHL_LOAD
|
||||
|
||||
@@ -260,15 +220,6 @@
|
||||
/* Define to 1 if `ut_xtime' is a member of `struct utmpx'. */
|
||||
#undef HAVE_STRUCT_UTMPX_UT_XTIME
|
||||
|
||||
/* Define to 1 if you have the <sys/capability.h> header file. */
|
||||
#undef HAVE_SYS_CAPABILITY_H
|
||||
|
||||
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||
#undef HAVE_SYS_IOCTL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/random.h> header file. */
|
||||
#undef HAVE_SYS_RANDOM_H
|
||||
|
||||
/* Define to 1 if you have the <sys/statfs.h> header file. */
|
||||
#undef HAVE_SYS_STATFS_H
|
||||
|
||||
@@ -281,9 +232,6 @@
|
||||
/* Define to 1 if you have the <tcb.h> header file. */
|
||||
#undef HAVE_TCB_H
|
||||
|
||||
/* Define to 1 if you have the <termio.h> header file. */
|
||||
#undef HAVE_TERMIO_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
@@ -296,18 +244,12 @@
|
||||
/* Define to 1 if `utime(file, NULL)' sets file's timestamp to the present. */
|
||||
#undef HAVE_UTIME_NULL
|
||||
|
||||
/* Define to 1 if you have the <utmp.h> header file. */
|
||||
#undef HAVE_UTMP_H
|
||||
|
||||
/* Define to support vendor settings. */
|
||||
#undef HAVE_VENDORDIR
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
/* Path for lastlog file. */
|
||||
#undef LASTLOG_FILE
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
#undef LT_OBJDIR
|
||||
|
||||
@@ -511,15 +453,3 @@
|
||||
|
||||
/* 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
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef gid_t
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
#undef uid_t
|
||||
|
||||
575
configure.ac
575
configure.ac
@@ -1,24 +1,29 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ([2.69])
|
||||
m4_define([libsubid_abi_major], 5)
|
||||
m4_define([libsubid_abi_minor], 0)
|
||||
m4_define([libsubid_abi_micro], 0)
|
||||
m4_define([libsubid_abi_major], [5])
|
||||
m4_define([libsubid_abi_minor], [0])
|
||||
m4_define([libsubid_abi_micro], [0])
|
||||
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
|
||||
AC_INIT([shadow], [4.16.0], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||
|
||||
AC_INIT([shadow], [4.19.2], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||
[https://github.com/shadow-maint/shadow])
|
||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
AM_SILENT_RULES([yes])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_SUBST([AM_DISTCHECK_CONFIGURE_FLAGS], ["$ac_configure_args"])
|
||||
|
||||
AC_SUBST([LIBSUBID_ABI_MAJOR], [libsubid_abi_major])
|
||||
AC_SUBST([LIBSUBID_ABI_MINOR], [libsubid_abi_minor])
|
||||
AC_SUBST([LIBSUBID_ABI_MICRO], [libsubid_abi_micro])
|
||||
AC_SUBST([LIBSUBID_ABI], [libsubid_abi])
|
||||
|
||||
dnl Some hacks...
|
||||
test "$prefix" = "NONE" && prefix="/usr"
|
||||
test "$prefix" = "/usr" && exec_prefix=""
|
||||
test "x$prefix" = "xNONE" && prefix="/usr"
|
||||
test "X$prefix" = "X/usr" && exec_prefix=""
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
|
||||
@@ -30,29 +35,21 @@ AM_MAINTAINER_MODE
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_YACC
|
||||
LT_INIT
|
||||
LT_LIB_DLLOAD
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(crypt.h utmp.h \
|
||||
termio.h sgtty.h sys/ioctl.h paths.h \
|
||||
sys/capability.h sys/random.h \
|
||||
gshadow.h lastlog.h rpc/key_prot.h acl/libacl.h \
|
||||
attr/libattr.h attr/error_context.h)
|
||||
|
||||
dnl shadow now uses the libc's shadow implementation
|
||||
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
|
||||
AC_CHECK_HEADER([shadow.h],[],[AC_MSG_ERROR([You need a libc with shadow.h])])
|
||||
|
||||
AC_CHECK_FUNCS(arc4random_buf futimes \
|
||||
getentropy getrandom getspnam getusershell \
|
||||
initgroups lckpwdf lutimes \
|
||||
setgroups updwtmpx innetgr \
|
||||
AC_CHECK_FUNCS([arc4random_buf \
|
||||
getentropy getrandom \
|
||||
lckpwdf lutimes \
|
||||
updwtmpx innetgr \
|
||||
getspnam_r \
|
||||
rpmatch \
|
||||
memset_explicit explicit_bzero stpecpy stpeprintf)
|
||||
memset_explicit explicit_bzero stpecpy stpeprintf])
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
@@ -63,273 +60,230 @@ AC_CHECK_MEMBERS([struct utmpx.ut_name,
|
||||
struct utmpx.ut_addr,
|
||||
struct utmpx.ut_addr_v6,
|
||||
struct utmpx.ut_time,
|
||||
struct utmpx.ut_xtime],,,[[#include <utmpx.h>]])
|
||||
struct utmpx.ut_xtime],[],[],[[#include <utmpx.h>]])
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_TYPE_GETGROUPS
|
||||
AC_FUNC_UTIME_NULL
|
||||
AC_REPLACE_FUNCS(putgrent putpwent putspent)
|
||||
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
|
||||
AC_REPLACE_FUNCS([putgrent putpwent putspent])
|
||||
AC_REPLACE_FUNCS([sgetgrent sgetpwent sgetspent])
|
||||
|
||||
AC_CHECK_FUNC(setpgrp)
|
||||
AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
|
||||
1,
|
||||
[Defined to 1 if you have the declaration of 'secure_getenv'])])
|
||||
AC_CHECK_FUNC([setpgrp])
|
||||
AC_CHECK_FUNC([secure_getenv],
|
||||
[AC_DEFINE([HAS_SECURE_GETENV],[1],[Defined to 1 if you have the declaration of 'secure_getenv'])]
|
||||
)
|
||||
|
||||
if test "$ac_cv_header_shadow_h" = "yes"; then
|
||||
AC_CACHE_CHECK(for working shadow group support,
|
||||
ac_cv_libc_shadowgrp,
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#include <shadow.h>
|
||||
#ifdef HAVE_GSHADOW_H
|
||||
#include <gshadow.h>
|
||||
#endif
|
||||
int
|
||||
main()
|
||||
{
|
||||
struct sgrp *sg = sgetsgent("test:x::");
|
||||
/* NYS libc on Red Hat 3.0.3 has broken shadow group support */
|
||||
return !sg || !sg->sg_adm || !sg->sg_mem;
|
||||
}]
|
||||
)],
|
||||
[ac_cv_libc_shadowgrp=yes],
|
||||
[ac_cv_libc_shadowgrp=no],
|
||||
[ac_cv_libc_shadowgrp=no]
|
||||
)
|
||||
)
|
||||
|
||||
if test "$ac_cv_libc_shadowgrp" = "yes"; then
|
||||
AC_DEFINE(HAVE_SHADOWGRP, 1, [Have working shadow group support in libc])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([location of shared mail directory], shadow_cv_maildir,
|
||||
AC_CACHE_CHECK([location of shared mail directory], [shadow_cv_maildir],
|
||||
[for shadow_cv_maildir in /var/mail /var/spool/mail /usr/spool/mail /usr/mail none; do
|
||||
if test -d $shadow_cv_maildir; then
|
||||
break
|
||||
fi
|
||||
done])
|
||||
if test $shadow_cv_maildir != none; then
|
||||
AC_DEFINE_UNQUOTED(MAIL_SPOOL_DIR, "$shadow_cv_maildir",
|
||||
AC_DEFINE_UNQUOTED([MAIL_SPOOL_DIR], ["$shadow_cv_maildir"],
|
||||
[Location of system mail spool directory.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([location of user mail file], shadow_cv_mailfile,
|
||||
AC_CACHE_CHECK([location of user mail file], [shadow_cv_mailfile],
|
||||
[for shadow_cv_mailfile in Mailbox mailbox Mail mail .mail none; do
|
||||
if test -f $HOME/$shadow_cv_mailfile; then
|
||||
break
|
||||
fi
|
||||
done])
|
||||
if test $shadow_cv_mailfile != none; then
|
||||
AC_DEFINE_UNQUOTED(MAIL_SPOOL_FILE, "$shadow_cv_mailfile",
|
||||
AC_DEFINE_UNQUOTED([MAIL_SPOOL_FILE], ["$shadow_cv_mailfile"],
|
||||
[Name of user's mail spool file if stored in user's home directory.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([location of utmp], shadow_cv_utmpdir,
|
||||
[for shadow_cv_utmpdir in /var/run /var/adm /usr/adm /etc none; do
|
||||
if test -f $shadow_cv_utmpdir/utmp; then
|
||||
break
|
||||
fi
|
||||
done])
|
||||
if test "$shadow_cv_utmpdir" = "none"; then
|
||||
AC_MSG_WARN(utmp file not found)
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(_UTMP_FILE, "$shadow_cv_utmpdir/utmp",
|
||||
[Path for utmp file.])
|
||||
|
||||
AC_CACHE_CHECK([location of faillog/lastlog/wtmp], shadow_cv_logdir,
|
||||
AC_CACHE_CHECK([location of faillog/lastlog/wtmp], [shadow_cv_logdir],
|
||||
[for shadow_cv_logdir in /var/log /var/adm /usr/adm /etc; do
|
||||
if test -d $shadow_cv_logdir; then
|
||||
break
|
||||
fi
|
||||
done])
|
||||
AC_DEFINE_UNQUOTED(_WTMP_FILE, "$shadow_cv_logdir/wtmp",
|
||||
[Path for wtmp file.])
|
||||
AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$shadow_cv_logdir/lastlog",
|
||||
[Path for lastlog file.])
|
||||
AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$shadow_cv_logdir/faillog",
|
||||
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,
|
||||
AC_ARG_ENABLE([shadowgrp],
|
||||
[AS_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_shadowgrp="yes" ;;
|
||||
no) enable_shadowgrp="no" ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-shadowgrp) ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-shadowgrp]) ;;
|
||||
esac],
|
||||
[enable_shadowgrp="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(man,
|
||||
AC_ARG_ENABLE([man],
|
||||
[AS_HELP_STRING([--enable-man],
|
||||
[regenerate roff man pages from Docbook @<:@default=no@:>@])],
|
||||
[enable_man="${enableval}"],
|
||||
[enable_man="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(account-tools-setuid,
|
||||
AC_ARG_ENABLE([account-tools-setuid],
|
||||
[AS_HELP_STRING([--enable-account-tools-setuid],
|
||||
[Install the user and group management tools setuid and authenticate the callers. This requires --with-libpam.])],
|
||||
[case "${enableval}" in
|
||||
yes) enable_acct_tools_setuid="yes" ;;
|
||||
no) enable_acct_tools_setuid="no" ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --enable-account-tools-setuid)
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-account-tools-setuid])
|
||||
;;
|
||||
esac],
|
||||
[enable_acct_tools_setuid="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(subordinate-ids,
|
||||
AC_ARG_ENABLE([subordinate-ids],
|
||||
[AS_HELP_STRING([--enable-subordinate-ids],
|
||||
[support subordinate ids @<:@default=yes@:>@])],
|
||||
[enable_subids="${enableval}"],
|
||||
[enable_subids="maybe"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(lastlog,
|
||||
AC_ARG_ENABLE([lastlog],
|
||||
[AS_HELP_STRING([--enable-lastlog],
|
||||
[enable lastlog @<:@default=no@:>@])],
|
||||
[enable_lastlog="${enableval}"],
|
||||
[enable_lastlog="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(logind,
|
||||
[AS_HELP_STRING([--enable-logind],
|
||||
[enable logind @<:@default=yes@:>@])],
|
||||
[enable_logind="${enableval}"],
|
||||
AC_ARG_ENABLE([logind],
|
||||
[AS_HELP_STRING([--disable-logind],
|
||||
[disable logind integration])],
|
||||
[
|
||||
AS_CASE([${enableval}],
|
||||
[yes],[],
|
||||
[no],[],
|
||||
[AC_MSG_ERROR([bad parameter value for --enable-logind=${enableval}. ]dnl
|
||||
[Supported values are: --enable-logind (or --enable-logind=yes) and --disable-logind (or --enable-logind=no).])]
|
||||
)
|
||||
],
|
||||
[enable_logind="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(audit,
|
||||
AC_ARG_WITH([audit],
|
||||
[AS_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
|
||||
[with_audit=$withval], [with_audit=maybe])
|
||||
AC_ARG_WITH(libpam,
|
||||
AC_ARG_WITH([libpam],
|
||||
[AS_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
|
||||
[with_libpam=$withval], [with_libpam=maybe])
|
||||
AC_ARG_WITH(btrfs,
|
||||
AC_ARG_WITH([btrfs],
|
||||
[AS_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])],
|
||||
[with_btrfs=$withval], [with_btrfs=maybe])
|
||||
AC_ARG_WITH(selinux,
|
||||
AC_ARG_WITH([selinux],
|
||||
[AS_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
|
||||
[with_selinux=$withval], [with_selinux=maybe])
|
||||
AC_ARG_WITH(acl,
|
||||
AC_ARG_WITH([acl],
|
||||
[AS_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
|
||||
[with_acl=$withval], [with_acl=maybe])
|
||||
AC_ARG_WITH(attr,
|
||||
AC_ARG_WITH([attr],
|
||||
[AS_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
|
||||
[with_attr=$withval], [with_attr=maybe])
|
||||
AC_ARG_WITH(skey,
|
||||
AC_ARG_WITH([skey],
|
||||
[AS_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
|
||||
[with_skey=$withval], [with_skey=no])
|
||||
AC_ARG_WITH(tcb,
|
||||
AC_ARG_WITH([tcb],
|
||||
[AS_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
|
||||
[with_tcb=$withval], [with_tcb=maybe])
|
||||
AC_ARG_WITH(sha-crypt,
|
||||
AC_ARG_WITH([sha-crypt],
|
||||
[AS_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
|
||||
[with_sha_crypt=$withval], [with_sha_crypt=yes])
|
||||
AC_ARG_WITH(bcrypt,
|
||||
AC_ARG_WITH([bcrypt],
|
||||
[AS_HELP_STRING([--with-bcrypt], [allow the bcrypt password encryption algorithm @<:@default=no@:>@])],
|
||||
[with_bcrypt=$withval], [with_bcrypt=no])
|
||||
AC_ARG_WITH(yescrypt,
|
||||
AC_ARG_WITH([yescrypt],
|
||||
[AS_HELP_STRING([--with-yescrypt], [allow the yescrypt password encryption algorithm @<:@default=no@:>@])],
|
||||
[with_yescrypt=$withval], [with_yescrypt=no])
|
||||
AC_ARG_WITH(nscd,
|
||||
AC_ARG_WITH([nscd],
|
||||
[AS_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
|
||||
[with_nscd=$withval], [with_nscd=yes])
|
||||
AC_ARG_WITH(sssd,
|
||||
AC_ARG_WITH([sssd],
|
||||
[AS_HELP_STRING([--with-sssd], [enable support for flushing sssd caches @<:@default=yes@:>@])],
|
||||
[with_sssd=$withval], [with_sssd=yes])
|
||||
AC_ARG_WITH(group-name-max-length,
|
||||
AC_ARG_WITH([group-name-max-length],
|
||||
[AS_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=32@:>@])],
|
||||
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
|
||||
AC_ARG_WITH(su,
|
||||
AC_ARG_WITH([su],
|
||||
[AS_HELP_STRING([--with-su], [build and install su program and man page @<:@default=yes@:>@])],
|
||||
[with_su=$withval], [with_su=yes])
|
||||
AC_ARG_WITH(libbsd,
|
||||
AC_ARG_WITH([libbsd],
|
||||
[AS_HELP_STRING([--with-libbsd], [use libbsd support @<:@default=yes if found@:>@])],
|
||||
[with_libbsd=$withval], [with_libbsd=yes])
|
||||
|
||||
if test "$with_group_name_max_length" = "no" ; then
|
||||
if test "X$with_group_name_max_length" = "Xno" ; then
|
||||
with_group_name_max_length=0
|
||||
elif test "$with_group_name_max_length" = "yes" ; then
|
||||
elif test "X$with_group_name_max_length" = "Xyes" ; then
|
||||
with_group_name_max_length=32
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max group name length])
|
||||
AC_SUBST(GROUP_NAME_MAX_LENGTH)
|
||||
AC_DEFINE_UNQUOTED([GROUP_NAME_MAX_LENGTH], [$with_group_name_max_length], [max group name length])
|
||||
AC_SUBST([GROUP_NAME_MAX_LENGTH])
|
||||
GROUP_NAME_MAX_LENGTH="$with_group_name_max_length"
|
||||
|
||||
|
||||
AM_CONDITIONAL(USE_SHA_CRYPT, test "x$with_sha_crypt" = "xyes")
|
||||
if test "$with_sha_crypt" = "yes"; then
|
||||
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
|
||||
AM_CONDITIONAL([USE_SHA_CRYPT], [test "x$with_sha_crypt" = "xyes"])
|
||||
if test "X$with_sha_crypt" = "Xyes"; then
|
||||
AC_DEFINE([USE_SHA_CRYPT], [1], [Define to allow the SHA256 and SHA512 password encryption algorithms])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(USE_BCRYPT, test "x$with_bcrypt" = "xyes")
|
||||
if test "$with_bcrypt" = "yes"; then
|
||||
AC_DEFINE(USE_BCRYPT, 1, [Define to allow the bcrypt password encryption algorithm])
|
||||
AM_CONDITIONAL([USE_BCRYPT], [test "x$with_bcrypt" = "xyes"])
|
||||
if test "X$with_bcrypt" = "Xyes"; then
|
||||
AC_DEFINE([USE_BCRYPT], [1], [Define to allow the bcrypt password encryption algorithm])
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(USE_YESCRYPT, test "x$with_yescrypt" = "xyes")
|
||||
if test "$with_yescrypt" = "yes"; then
|
||||
AC_DEFINE(USE_YESCRYPT, 1, [Define to allow the yescrypt password encryption algorithm])
|
||||
AM_CONDITIONAL([USE_YESCRYPT], [test "x$with_yescrypt" = "xyes"])
|
||||
if test "X$with_yescrypt" = "Xyes"; then
|
||||
AC_DEFINE([USE_YESCRYPT], [1], [Define to allow the yescrypt password encryption algorithm])
|
||||
fi
|
||||
|
||||
if test "$with_nscd" = "yes"; then
|
||||
AC_CHECK_FUNC(posix_spawn,
|
||||
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
|
||||
if test "X$with_nscd" = "Xyes"; then
|
||||
AC_CHECK_FUNC([posix_spawn],
|
||||
[AC_DEFINE([USE_NSCD], [1], [Define to support flushing of nscd caches])],
|
||||
[AC_MSG_ERROR([posix_spawn is needed for nscd support])])
|
||||
fi
|
||||
|
||||
if test "$with_sssd" = "yes"; then
|
||||
AC_CHECK_FUNC(posix_spawn,
|
||||
[AC_DEFINE(USE_SSSD, 1, [Define to support flushing of sssd caches])],
|
||||
if test "X$with_sssd" = "Xyes"; then
|
||||
AC_CHECK_FUNC([posix_spawn],
|
||||
[AC_DEFINE([USE_SSSD], [1], [Define to support flushing of sssd caches])],
|
||||
[AC_MSG_ERROR([posix_spawn is needed for sssd support])])
|
||||
fi
|
||||
|
||||
AS_IF([test "$with_su" != "no"], AC_DEFINE(WITH_SU, 1, [Build with su]))
|
||||
AS_IF([test "$with_su" != "no"], [AC_DEFINE([WITH_SU], [1], [Build with su])])
|
||||
AM_CONDITIONAL([WITH_SU], [test "x$with_su" != "xno"])
|
||||
|
||||
dnl Check for some functions in libc first, only if not found check for
|
||||
dnl other libraries. This should prevent linking libnsl if not really
|
||||
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
|
||||
|
||||
AC_SEARCH_LIBS(gethostbyname, nsl)
|
||||
AC_SEARCH_LIBS([gethostbyname], [nsl])
|
||||
|
||||
PKG_CHECK_MODULES([CMOCKA], [cmocka], [have_cmocka="yes"],
|
||||
[AC_MSG_WARN([libcmocka not found, cmocka tests will not be built])])
|
||||
AM_CONDITIONAL([HAVE_CMOCKA], [test x$have_cmocka = xyes])
|
||||
|
||||
AC_ARG_ENABLE([vendordir],
|
||||
[AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files])],[],[])
|
||||
AC_CHECK_LIB([econf],[econf_readDirs],[LIBECONF="-leconf"],[LIBECONF=""])
|
||||
if test -n "$LIBECONF"; then
|
||||
AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"],
|
||||
[Directory for distribution provided configuration files])
|
||||
ECONF_CPPFLAGS="-DUSE_ECONF=1"
|
||||
AC_ARG_ENABLE([vendordir],
|
||||
AS_HELP_STRING([--enable-vendordir=DIR], [Directory for distribution provided configuration files]),,[])
|
||||
fi
|
||||
AC_SUBST(ECONF_CPPFLAGS)
|
||||
AC_SUBST(LIBECONF)
|
||||
AC_SUBST([ECONF_CPPFLAGS])
|
||||
AC_SUBST([LIBECONF])
|
||||
AC_SUBST([VENDORDIR], [$enable_vendordir])
|
||||
if test "x$enable_vendordir" != x; then
|
||||
AC_DEFINE(HAVE_VENDORDIR, 1, [Define to support vendor settings.])
|
||||
AC_DEFINE([HAVE_VENDORDIR], [1], [Define to support vendor settings.])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
|
||||
|
||||
if test "$enable_shadowgrp" = "yes"; then
|
||||
AC_DEFINE(SHADOWGRP, 1, [Define to support the shadow group file.])
|
||||
if test "X$enable_shadowgrp" = "Xyes"; then
|
||||
AC_DEFINE([SHADOWGRP], [1], [Define to support the shadow group file.])
|
||||
fi
|
||||
AM_CONDITIONAL(SHADOWGRP, test "x$enable_shadowgrp" = "xyes")
|
||||
AM_CONDITIONAL([SHADOWGRP], [test "x$enable_shadowgrp" = "xyes"])
|
||||
|
||||
if test "$enable_man" = "yes"; then
|
||||
if test "X$enable_man" = "Xyes"; then
|
||||
dnl
|
||||
dnl Check for xsltproc
|
||||
dnl
|
||||
@@ -341,21 +295,21 @@ if test "$enable_man" = "yes"; then
|
||||
|
||||
dnl check for DocBook DTD and stylesheets in the local catalog.
|
||||
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.5//EN],
|
||||
[DocBook XML DTD V4.5], [], enable_man=no)
|
||||
[DocBook XML DTD V4.5], [], [enable_man=no])
|
||||
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
|
||||
[DocBook XSL Stylesheets >= 1.70.1], [], enable_man=no)
|
||||
[DocBook XSL Stylesheets >= 1.70.1], [], [enable_man=no])
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_REGENERATE_MAN, test "x$enable_man" != "xno")
|
||||
AM_CONDITIONAL([ENABLE_REGENERATE_MAN], [test "x$enable_man" != "xno"])
|
||||
|
||||
if test "$enable_subids" != "no"; then
|
||||
dnl
|
||||
dnl FIXME: check if 32 bit UIDs/GIDs are supported by libc
|
||||
dnl
|
||||
AC_CHECK_SIZEOF([uid_t],, [#include "sys/types.h"])
|
||||
AC_CHECK_SIZEOF([gid_t],, [#include "sys/types.h"])
|
||||
AC_CHECK_SIZEOF([uid_t],[], [[#include "sys/types.h"]])
|
||||
AC_CHECK_SIZEOF([gid_t],[], [[#include "sys/types.h"]])
|
||||
|
||||
if test "$ac_cv_sizeof_uid_t" -ge 4 && test "$ac_cv_sizeof_gid_t" -ge 4; then
|
||||
AC_DEFINE(ENABLE_SUBIDS, 1, [Define to support the subordinate IDs.])
|
||||
AC_DEFINE([ENABLE_SUBIDS], [1], [Define to support the subordinate IDs.])
|
||||
enable_subids="yes"
|
||||
else
|
||||
if test "x$enable_subids" = "xyes"; then
|
||||
@@ -364,55 +318,54 @@ if test "$enable_subids" != "no"; then
|
||||
enable_subids="no"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_SUBIDS, test "x$enable_subids" != "xno")
|
||||
AM_CONDITIONAL([ENABLE_SUBIDS], [test "x$enable_subids" != "xno"])
|
||||
|
||||
if test "$enable_lastlog" = "yes" && test "$ac_cv_header_lastlog_h" = "yes"; then
|
||||
AC_CACHE_CHECK(for ll_host in struct lastlog,
|
||||
ac_cv_struct_lastlog_ll_host,
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <lastlog.h>],
|
||||
[struct lastlog ll; char *cp = ll.ll_host;]
|
||||
)],
|
||||
if test "X$enable_lastlog" = "Xyes" && test "X$ac_cv_header_lastlog_h" = "Xyes"; then
|
||||
AC_CACHE_CHECK([for ll_host in struct lastlog],
|
||||
[ac_cv_struct_lastlog_ll_host],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <lastlog.h>]],
|
||||
[struct lastlog ll; char *cp = ll.ll_host;])],
|
||||
[ac_cv_struct_lastlog_ll_host=yes],
|
||||
[ac_cv_struct_lastlog_ll_host=no]
|
||||
)
|
||||
[ac_cv_struct_lastlog_ll_host=no])
|
||||
]
|
||||
)
|
||||
|
||||
if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
|
||||
AC_DEFINE(HAVE_LL_HOST, 1,
|
||||
if test "X$ac_cv_struct_lastlog_ll_host" = "Xyes"; then
|
||||
AC_DEFINE([HAVE_LL_HOST], [1],
|
||||
[Define if struct lastlog has ll_host])
|
||||
AC_DEFINE(ENABLE_LASTLOG, 1, [Define to support lastlog.])
|
||||
AC_DEFINE([ENABLE_LASTLOG], [1], [Define to support lastlog.])
|
||||
enable_lastlog="yes"
|
||||
else
|
||||
AC_MSG_ERROR([Cannot enable support for lastlog on systems where the data structures aren't available])
|
||||
enable_subids="no"
|
||||
enable_lastlog="no"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_LASTLOG, test "x$enable_lastlog" != "xno")
|
||||
AM_CONDITIONAL([ENABLE_LASTLOG], [test "x$enable_lastlog" != "xno"])
|
||||
|
||||
AC_SUBST(LIBSYSTEMD)
|
||||
if test "$enable_logind" = "yes"; then
|
||||
AC_CHECK_LIB(systemd, sd_session_get_remote_host,
|
||||
[enable_logind="yes"; [LIBSYSTEMD=-lsystemd];
|
||||
AC_DEFINE(ENABLE_LOGIND, 1,
|
||||
[Define to manage session support with logind.])],
|
||||
[enable_logind="no"])
|
||||
AC_SUBST([LIBSYSTEMD])
|
||||
if test "X$enable_logind" = "Xyes"; then
|
||||
AC_CHECK_LIB([systemd], [sd_session_get_remote_host],
|
||||
[
|
||||
LIBSYSTEMD=-lsystemd
|
||||
AC_DEFINE([ENABLE_LOGIND], [1], [Define to manage session support with logind.])
|
||||
],[
|
||||
AC_MSG_ERROR([libsystemd not found. If logind integration is not required, disable it using the --disable-logind option. ]dnl
|
||||
[ If logind integration is required, consider installing systemd or another package that provides libsystemd.])
|
||||
]
|
||||
)
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_LOGIND, test "x$enable_logind" != "xno")
|
||||
AM_CONDITIONAL([ENABLE_LOGIND], [test "X$enable_logind" = "Xyes"])
|
||||
|
||||
AC_SUBST(LIBCRYPT)
|
||||
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
|
||||
AC_CHECK_LIB([crypt], [crypt], [LIBCRYPT=-lcrypt],
|
||||
[AC_MSG_ERROR([crypt() not found])])
|
||||
AC_SUBST([LIBCRYPT])
|
||||
|
||||
AC_SUBST(LIYESCRYPT)
|
||||
AC_CHECK_LIB(crypt, crypt, [LIYESCRYPT=-lcrypt],
|
||||
[AC_MSG_ERROR([crypt() not found])])
|
||||
|
||||
AC_SUBST(LIBBSD)
|
||||
AC_SUBST([LIBBSD])
|
||||
if test "$with_libbsd" != "no"; then
|
||||
AC_SEARCH_LIBS([readpassphrase], [bsd], [], [
|
||||
AC_MSG_ERROR([readpassphrase() is missing, either from libc or libbsd])
|
||||
])
|
||||
AS_IF([test "$ac_cv_search_readpassphrase" = "-lbsd"], [
|
||||
AS_IF([test "X$ac_cv_search_readpassphrase" = "X-lbsd"], [
|
||||
PKG_CHECK_MODULES([LIBBSD], [libbsd-overlay])
|
||||
])
|
||||
dnl Make sure either the libc or libbsd provide the header.
|
||||
@@ -423,29 +376,29 @@ if test "$with_libbsd" != "no"; then
|
||||
AC_MSG_ERROR([readpassphrase.h is missing])
|
||||
])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
AC_DEFINE(WITH_LIBBSD, 1, [Build shadow with libbsd support])
|
||||
AC_DEFINE([WITH_LIBBSD], [1], [Build shadow with libbsd support])
|
||||
else
|
||||
AC_DEFINE(WITH_LIBBSD, 0, [Build shadow without libbsd support])
|
||||
AC_DEFINE([WITH_LIBBSD], [0], [Build shadow without libbsd support])
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_LIBBSD, test x$with_libbsd = xyes)
|
||||
AM_CONDITIONAL([WITH_LIBBSD], [test x$with_libbsd = xyes])
|
||||
|
||||
AC_SUBST(LIBACL)
|
||||
AC_SUBST([LIBACL])
|
||||
if test "$with_acl" != "no"; then
|
||||
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
|
||||
if test "$acl_header$with_acl" = "noyes" ; then
|
||||
AC_CHECK_HEADERS([acl/libacl.h attr/error_context.h], [acl_header="yes"], [acl_header="no"])
|
||||
if test "X$acl_header$with_acl" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([acl/libacl.h or attr/error_context.h is missing])
|
||||
elif test "$acl_header" = "yes" ; then
|
||||
AC_CHECK_LIB(acl, perm_copy_file,
|
||||
[AC_CHECK_LIB(acl, perm_copy_fd,
|
||||
elif test "X$acl_header" = "Xyes" ; then
|
||||
AC_CHECK_LIB([acl], [perm_copy_file],
|
||||
[AC_CHECK_LIB([acl], [perm_copy_fd],
|
||||
[acl_lib="yes"],
|
||||
[acl_lib="no"])],
|
||||
[acl_lib="no"])
|
||||
if test "$acl_lib$with_acl" = "noyes" ; then
|
||||
if test "X$acl_lib$with_acl" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libacl not found])
|
||||
elif test "$acl_lib" = "no" ; then
|
||||
elif test "X$acl_lib" = "Xno" ; then
|
||||
with_acl="no"
|
||||
else
|
||||
AC_DEFINE(WITH_ACL, 1,
|
||||
AC_DEFINE([WITH_ACL], [1],
|
||||
[Build shadow with ACL support])
|
||||
LIBACL="-lacl"
|
||||
with_acl="yes"
|
||||
@@ -455,23 +408,23 @@ if test "$with_acl" != "no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBATTR)
|
||||
AC_SUBST([LIBATTR])
|
||||
if test "$with_attr" != "no"; then
|
||||
AC_CHECK_HEADERS(attr/libattr.h attr/error_context.h, [attr_header="yes"], [attr_header="no"])
|
||||
if test "$attr_header$with_attr" = "noyes" ; then
|
||||
AC_CHECK_HEADERS([attr/libattr.h attr/error_context.h], [attr_header="yes"], [attr_header="no"])
|
||||
if test "X$attr_header$with_attr" = "noyes" ; then
|
||||
AC_MSG_ERROR([attr/libattr.h or attr/error_context.h is missing])
|
||||
elif test "$attr_header" = "yes" ; then
|
||||
AC_CHECK_LIB(attr, attr_copy_file,
|
||||
[AC_CHECK_LIB(attr, attr_copy_fd,
|
||||
elif test "X$attr_header" = "Xyes" ; then
|
||||
AC_CHECK_LIB([attr], [attr_copy_file],
|
||||
[AC_CHECK_LIB([attr], [attr_copy_fd],
|
||||
[attr_lib="yes"],
|
||||
[attr_lib="no"])],
|
||||
[attr_lib="no"])
|
||||
if test "$attr_lib$with_attr" = "noyes" ; then
|
||||
if test "X$attr_lib$with_attr" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libattr not found])
|
||||
elif test "$attr_lib" = "no" ; then
|
||||
elif test "X$attr_lib" = "Xno" ; then
|
||||
with_attr="no"
|
||||
else
|
||||
AC_DEFINE(WITH_ATTR, 1,
|
||||
AC_DEFINE([WITH_ATTR], [1],
|
||||
[Build shadow with Extended Attributes support])
|
||||
LIBATTR="-lattr"
|
||||
with_attr="yes"
|
||||
@@ -481,29 +434,29 @@ if test "$with_attr" != "no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBAUDIT)
|
||||
AC_SUBST([LIBAUDIT])
|
||||
if test "$with_audit" != "no"; then
|
||||
AC_CHECK_HEADER(libaudit.h, [audit_header="yes"], [audit_header="no"])
|
||||
if test "$audit_header$with_audit" = "noyes" ; then
|
||||
AC_CHECK_HEADER([libaudit.h], [audit_header="yes"], [audit_header="no"])
|
||||
if test "X$audit_header$with_audit" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libaudit.h is missing])
|
||||
elif test "$audit_header" = "yes"; then
|
||||
AC_CHECK_DECL(AUDIT_ADD_USER,,[audit_header="no"],[#include <libaudit.h>])
|
||||
AC_CHECK_DECL(AUDIT_DEL_USER,,[audit_header="no"],[#include <libaudit.h>])
|
||||
AC_CHECK_DECL(AUDIT_ADD_GROUP,,[audit_header="no"],[#include <libaudit.h>])
|
||||
AC_CHECK_DECL(AUDIT_DEL_GROUP,,[audit_header="no"],[#include <libaudit.h>])
|
||||
if test "$audit_header$with_audit" = "noyes" ; then
|
||||
elif test "X$audit_header" = "Xyes"; then
|
||||
AC_CHECK_DECL([AUDIT_ADD_USER],[],[audit_header="no"],[[#include <libaudit.h>]])
|
||||
AC_CHECK_DECL([AUDIT_DEL_USER],[],[audit_header="no"],[[#include <libaudit.h>]])
|
||||
AC_CHECK_DECL([AUDIT_ADD_GROUP],[],[audit_header="no"],[[#include <libaudit.h>]])
|
||||
AC_CHECK_DECL([AUDIT_DEL_GROUP],[],[audit_header="no"],[[#include <libaudit.h>]])
|
||||
if test "X$audit_header$with_audit" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([AUDIT_ADD_USER AUDIT_DEL_USER AUDIT_ADD_GROUP or AUDIT_DEL_GROUP missing from libaudit.h])
|
||||
fi
|
||||
fi
|
||||
if test "$audit_header" = "yes"; then
|
||||
AC_CHECK_LIB(audit, audit_log_acct_message,
|
||||
if test "X$audit_header" = "Xyes"; then
|
||||
AC_CHECK_LIB([audit], [audit_log_acct_message],
|
||||
[audit_lib="yes"], [audit_lib="no"])
|
||||
if test "$audit_lib$with_audit" = "noyes" ; then
|
||||
if test "X$audit_lib$with_audit" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libaudit not found])
|
||||
elif test "$audit_lib" = "no" ; then
|
||||
elif test "X$audit_lib" = "Xno" ; then
|
||||
with_audit="no"
|
||||
else
|
||||
AC_DEFINE(WITH_AUDIT, 1,
|
||||
AC_DEFINE([WITH_AUDIT], [1],
|
||||
[Define if you want to enable Audit messages])
|
||||
LIBAUDIT="-laudit"
|
||||
with_audit="yes"
|
||||
@@ -516,43 +469,43 @@ fi
|
||||
if test "$with_btrfs" != "no"; then
|
||||
AC_CHECK_HEADERS([sys/statfs.h linux/magic.h linux/btrfs_tree.h], \
|
||||
[btrfs_headers="yes"], [btrfs_headers="no"])
|
||||
if test "$btrfs_headers$with_btrfs" = "noyes" ; then
|
||||
if test "X$btrfs_headers$with_btrfs" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([One of sys/statfs.h linux/magic.h linux/btrfs_tree.h is missing])
|
||||
fi
|
||||
|
||||
if test "$btrfs_headers" = "yes" ; then
|
||||
AC_DEFINE(WITH_BTRFS, 1, [Build shadow with BtrFS support])
|
||||
if test "X$btrfs_headers" = "Xyes" ; then
|
||||
AC_DEFINE([WITH_BTRFS], [1], [Build shadow with BtrFS support])
|
||||
with_btrfs="yes"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_BTRFS, test x$with_btrfs = xyes)
|
||||
AM_CONDITIONAL([WITH_BTRFS], [test x$with_btrfs = xyes])
|
||||
|
||||
AC_SUBST(LIBSELINUX)
|
||||
AC_SUBST(LIBSEMANAGE)
|
||||
AC_SUBST([LIBSELINUX])
|
||||
AC_SUBST([LIBSEMANAGE])
|
||||
if test "$with_selinux" != "no"; then
|
||||
AC_CHECK_HEADERS(selinux/selinux.h, [selinux_header="yes"], [selinux_header="no"])
|
||||
if test "$selinux_header$with_selinux" = "noyes" ; then
|
||||
AC_CHECK_HEADERS([selinux/selinux.h], [selinux_header="yes"], [selinux_header="no"])
|
||||
if test "X$selinux_header$with_selinux" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([selinux/selinux.h is missing])
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(semanage/semanage.h, [semanage_header="yes"], [semanage_header="no"])
|
||||
if test "$semanage_header$with_selinux" = "noyes" ; then
|
||||
AC_CHECK_HEADERS([semanage/semanage.h], [semanage_header="yes"], [semanage_header="no"])
|
||||
if test "X$semanage_header$with_selinux" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([semanage/semanage.h is missing])
|
||||
fi
|
||||
|
||||
if test "$selinux_header$semanage_header" = "yesyes" ; then
|
||||
AC_CHECK_LIB(selinux, is_selinux_enabled, [selinux_lib="yes"], [selinux_lib="no"])
|
||||
if test "$selinux_lib$with_selinux" = "noyes" ; then
|
||||
if test "X$selinux_header$semanage_header" = "Xyesyes" ; then
|
||||
AC_CHECK_LIB([selinux], [is_selinux_enabled], [selinux_lib="yes"], [selinux_lib="no"])
|
||||
if test "X$selinux_lib$with_selinux" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libselinux not found])
|
||||
fi
|
||||
|
||||
AC_CHECK_LIB(semanage, semanage_connect, [semanage_lib="yes"], [semanage_lib="no"])
|
||||
if test "$semanage_lib$with_selinux" = "noyes" ; then
|
||||
AC_CHECK_LIB([semanage], [semanage_connect], [semanage_lib="yes"], [semanage_lib="no"])
|
||||
if test "X$semanage_lib$with_selinux" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libsemanage not found])
|
||||
fi
|
||||
|
||||
if test "$selinux_lib$semanage_lib" = "yesyes" ; then
|
||||
AC_DEFINE(WITH_SELINUX, 1,
|
||||
if test "X$selinux_lib$semanage_lib" = "Xyesyes" ; then
|
||||
AC_DEFINE([WITH_SELINUX], [1],
|
||||
[Build shadow with SELinux support])
|
||||
LIBSELINUX="-lselinux"
|
||||
LIBSEMANAGE="-lsemanage"
|
||||
@@ -565,19 +518,19 @@ if test "$with_selinux" != "no"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBTCB)
|
||||
AC_SUBST([LIBTCB])
|
||||
if test "$with_tcb" != "no"; then
|
||||
AC_CHECK_HEADERS(tcb.h, [tcb_header="yes"], [tcb_header="no"])
|
||||
if test "$tcb_header$with_tcb" = "noyes" ; then
|
||||
AC_CHECK_HEADERS([tcb.h], [tcb_header="yes"], [tcb_header="no"])
|
||||
if test "X$tcb_header$with_tcb" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([tcb.h is missing])
|
||||
elif test "$tcb_header" = "yes" ; then
|
||||
AC_CHECK_LIB(tcb, tcb_is_suspect, [tcb_lib="yes"], [tcb_lib="no"])
|
||||
if test "$tcb_lib$with_tcb" = "noyes" ; then
|
||||
elif test "X$tcb_header" = "Xyes" ; then
|
||||
AC_CHECK_LIB([tcb], [tcb_is_suspect], [tcb_lib="yes"], [tcb_lib="no"])
|
||||
if test "X$tcb_lib$with_tcb" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libtcb not found])
|
||||
elif test "$tcb_lib" = "no" ; then
|
||||
elif test "X$tcb_lib" = "Xno" ; then
|
||||
with_tcb="no"
|
||||
else
|
||||
AC_DEFINE(WITH_TCB, 1, [Build shadow with tcb support (incomplete)])
|
||||
AC_DEFINE([WITH_TCB], [1], [Build shadow with tcb support (incomplete)])
|
||||
LIBTCB="-ltcb"
|
||||
with_tcb="yes"
|
||||
fi
|
||||
@@ -585,39 +538,39 @@ if test "$with_tcb" != "no"; then
|
||||
with_tcb="no"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(WITH_TCB, test x$with_tcb = xyes)
|
||||
AM_CONDITIONAL([WITH_TCB], [test x$with_tcb = xyes])
|
||||
|
||||
AC_SUBST(LIBPAM)
|
||||
AC_SUBST([LIBPAM])
|
||||
if test "$with_libpam" != "no"; then
|
||||
AC_CHECK_LIB(pam, pam_start,
|
||||
AC_CHECK_LIB([pam], [pam_start],
|
||||
[pam_lib="yes"], [pam_lib="no"])
|
||||
if test "$pam_lib$with_libpam" = "noyes" ; then
|
||||
AC_MSG_ERROR(libpam not found)
|
||||
if test "X$pam_lib$with_libpam" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([libpam not found])
|
||||
fi
|
||||
|
||||
LIBPAM="-lpam"
|
||||
pam_conv_function="no"
|
||||
|
||||
AC_CHECK_LIB(pam, openpam_ttyconv,
|
||||
AC_CHECK_LIB([pam], [openpam_ttyconv],
|
||||
[pam_conv_function="openpam_ttyconv"],
|
||||
AC_CHECK_LIB(pam_misc, misc_conv,
|
||||
[pam_conv_function="misc_conv"; LIBPAM="$LIBPAM -lpam_misc"])
|
||||
[AC_CHECK_LIB([pam_misc], [misc_conv],
|
||||
[pam_conv_function="misc_conv"; LIBPAM="$LIBPAM -lpam_misc"])]
|
||||
)
|
||||
|
||||
if test "$pam_conv_function$with_libpam" = "noyes" ; then
|
||||
AC_MSG_ERROR(PAM conversation function not found)
|
||||
if test "X$pam_conv_function$with_libpam" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([PAM conversation function not found])
|
||||
fi
|
||||
|
||||
pam_headers_found=no
|
||||
AC_CHECK_HEADERS( [security/openpam.h security/pam_misc.h],
|
||||
[ pam_headers_found=yes ; break ], [],
|
||||
[ #include <security/pam_appl.h> ] )
|
||||
if test "$pam_headers_found$with_libpam" = "noyes" ; then
|
||||
AC_MSG_ERROR(PAM headers not found)
|
||||
[[#include <security/pam_appl.h>]] )
|
||||
if test "X$pam_headers_found$with_libpam" = "Xnoyes" ; then
|
||||
AC_MSG_ERROR([PAM headers not found])
|
||||
fi
|
||||
|
||||
|
||||
if test "$pam_lib$pam_headers_found" = "yesyes" -a "$pam_conv_function" != "no" ; then
|
||||
if test "X$pam_lib$pam_headers_found" = "Xyesyes" && test "$pam_conv_function" != "no" ; then
|
||||
with_libpam="yes"
|
||||
else
|
||||
with_libpam="no"
|
||||
@@ -625,87 +578,86 @@ if test "$with_libpam" != "no"; then
|
||||
fi
|
||||
fi
|
||||
dnl Now with_libpam is either yes or no
|
||||
if test "$with_libpam" = "yes"; then
|
||||
if test "X$with_libpam" = "Xyes"; then
|
||||
AC_CHECK_DECLS([PAM_ESTABLISH_CRED,
|
||||
PAM_DELETE_CRED,
|
||||
PAM_NEW_AUTHTOK_REQD,
|
||||
PAM_DATA_SILENT],
|
||||
[], [], [#include <security/pam_appl.h>])
|
||||
[], [], [[#include <security/pam_appl.h>]])
|
||||
|
||||
|
||||
save_libs=$LIBS
|
||||
LIBS="$LIBS $LIBPAM"
|
||||
# We do not use AC_CHECK_FUNCS to avoid duplicated definition with
|
||||
# Linux PAM.
|
||||
AC_CHECK_FUNC(pam_fail_delay, [AC_DEFINE(HAS_PAM_FAIL_DELAY, 1, [Define to 1 if you have the declaration of 'pam_fail_delay'])])
|
||||
AC_CHECK_FUNC([pam_fail_delay], [AC_DEFINE([HAS_PAM_FAIL_DELAY], [1], [Define to 1 if you have the declaration of 'pam_fail_delay'])])
|
||||
LIBS=$save_libs
|
||||
|
||||
AC_DEFINE(USE_PAM, 1, [Define to support Pluggable Authentication Modules])
|
||||
AC_DEFINE_UNQUOTED(SHADOW_PAM_CONVERSATION, [$pam_conv_function],[PAM conversation to use])
|
||||
AM_CONDITIONAL(USE_PAM, [true])
|
||||
AC_DEFINE([USE_PAM], [1], [Define to support Pluggable Authentication Modules])
|
||||
AC_DEFINE_UNQUOTED([SHADOW_PAM_CONVERSATION], [$pam_conv_function],[PAM conversation to use])
|
||||
|
||||
AC_MSG_CHECKING(use login and su access checking if PAM not used)
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_CHECKING([use login and su access checking if PAM not used])
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
AC_DEFINE(SU_ACCESS, 1, [Define to support /etc/suauth su access control.])
|
||||
AM_CONDITIONAL(USE_PAM, [false])
|
||||
AC_MSG_CHECKING(use login and su access checking if PAM not used)
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([SU_ACCESS], [1], [Define to support /etc/suauth su access control.])
|
||||
AC_MSG_CHECKING([use login and su access checking if PAM not used])
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
AM_CONDITIONAL([USE_PAM], [test "X$with_libpam" = "Xyes"])
|
||||
|
||||
if test "$enable_acct_tools_setuid" != "no"; then
|
||||
if test "$with_libpam" != "yes"; then
|
||||
if test "$enable_acct_tools_setuid" = "yes"; then
|
||||
AC_MSG_ERROR(PAM support is required for --enable-account-tools-setuid)
|
||||
if test "X$enable_acct_tools_setuid" = "Xyes"; then
|
||||
AC_MSG_ERROR([PAM support is required for --enable-account-tools-setuid])
|
||||
else
|
||||
enable_acct_tools_setuid="no"
|
||||
fi
|
||||
else
|
||||
enable_acct_tools_setuid="yes"
|
||||
fi
|
||||
if test "$enable_acct_tools_setuid" = "yes"; then
|
||||
AC_DEFINE(ACCT_TOOLS_SETUID,
|
||||
1,
|
||||
if test "X$enable_acct_tools_setuid" = "Xyes"; then
|
||||
AC_DEFINE([ACCT_TOOLS_SETUID],
|
||||
[1],
|
||||
[Define if account management tools should be installed setuid and authenticate the callers])
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(ACCT_TOOLS_SETUID, test "x$enable_acct_tools_setuid" = "xyes")
|
||||
AM_CONDITIONAL([ACCT_TOOLS_SETUID], [test "x$enable_acct_tools_setuid" = "xyes"])
|
||||
|
||||
|
||||
AC_ARG_WITH(fcaps,
|
||||
AC_ARG_WITH([fcaps],
|
||||
[AS_HELP_STRING([--with-fcaps], [use file capabilities instead of suid binaries for newuidmap/newgidmap @<:@default=no@:>@])],
|
||||
[with_fcaps=$withval], [with_fcaps=no])
|
||||
AM_CONDITIONAL(FCAPS, test "x$with_fcaps" = "xyes")
|
||||
AM_CONDITIONAL([FCAPS], [test "x$with_fcaps" = "xyes"])
|
||||
|
||||
if test "x$with_fcaps" = "xyes"; then
|
||||
AC_CHECK_PROGS(capcmd, "setcap")
|
||||
AC_CHECK_PROGS([capcmd], ["setcap"])
|
||||
if test "x$capcmd" = "x" ; then
|
||||
AC_MSG_ERROR([setcap command not available])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(LIBSKEY)
|
||||
AC_SUBST(LIBMD)
|
||||
if test "$with_skey" = "yes"; then
|
||||
AC_CHECK_LIB(md, MD5Init, [LIBMD=-lmd])
|
||||
AC_CHECK_LIB(skey, skeychallenge, [LIBSKEY=-lskey],
|
||||
[AC_MSG_ERROR([liskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
|
||||
AC_DEFINE(SKEY, 1, [Define to support S/Key logins.])
|
||||
AC_SUBST([LIBSKEY])
|
||||
AC_SUBST([LIBMD])
|
||||
if test "X$with_skey" = "Xyes"; then
|
||||
AC_CHECK_LIB([md], [MD5Init], [LIBMD=-lmd])
|
||||
AC_CHECK_LIB([skey], [skeychallenge], [LIBSKEY=-lskey],
|
||||
[AC_MSG_ERROR([libskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
|
||||
AC_DEFINE([SKEY], [1], [Define to support S/Key logins.])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdio.h>
|
||||
#include <skey.h>
|
||||
]], [[
|
||||
skeychallenge((void*)0, (void*)0, (void*)0, 0);
|
||||
]])],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])],[])
|
||||
]])],[AC_DEFINE([SKEY_BSD_STYLE], [1], [Define to support newer BSD S/Key API])],[])
|
||||
fi
|
||||
|
||||
AC_CHECK_FUNC(fgetpwent_r, [AC_DEFINE(HAVE_FGETPWENT_R, 1, [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
|
||||
AC_CHECK_FUNC([fgetpwent_r], [AC_DEFINE([HAVE_FGETPWENT_R], [1], [Defined to 1 if you have the declaration of 'fgetpwent_r'])])
|
||||
|
||||
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
|
||||
AC_DEFINE_UNQUOTED([SHELL], ["$SHELL"], [The default shell.])
|
||||
|
||||
AM_GNU_GETTEXT_VERSION([0.19])
|
||||
AM_GNU_GETTEXT([external], [need-ngettext])
|
||||
AM_CONDITIONAL(USE_NLS, test "x$USE_NLS" = "xyes")
|
||||
AM_CONDITIONAL([USE_NLS], [test "x$USE_NLS" = "xyes"])
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
@@ -737,7 +689,6 @@ AC_CONFIG_FILES([
|
||||
libsubid/Makefile
|
||||
libsubid/subid.h
|
||||
src/Makefile
|
||||
contrib/Makefile
|
||||
etc/Makefile
|
||||
etc/pam.d/Makefile
|
||||
etc/shadow-maint/Makefile
|
||||
@@ -745,30 +696,28 @@ AC_CONFIG_FILES([
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
echo
|
||||
echo "shadow will be compiled with the following features:"
|
||||
echo
|
||||
echo " auditing support: $with_audit"
|
||||
echo " PAM support: $with_libpam"
|
||||
if test "$with_libpam" = "yes"; then
|
||||
echo " suid account management tools: $enable_acct_tools_setuid"
|
||||
fi
|
||||
echo " SELinux support: $with_selinux"
|
||||
echo " BtrFS support: $with_btrfs"
|
||||
echo " ACL support: $with_acl"
|
||||
echo " Extended Attributes support: $with_attr"
|
||||
echo " tcb support (incomplete): $with_tcb"
|
||||
echo " shadow group support: $enable_shadowgrp"
|
||||
echo " S/Key support: $with_skey"
|
||||
echo " SHA passwords encryption: $with_sha_crypt"
|
||||
echo " bcrypt passwords encryption: $with_bcrypt"
|
||||
echo " yescrypt passwords encryption: $with_yescrypt"
|
||||
echo " nscd support: $with_nscd"
|
||||
echo " sssd support: $with_sssd"
|
||||
echo " subordinate IDs support: $enable_subids"
|
||||
echo " enable lastlog: $enable_lastlog"
|
||||
echo " enable logind: $enable_logind"
|
||||
echo " use file caps: $with_fcaps"
|
||||
echo " install su: $with_su"
|
||||
echo " enabled vendor dir: $enable_vendordir"
|
||||
echo
|
||||
AC_MSG_NOTICE([shadow ${PACKAGE_VERSION} has been configured with the following features:
|
||||
|
||||
auditing support: $with_audit
|
||||
PAM support: $with_libpam
|
||||
suid account management tools: $enable_acct_tools_setuid
|
||||
SELinux support: $with_selinux
|
||||
BtrFS support: $with_btrfs
|
||||
ACL support: $with_acl
|
||||
Extended Attributes support: $with_attr
|
||||
tcb support (incomplete): $with_tcb
|
||||
shadow group support: $enable_shadowgrp
|
||||
S/Key support: $with_skey
|
||||
SHA passwords encryption: $with_sha_crypt
|
||||
bcrypt passwords encryption: $with_bcrypt
|
||||
yescrypt passwords encryption: $with_yescrypt
|
||||
nscd support: $with_nscd
|
||||
sssd support: $with_sssd
|
||||
subordinate IDs support: $enable_subids
|
||||
enable lastlog: $enable_lastlog
|
||||
enable logind: $enable_logind
|
||||
use file caps: $with_fcaps
|
||||
install su: $with_su
|
||||
enabled vendor dir: $enable_vendordir
|
||||
|
||||
])
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
@@ -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
|
||||
@@ -1,502 +0,0 @@
|
||||
/****
|
||||
** 04/21/96
|
||||
** hacked even more, replaced gets() with something slightly harder to buffer
|
||||
** overflow. Added support for setting a default quota on new account, with
|
||||
** edquota -p. Other cleanups for security, I let some users run adduser suid
|
||||
** root to add new accounts. (overflow checks, clobber environment, valid
|
||||
** shell checks, restrictions on gid + home dir settings).
|
||||
|
||||
** Added max. username length. Used syslog() a bit for important events.
|
||||
** Support to immediately expire account with passwd -e.
|
||||
|
||||
** Called it version 2.0! Because I felt like it!
|
||||
|
||||
** -- Chris, chris@ferret.lmh.ox.ac.uk
|
||||
|
||||
** 03/17/96
|
||||
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
|
||||
** --marekm
|
||||
**
|
||||
** 02/26/96
|
||||
** modified to call shadow utils (useradd,chage,passwd) on shadowed
|
||||
** systems - Cristian Gafton, gafton@sorosis.ro
|
||||
**
|
||||
** 6/27/95
|
||||
** shadow-adduser 1.4:
|
||||
**
|
||||
** now it copies the /etc/skel dir into the person's dir,
|
||||
** makes the mail folders, changed some defaults and made a 'make
|
||||
** install' just for the hell of it.
|
||||
**
|
||||
** Greg Gallagher
|
||||
** CIN.Net
|
||||
**
|
||||
** 1/28/95
|
||||
** shadow-adduser 1.3:
|
||||
**
|
||||
** Basically a bug-fix on my additions in 1.2. Thanks to Terry Stewart
|
||||
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
|
||||
** It was such a stupid bug that I would have never seen it myself.
|
||||
**
|
||||
** Brandon
|
||||
*****
|
||||
** 01/27/95
|
||||
**
|
||||
** shadow-adduser 1.2:
|
||||
** I took the C source from adduser-shadow (credits are below) and made
|
||||
** it a little more worthwhile. Many small changes... Here's
|
||||
** the ones I can remember:
|
||||
**
|
||||
** Removed support for non-shadowed systems (if you don't have shadow,
|
||||
** use the original adduser, don't get this shadow version!)
|
||||
** Added support for the correct /etc/shadow fields (Min days before
|
||||
** password change, max days before password change, Warning days,
|
||||
** and how many days from expiry date does the account go invalid)
|
||||
** The previous version just left all of those fields blank.
|
||||
** There is still one field left (expiry date for the account, period)
|
||||
** which I have left blank because I do not use it and didn't want to
|
||||
** spend any more time on this. I'm sure someone will put it in and
|
||||
** tack another plethora of credits on here. :)
|
||||
** Added in the password date field, which should always reflect the last
|
||||
** date the password was changed, for expiry purposes. "passwd" always
|
||||
** updates this field, so the adduser program should set it up right
|
||||
** initially (or a user could keep their initial password forever ;)
|
||||
** The number is in days since Jan 1st, 1970.
|
||||
**
|
||||
** Have fun with it, and someone please make
|
||||
** a real version(this is still just a hack)
|
||||
** for us all to use (and Email it to me???)
|
||||
**
|
||||
** Brandon
|
||||
** photon@usis.com
|
||||
**
|
||||
*****
|
||||
** adduser 1.0: add a new user account (For systems not using shadow)
|
||||
** With a nice little interface and a will to do all the work for you.
|
||||
**
|
||||
** Craig Hagan
|
||||
** hagan@opine.cs.umass.edu
|
||||
**
|
||||
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
|
||||
** chris@slinky.cs.umass.edu
|
||||
**
|
||||
*****
|
||||
**
|
||||
** 01/19/95
|
||||
**
|
||||
** FURTHER modifications to enable shadow passwd support (kludged, but
|
||||
** no more so than the original) by Dan Crowson - dcrowson@mo.net
|
||||
**
|
||||
** Search on DAN for all changes...
|
||||
**
|
||||
*****
|
||||
**
|
||||
** cc -O -o adduser adduser.c
|
||||
** Use gcc if you have it... (political reasons beyond my control) (chris)
|
||||
**
|
||||
** I've gotten this program to work with success under Linux (without
|
||||
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
|
||||
** on any system that uses no shadow. (chris)
|
||||
**
|
||||
** If you have no crypt() then try
|
||||
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
|
||||
** I'm not sure how login operates with no crypt()... I guess
|
||||
** the same way we're doing it here.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
|
||||
* immediately upon next login */
|
||||
#define HAVE_QUOTAS /* Obvious */
|
||||
#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change
|
||||
* password expiry values (if running suid root) */
|
||||
|
||||
#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */
|
||||
#define LOGGING /* If we want to log various things to syslog */
|
||||
#define MAX_USRNAME 8 /* Longer usernames seem to work on my system....
|
||||
* But they're probably a poor idea */
|
||||
|
||||
|
||||
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
|
||||
#define DEFAULT_HOME "/home"
|
||||
#define USERADD_PATH "/usr/sbin/useradd"
|
||||
#define CHAGE_PATH "/usr/bin/chage"
|
||||
#define PASSWD_PATH "/usr/bin/passwd"
|
||||
#define EDQUOTA_PATH "/usr/sbin/edquota"
|
||||
#define QUOTA_DEFAULT "defuser"
|
||||
#define DEFAULT_GROUP 100
|
||||
|
||||
#define DEFAULT_MIN_PASS 0
|
||||
#define DEFAULT_MAX_PASS 100
|
||||
#define DEFAULT_WARN_PASS 14
|
||||
#define DEFAULT_USER_DIE 366
|
||||
|
||||
void safeget (char *, int);
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
char foo[32];
|
||||
char usrname[32], person[32], dir[32], shell[32];
|
||||
unsigned int group, min_pass, max_pass, warn_pass, user_die;
|
||||
/* the group and uid of the new user */
|
||||
int bad = 0, done = 0, correct = 0, olduid;
|
||||
char cmd[255];
|
||||
struct group *grp;
|
||||
|
||||
/* flags, in order:
|
||||
* bad to see if the username is in /etc/passwd, or if strange stuff has
|
||||
* been typed if the user might be put in group 0
|
||||
* done allows the program to exit when a user has been added
|
||||
* correct loops until a username is found that isn't in /etc/passwd
|
||||
*/
|
||||
|
||||
/* The real program starts HERE! */
|
||||
|
||||
if (geteuid () != 0)
|
||||
{
|
||||
printf ("It seems you don't have access to add a new user. Try\n");
|
||||
printf ("logging in as root or su root to gain superuser access.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Sanity checks
|
||||
*/
|
||||
|
||||
#ifdef LOGGING
|
||||
openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
|
||||
syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
|
||||
#endif
|
||||
|
||||
if (!(grp = getgrgid (DEFAULT_GROUP)))
|
||||
{
|
||||
printf ("Error: the default group %d does not exist on this system!\n",
|
||||
DEFAULT_GROUP);
|
||||
printf ("adduser must be recompiled.\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: failed. no such default group\n");
|
||||
closelog ();
|
||||
#endif
|
||||
exit (1);
|
||||
};
|
||||
|
||||
while (!correct)
|
||||
{ /* loop until a "good" usrname is chosen */
|
||||
while (!done)
|
||||
{
|
||||
printf ("\nLogin to add (^C to quit): ");
|
||||
fflush (stdout);
|
||||
|
||||
safeget (usrname, sizeof (usrname));
|
||||
|
||||
if (!strlen (usrname))
|
||||
{
|
||||
printf ("Empty input.\n");
|
||||
done = 0;
|
||||
continue;
|
||||
};
|
||||
|
||||
/* what I saw here before made me think maybe I was running DOS */
|
||||
/* might this be a solution? (chris) */
|
||||
if (strlen (usrname) > MAX_USRNAME)
|
||||
{
|
||||
printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
|
||||
done = 0;
|
||||
}
|
||||
else if (getpwnam (usrname) != NULL)
|
||||
{
|
||||
printf ("That name is in use, choose another.\n");
|
||||
done = 0;
|
||||
}
|
||||
else if (strchr (usrname, ' ') != NULL)
|
||||
{
|
||||
printf ("No spaces in username!!\n");
|
||||
done = 0;
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}; /* done, we have a valid new user name */
|
||||
|
||||
/* all set, get the rest of the stuff */
|
||||
printf ("\nEditing information for new user [%s]\n", usrname);
|
||||
|
||||
printf ("\nFull Name [%s]: ", usrname);
|
||||
fflush (stdout);
|
||||
safeget (person, sizeof (person));
|
||||
if (!strlen (person))
|
||||
{
|
||||
bzero (person, sizeof (person));
|
||||
strcpy (person, usrname);
|
||||
};
|
||||
|
||||
if (getuid () == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
bad = 0;
|
||||
printf ("GID [%d]: ", DEFAULT_GROUP);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
if (!strlen (foo))
|
||||
group = DEFAULT_GROUP;
|
||||
else if (isdigit (*foo))
|
||||
{
|
||||
group = atoi (foo);
|
||||
if (!(grp = getgrgid (group)))
|
||||
{
|
||||
printf ("unknown gid %s\n", foo);
|
||||
group = DEFAULT_GROUP;
|
||||
bad = 1;
|
||||
};
|
||||
}
|
||||
else if ((grp = getgrnam (foo)))
|
||||
group = grp->gr_gid;
|
||||
else
|
||||
{
|
||||
printf ("unknown group %s\n", foo);
|
||||
group = DEFAULT_GROUP;
|
||||
bad = 1;
|
||||
}
|
||||
if (group == 0)
|
||||
{ /* You're not allowed to make root group users! */
|
||||
printf ("Creation of root group users not allowed (must be done by hand)\n");
|
||||
group = DEFAULT_GROUP;
|
||||
bad = 1;
|
||||
};
|
||||
}
|
||||
while (bad);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Group will be default of: %d\n", DEFAULT_GROUP);
|
||||
group = DEFAULT_GROUP;
|
||||
}
|
||||
|
||||
if (getuid () == 0)
|
||||
{
|
||||
printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
|
||||
printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
|
||||
fflush (stdout);
|
||||
safeget (dir, sizeof (dir));
|
||||
if (!strlen (dir))
|
||||
{ /* hit return */
|
||||
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
|
||||
}
|
||||
else if (dir[strlen (dir) - 1] == '/')
|
||||
sprintf (dir+strlen(dir), "%s", usrname);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
|
||||
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
|
||||
}
|
||||
|
||||
printf ("\nShell [%s]: ", DEFAULT_SHELL);
|
||||
fflush (stdout);
|
||||
safeget (shell, sizeof (shell));
|
||||
if (!strlen (shell))
|
||||
sprintf (shell, "%s", DEFAULT_SHELL);
|
||||
else
|
||||
{
|
||||
char *sh;
|
||||
int ok = 0;
|
||||
#ifdef HAVE_GETUSERSHELL
|
||||
setusershell ();
|
||||
while ((sh = getusershell ()) != NULL)
|
||||
if (!strcmp (shell, sh))
|
||||
ok = 1;
|
||||
endusershell ();
|
||||
#endif
|
||||
if (!ok)
|
||||
{
|
||||
if (getuid () == 0)
|
||||
printf ("Warning: root allowed non standard shell\n");
|
||||
else
|
||||
{
|
||||
printf ("Shell NOT in /etc/shells, DEFAULT used\n");
|
||||
sprintf (shell, "%s", DEFAULT_SHELL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXPIRE_VALS_SET
|
||||
if (getuid () == 0)
|
||||
{
|
||||
#endif
|
||||
printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
if (strlen (foo) > 1)
|
||||
min_pass = DEFAULT_MIN_PASS;
|
||||
else
|
||||
min_pass = atoi (foo);
|
||||
|
||||
printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
if (strlen (foo) > 1)
|
||||
max_pass = atoi (foo);
|
||||
else
|
||||
max_pass = DEFAULT_MAX_PASS;
|
||||
|
||||
printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
warn_pass = atoi (foo);
|
||||
if (warn_pass == 0)
|
||||
|
||||
warn_pass = DEFAULT_WARN_PASS;
|
||||
|
||||
printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
user_die = atoi (foo);
|
||||
if (user_die == 0)
|
||||
user_die = DEFAULT_USER_DIE;
|
||||
|
||||
#ifdef EXPIRE_VALS_SET
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\nSorry, account expiry values are set.\n");
|
||||
user_die = DEFAULT_USER_DIE;
|
||||
warn_pass = DEFAULT_WARN_PASS;
|
||||
max_pass = DEFAULT_MAX_PASS;
|
||||
min_pass = DEFAULT_MIN_PASS;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf ("\nInformation for new user [%s] [%s]:\n", usrname, person);
|
||||
printf ("Home directory: [%s] Shell: [%s]\n", dir, shell);
|
||||
printf ("GID: [%d]\n", group);
|
||||
printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
|
||||
min_pass, max_pass, warn_pass, user_die);
|
||||
printf ("\nIs this correct? [y/N]: ");
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
|
||||
done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
|
||||
|
||||
if (bad != 1)
|
||||
printf ("\nUser [%s] not added\n", usrname);
|
||||
}
|
||||
|
||||
/* Clobber the environment, I run this suid root sometimes to let
|
||||
* non root privileged accounts add users --chris */
|
||||
|
||||
*environ = NULL;
|
||||
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
|
||||
USERADD_PATH, group, dir, shell, person, usrname);
|
||||
printf ("Calling useradd to add new user:\n%s\n", cmd);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("User add failed!\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "could not add new user\n");
|
||||
closelog ();
|
||||
#endif
|
||||
exit (errno);
|
||||
};
|
||||
|
||||
olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root
|
||||
*/
|
||||
setuid (0);
|
||||
|
||||
bzero (cmd, sizeof (cmd));
|
||||
|
||||
/* Chage runs suid root. => we need ruid root to run it with
|
||||
* anything other than chage -l
|
||||
*/
|
||||
|
||||
sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
|
||||
min_pass, max_pass, warn_pass, user_die, usrname);
|
||||
printf ("%s\n", cmd);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("There was an error setting password expire values\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "password expire values could not be set\n");
|
||||
#endif
|
||||
};
|
||||
|
||||
/* I want to add a user completely with one easy command --chris */
|
||||
|
||||
#ifdef HAVE_QUOTAS
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
|
||||
printf ("%s\n", cmd);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("\nWarning: error setting quota\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
|
||||
#endif /* LOGGING */
|
||||
}
|
||||
else
|
||||
printf ("\nDefault quota set.\n");
|
||||
#endif /* HAVE_QUOTAS */
|
||||
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("\nWarning: error setting password\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: password set failed!\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef IMMEDIATE_CHANGE
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("\nWarning: error expiring password\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: password expire failed!\n");
|
||||
#endif /* LOGGING */
|
||||
}
|
||||
#endif /* IMMEDIATE_CHANGE */
|
||||
|
||||
setuid (olduid);
|
||||
|
||||
#ifdef LOGGING
|
||||
closelog ();
|
||||
#endif
|
||||
|
||||
printf ("\nDone.\n");
|
||||
}
|
||||
|
||||
void
|
||||
safeget (char *buf, int maxlen)
|
||||
{
|
||||
int c, i = 0, bad = 0;
|
||||
char *bstart = buf;
|
||||
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
|
||||
{
|
||||
bad = (!isalnum (c) && (c != '_') && (c != ' '));
|
||||
*(buf++) = c;
|
||||
}
|
||||
*buf = '\0';
|
||||
|
||||
if (bad)
|
||||
{
|
||||
printf ("\nString contained banned character. Please stick to alphanumerics.\n");
|
||||
*bstart = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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..."
|
||||
@@ -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='[1m' # start embolden
|
||||
E='[m' # 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.
|
||||
16
doc/HOWTO
16
doc/HOWTO
@@ -346,7 +346,7 @@
|
||||
return value points to static data whose content is overwritten by
|
||||
each call.
|
||||
|
||||
Warning: The key space consists of 2**56 equal 7.2e16 possible values.
|
||||
Warning: the key space consists of 2**56 equal 7.2e16 possible values.
|
||||
Exhaustive searches of this key space are possible using massively
|
||||
parallel computers. Software, such as crack(1), is available which
|
||||
will search the portion of this key space that is generally used by
|
||||
@@ -471,12 +471,12 @@
|
||||
|
||||
The Shadow Suite contains replacement programs for:
|
||||
|
||||
su, login, passwd, newgrp, chfn, chsh, and id
|
||||
su, login, passwd, newgrp, chfn, chsh
|
||||
|
||||
The package also contains the new programs:
|
||||
|
||||
chage, newusers, dpasswd, gpasswd, useradd, userdel, usermod,
|
||||
groupadd, groupdel, groupmod, groups, pwck, grpck, lastlog, pwconv,
|
||||
groupadd, groupdel, groupmod, pwck, grpck, lastlog, pwconv,
|
||||
and pwunconv
|
||||
|
||||
Additionally, the library: libshadow.a is included for writing and/or
|
||||
@@ -586,8 +586,6 @@
|
||||
|
||||
· /usr/bin/chsh
|
||||
|
||||
· /usr/bin/id
|
||||
|
||||
The BETA package has a save target in the Makefile, but it's commented
|
||||
out because different distributions place the programs in different
|
||||
places.
|
||||
@@ -637,8 +635,6 @@
|
||||
|
||||
· /usr/man/man1/chsh.1.gz
|
||||
|
||||
· /usr/man/man1/id.1.gz
|
||||
|
||||
· /usr/man/man1/login.1.gz
|
||||
|
||||
· /usr/man/man1/passwd.1.gz
|
||||
@@ -1000,7 +996,7 @@
|
||||
sudo for the shadow suite, is available as at:
|
||||
<ftp://sunsite.unc.edu/pub/Linux/system/Admin/sudo-1.2-shadow.tgz>
|
||||
|
||||
Warning: When you install sudo your /etc/sudoers file will be replaced
|
||||
Warning: when you install sudo your /etc/sudoers file will be replaced
|
||||
with a default one, so you need to make a backup of it if you have
|
||||
added anything to the default one. (you could also edit the Makefile
|
||||
and remove the line that copies the default file to /etc).
|
||||
@@ -1377,7 +1373,7 @@
|
||||
users or changing the group password, the /etc/gshadow file will be
|
||||
changed.
|
||||
|
||||
The programs groups, groupadd, groupmod, and groupdel are provided as
|
||||
The programs groupadd, groupmod, and groupdel are provided as
|
||||
part of the Shadow Suite to modify groups.
|
||||
|
||||
The format of the /etc/group file is as follows:
|
||||
@@ -1755,7 +1751,7 @@
|
||||
}
|
||||
#ifdef HAS_SHADOW
|
||||
if ((pw->pw_passwd && pw->pw_passwd[0] == '@'
|
||||
&& pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
|
||||
&& pw_auth(pw->pw_passwd+1, pw->pw_name))
|
||||
|| !valid (passwd, pw)) {
|
||||
return (UPAP_AUTHNAK);
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = @AM_DISTCHECK_CONFIGURE_FLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
@@ -204,7 +205,6 @@ LIBSYSTEMD = @LIBSYSTEMD@
|
||||
LIBTCB = @LIBTCB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LIYESCRYPT = @LIYESCRYPT@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
@@ -251,8 +251,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@
|
||||
|
||||
@@ -222,6 +222,7 @@ am__relativize = \
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = @AM_DISTCHECK_CONFIGURE_FLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
@@ -293,7 +294,6 @@ LIBSYSTEMD = @LIBSYSTEMD@
|
||||
LIBTCB = @LIBTCB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LIYESCRYPT = @LIYESCRYPT@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
@@ -340,8 +340,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@
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#
|
||||
# Delay in seconds before being allowed another attempt after a login failure
|
||||
# Note: When PAM is used, some modules may enforce a minimum delay (e.g.
|
||||
# Note: when PAM is used, some modules may enforce a minimum delay (e.g.
|
||||
# pam_unix(8) enforces a 2s delay)
|
||||
#
|
||||
FAIL_DELAY 3
|
||||
@@ -276,7 +276,7 @@ PASS_ALWAYS_WARN yes
|
||||
#
|
||||
# Number of significant characters in the password for crypt().
|
||||
# Default is 8, don't change unless your crypt() is better.
|
||||
# Ignored if MD5_CRYPT_ENAB set to "yes".
|
||||
# Only used for DES encryption algorithm.
|
||||
#
|
||||
#PASS_MAX_LEN 8
|
||||
|
||||
@@ -308,7 +308,7 @@ CHFN_RESTRICT rwh
|
||||
# Set to "no" if you need to copy encrypted passwords to other systems
|
||||
# which don't understand the new algorithm. Default is "no".
|
||||
#
|
||||
# Note: If you use PAM, it is recommended to use a value consistent with
|
||||
# Note: if you use PAM, it is recommended to use a value consistent with
|
||||
# the PAM modules configuration.
|
||||
#
|
||||
# This variable is deprecated. You should use ENCRYPT_METHOD instead.
|
||||
@@ -326,7 +326,7 @@ CHFN_RESTRICT rwh
|
||||
# MD5 and DES should not be used for new hashes, see crypt(5) for recommendations.
|
||||
# Overrides the MD5_CRYPT_ENAB option
|
||||
#
|
||||
# Note: If you use PAM, it is recommended to use a value consistent with
|
||||
# Note: if you use PAM, it is recommended to use a value consistent with
|
||||
# the PAM modules configuration.
|
||||
#
|
||||
#ENCRYPT_METHOD DES
|
||||
@@ -467,7 +467,7 @@ PREVENT_NO_AUTH superuser
|
||||
# Used in pam_timestamp module to calculate the keyed-hash message
|
||||
# authentication code.
|
||||
#
|
||||
# Note: It is recommended to check hmac(3) to see the possible algorithms
|
||||
# Note: it is recommended to check hmac(3) to see the possible algorithms
|
||||
# that are available in your system.
|
||||
#
|
||||
#HMAC_CRYPTO_ALGO SHA512
|
||||
|
||||
@@ -11,7 +11,6 @@ pamd_files = \
|
||||
passwd
|
||||
|
||||
pamd_acct_tools_files = \
|
||||
chage \
|
||||
chgpasswd \
|
||||
groupadd \
|
||||
groupdel \
|
||||
|
||||
@@ -165,6 +165,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = @AM_DISTCHECK_CONFIGURE_FLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
@@ -236,7 +237,6 @@ LIBSYSTEMD = @LIBSYSTEMD@
|
||||
LIBTCB = @LIBTCB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LIYESCRYPT = @LIYESCRYPT@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
@@ -283,8 +283,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@
|
||||
@@ -342,7 +340,6 @@ top_srcdir = @top_srcdir@
|
||||
pamd_files = chpasswd chfn chsh groupmems login newusers passwd \
|
||||
$(am__append_2)
|
||||
pamd_acct_tools_files = \
|
||||
chage \
|
||||
chgpasswd \
|
||||
groupadd \
|
||||
groupdel \
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#%PAM-1.0
|
||||
auth sufficient pam_rootok.so
|
||||
account required pam_permit.so
|
||||
password include system-auth
|
||||
@@ -130,6 +130,7 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
|
||||
AM_DISTCHECK_CONFIGURE_FLAGS = @AM_DISTCHECK_CONFIGURE_FLAGS@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
@@ -201,7 +202,6 @@ LIBSYSTEMD = @LIBSYSTEMD@
|
||||
LIBTCB = @LIBTCB@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LIYESCRYPT = @LIYESCRYPT@
|
||||
LN_S = @LN_S@
|
||||
LTLIBICONV = @LTLIBICONV@
|
||||
LTLIBINTL = @LTLIBINTL@
|
||||
@@ -248,8 +248,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@
|
||||
|
||||
164
lib/Makefile.am
164
lib/Makefile.am
@@ -29,16 +29,24 @@ libshadow_la_SOURCES = \
|
||||
age.c \
|
||||
agetpass.c \
|
||||
agetpass.h \
|
||||
alloc.c \
|
||||
alloc.h \
|
||||
alloc/calloc.c \
|
||||
alloc/calloc.h \
|
||||
alloc/malloc.c \
|
||||
alloc/malloc.h \
|
||||
alloc/realloc.c \
|
||||
alloc/realloc.h \
|
||||
alloc/reallocf.c \
|
||||
alloc/reallocf.h \
|
||||
atoi/a2i.c \
|
||||
atoi/a2i.h \
|
||||
atoi/str2i.c \
|
||||
atoi/str2i.h \
|
||||
atoi/strtoi.c \
|
||||
atoi/strtoi.h \
|
||||
atoi/strtou_noneg.c \
|
||||
atoi/strtou_noneg.h \
|
||||
atoi/getnum.c \
|
||||
atoi/getnum.h \
|
||||
atoi/strtoi/strtoi.c \
|
||||
atoi/strtoi/strtoi.h \
|
||||
atoi/strtoi/strtou.c \
|
||||
atoi/strtoi/strtou.h \
|
||||
atoi/strtoi/strtou_noneg.c \
|
||||
atoi/strtoi/strtou_noneg.h \
|
||||
attr.h \
|
||||
audit_help.c \
|
||||
basename.c \
|
||||
@@ -47,6 +55,8 @@ libshadow_la_SOURCES = \
|
||||
cast.h \
|
||||
chkname.c \
|
||||
chkname.h \
|
||||
chkhash.c \
|
||||
chkhash.h \
|
||||
chowndir.c \
|
||||
chowntty.c \
|
||||
cleanup.c \
|
||||
@@ -60,22 +70,28 @@ libshadow_la_SOURCES = \
|
||||
defines.h \
|
||||
encrypt.c \
|
||||
env.c \
|
||||
exit_if_null.c \
|
||||
exit_if_null.h \
|
||||
exitcodes.h \
|
||||
faillog.h \
|
||||
failure.c \
|
||||
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 \
|
||||
get_gid.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 \
|
||||
get_uid.c \
|
||||
getdate.h \
|
||||
getdate.y \
|
||||
getdef.c \
|
||||
getdef.h \
|
||||
getgr_nam_gid.c \
|
||||
@@ -84,7 +100,6 @@ libshadow_la_SOURCES = \
|
||||
groupio.c \
|
||||
groupmem.c \
|
||||
groupio.h \
|
||||
gshadow.c \
|
||||
hushed.c \
|
||||
idmapping.h \
|
||||
idmapping.c \
|
||||
@@ -94,10 +109,7 @@ libshadow_la_SOURCES = \
|
||||
lockpw.c \
|
||||
loginprompt.c \
|
||||
mail.c \
|
||||
memzero.c \
|
||||
memzero.h \
|
||||
motd.c \
|
||||
must_be.h \
|
||||
myname.c \
|
||||
nss.c \
|
||||
nscd.c \
|
||||
@@ -123,16 +135,46 @@ libshadow_la_SOURCES = \
|
||||
run_part.h \
|
||||
run_part.c \
|
||||
salt.c \
|
||||
search/cmp/cmp.c \
|
||||
search/cmp/cmp.h \
|
||||
search/l/lfind.c \
|
||||
search/l/lfind.h \
|
||||
search/l/lsearch.c \
|
||||
search/l/lsearch.h \
|
||||
search/sort/qsort.c \
|
||||
search/sort/qsort.h \
|
||||
selinux.c \
|
||||
semanage.c \
|
||||
setugid.c \
|
||||
setupenv.c \
|
||||
sgetgrent.c \
|
||||
sgetpwent.c \
|
||||
sgetspent.c \
|
||||
sgroupio.c \
|
||||
sgroupio.h\
|
||||
shadow.c \
|
||||
sgroupio.h \
|
||||
shadow/group/sgetgrent.c \
|
||||
shadow/group/sgetgrent.h \
|
||||
shadow/grp/agetgroups.c \
|
||||
shadow/grp/agetgroups.h \
|
||||
shadow/gshadow/endsgent.c \
|
||||
shadow/gshadow/endsgent.h \
|
||||
shadow/gshadow/fgetsgent.c \
|
||||
shadow/gshadow/fgetsgent.h \
|
||||
shadow/gshadow/getsgent.c \
|
||||
shadow/gshadow/getsgent.h \
|
||||
shadow/gshadow/getsgnam.c \
|
||||
shadow/gshadow/getsgnam.h \
|
||||
shadow/gshadow/gshadow.c \
|
||||
shadow/gshadow/gshadow.h \
|
||||
shadow/gshadow/putsgent.c \
|
||||
shadow/gshadow/putsgent.h \
|
||||
shadow/gshadow/setsgent.c \
|
||||
shadow/gshadow/setsgent.h \
|
||||
shadow/gshadow/sgetsgent.c \
|
||||
shadow/gshadow/sgetsgent.h \
|
||||
shadow/gshadow/sgrp.c \
|
||||
shadow/gshadow/sgrp.h \
|
||||
shadow/passwd/sgetpwent.c \
|
||||
shadow/passwd/sgetpwent.h \
|
||||
shadow/shadow/sgetspent.c \
|
||||
shadow/shadow/sgetspent.h \
|
||||
shadowio.c \
|
||||
shadowio.h \
|
||||
shadowlog.c \
|
||||
@@ -144,18 +186,74 @@ libshadow_la_SOURCES = \
|
||||
spawn.c \
|
||||
sssd.c \
|
||||
sssd.h \
|
||||
string/sprintf.c \
|
||||
string/sprintf.h \
|
||||
string/stpecpy.c \
|
||||
string/stpecpy.h \
|
||||
string/stpeprintf.c \
|
||||
string/stpeprintf.h \
|
||||
string/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/strchr/strchrcnt.c \
|
||||
string/strchr/strchrcnt.h \
|
||||
string/strchr/strchrscnt.c \
|
||||
string/strchr/strchrscnt.h \
|
||||
string/strchr/strnul.c \
|
||||
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/strneq.c \
|
||||
string/strcmp/strneq.h \
|
||||
string/strcmp/strprefix.c \
|
||||
string/strcmp/strprefix.h \
|
||||
string/strcpy/stpecpy.c \
|
||||
string/strcpy/stpecpy.h \
|
||||
string/strcpy/strncat.c \
|
||||
string/strcpy/strncat.h \
|
||||
string/strcpy/strncpy.c \
|
||||
string/strcpy/strncpy.h \
|
||||
string/strcpy/strtcpy.c \
|
||||
string/strcpy/strtcpy.h \
|
||||
string/strdup/strdup.c \
|
||||
string/strdup/strdup.h \
|
||||
string/strdup/strndupa.c \
|
||||
string/strdup/strndupa.h \
|
||||
string/strdup/strndup.c \
|
||||
string/strdup/strndup.h \
|
||||
string/strerrno.c \
|
||||
string/strerrno.h \
|
||||
string/strftime.c \
|
||||
string/strftime.h \
|
||||
string/strncpy.h \
|
||||
string/strtcpy.c \
|
||||
string/strtcpy.h \
|
||||
string/zustr2stp.h \
|
||||
string/strspn/stpspn.c \
|
||||
string/strspn/stpspn.h \
|
||||
string/strspn/stprcspn.c \
|
||||
string/strspn/stprcspn.h \
|
||||
string/strspn/stprspn.c \
|
||||
string/strspn/stprspn.h \
|
||||
string/strspn/strrcspn.c \
|
||||
string/strspn/strrcspn.h \
|
||||
string/strspn/strrspn.c \
|
||||
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 \
|
||||
strtoday.c \
|
||||
sub.c \
|
||||
subordinateio.h \
|
||||
@@ -164,6 +262,7 @@ libshadow_la_SOURCES = \
|
||||
time/day_to_str.c \
|
||||
time/day_to_str.h \
|
||||
ttytype.c \
|
||||
typetraits.h \
|
||||
tz.c \
|
||||
ulimit.c \
|
||||
user_busy.c \
|
||||
@@ -210,5 +309,4 @@ endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
.indent.pro \
|
||||
gshadow_.h \
|
||||
xgetXXbyYY.c
|
||||
|
||||
1614
lib/Makefile.in
1614
lib/Makefile.in
File diff suppressed because it is too large
Load Diff
152
lib/addgrps.c
152
lib/addgrps.c
@@ -1,114 +1,88 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2009, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 1989-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2001-2006, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
|
||||
#include "config.h"
|
||||
|
||||
#if !defined(USE_PAM)
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "alloc/reallocf.h"
|
||||
#include "search/l/lsearch.h"
|
||||
#include "shadow/grp/agetgroups.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strchr/strchrscnt.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#define SEP ",:"
|
||||
/*
|
||||
* Add groups with names from LIST (separated by commas or colons)
|
||||
* to the supplementary group set. Silently ignore groups which are
|
||||
* already there. Warning: uses strtok().
|
||||
* already there.
|
||||
*/
|
||||
int add_groups (const char *list)
|
||||
int
|
||||
add_groups(const char *list)
|
||||
{
|
||||
GETGROUPS_T *grouplist;
|
||||
size_t i;
|
||||
int ngroups;
|
||||
bool added;
|
||||
char *token;
|
||||
char buf[1024];
|
||||
int ret;
|
||||
char *dup;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
gid_t *gids;
|
||||
size_t n;
|
||||
|
||||
if (strlen (list) >= sizeof (buf)) {
|
||||
errno = EINVAL;
|
||||
gids = agetgroups(&n);
|
||||
if (gids == NULL)
|
||||
return -1;
|
||||
}
|
||||
strcpy (buf, list);
|
||||
|
||||
i = 16;
|
||||
for (;;) {
|
||||
grouplist = MALLOC(i, GETGROUPS_T);
|
||||
if (NULL == grouplist) {
|
||||
return -1;
|
||||
}
|
||||
ngroups = getgroups (i, grouplist);
|
||||
if ( ( (-1 == ngroups)
|
||||
&& (EINVAL != errno))
|
||||
|| (i > (size_t)ngroups)) {
|
||||
/* Unexpected failure of getgroups or successful
|
||||
* reception of the groups */
|
||||
break;
|
||||
}
|
||||
/* not enough room, so try allocating a larger buffer */
|
||||
free (grouplist);
|
||||
i *= 2;
|
||||
}
|
||||
if (ngroups < 0) {
|
||||
free (grouplist);
|
||||
gids = reallocf_T(gids, n + strchrscnt(list, ",:") + 1, gid_t);
|
||||
if (gids == NULL)
|
||||
return -1;
|
||||
|
||||
dup = strdup(list);
|
||||
if (dup == NULL)
|
||||
goto free_gids;
|
||||
|
||||
if (!streq(dup, "")) {
|
||||
char *g, *p;
|
||||
|
||||
p = dup;
|
||||
while (NULL != (g = strsep(&p, ",:"))) {
|
||||
struct group *grp;
|
||||
|
||||
grp = getgrnam(g); /* local, no need for xgetgrnam */
|
||||
if (NULL == grp) {
|
||||
fprintf(shadow_logfd, _("Warning: unknown group %s\n"), g);
|
||||
continue;
|
||||
}
|
||||
|
||||
LSEARCH(gid_t, &grp->gr_gid, gids, &n);
|
||||
}
|
||||
}
|
||||
free(dup);
|
||||
|
||||
if (setgroups(n, gids) == -1) {
|
||||
fprintf(shadow_logfd, "setgroups: %s\n", strerrno());
|
||||
goto free_gids;
|
||||
}
|
||||
|
||||
added = false;
|
||||
for (token = strtok (buf, SEP); NULL != token; token = strtok (NULL, SEP)) {
|
||||
struct group *grp;
|
||||
|
||||
grp = getgrnam (token); /* local, no need for xgetgrnam */
|
||||
if (NULL == grp) {
|
||||
fprintf (shadow_logfd, _("Warning: unknown group %s\n"),
|
||||
token);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++);
|
||||
|
||||
if (i < (size_t)ngroups) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
|
||||
fputs (_("Warning: too many groups\n"), shadow_logfd);
|
||||
break;
|
||||
}
|
||||
grouplist = REALLOCF(grouplist, (size_t) ngroups + 1, GETGROUPS_T);
|
||||
if (grouplist == NULL) {
|
||||
return -1;
|
||||
}
|
||||
grouplist[ngroups] = grp->gr_gid;
|
||||
ngroups++;
|
||||
added = true;
|
||||
}
|
||||
|
||||
if (added) {
|
||||
ret = setgroups (ngroups, grouplist);
|
||||
free (grouplist);
|
||||
return ret;
|
||||
}
|
||||
|
||||
free (grouplist);
|
||||
free(gids);
|
||||
return 0;
|
||||
}
|
||||
#else /* HAVE_SETGROUPS && !USE_PAM */
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /* HAVE_SETGROUPS && !USE_PAM */
|
||||
|
||||
free_gids:
|
||||
free(gids);
|
||||
return -1;
|
||||
}
|
||||
#else /* !USE_PAM */
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /* !USE_PAM */
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "adds.h"
|
||||
|
||||
@@ -11,5 +11,3 @@
|
||||
|
||||
extern inline long addsl2(long a, long b);
|
||||
extern inline long addslN(size_t n, long addend[n]);
|
||||
|
||||
extern inline int cmpl(const void *p1, const void *p2);
|
||||
|
||||
26
lib/adds.h
26
lib/adds.h
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
#define SHADOW_INCLUDE_LIB_ADDS_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "search/sort/qsort.h"
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
@@ -20,15 +20,13 @@
|
||||
({ \
|
||||
long addend_[] = {a, b, __VA_ARGS__}; \
|
||||
\
|
||||
addslN(NITEMS(addend_), addend_); \
|
||||
addslN(countof(addend_), addend_); \
|
||||
})
|
||||
|
||||
|
||||
inline long addsl2(long a, long b);
|
||||
inline long addslN(size_t n, long addend[n]);
|
||||
|
||||
inline int cmpl(const void *p1, const void *p2);
|
||||
|
||||
|
||||
inline long
|
||||
addsl2(long a, long b)
|
||||
@@ -57,7 +55,7 @@ addslN(size_t n, long addend[n])
|
||||
|
||||
e = errno;
|
||||
while (n > 1) {
|
||||
qsort(addend, n, sizeof(addend[0]), cmpl);
|
||||
QSORT(long, addend, n);
|
||||
|
||||
errno = 0;
|
||||
addend[0] = addsl2(addend[0], addend[--n]);
|
||||
@@ -69,18 +67,4 @@ addslN(size_t n, long addend[n])
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
cmpl(const void *p1, const void *p2)
|
||||
{
|
||||
const long *l1 = p1;
|
||||
const long *l2 = p2;
|
||||
|
||||
if (*l1 < *l2)
|
||||
return -1;
|
||||
if (*l1 > *l2)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "defines.h"
|
||||
#include "exitcodes.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadow/gshadow/endsgent.h"
|
||||
|
||||
|
||||
#ident "$Id$"
|
||||
@@ -106,7 +107,7 @@ int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp)
|
||||
* passwd to work just like it would had they executed
|
||||
* it from the command line while logged in.
|
||||
*/
|
||||
#if defined(HAVE_INITGROUPS) && ! defined(USE_PAM)
|
||||
#if !defined(USE_PAM)
|
||||
if (setup_uid_gid (pw, false) != 0)
|
||||
#else
|
||||
if (setup_uid_gid (pw) != 0)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "agetpass.h"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "alloc.h"
|
||||
#include "alloc/malloc.h"
|
||||
|
||||
#if WITH_LIBBSD == 0
|
||||
#include "freezero.h"
|
||||
@@ -106,7 +106,7 @@ agetpass_internal(const char *prompt, int flags)
|
||||
* Let's add one more byte, and if the password uses it, it
|
||||
* means the introduced password was longer than PASS_MAX.
|
||||
*/
|
||||
pass = MALLOC(PASS_MAX + 2, char);
|
||||
pass = malloc_T(PASS_MAX + 2, char);
|
||||
if (pass == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -135,7 +135,7 @@ agetpass(const char *prompt)
|
||||
char *
|
||||
agetpass_stdin()
|
||||
{
|
||||
return agetpass_internal(NULL, RPP_STDIN);
|
||||
return agetpass_internal("", RPP_STDIN);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#define SHADOW_INCLUDE_LIB_AGETPASS_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "attr.h"
|
||||
#include "defines.h"
|
||||
|
||||
73
lib/alloc.c
73
lib/alloc.c
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
* SPDX-FileCopyrightText: 2023 , Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/* Replacements for malloc and strdup with error checking. Too trivial
|
||||
to be worth copyrighting :-). I did that because a lot of code used
|
||||
malloc and strdup without checking for NULL pointer, and I like some
|
||||
message better than a core dump... --marekm
|
||||
|
||||
Yeh, but. Remember that bailing out might leave the system in some
|
||||
bizarre state. You really want to put in error checking, then add
|
||||
some back-out failure recovery code. -- jfh */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "alloc.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
|
||||
|
||||
extern inline void *xmalloc(size_t size);
|
||||
extern inline void *xmallocarray(size_t nmemb, size_t size);
|
||||
extern inline void *mallocarray(size_t nmemb, size_t size);
|
||||
extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
|
||||
extern inline char *xstrdup(const char *str);
|
||||
|
||||
|
||||
void *
|
||||
xcalloc(size_t nmemb, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = calloc(nmemb, size);
|
||||
if (p == NULL)
|
||||
goto x;
|
||||
|
||||
return p;
|
||||
|
||||
x:
|
||||
fprintf(log_get_logfd(), _("%s: %s\n"),
|
||||
log_get_progname(), strerror(errno));
|
||||
exit(13);
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
xreallocarray(void *p, size_t nmemb, size_t size)
|
||||
{
|
||||
p = reallocarrayf(p, nmemb, size);
|
||||
if (p == NULL)
|
||||
goto x;
|
||||
|
||||
return p;
|
||||
|
||||
x:
|
||||
fprintf(log_get_logfd(), _("%s: %s\n"),
|
||||
log_get_progname(), strerror(errno));
|
||||
exit(13);
|
||||
}
|
||||
101
lib/alloc.h
101
lib/alloc.h
@@ -1,101 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_MALLOC_H_
|
||||
#define SHADOW_INCLUDE_LIB_MALLOC_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "attr.h"
|
||||
#include "defines.h"
|
||||
|
||||
|
||||
#define CALLOC(n, type) ((type *) calloc(n, sizeof(type)))
|
||||
#define XCALLOC(n, type) ((type *) xcalloc(n, sizeof(type)))
|
||||
#define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
|
||||
#define XMALLOC(n, type) ((type *) xmallocarray(n, sizeof(type)))
|
||||
|
||||
#define REALLOC(ptr, n, type) \
|
||||
( \
|
||||
_Generic(ptr, type *: (type *) reallocarray(ptr, n, sizeof(type))) \
|
||||
)
|
||||
|
||||
#define REALLOCF(ptr, n, type) \
|
||||
( \
|
||||
_Generic(ptr, type *: (type *) reallocarrayf(ptr, n, sizeof(type))) \
|
||||
)
|
||||
|
||||
#define XREALLOC(ptr, n, type) \
|
||||
( \
|
||||
_Generic(ptr, type *: (type *) xreallocarray(ptr, n, sizeof(type))) \
|
||||
)
|
||||
|
||||
|
||||
ATTR_MALLOC(free)
|
||||
inline void *xmalloc(size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline void *xmallocarray(size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline void *mallocarray(size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
inline char *xstrdup(const char *str);
|
||||
|
||||
ATTR_MALLOC(free)
|
||||
void *xcalloc(size_t nmemb, size_t size);
|
||||
ATTR_MALLOC(free)
|
||||
void *xreallocarray(void *p, size_t nmemb, size_t size);
|
||||
|
||||
|
||||
inline void *
|
||||
xmalloc(size_t size)
|
||||
{
|
||||
return xmallocarray(1, size);
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
xmallocarray(size_t nmemb, size_t size)
|
||||
{
|
||||
return xreallocarray(NULL, nmemb, size);
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
mallocarray(size_t nmemb, size_t size)
|
||||
{
|
||||
return reallocarray(NULL, nmemb, size);
|
||||
}
|
||||
|
||||
|
||||
inline void *
|
||||
reallocarrayf(void *p, size_t nmemb, size_t size)
|
||||
{
|
||||
void *q;
|
||||
|
||||
q = reallocarray(p, nmemb, size);
|
||||
|
||||
/* realloc(p, 0) is equivalent to free(p); avoid double free. */
|
||||
if (q == NULL && nmemb != 0 && size != 0)
|
||||
free(p);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
inline char *
|
||||
xstrdup(const char *str)
|
||||
{
|
||||
return strcpy(XMALLOC(strlen(str) + 1, char), str);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
11
lib/alloc/calloc.c
Normal file
11
lib/alloc/calloc.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alloc/calloc.h"
|
||||
29
lib/alloc/calloc.h
Normal file
29
lib/alloc/calloc.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ALLOC_CALLOC_H_
|
||||
#define SHADOW_INCLUDE_LIB_ALLOC_CALLOC_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "exit_if_null.h"
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
// calloc_T - calloc type-safe
|
||||
#define calloc_T(n, T) calloc_T_(n, typeas(T))
|
||||
#define calloc_T_(n, T) \
|
||||
({ \
|
||||
(T *){calloc(n, sizeof(T))}; \
|
||||
})
|
||||
|
||||
|
||||
// xcalloc_T - exit-on-error calloc type-safe
|
||||
#define xcalloc_T(n, T) exit_if_null(calloc_T(n, T))
|
||||
|
||||
|
||||
#endif // include guard
|
||||
16
lib/alloc/malloc.c
Normal file
16
lib/alloc/malloc.c
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alloc/malloc.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
extern inline void *mallocarray(size_t nmemb, size_t size);
|
||||
43
lib/alloc/malloc.h
Normal file
43
lib/alloc/malloc.h
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ALLOC_MALLOC_H_
|
||||
#define SHADOW_INCLUDE_LIB_ALLOC_MALLOC_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "attr.h"
|
||||
#include "exit_if_null.h"
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
// malloc_T - malloc type-safe
|
||||
#define malloc_T(n, T) malloc_T_(n, typeas(T))
|
||||
#define malloc_T_(n, T) \
|
||||
({ \
|
||||
(T *){mallocarray(n, sizeof(T))}; \
|
||||
})
|
||||
|
||||
|
||||
// xmalloc_T - exit-on-error malloc type-safe
|
||||
#define xmalloc_T(n, T) exit_if_null(malloc_T(n, T))
|
||||
|
||||
|
||||
// mallocarray - malloc array
|
||||
ATTR_ALLOC_SIZE(1, 2)
|
||||
ATTR_MALLOC(free)
|
||||
inline void *mallocarray(size_t nmemb, size_t size);
|
||||
|
||||
|
||||
inline void *
|
||||
mallocarray(size_t nmemb, size_t size)
|
||||
{
|
||||
return reallocarray(NULL, nmemb, size);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
11
lib/alloc/realloc.c
Normal file
11
lib/alloc/realloc.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alloc/realloc.h"
|
||||
32
lib/alloc/realloc.h
Normal file
32
lib/alloc/realloc.h
Normal file
@@ -0,0 +1,32 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ALLOC_REALLOC_H_
|
||||
#define SHADOW_INCLUDE_LIB_ALLOC_REALLOC_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "exit_if_null.h"
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
// realloc_T - realloc type-safe
|
||||
#define realloc_T(p, n, T) realloc_T_(p, n, typeas(T))
|
||||
#define realloc_T_(p, n, T) \
|
||||
({ \
|
||||
_Generic(p, T *: (void)0); \
|
||||
(T *){reallocarray_(p, n, sizeof(T))}; \
|
||||
})
|
||||
|
||||
#define reallocarray_(p, n, size) reallocarray(p, (n) ?: 1, (size) ?: 1)
|
||||
|
||||
|
||||
// xrealloc_T - exit-on-error realloc type-safe
|
||||
#define xrealloc_T(p, n, T) exit_if_null(realloc_T(p, n, T))
|
||||
|
||||
|
||||
#endif // include guard
|
||||
16
lib/alloc/reallocf.c
Normal file
16
lib/alloc/reallocf.c
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1998, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2003-2006, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "alloc/reallocf.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
extern inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
|
||||
48
lib/alloc/reallocf.h
Normal file
48
lib/alloc/reallocf.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ALLOC_REALLOCF_H_
|
||||
#define SHADOW_INCLUDE_LIB_ALLOC_REALLOCF_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "attr.h"
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
// reallocf_T - realloc free-on-error type-safe
|
||||
#define reallocf_T(p, n, T) reallocf_T_(p, n, typeas(T))
|
||||
#define reallocf_T_(p, n, T) \
|
||||
({ \
|
||||
_Generic(p, T *: (void)0); \
|
||||
(T *){reallocarrayf_(p, n, sizeof(T))}; \
|
||||
})
|
||||
|
||||
#define reallocarrayf_(p, n, size) reallocarrayf(p, (n) ?: 1, (size) ?: 1)
|
||||
|
||||
|
||||
// reallocarrayf - realloc array free-on-error
|
||||
ATTR_ALLOC_SIZE(2, 3)
|
||||
ATTR_MALLOC(free)
|
||||
inline void *reallocarrayf(void *p, size_t nmemb, size_t size);
|
||||
|
||||
|
||||
inline void *
|
||||
reallocarrayf(void *p, size_t nmemb, size_t size)
|
||||
{
|
||||
void *q;
|
||||
|
||||
q = reallocarray(p, nmemb ?: 1, size ?: 1);
|
||||
|
||||
if (q == NULL)
|
||||
free(p);
|
||||
return q;
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,46 +1,7 @@
|
||||
// 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 "config.h"
|
||||
|
||||
#include "atoi/a2i.h"
|
||||
|
||||
|
||||
extern inline int a2sh_c(short *restrict n, const char *s,
|
||||
const char **restrict endp, int base, short min, short max);
|
||||
extern inline int a2si_c(int *restrict n, const char *s,
|
||||
const char **restrict endp, int base, int min, int max);
|
||||
extern inline int a2sl_c(long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, long min, long max);
|
||||
extern inline int a2sll_c(long long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, long long min, long long max);
|
||||
extern inline int a2uh_c(unsigned short *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned short min,
|
||||
unsigned short max);
|
||||
extern inline int a2ui_c(unsigned int *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned int min, unsigned int max);
|
||||
extern inline int a2ul_c(unsigned long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned long min, unsigned long max);
|
||||
extern inline int a2ull_c(unsigned long long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned long long min,
|
||||
unsigned long long max);
|
||||
|
||||
|
||||
extern inline int a2sh_nc(short *restrict n, char *s,
|
||||
char **restrict endp, int base, short min, short max);
|
||||
extern inline int a2si_nc(int *restrict n, char *s,
|
||||
char **restrict endp, int base, int min, int max);
|
||||
extern inline int a2sl_nc(long *restrict n, char *s,
|
||||
char **restrict endp, int base, long min, long max);
|
||||
extern inline int a2sll_nc(long long *restrict n, char *s,
|
||||
char **restrict endp, int base, long long min, long long max);
|
||||
extern inline int a2uh_nc(unsigned short *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned short min, unsigned short max);
|
||||
extern inline int a2ui_nc(unsigned int *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned int min, unsigned int max);
|
||||
extern inline int a2ul_nc(unsigned long *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned long min, unsigned long max);
|
||||
extern inline int a2ull_nc(unsigned long long *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned long long min,
|
||||
unsigned long long max);
|
||||
|
||||
413
lib/atoi/a2i.h
413
lib/atoi/a2i.h
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
@@ -6,381 +6,64 @@
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_A2I_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "atoi/strtoi.h"
|
||||
#include "atoi/strtou_noneg.h"
|
||||
#include "attr.h"
|
||||
#include "atoi/strtoi/strtoi.h"
|
||||
#include "atoi/strtoi/strtou_noneg.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
|
||||
/*
|
||||
* See the manual of these macros in liba2i's documentation:
|
||||
* <http://www.alejandro-colomar.es/share/dist/liba2i/git/HEAD/liba2i-HEAD.pdf>
|
||||
*/
|
||||
// a2i - alpha to integer
|
||||
#define a2i(T, n, s, endp, base, min, max) \
|
||||
({ \
|
||||
T *n_ = n; \
|
||||
QChar_of(s) **endp_ = endp; \
|
||||
T min_ = min; \
|
||||
T max_ = max; \
|
||||
\
|
||||
int status; \
|
||||
\
|
||||
*n_ = _Generic((T){0}, \
|
||||
short: strtoi_, \
|
||||
int: strtoi_, \
|
||||
long: strtoi_, \
|
||||
long long: strtoi_, \
|
||||
unsigned short: strtou_noneg, \
|
||||
unsigned int: strtou_noneg, \
|
||||
unsigned long: strtou_noneg, \
|
||||
unsigned long long: strtou_noneg \
|
||||
)(s, (char **) endp_, base, min_, max_, &status); \
|
||||
\
|
||||
if (status != 0) \
|
||||
errno = status; \
|
||||
-!!status; \
|
||||
})
|
||||
|
||||
|
||||
#define a2i(TYPE, n, s, ...) \
|
||||
( \
|
||||
_Generic((void (*)(TYPE, typeof(s))) 0, \
|
||||
void (*)(short, const char *): a2sh_c, \
|
||||
void (*)(short, const void *): a2sh_c, \
|
||||
void (*)(short, char *): a2sh_nc, \
|
||||
void (*)(short, void *): a2sh_nc, \
|
||||
void (*)(int, const char *): a2si_c, \
|
||||
void (*)(int, const void *): a2si_c, \
|
||||
void (*)(int, char *): a2si_nc, \
|
||||
void (*)(int, void *): a2si_nc, \
|
||||
void (*)(long, const char *): a2sl_c, \
|
||||
void (*)(long, const void *): a2sl_c, \
|
||||
void (*)(long, char *): a2sl_nc, \
|
||||
void (*)(long, void *): a2sl_nc, \
|
||||
void (*)(long long, const char *): a2sll_c, \
|
||||
void (*)(long long, const void *): a2sll_c, \
|
||||
void (*)(long long, char *): a2sll_nc, \
|
||||
void (*)(long long, void *): a2sll_nc, \
|
||||
void (*)(unsigned short, const char *): a2uh_c, \
|
||||
void (*)(unsigned short, const void *): a2uh_c, \
|
||||
void (*)(unsigned short, char *): a2uh_nc, \
|
||||
void (*)(unsigned short, void *): a2uh_nc, \
|
||||
void (*)(unsigned int, const char *): a2ui_c, \
|
||||
void (*)(unsigned int, const void *): a2ui_c, \
|
||||
void (*)(unsigned int, char *): a2ui_nc, \
|
||||
void (*)(unsigned int, void *): a2ui_nc, \
|
||||
void (*)(unsigned long, const char *): a2ul_c, \
|
||||
void (*)(unsigned long, const void *): a2ul_c, \
|
||||
void (*)(unsigned long, char *): a2ul_nc, \
|
||||
void (*)(unsigned long, void *): a2ul_nc, \
|
||||
void (*)(unsigned long long, const char *): a2ull_c, \
|
||||
void (*)(unsigned long long, const void *): a2ull_c, \
|
||||
void (*)(unsigned long long, char *): a2ull_nc, \
|
||||
void (*)(unsigned long long, void *): a2ull_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
#define a2sh(...) a2i(short, __VA_ARGS__)
|
||||
#define a2si(...) a2i(int, __VA_ARGS__)
|
||||
#define a2sl(...) a2i(long, __VA_ARGS__)
|
||||
#define a2sll(...) a2i(long long, __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__)
|
||||
|
||||
#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 str2i(T, ...) a2i(T, __VA_ARGS__, NULL, 0, type_min(T), type_max(T))
|
||||
|
||||
#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 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 a2sl(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2sl_c, \
|
||||
const void *: a2sl_c, \
|
||||
char *: a2sl_nc, \
|
||||
void *: a2sl_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2sll(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2sll_c, \
|
||||
const void *: a2sll_c, \
|
||||
char *: a2sll_nc, \
|
||||
void *: a2sll_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2uh(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2uh_c, \
|
||||
const void *: a2uh_c, \
|
||||
char *: a2uh_nc, \
|
||||
void *: a2uh_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2ui(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2ui_c, \
|
||||
const void *: a2ui_c, \
|
||||
char *: a2ui_nc, \
|
||||
void *: a2ui_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2ul(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2ul_c, \
|
||||
const void *: a2ul_c, \
|
||||
char *: a2ul_nc, \
|
||||
void *: a2ul_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2ull(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2ull_c, \
|
||||
const void *: a2ull_c, \
|
||||
char *: a2ull_nc, \
|
||||
void *: a2ull_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2sh_c(short *restrict n, const char *s,
|
||||
const char **restrict endp, int base, short min, short max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2si_c(int *restrict n, const char *s,
|
||||
const char **restrict endp, int base, int min, int max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2sl_c(long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, long min, long max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2sll_c(long long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, long long min, long long max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2uh_c(unsigned short *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned short min,
|
||||
unsigned short max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2ui_c(unsigned int *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned int min, unsigned int max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2ul_c(unsigned long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned long min, unsigned long max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2ull_c(unsigned long long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned long long min,
|
||||
unsigned long long max);
|
||||
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2sh_nc(short *restrict n, char *s,
|
||||
char **restrict endp, int base, short min, short max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2si_nc(int *restrict n, char *s,
|
||||
char **restrict endp, int base, int min, int max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2sl_nc(long *restrict n, char *s,
|
||||
char **restrict endp, int base, long min, long max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2sll_nc(long long *restrict n, char *s,
|
||||
char **restrict endp, int base, long long min, long long max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2uh_nc(unsigned short *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned short min, unsigned short max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2ui_nc(unsigned int *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned int min, unsigned int max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2ul_nc(unsigned long *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned long min, unsigned long max);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1) ATTR_ACCESS(write_only, 3)
|
||||
inline int a2ull_nc(unsigned long long *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned long long min,
|
||||
unsigned long long max);
|
||||
|
||||
|
||||
inline int
|
||||
a2sh_c(short *restrict n, const char *s,
|
||||
const char **restrict endp, int base, short min, short max)
|
||||
{
|
||||
return a2sh(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2si_c(int *restrict n, const char *s,
|
||||
const char **restrict endp, int base, int min, int max)
|
||||
{
|
||||
return a2si(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2sl_c(long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, long min, long max)
|
||||
{
|
||||
return a2sl(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2sll_c(long long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, long long min, long long max)
|
||||
{
|
||||
return a2sll(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2uh_c(unsigned short *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned short min,
|
||||
unsigned short max)
|
||||
{
|
||||
return a2uh(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2ui_c(unsigned int *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned int min, unsigned int max)
|
||||
{
|
||||
return a2ui(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2ul_c(unsigned long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned long min, unsigned long max)
|
||||
{
|
||||
return a2ul(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2ull_c(unsigned long long *restrict n, const char *s,
|
||||
const char **restrict endp, int base, unsigned long long min,
|
||||
unsigned long long max)
|
||||
{
|
||||
return a2ull(n, (char *) s, (char **) endp, base, min, max);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2sh_nc(short *restrict n, char *s,
|
||||
char **restrict endp, int base, short min, short max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtoi_(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2si_nc(int *restrict n, char *s,
|
||||
char **restrict endp, int base, int min, int max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtoi_(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2sl_nc(long *restrict n, char *s,
|
||||
char **restrict endp, int base, long min, long max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtoi_(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2sll_nc(long long *restrict n, char *s,
|
||||
char **restrict endp, int base, long long min, long long max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtoi_(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2uh_nc(unsigned short *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned short min,
|
||||
unsigned short max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtou_noneg(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2ui_nc(unsigned int *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned int min, unsigned int max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtou_noneg(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2ul_nc(unsigned long *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned long min, unsigned long max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtou_noneg(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
a2ull_nc(unsigned long long *restrict n, char *s,
|
||||
char **restrict endp, int base, unsigned long long min,
|
||||
unsigned long long max)
|
||||
{
|
||||
int status;
|
||||
|
||||
*n = strtou_noneg(s, endp, base, min, max, &status);
|
||||
if (status != 0) {
|
||||
errno = status;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#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
|
||||
|
||||
16
lib/atoi/getnum.c
Normal file
16
lib/atoi/getnum.c
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "atoi/getnum.h"
|
||||
|
||||
|
||||
extern inline int get_fd(const char *restrict fdstr, int *restrict fd);
|
||||
extern inline int get_gid(const char *restrict gidstr, gid_t *restrict gid);
|
||||
extern inline int get_pid(const char *restrict pidstr, pid_t *restrict pid);
|
||||
extern inline int get_uid(const char *restrict uidstr, uid_t *restrict uid);
|
||||
59
lib/atoi/getnum.h
Normal file
59
lib/atoi/getnum.h
Normal file
@@ -0,0 +1,59 @@
|
||||
// SPDX-FileCopyrightText: 2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_GETNUM_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_GETNUM_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "atoi/a2i.h"
|
||||
#include "attr.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
|
||||
inline int get_fd(const char *restrict fdstr, int *restrict fd);
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
|
||||
inline int get_gid(const char *restrict gidstr, gid_t *restrict gid);
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
|
||||
inline int get_pid(const char *restrict pidstr, pid_t *restrict pid);
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2)
|
||||
inline int get_uid(const char *restrict uidstr, uid_t *restrict uid);
|
||||
|
||||
|
||||
inline int
|
||||
get_fd(const char *restrict fdstr, int *restrict fd)
|
||||
{
|
||||
return a2si(fd, fdstr, NULL, 10, 0, INT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
get_gid(const char *restrict gidstr, gid_t *restrict gid)
|
||||
{
|
||||
return a2i(gid_t, gid, gidstr, NULL, 10, type_min(gid_t), type_max(gid_t));
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
get_pid(const char *restrict pidstr, pid_t *restrict pid)
|
||||
{
|
||||
return a2i(pid_t, pid, pidstr, NULL, 10, 1, type_max(pid_t));
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
get_uid(const char *restrict uidstr, uid_t *restrict uid)
|
||||
{
|
||||
return a2i(uid_t, uid, uidstr, NULL, 10, type_min(uid_t), type_max(uid_t));
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,18 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/str2i.h"
|
||||
|
||||
|
||||
extern inline int str2sh(short *restrict n, const char *restrict s);
|
||||
extern inline int str2si(int *restrict n, const char *restrict s);
|
||||
extern inline int str2sl(long *restrict n, const char *restrict s);
|
||||
extern inline int str2sll(long long *restrict n, const char *restrict s);
|
||||
extern inline int str2uh(unsigned short *restrict n, const char *restrict s);
|
||||
extern inline int str2ui(unsigned int *restrict n, const char *restrict s);
|
||||
extern inline int str2ul(unsigned long *restrict n, const char *restrict s);
|
||||
extern inline int str2ull(unsigned long long *restrict n, const char *restrict s);
|
||||
108
lib/atoi/str2i.h
108
lib/atoi/str2i.h
@@ -1,108 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "atoi/a2i.h"
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
#define str2i(TYPE, ...) \
|
||||
( \
|
||||
_Generic((TYPE) 0, \
|
||||
short: str2sh, \
|
||||
int: str2si, \
|
||||
long: str2sl, \
|
||||
long long: str2sll, \
|
||||
unsigned short: str2uh, \
|
||||
unsigned int: str2ui, \
|
||||
unsigned long: str2ul, \
|
||||
unsigned long long: str2ull \
|
||||
)(__VA_ARGS__) \
|
||||
)
|
||||
|
||||
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2sh(short *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2si(int *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2sl(long *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2sll(long long *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2uh(unsigned short *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2ui(unsigned int *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2ul(unsigned long *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2ull(unsigned long long *restrict n, const char *restrict s);
|
||||
|
||||
|
||||
inline int
|
||||
str2sh(short *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2si(int *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2si(n, s, NULL, 0, INT_MIN, INT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2sl(long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2sll(long long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2uh(unsigned short *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2uh(n, s, NULL, 0, 0, USHRT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2ui(unsigned int *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2ui(n, s, NULL, 0, 0, UINT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2ul(unsigned long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2ul(n, s, NULL, 0, 0, ULONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2ull(unsigned long long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2ull(n, s, NULL, 0, 0, ULLONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,15 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/strtoi.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
|
||||
intmax_t min, intmax_t max, int *restrict status);
|
||||
extern inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
|
||||
uintmax_t min, uintmax_t max, int *restrict status);
|
||||
@@ -1,96 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
#define strtoNmax(TYPE, ...) \
|
||||
( \
|
||||
_Generic((TYPE) 0, \
|
||||
intmax_t: strtoimax, \
|
||||
uintmax_t: strtoumax \
|
||||
)(__VA_ARGS__) \
|
||||
)
|
||||
|
||||
|
||||
#define strtoN(s, endp, base, min, max, status, TYPE) \
|
||||
({ \
|
||||
const char *s_ = s; \
|
||||
char **endp_ = endp; \
|
||||
int base_ = base; \
|
||||
TYPE min_ = min; \
|
||||
TYPE max_ = max; \
|
||||
int *status_ = status; \
|
||||
\
|
||||
int e_, st_; \
|
||||
char *end_; \
|
||||
TYPE n_; \
|
||||
\
|
||||
if (endp_ == NULL) \
|
||||
endp_ = &end_; \
|
||||
if (status_ == NULL) \
|
||||
status_ = &st_; \
|
||||
\
|
||||
if (base_ != 0 && (base_ < 0 || base_ > 36)) { \
|
||||
*status_ = EINVAL; \
|
||||
n_ = 0; \
|
||||
\
|
||||
} else { \
|
||||
e_ = errno; \
|
||||
errno = 0; \
|
||||
n_ = strtoNmax(TYPE, s_, endp_, base_); \
|
||||
\
|
||||
if (*endp_ == s_) \
|
||||
*status_ = ECANCELED; \
|
||||
else if (errno == ERANGE || n_ < min_ || n_ > max_) \
|
||||
*status_ = ERANGE; \
|
||||
else if (**endp_ != '\0') \
|
||||
*status_ = ENOTSUP; \
|
||||
else \
|
||||
*status_ = 0; \
|
||||
\
|
||||
errno = e_; \
|
||||
} \
|
||||
MAX(min_, MIN(max_, n_)); \
|
||||
})
|
||||
|
||||
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
|
||||
inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
|
||||
intmax_t min, intmax_t max, int *restrict status);
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
|
||||
inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
|
||||
uintmax_t min, uintmax_t max, int *restrict status);
|
||||
|
||||
|
||||
inline intmax_t
|
||||
strtoi_(const char *s, char **restrict endp, int base,
|
||||
intmax_t min, intmax_t max, int *restrict status)
|
||||
{
|
||||
return strtoN(s, endp, base, min, max, status, intmax_t);
|
||||
}
|
||||
|
||||
|
||||
inline uintmax_t
|
||||
strtou_(const char *s, char **restrict endp, int base,
|
||||
uintmax_t min, uintmax_t max, int *restrict status)
|
||||
{
|
||||
return strtoN(s, endp, base, min, max, status, uintmax_t);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
13
lib/atoi/strtoi/strtoi.c
Normal file
13
lib/atoi/strtoi/strtoi.c
Normal file
@@ -0,0 +1,13 @@
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "atoi/strtoi/strtoi.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
|
||||
intmax_t min, intmax_t max, int *restrict status);
|
||||
64
lib/atoi/strtoi/strtoi.h
Normal file
64
lib/atoi/strtoi/strtoi.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOI_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOI_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
|
||||
inline intmax_t strtoi_(const char *s, char **restrict endp, int base,
|
||||
intmax_t min, intmax_t max, int *restrict status);
|
||||
|
||||
|
||||
inline intmax_t
|
||||
strtoi_(const char *s, char **restrict endp, int base,
|
||||
intmax_t min, intmax_t max, int *restrict status)
|
||||
{
|
||||
int e, st;
|
||||
char *end;
|
||||
intmax_t n;
|
||||
|
||||
if (endp == NULL)
|
||||
endp = &end;
|
||||
if (status == NULL)
|
||||
status = &st;
|
||||
|
||||
if (base != 0 && (base < 2 || base > 36)) {
|
||||
*status = EINVAL;
|
||||
return MAX(min, MIN(max, 0));
|
||||
}
|
||||
|
||||
e = errno;
|
||||
errno = 0;
|
||||
|
||||
n = strtoimax(s, endp, base);
|
||||
|
||||
if (*endp == s)
|
||||
*status = ECANCELED;
|
||||
else if (errno == ERANGE || n < min || n > max)
|
||||
*status = ERANGE;
|
||||
else if (**endp != '\0')
|
||||
*status = ENOTSUP;
|
||||
else
|
||||
*status = 0;
|
||||
|
||||
errno = e;
|
||||
|
||||
return MAX(min, MIN(max, n));
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
13
lib/atoi/strtoi/strtou.c
Normal file
13
lib/atoi/strtoi/strtou.c
Normal file
@@ -0,0 +1,13 @@
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "atoi/strtoi/strtou.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
|
||||
uintmax_t min, uintmax_t max, int *restrict status);
|
||||
64
lib/atoi/strtoi/strtou.h
Normal file
64
lib/atoi/strtoi/strtou.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
ATTR_STRING(1) ATTR_ACCESS(write_only, 2) ATTR_ACCESS(write_only, 6)
|
||||
inline uintmax_t strtou_(const char *s, char **restrict endp, int base,
|
||||
uintmax_t min, uintmax_t max, int *restrict status);
|
||||
|
||||
|
||||
inline uintmax_t
|
||||
strtou_(const char *s, char **restrict endp, int base,
|
||||
uintmax_t min, uintmax_t max, int *restrict status)
|
||||
{
|
||||
int e, st;
|
||||
char *end;
|
||||
uintmax_t n;
|
||||
|
||||
if (endp == NULL)
|
||||
endp = &end;
|
||||
if (status == NULL)
|
||||
status = &st;
|
||||
|
||||
if (base != 0 && (base < 2 || base > 36)) {
|
||||
*status = EINVAL;
|
||||
return MAX(min, 0);
|
||||
}
|
||||
|
||||
e = errno;
|
||||
errno = 0;
|
||||
|
||||
n = strtoumax(s, endp, base);
|
||||
|
||||
if (*endp == s)
|
||||
*status = ECANCELED;
|
||||
else if (errno == ERANGE || n < min || n > max)
|
||||
*status = ERANGE;
|
||||
else if (**endp != '\0')
|
||||
*status = ENOTSUP;
|
||||
else
|
||||
*status = 0;
|
||||
|
||||
errno = e;
|
||||
|
||||
return MAX(min, MIN(max, n));
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include "atoi/strtou_noneg.h"
|
||||
#include "atoi/strtoi/strtou_noneg.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
// SPDX-FileCopyrightText: 2023, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STRTOU_NONEG_H_
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_NONEG_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STRTOI_STRTOU_NONEG_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "atoi/strtoi.h"
|
||||
#include "atoi/strtoi/strtoi.h"
|
||||
#include "atoi/strtoi/strtou.h"
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
45
lib/attr.h
45
lib/attr.h
@@ -5,28 +5,57 @@
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define MAYBE_UNUSED __attribute__((unused))
|
||||
# define NORETURN __attribute__((__noreturn__))
|
||||
# define format_attr(type, fmt, va) __attribute__((format(type, fmt, va)))
|
||||
# define ATTR_ACCESS(...) __attribute__((access(__VA_ARGS__)))
|
||||
#if !defined(__has_c_attribute)
|
||||
# define __has_c_attribute(x) 0
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_c_attribute(maybe_unused)
|
||||
# define MAYBE_UNUSED [[maybe_unused]]
|
||||
#else
|
||||
# define MAYBE_UNUSED
|
||||
#endif
|
||||
|
||||
#if __has_c_attribute(noreturn)
|
||||
# define NORETURN [[noreturn]]
|
||||
#else
|
||||
# define NORETURN
|
||||
#endif
|
||||
|
||||
#if __has_c_attribute(gnu::format)
|
||||
# define format_attr(type, fmt, va) [[gnu::format(type, fmt, va)]]
|
||||
#else
|
||||
# define format_attr(type, fmt, va)
|
||||
#endif
|
||||
|
||||
#if __has_c_attribute(gnu::access)
|
||||
# define ATTR_ACCESS(...) [[gnu::access(__VA_ARGS__)]]
|
||||
#else
|
||||
# define ATTR_ACCESS(...)
|
||||
#endif
|
||||
|
||||
#if __has_c_attribute(gnu::alloc_size)
|
||||
# define ATTR_ALLOC_SIZE(...) [[gnu::alloc_size(__VA_ARGS__)]]
|
||||
#else
|
||||
# define ATTR_ALLOC_SIZE(...)
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 11) && !defined(__clang__)
|
||||
# define ATTR_MALLOC(deallocator) [[gnu::malloc(deallocator)]]
|
||||
#else
|
||||
# define ATTR_MALLOC(deallocator)
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ >= 14)
|
||||
# define ATTR_STRING(...) [[gnu::null_terminated_string_arg(__VA_ARGS__)]]
|
||||
#if __has_c_attribute(gnu::null_terminated_string_arg)
|
||||
# define ATTR_STRING(i) [[gnu::null_terminated_string_arg(i)]]
|
||||
#else
|
||||
# define ATTR_STRING(...)
|
||||
# define ATTR_STRING(i)
|
||||
#endif
|
||||
|
||||
#if __has_c_attribute(gnu::nonstring)
|
||||
# define ATTR_NONSTRING [[gnu::nonstring]]
|
||||
#else
|
||||
# define ATTR_NONSTRING
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
|
||||
@@ -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,17 +48,20 @@ 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.
|
||||
* pgname - program's name
|
||||
* 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", "changing finger info", "deleting group"
|
||||
* name - user's account or group name. If not available use NULL.
|
||||
* id - uid or gid that the operation is being performed on. This is used
|
||||
* only when user is NULL.
|
||||
*/
|
||||
void audit_logger (int type, MAYBE_UNUSED const char *pgname, const char *op,
|
||||
void audit_logger (int type, const char *op,
|
||||
const char *name, unsigned int id,
|
||||
shadow_audit_result result)
|
||||
{
|
||||
@@ -68,6 +73,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)) {
|
||||
stprintf_a(buf, "%s %s=%s", op, grp_type,
|
||||
audit_encode_value(enc_group, grp, len));
|
||||
} else {
|
||||
stprintf_a(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) {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 1990-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1997, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2003-2005, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
/*
|
||||
* basename.c - not worth copyrighting :-). Some versions of Linux libc
|
||||
@@ -13,19 +11,21 @@
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
/*@observer@*/const char *Basename (const char *str)
|
||||
#include "string/strspn/stprcspn.h"
|
||||
|
||||
|
||||
/*@observer@*/const char *
|
||||
Basename(const char *str)
|
||||
{
|
||||
if (str == NULL) {
|
||||
abort ();
|
||||
}
|
||||
|
||||
char *cp = strrchr (str, '/');
|
||||
|
||||
return (NULL != cp) ? cp + 1 : str;
|
||||
return stprcspn(str, "/");
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define SHADOW_INCLUDE_LIB_BIT_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#define SHADOW_INCLUDE_LIB_CAST_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#define const_cast(T, p) _Generic(p, const T: (T) (p))
|
||||
|
||||
82
lib/chkhash.c
Normal file
82
lib/chkhash.c
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "chkhash.h"
|
||||
|
||||
#include <regex.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
|
||||
|
||||
/*
|
||||
* match_regex - return true if match, false if not
|
||||
*/
|
||||
bool
|
||||
match_regex(const char *pattern, const char *string)
|
||||
{
|
||||
regex_t regex;
|
||||
int result;
|
||||
|
||||
if (regcomp(®ex, pattern, REG_EXTENDED) != 0)
|
||||
return false;
|
||||
|
||||
result = regexec(®ex, string, 0, NULL, 0);
|
||||
regfree(®ex);
|
||||
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* is_valid_hash - check if the given string is a valid password hash
|
||||
*
|
||||
* Returns true if the string appears to be a valid hash, false otherwise.
|
||||
*
|
||||
* regex from: https://man.archlinux.org/man/crypt.5.en
|
||||
*/
|
||||
bool
|
||||
is_valid_hash(const char *hash)
|
||||
{
|
||||
hash = strprefix(hash, "!") ?: hash;
|
||||
|
||||
// Passwordless account; discouraged
|
||||
if (streq(hash, ""))
|
||||
return true;
|
||||
|
||||
if (streq(hash, "*"))
|
||||
return true;
|
||||
|
||||
// Minimum hash length
|
||||
if (strlen(hash) < 13)
|
||||
return false;
|
||||
|
||||
// Yescrypt: $y$ + algorithm parameters + $ + salt + $ + 43-char (minimum) hash
|
||||
if (match_regex("^\\$y\\$[./A-Za-z0-9]+\\$[./A-Za-z0-9]{1,86}\\$[./A-Za-z0-9]{43}$", hash))
|
||||
return true;
|
||||
|
||||
// Bcrypt: $2[abxy]$ + 2-digit cost + $ + 53-char hash
|
||||
if (match_regex("^\\$2[abxy]\\$[0-9]{2}\\$[./A-Za-z0-9]{53}$", hash))
|
||||
return true;
|
||||
|
||||
// SHA-512: $6$ + salt + $ + 86-char hash
|
||||
if (match_regex("^\\$6\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{86}$", hash))
|
||||
return true;
|
||||
|
||||
// SHA-256: $5$ + salt + $ + 43-char hash
|
||||
if (match_regex("^\\$5\\$(rounds=[1-9][0-9]{3,8}\\$)?[^$:\\n]{1,16}\\$[./A-Za-z0-9]{43}$", hash))
|
||||
return true;
|
||||
|
||||
// MD5: $1$ + salt + $ + 22-char hash
|
||||
if (match_regex("^\\$1\\$[^$:\\n]{1,8}\\$[./A-Za-z0-9]{22}$", hash))
|
||||
return true;
|
||||
|
||||
// DES: exactly 13 characters from [A-Za-z0-9./]
|
||||
if (match_regex("^[./A-Za-z0-9]{13}$", hash))
|
||||
return true;
|
||||
|
||||
// Not a valid hash
|
||||
return false;
|
||||
}
|
||||
13
lib/chkhash.h
Normal file
13
lib/chkhash.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef SHADOW_INCLUDE_CHKHASH_H
|
||||
#define SHADOW_INCLUDE_CHKHASH_H
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
||||
bool is_valid_hash(const char *hash);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-FileCopyrightText: 1996-2000, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2001-2005, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2005-2008, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
@@ -12,10 +12,14 @@
|
||||
* return values:
|
||||
* true - OK
|
||||
* false - bad name
|
||||
* errors:
|
||||
* EINVAL Invalid name
|
||||
* EILSEQ Invalid name character sequence (acceptable with --badname)
|
||||
* EOVERFLOW Name longer than maximum size
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
@@ -24,10 +28,20 @@
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
#include "string/ctype/strchrisascii/strchriscntrl.h"
|
||||
#include "string/ctype/strisascii/strisdigit.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strcaseeq.h"
|
||||
|
||||
|
||||
#ifndef LOGIN_NAME_MAX
|
||||
# define LOGIN_NAME_MAX 256
|
||||
#endif
|
||||
|
||||
|
||||
int allow_bad_names = false;
|
||||
@@ -38,81 +52,93 @@ login_name_max_size(void)
|
||||
{
|
||||
long conf;
|
||||
|
||||
errno = 0;
|
||||
conf = sysconf(_SC_LOGIN_NAME_MAX);
|
||||
if (conf == -1 && errno != 0)
|
||||
if (conf == -1)
|
||||
return LOGIN_NAME_MAX;
|
||||
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
static bool is_valid_name (const char *name)
|
||||
static bool
|
||||
is_valid_name(const char *name)
|
||||
{
|
||||
if (streq(name, "")
|
||||
|| streq(name, ".")
|
||||
|| streq(name, "..")
|
||||
|| strspn(name, "-")
|
||||
|| strpbrk(name, " \"#',/:;")
|
||||
|| strchriscntrl(name)
|
||||
|| strisdigit(name))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (allow_bad_names) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* User/group names must match BRE regex:
|
||||
* [a-zA-Z0-9_.][a-zA-Z0-9_.-]*$\?
|
||||
*
|
||||
* as a non-POSIX, extension, allow "$" as the last char for
|
||||
* sake of Samba 3.x "add machine script"
|
||||
*
|
||||
* Also do not allow fully numeric names or just "." or "..".
|
||||
*/
|
||||
int numeric;
|
||||
* User/group names must match BRE regex:
|
||||
* [a-zA-Z0-9_.][a-zA-Z0-9_.-]*$\?
|
||||
*
|
||||
* as a non-POSIX, extension, allow "$" as the last char for
|
||||
* sake of Samba 3.x "add machine script"
|
||||
*/
|
||||
|
||||
if ('\0' == *name ||
|
||||
('.' == *name && (('.' == name[1] && '\0' == name[2]) ||
|
||||
'\0' == name[1])) ||
|
||||
!((*name >= 'a' && *name <= 'z') ||
|
||||
if (!((*name >= 'a' && *name <= 'z') ||
|
||||
(*name >= 'A' && *name <= 'Z') ||
|
||||
(*name >= '0' && *name <= '9') ||
|
||||
*name == '_' ||
|
||||
*name == '.')) {
|
||||
*name == '.'))
|
||||
{
|
||||
errno = EILSEQ;
|
||||
return false;
|
||||
}
|
||||
|
||||
numeric = isdigit(*name);
|
||||
|
||||
while ('\0' != *++name) {
|
||||
while (!streq(++name, "")) {
|
||||
if (!((*name >= 'a' && *name <= 'z') ||
|
||||
(*name >= 'A' && *name <= 'Z') ||
|
||||
(*name >= '0' && *name <= '9') ||
|
||||
*name == '_' ||
|
||||
*name == '.' ||
|
||||
*name == '-' ||
|
||||
(*name == '$' && name[1] == '\0')
|
||||
)) {
|
||||
streq(name, "$")
|
||||
))
|
||||
{
|
||||
errno = EILSEQ;
|
||||
return false;
|
||||
}
|
||||
numeric &= isdigit(*name);
|
||||
}
|
||||
|
||||
return !numeric;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
is_valid_user_name(const char *name)
|
||||
{
|
||||
if (strlen(name) >= login_name_max_size())
|
||||
if (strlen(name) >= login_name_max_size()) {
|
||||
errno = EOVERFLOW;
|
||||
return false;
|
||||
}
|
||||
|
||||
return is_valid_name(name);
|
||||
}
|
||||
|
||||
|
||||
bool is_valid_group_name (const char *name)
|
||||
bool
|
||||
is_valid_group_name(const char *name)
|
||||
{
|
||||
/*
|
||||
* Arbitrary limit for group names.
|
||||
* HP-UX 10 limits to 16 characters
|
||||
*/
|
||||
if ( (GROUP_NAME_MAX_LENGTH > 0)
|
||||
&& (strlen (name) > GROUP_NAME_MAX_LENGTH)) {
|
||||
&& (strlen (name) > GROUP_NAME_MAX_LENGTH))
|
||||
{
|
||||
errno = EOVERFLOW;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -7,18 +7,21 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
|
||||
|
||||
static int chown_tree_at (int at_fd,
|
||||
const char *path,
|
||||
uid_t old_uid,
|
||||
@@ -56,8 +59,8 @@ static int chown_tree_at (int at_fd,
|
||||
/*
|
||||
* Skip the "." and ".." entries
|
||||
*/
|
||||
if ( (strcmp (ent->d_name, ".") == 0)
|
||||
|| (strcmp (ent->d_name, "..") == 0)) {
|
||||
if ( streq(ent->d_name, ".")
|
||||
|| streq(ent->d_name, "..")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@@ -44,7 +44,7 @@ void do_cleanups (void)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Make sure there were no overflow */
|
||||
/* Make sure there were no overflows */
|
||||
assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-1]);
|
||||
|
||||
if (getpid () != cleanup_pid) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@@ -27,7 +27,7 @@ void cleanup_report_add_group (void *group_name)
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add group %s", name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
audit_logger (AUDIT_ADD_GROUP,
|
||||
"",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -45,7 +45,7 @@ void cleanup_report_del_group (void *group_name)
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to remove group %s", name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_DEL_GROUP, log_get_progname(),
|
||||
audit_logger (AUDIT_DEL_GROUP,
|
||||
"",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -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,
|
||||
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,
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -100,8 +100,8 @@ 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",
|
||||
audit_logger (AUDIT_ADD_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,
|
||||
"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,
|
||||
"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,
|
||||
"removing-shadow-group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -179,15 +179,17 @@ void cleanup_report_del_group_gshadow (void *group_name)
|
||||
*
|
||||
* It should be registered after the group file is successfully locked.
|
||||
*/
|
||||
void cleanup_unlock_group (MAYBE_UNUSED void *arg)
|
||||
void cleanup_unlock_group (void *process_selinux)
|
||||
{
|
||||
if (gr_unlock () == 0) {
|
||||
bool process = *((bool *) process_selinux);
|
||||
|
||||
if (gr_unlock (process) == 0) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
log_get_progname(), gr_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking group file",
|
||||
audit_logger_message ("unlocking-group",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
@@ -199,15 +201,17 @@ void cleanup_unlock_group (MAYBE_UNUSED void *arg)
|
||||
*
|
||||
* It should be registered after the gshadow file is successfully locked.
|
||||
*/
|
||||
void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg)
|
||||
void cleanup_unlock_gshadow (void *process_selinux)
|
||||
{
|
||||
if (sgr_unlock () == 0) {
|
||||
bool process = *((bool *) process_selinux);
|
||||
|
||||
if (sgr_unlock (process) == 0) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
log_get_progname(), sgr_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking gshadow file",
|
||||
audit_logger_message ("unlocking-gshadow",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "attr.h"
|
||||
#include "defines.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
@@ -27,7 +26,7 @@ void cleanup_report_add_user (void *user_name)
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add user %s", name));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, log_get_progname(),
|
||||
audit_logger (AUDIT_ADD_USER,
|
||||
"",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -44,7 +43,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,
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -64,8 +63,8 @@ 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",
|
||||
audit_logger (AUDIT_ADD_USER,
|
||||
"adding-user",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -84,8 +83,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,
|
||||
"adding-shadow-user",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -96,15 +95,17 @@ void cleanup_report_add_user_shadow (void *user_name)
|
||||
*
|
||||
* It should be registered after the passwd database is successfully locked.
|
||||
*/
|
||||
void cleanup_unlock_passwd (MAYBE_UNUSED void *arg)
|
||||
void cleanup_unlock_passwd (void *process_selinux)
|
||||
{
|
||||
if (pw_unlock () == 0) {
|
||||
bool process = *((bool *) process_selinux);
|
||||
|
||||
if (pw_unlock (process) == 0) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
log_get_progname(), pw_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking passwd file",
|
||||
audit_logger_message ("unlocking-passwd",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
@@ -115,15 +116,17 @@ void cleanup_unlock_passwd (MAYBE_UNUSED void *arg)
|
||||
*
|
||||
* It should be registered after the shadow database is successfully locked.
|
||||
*/
|
||||
void cleanup_unlock_shadow (MAYBE_UNUSED void *arg)
|
||||
void cleanup_unlock_shadow (void *process_selinux)
|
||||
{
|
||||
if (spw_unlock () == 0) {
|
||||
bool process = *((bool *) process_selinux);
|
||||
|
||||
if (spw_unlock (process) == 0) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to unlock %s\n"),
|
||||
log_get_progname(), spw_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking shadow file",
|
||||
audit_logger_message ("unlocking-shadow",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
240
lib/commonio.c
240
lib/commonio.c
@@ -7,32 +7,40 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "defines.h"
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <utime.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "memzero.h"
|
||||
#include "alloc/malloc.h"
|
||||
#include "atoi/getnum.h"
|
||||
#include "commonio.h"
|
||||
#include "defines.h"
|
||||
#include "nscd.h"
|
||||
#include "sssd.h"
|
||||
#ifdef WITH_TCB
|
||||
#include <tcb.h>
|
||||
#endif /* WITH_TCB */
|
||||
#include "prototypes.h"
|
||||
#include "commonio.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/sprintf.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/strerrno.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
@@ -69,17 +77,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 {
|
||||
@@ -89,9 +90,7 @@ int lrename (const char *old, const char *new)
|
||||
|
||||
res = rename (old, new);
|
||||
|
||||
#ifdef __GLIBC__
|
||||
free (r);
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -104,7 +103,7 @@ static int check_link_count (const char *file, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s file stat error: %s\n",
|
||||
shadow_progname, file, strerror (errno));
|
||||
shadow_progname, file, strerrno());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -135,19 +134,19 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: %s\n",
|
||||
shadow_progname, file, strerror (errno));
|
||||
shadow_progname, file, strerrno());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid = getpid ();
|
||||
SNPRINTF(buf, "%lu", (unsigned long) pid);
|
||||
stprintf_a(buf, "%lu", (unsigned long) pid);
|
||||
len = (ssize_t) strlen (buf) + 1;
|
||||
if (write_full(fd, buf, len) == -1) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s file write error: %s\n",
|
||||
shadow_progname, file, strerror (errno));
|
||||
shadow_progname, file, strerrno());
|
||||
}
|
||||
(void) close (fd);
|
||||
unlink (file);
|
||||
@@ -157,7 +156,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s file sync error: %s\n",
|
||||
shadow_progname, file, strerror (errno));
|
||||
shadow_progname, file, strerrno());
|
||||
}
|
||||
(void) close (fd);
|
||||
unlink (file);
|
||||
@@ -176,13 +175,13 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: %s: %s\n",
|
||||
shadow_progname, lock, strerror (errno));
|
||||
shadow_progname, lock, strerrno());
|
||||
}
|
||||
unlink (file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
len = read (fd, buf, sizeof (buf) - 1);
|
||||
len = read(fd, buf, sizeof(buf) - 1);
|
||||
close (fd);
|
||||
if (len <= 0) {
|
||||
if (log) {
|
||||
@@ -194,7 +193,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
stpcpy(&buf[len], "");
|
||||
if (get_pid(buf, &pid) == -1) {
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
@@ -219,7 +218,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: cannot get lock %s: %s\n",
|
||||
shadow_progname, lock, strerror (errno));
|
||||
shadow_progname, lock, strerrno());
|
||||
}
|
||||
unlink (file);
|
||||
return 0;
|
||||
@@ -232,7 +231,7 @@ static int do_lock_file (const char *file, const char *lock, bool log)
|
||||
if (log) {
|
||||
(void) fprintf (shadow_logfd,
|
||||
"%s: cannot get lock %s: %s\n",
|
||||
shadow_progname, lock, strerror (errno));
|
||||
shadow_progname, lock, strerrno());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -330,9 +329,8 @@ static void free_linked_list (struct commonio_db *db)
|
||||
|
||||
free (p->line);
|
||||
|
||||
if (NULL != p->eptr) {
|
||||
db->ops->free (p->eptr);
|
||||
}
|
||||
if (NULL != p->eptr)
|
||||
db->ops->cio_free(p->eptr);
|
||||
|
||||
free (p);
|
||||
}
|
||||
@@ -342,7 +340,7 @@ static void free_linked_list (struct commonio_db *db)
|
||||
|
||||
int commonio_setname (struct commonio_db *db, const char *name)
|
||||
{
|
||||
SNPRINTF(db->filename, "%s", name);
|
||||
stprintf_a(db->filename, "%s", name);
|
||||
db->setname = true;
|
||||
return 1;
|
||||
}
|
||||
@@ -364,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) {
|
||||
@@ -466,13 +467,13 @@ static void dec_lock_count (void)
|
||||
}
|
||||
|
||||
|
||||
int commonio_unlock (struct commonio_db *db)
|
||||
int commonio_unlock (struct commonio_db *db, bool process_selinux)
|
||||
{
|
||||
char lock[1029];
|
||||
|
||||
if (db->isopen) {
|
||||
db->readonly = true;
|
||||
if (commonio_close (db) == 0) {
|
||||
if (commonio_close (db, process_selinux) == 0) {
|
||||
if (db->locked) {
|
||||
dec_lock_count ();
|
||||
}
|
||||
@@ -485,7 +486,7 @@ int commonio_unlock (struct commonio_db *db)
|
||||
* then call ulckpwdf() (if used) on last unlock.
|
||||
*/
|
||||
db->locked = false;
|
||||
SNPRINTF(lock, "%s.lock", db->filename);
|
||||
stprintf_a(lock, "%s.lock", db->filename);
|
||||
unlink (lock);
|
||||
dec_lock_count ();
|
||||
return 1;
|
||||
@@ -519,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, "-");
|
||||
}
|
||||
|
||||
|
||||
@@ -547,7 +548,7 @@ static void add_one_entry_nis (struct commonio_db *db,
|
||||
struct commonio_entry *p;
|
||||
|
||||
for (p = db->head; NULL != p; p = p->next) {
|
||||
if (name_is_nis (p->eptr ? db->ops->getname (p->eptr)
|
||||
if (name_is_nis (p->eptr ? db->ops->cio_getname(p->eptr)
|
||||
: p->line)) {
|
||||
/*@-mustfreeonly@*/
|
||||
newp->next = p;
|
||||
@@ -566,16 +567,12 @@ static void add_one_entry_nis (struct commonio_db *db,
|
||||
}
|
||||
#endif /* KEEP_NIS_AT_END */
|
||||
|
||||
/* Initial buffer size, as well as increment if not sufficient
|
||||
(for reading very long lines in group files). */
|
||||
#define BUFLEN 4096
|
||||
|
||||
int commonio_open (struct commonio_db *db, int mode)
|
||||
int
|
||||
commonio_open(struct commonio_db *db, int mode)
|
||||
{
|
||||
char *buf;
|
||||
char *cp;
|
||||
char *line;
|
||||
struct commonio_entry *p;
|
||||
void *eptr = NULL;
|
||||
int flags = mode;
|
||||
size_t buflen;
|
||||
@@ -634,34 +631,12 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
buflen = BUFLEN;
|
||||
buf = MALLOC(buflen, char);
|
||||
if (NULL == buf) {
|
||||
goto cleanup_ENOMEM;
|
||||
}
|
||||
buf = NULL;
|
||||
while (getline(&buf, &buflen, db->fp) != -1) {
|
||||
struct commonio_entry *p;
|
||||
|
||||
while (db->ops->fgets (buf, buflen, db->fp) == buf) {
|
||||
while ( (strrchr (buf, '\n') == NULL)
|
||||
&& (feof (db->fp) == 0)) {
|
||||
size_t len;
|
||||
|
||||
buflen += BUFLEN;
|
||||
cp = REALLOC(buf, buflen, char);
|
||||
if (NULL == cp) {
|
||||
goto cleanup_buf;
|
||||
}
|
||||
buf = cp;
|
||||
len = strlen (buf);
|
||||
if (db->ops->fgets (buf + len,
|
||||
(int) (buflen - len),
|
||||
db->fp) == NULL) {
|
||||
goto cleanup_buf;
|
||||
}
|
||||
}
|
||||
cp = strrchr (buf, '\n');
|
||||
if (NULL != cp) {
|
||||
*cp = '\0';
|
||||
}
|
||||
if (stpsep(buf, "\n") == NULL)
|
||||
goto cleanup_buf;
|
||||
|
||||
line = strdup (buf);
|
||||
if (NULL == line) {
|
||||
@@ -671,16 +646,16 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
if (name_is_nis (line)) {
|
||||
eptr = NULL;
|
||||
} else {
|
||||
eptr = db->ops->parse (line);
|
||||
eptr = db->ops->cio_parse(line);
|
||||
if (NULL != eptr) {
|
||||
eptr = db->ops->dup (eptr);
|
||||
eptr = db->ops->cio_dup(eptr);
|
||||
if (NULL == eptr) {
|
||||
goto cleanup_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p = MALLOC(1, struct commonio_entry);
|
||||
p = malloc_T(1, struct commonio_entry);
|
||||
if (NULL == p) {
|
||||
goto cleanup_entry;
|
||||
}
|
||||
@@ -698,7 +673,7 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
goto cleanup_errno;
|
||||
}
|
||||
|
||||
if ((NULL != db->ops->open_hook) && (db->ops->open_hook () == 0)) {
|
||||
if ((NULL != db->ops->cio_open_hook) && (db->ops->cio_open_hook() == 0)) {
|
||||
goto cleanup_errno;
|
||||
}
|
||||
|
||||
@@ -706,14 +681,12 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
return 1;
|
||||
|
||||
cleanup_entry:
|
||||
if (NULL != eptr) {
|
||||
db->ops->free (eptr);
|
||||
}
|
||||
if (NULL != eptr)
|
||||
db->ops->cio_free(eptr);
|
||||
cleanup_line:
|
||||
free (line);
|
||||
cleanup_buf:
|
||||
free (buf);
|
||||
cleanup_ENOMEM:
|
||||
errno = ENOMEM;
|
||||
cleanup_errno:
|
||||
saved_errno = errno;
|
||||
@@ -724,6 +697,7 @@ int commonio_open (struct commonio_db *db, int mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Sort given db according to cmp function (usually compares uids)
|
||||
*/
|
||||
@@ -757,7 +731,7 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
|
||||
return 0;
|
||||
}
|
||||
|
||||
entries = MALLOC(n, struct commonio_entry *);
|
||||
entries = malloc_T(n, struct commonio_entry *);
|
||||
if (entries == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -776,7 +750,7 @@ commonio_sort (struct commonio_db *db, int (*cmp) (const void *, const void *))
|
||||
entries[n] = ptr;
|
||||
n++;
|
||||
}
|
||||
qsort (entries, n, sizeof (struct commonio_entry *), cmp);
|
||||
qsort(entries, n, sizeof(struct commonio_entry *), cmp);
|
||||
|
||||
/* Take care of the head and tail separately */
|
||||
db->head = entries[0];
|
||||
@@ -825,17 +799,15 @@ int commonio_sort_wrt (struct commonio_db *shadow,
|
||||
if (NULL == pw_ptr->eptr) {
|
||||
continue;
|
||||
}
|
||||
name = passwd->ops->getname (pw_ptr->eptr);
|
||||
name = passwd->ops->cio_getname(pw_ptr->eptr);
|
||||
for (spw_ptr = shadow->head;
|
||||
NULL != spw_ptr;
|
||||
spw_ptr = spw_ptr->next) {
|
||||
if (NULL == spw_ptr->eptr) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp (name, shadow->ops->getname (spw_ptr->eptr))
|
||||
== 0) {
|
||||
if (streq(name, shadow->ops->cio_getname(spw_ptr->eptr)))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (NULL == spw_ptr) {
|
||||
continue;
|
||||
@@ -876,13 +848,13 @@ static int write_all (const struct commonio_db *db)
|
||||
if (p->changed) {
|
||||
eptr = p->eptr;
|
||||
assert (NULL != eptr);
|
||||
if (db->ops->put (eptr, db->fp) != 0) {
|
||||
if (db->ops->cio_put(eptr, db->fp) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else if (NULL != p->line) {
|
||||
if (db->ops->fputs (p->line, db->fp) == EOF) {
|
||||
if (fputs(p->line, db->fp) == EOF)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (putc ('\n', db->fp) == EOF) {
|
||||
return -1;
|
||||
}
|
||||
@@ -892,9 +864,10 @@ static int write_all (const struct commonio_db *db)
|
||||
}
|
||||
|
||||
|
||||
int commonio_close (struct commonio_db *db)
|
||||
int
|
||||
commonio_close(struct commonio_db *db, MAYBE_UNUSED bool process_selinux)
|
||||
{
|
||||
int errors = 0;
|
||||
bool errors = false;
|
||||
char buf[1024];
|
||||
struct stat sb;
|
||||
|
||||
@@ -912,11 +885,11 @@ int commonio_close (struct commonio_db *db)
|
||||
goto success;
|
||||
}
|
||||
|
||||
if ((NULL != db->ops->close_hook) && (db->ops->close_hook () == 0)) {
|
||||
if ((NULL != db->ops->cio_close_hook) && (db->ops->cio_close_hook() == 0)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
memzero (&sb, sizeof sb);
|
||||
memzero(&sb, sizeof(sb));
|
||||
if (NULL != db->fp) {
|
||||
if (fstat (fileno (db->fp), &sb) != 0) {
|
||||
(void) fclose (db->fp);
|
||||
@@ -927,33 +900,35 @@ int commonio_close (struct commonio_db *db)
|
||||
/*
|
||||
* Create backup file.
|
||||
*/
|
||||
if (SNPRINTF(buf, "%s-", db->filename) == -1) {
|
||||
if (stprintf_a(buf, "%s-", db->filename) == -1) {
|
||||
(void) fclose (db->fp);
|
||||
db->fp = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors++;
|
||||
if (process_selinux
|
||||
&& set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors = true;
|
||||
}
|
||||
#endif
|
||||
if (create_backup (buf, db->fp) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (fclose (db->fp) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
|
||||
db->fp = NULL;
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (reset_selinux_file_context () != 0) {
|
||||
errors++;
|
||||
if (process_selinux
|
||||
&& reset_selinux_file_context () != 0) {
|
||||
errors = true;
|
||||
}
|
||||
#endif
|
||||
if (errors != 0)
|
||||
if (errors)
|
||||
goto fail;
|
||||
} else {
|
||||
/*
|
||||
@@ -964,12 +939,13 @@ int commonio_close (struct commonio_db *db)
|
||||
sb.st_gid = db->st_gid;
|
||||
}
|
||||
|
||||
if (SNPRINTF(buf, "%s+", db->filename) == -1)
|
||||
if (stprintf_a(buf, "%s+", db->filename) == -1)
|
||||
goto fail;
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors++;
|
||||
if (process_selinux
|
||||
&& set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -979,24 +955,24 @@ int commonio_close (struct commonio_db *db)
|
||||
}
|
||||
|
||||
if (write_all (db) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (fflush (db->fp) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (fsync (fileno (db->fp)) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
|
||||
if (fclose (db->fp) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
|
||||
db->fp = NULL;
|
||||
|
||||
if (errors != 0) {
|
||||
if (errors) {
|
||||
unlink (buf);
|
||||
goto fail;
|
||||
}
|
||||
@@ -1006,7 +982,8 @@ int commonio_close (struct commonio_db *db)
|
||||
}
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (reset_selinux_file_context () != 0) {
|
||||
if (process_selinux
|
||||
&& reset_selinux_file_context () != 0) {
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
@@ -1014,11 +991,11 @@ int commonio_close (struct commonio_db *db)
|
||||
nscd_need_reload = true;
|
||||
goto success;
|
||||
fail:
|
||||
errors++;
|
||||
errors = true;
|
||||
success:
|
||||
|
||||
free_linked_list (db);
|
||||
return errors == 0;
|
||||
return !errors;
|
||||
}
|
||||
|
||||
static /*@dependent@*/ /*@null@*/struct commonio_entry *next_entry_by_name (
|
||||
@@ -1036,7 +1013,7 @@ static /*@dependent@*/ /*@null@*/struct commonio_entry *next_entry_by_name (
|
||||
for (p = pos; NULL != p; p = p->next) {
|
||||
ep = p->eptr;
|
||||
if ( (NULL != ep)
|
||||
&& (strcmp (db->ops->getname (ep), name) == 0)) {
|
||||
&& streq(db->ops->cio_getname(ep), name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1060,19 +1037,19 @@ int commonio_update (struct commonio_db *db, const void *eptr)
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
nentry = db->ops->dup (eptr);
|
||||
nentry = db->ops->cio_dup(eptr);
|
||||
if (NULL == nentry) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
p = find_entry_by_name (db, db->ops->getname (eptr));
|
||||
p = find_entry_by_name(db, db->ops->cio_getname(eptr));
|
||||
if (NULL != p) {
|
||||
if (next_entry_by_name (db, p->next, db->ops->getname (eptr)) != NULL) {
|
||||
fprintf (shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename);
|
||||
db->ops->free (nentry);
|
||||
if (next_entry_by_name(db, p->next, db->ops->cio_getname(eptr)) != NULL) {
|
||||
fprintf(shadow_logfd, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->cio_getname(eptr), db->filename);
|
||||
db->ops->cio_free(nentry);
|
||||
return 0;
|
||||
}
|
||||
db->ops->free (p->eptr);
|
||||
db->ops->cio_free(p->eptr);
|
||||
p->eptr = nentry;
|
||||
p->changed = true;
|
||||
db->cursor = p;
|
||||
@@ -1081,9 +1058,9 @@ int commonio_update (struct commonio_db *db, const void *eptr)
|
||||
return 1;
|
||||
}
|
||||
/* not found, new entry */
|
||||
p = MALLOC(1, struct commonio_entry);
|
||||
p = malloc_T(1, struct commonio_entry);
|
||||
if (NULL == p) {
|
||||
db->ops->free (nentry);
|
||||
db->ops->cio_free(nentry);
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
@@ -1112,15 +1089,15 @@ int commonio_append (struct commonio_db *db, const void *eptr)
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
nentry = db->ops->dup (eptr);
|
||||
nentry = db->ops->cio_dup(eptr);
|
||||
if (NULL == nentry) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
/* new entry */
|
||||
p = MALLOC(1, struct commonio_entry);
|
||||
p = malloc_T(1, struct commonio_entry);
|
||||
if (NULL == p) {
|
||||
db->ops->free (nentry);
|
||||
db->ops->cio_free(nentry);
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
@@ -1181,9 +1158,8 @@ int commonio_remove (struct commonio_db *db, const char *name)
|
||||
|
||||
free (p->line);
|
||||
|
||||
if (NULL != p->eptr) {
|
||||
db->ops->free (p->eptr);
|
||||
}
|
||||
if (NULL != p->eptr)
|
||||
db->ops->cio_free(p->eptr);
|
||||
|
||||
free(p);
|
||||
|
||||
@@ -1242,7 +1218,7 @@ int commonio_rewind (struct commonio_db *db)
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
if (NULL == db->cursor) {
|
||||
db->cursor = db->head;
|
||||
|
||||
@@ -35,39 +35,30 @@ struct commonio_ops {
|
||||
* Make a copy of the object (for example, struct passwd)
|
||||
* and all strings pointed by it, in malloced memory.
|
||||
*/
|
||||
/*@null@*/ /*@only@*/void *(*dup) (const void *);
|
||||
/*@null@*/ /*@only@*/void *(*cio_dup)(const void *);
|
||||
|
||||
/*
|
||||
* free() the object including any strings pointed by it.
|
||||
*/
|
||||
void (*free)(/*@only@*/void *);
|
||||
void (*cio_free)(/*@only@*/void *);
|
||||
|
||||
/*
|
||||
* Return the name of the object (for example, pw_name
|
||||
* for struct passwd).
|
||||
*/
|
||||
const char *(*getname) (const void *);
|
||||
const char *(*cio_getname)(const void *);
|
||||
|
||||
/*
|
||||
* Parse a string, return object (in static area -
|
||||
* should be copied using the dup operation above).
|
||||
*/
|
||||
void *(*parse) (const char *);
|
||||
void *(*cio_parse)(const char *);
|
||||
|
||||
/*
|
||||
* Write the object to the file (this calls putpwent()
|
||||
* for struct passwd, for example).
|
||||
*/
|
||||
int (*put) (const void *, FILE *);
|
||||
|
||||
/*
|
||||
* fgets and fputs (can be replaced by versions that
|
||||
* understand line continuation conventions).
|
||||
*/
|
||||
ATTR_ACCESS(write_only, 1, 2)
|
||||
/*@null@*/char *(*fgets)(/*@returned@*/char *restrict s, int n,
|
||||
FILE *restrict stream);
|
||||
int (*fputs) (const char *, FILE *);
|
||||
int (*cio_put)(const void *, FILE *);
|
||||
|
||||
/*
|
||||
* open_hook and close_hook.
|
||||
@@ -75,8 +66,8 @@ struct commonio_ops {
|
||||
* is open or before it is closed.
|
||||
* They return 0 on failure and 1 on success.
|
||||
*/
|
||||
/*@null@*/int (*open_hook) (void);
|
||||
/*@null@*/int (*close_hook) (void);
|
||||
/*@null@*/int (*cio_open_hook)(void);
|
||||
/*@null@*/int (*cio_close_hook)(void);
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -103,7 +94,7 @@ struct commonio_db {
|
||||
#endif
|
||||
/*
|
||||
* Default permissions and owner for newly created data file.
|
||||
*/
|
||||
*/
|
||||
mode_t st_mode;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
@@ -138,8 +129,8 @@ extern int commonio_append (struct commonio_db *, const void *);
|
||||
extern int commonio_remove (struct commonio_db *, const char *);
|
||||
extern int commonio_rewind (struct commonio_db *);
|
||||
extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *);
|
||||
extern int commonio_close (struct commonio_db *);
|
||||
extern int commonio_unlock (struct commonio_db *);
|
||||
extern int commonio_close (struct commonio_db *, bool);
|
||||
extern int commonio_unlock (struct commonio_db *, bool);
|
||||
extern void commonio_del_entry (struct commonio_db *,
|
||||
const struct commonio_entry *);
|
||||
extern int commonio_sort_wrt (struct commonio_db *shadow,
|
||||
|
||||
@@ -8,21 +8,27 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strtcpy.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strcpy/strtcpy.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
/*
|
||||
* This is now rather generic function which decides if "tty" is listed
|
||||
* under "cfgin" in config (directly or indirectly). Fallback to default if
|
||||
* something is bad.
|
||||
*/
|
||||
static bool is_listed (const char *cfgin, const char *tty, bool def)
|
||||
static bool
|
||||
is_listed(const char *cfgin, const char *tty, bool def)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024], *s;
|
||||
@@ -45,14 +51,13 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
|
||||
|
||||
if (*cons != '/') {
|
||||
char *pbuf;
|
||||
STRTCPY(buf, cons);
|
||||
pbuf = &buf[0];
|
||||
while ((s = strtok (pbuf, ":")) != NULL) {
|
||||
if (strcmp (s, tty) == 0) {
|
||||
|
||||
strtcpy_a(buf, cons);
|
||||
pbuf = buf;
|
||||
while (NULL != (s = strsep(&pbuf, ":"))) {
|
||||
if (streq(s, tty)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pbuf = NULL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -71,10 +76,9 @@ static bool is_listed (const char *cfgin, const char *tty, bool def)
|
||||
* See if this tty is listed in the console file.
|
||||
*/
|
||||
|
||||
while (fgets (buf, sizeof (buf), fp) != NULL) {
|
||||
/* Remove optional trailing '\n'. */
|
||||
buf[strcspn (buf, "\n")] = '\0';
|
||||
if (strcmp (buf, tty) == 0) {
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
stpsep(buf, "\n");
|
||||
if (streq(buf, tty)) {
|
||||
(void) fclose (fp);
|
||||
return true;
|
||||
}
|
||||
@@ -100,9 +104,7 @@ static bool 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);
|
||||
}
|
||||
|
||||
118
lib/copydir.c
118
lib/copydir.c
@@ -7,7 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "alloc/malloc.h"
|
||||
#include "attr.h"
|
||||
#include "fs/readlink/areadlink.h"
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#ifdef WITH_SELINUX
|
||||
@@ -36,7 +38,10 @@
|
||||
#include <attr/libattr.h>
|
||||
#endif /* WITH_ATTR */
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
|
||||
static /*@null@*/const char *src_orig;
|
||||
@@ -66,14 +71,11 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static /*@null@*/char *readlink_malloc (const char *filename);
|
||||
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid);
|
||||
static int copy_hardlink (const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
struct link_name *lp);
|
||||
static int copy_special (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
@@ -97,7 +99,8 @@ static int fchown_if_needed (int fdst, const struct stat *statp,
|
||||
* error_acl - format the error messages for the ACL and EQ libraries.
|
||||
*/
|
||||
format_attr(printf, 2, 3)
|
||||
static void error_acl (MAYBE_UNUSED struct error_context *ctx, const char *fmt, ...)
|
||||
static void
|
||||
error_acl(struct error_context *, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
FILE *shadow_logfd = log_get_logfd();
|
||||
@@ -114,7 +117,7 @@ static void error_acl (MAYBE_UNUSED struct error_context *ctx, const char *fmt,
|
||||
if (vfprintf (shadow_logfd, fmt, ap) != 0) {
|
||||
(void) fputs (_(": "), shadow_logfd);
|
||||
}
|
||||
(void) fprintf (shadow_logfd, "%s\n", strerror (errno));
|
||||
(void) fprintf(shadow_logfd, "%s\n", strerrno());
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
@@ -226,11 +229,11 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lp = XMALLOC(1, struct link_name);
|
||||
lp = xmalloc_T(1, struct link_name);
|
||||
lp->ln_dev = sb->st_dev;
|
||||
lp->ln_ino = sb->st_ino;
|
||||
lp->ln_count = sb->st_nlink;
|
||||
xasprintf(&lp->ln_name, "%s%s", dst_orig, name + strlen(src_orig));
|
||||
lp->ln_name = xaprintf("%s%s", dst_orig, name + strlen(src_orig));
|
||||
lp->ln_next = links;
|
||||
links = lp;
|
||||
|
||||
@@ -306,26 +309,26 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
|
||||
dst_orig = dst->full_path;
|
||||
set_orig = true;
|
||||
}
|
||||
while ((0 == err) && (ent = readdir (dir)) != NULL) {
|
||||
while (0 == err && NULL != (ent = readdir(dir))) {
|
||||
char *src_name = NULL;
|
||||
char *dst_name;
|
||||
struct path_info src_entry, dst_entry;
|
||||
/*
|
||||
* Skip the "." and ".." entries
|
||||
*/
|
||||
if (strcmp(ent->d_name, ".") == 0 ||
|
||||
strcmp(ent->d_name, "..") == 0)
|
||||
if (streq(ent->d_name, ".") ||
|
||||
streq(ent->d_name, ".."))
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -433,7 +436,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
*/
|
||||
|
||||
else if (S_ISLNK (sb.st_mode)) {
|
||||
err = copy_symlink (src, dst, reset_selinux, &sb, mt,
|
||||
err = copy_symlink (src, dst, &sb, mt,
|
||||
old_uid, new_uid, old_gid, new_gid);
|
||||
}
|
||||
|
||||
@@ -442,7 +445,7 @@ static int copy_entry (const struct path_info *src, const struct path_info *dst,
|
||||
*/
|
||||
|
||||
else if ((lp = check_link (src->full_path, &sb)) != NULL) {
|
||||
err = copy_hardlink (dst, reset_selinux, lp);
|
||||
err = copy_hardlink (dst, lp);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -498,14 +501,14 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
return -1;
|
||||
}
|
||||
#endif /* WITH_SELINUX */
|
||||
/*
|
||||
* If the destination is already a directory, don't change it
|
||||
* but copy into it (recursively).
|
||||
*/
|
||||
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
|
||||
return (copy_tree_impl (src, dst, false, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0);
|
||||
}
|
||||
/*
|
||||
* If the destination is already a directory, don't change it
|
||||
* but copy into it (recursively).
|
||||
*/
|
||||
if (fstatat(dst->dirfd, dst->name, &dst_sb, AT_SYMLINK_NOFOLLOW) == 0 && S_ISDIR(dst_sb.st_mode)) {
|
||||
return (copy_tree_impl (src, dst, false, reset_selinux,
|
||||
old_uid, new_uid, old_gid, new_gid) != 0);
|
||||
}
|
||||
|
||||
if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0)
|
||||
|| (chownat_if_needed (dst, statp,
|
||||
@@ -536,42 +539,6 @@ static int copy_dir (const struct path_info *src, const struct path_info *dst,
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* readlink_malloc - wrapper for readlink
|
||||
*
|
||||
* return NULL on error.
|
||||
* The return string shall be freed by the caller.
|
||||
*/
|
||||
static /*@null@*/char *readlink_malloc (const char *filename)
|
||||
{
|
||||
size_t size = 1024;
|
||||
|
||||
while (true) {
|
||||
ssize_t nchars;
|
||||
char *buffer = MALLOC(size, char);
|
||||
if (NULL == buffer) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nchars = readlink (filename, buffer, size);
|
||||
|
||||
if (nchars < 0) {
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size_t) nchars < size) { /* The buffer was large enough */
|
||||
/* readlink does not nul-terminate */
|
||||
buffer[nchars] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Try again with a bigger buffer */
|
||||
free (buffer);
|
||||
size *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_symlink - copy a symlink
|
||||
*
|
||||
@@ -583,7 +550,6 @@ static /*@null@*/char *readlink_malloc (const char *filename)
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_symlink (const struct path_info *src, const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@@ -602,19 +568,18 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
|
||||
* destination directory name.
|
||||
*/
|
||||
|
||||
oldlink = readlink_malloc (src->full_path);
|
||||
if (NULL == oldlink) {
|
||||
oldlink = areadlink(src->full_path);
|
||||
if (NULL == oldlink)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* If src was a link to an entry of the src_orig directory itself,
|
||||
* create a link to the corresponding entry in the dst_orig
|
||||
* directory.
|
||||
*/
|
||||
if (strncmp(oldlink, src_orig, strlen(src_orig)) == 0) {
|
||||
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;
|
||||
}
|
||||
@@ -655,7 +620,6 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_hardlink (const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
struct link_name *lp)
|
||||
{
|
||||
/* FIXME: selinux, ACL, Extended Attributes needed? */
|
||||
@@ -686,8 +650,8 @@ static int copy_hardlink (const struct path_info *dst,
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int
|
||||
copy_special(const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
copy_special(MAYBE_UNUSED const struct path_info *src, const struct path_info *dst,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@@ -742,7 +706,7 @@ copy_special(const struct path_info *src, const struct path_info *dst,
|
||||
* Return 0 on success, -1 on error.
|
||||
*/
|
||||
static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
bool reset_selinux,
|
||||
MAYBE_UNUSED bool reset_selinux,
|
||||
const struct stat *statp, const struct timespec mt[],
|
||||
uid_t old_uid, uid_t new_uid,
|
||||
gid_t old_gid, gid_t new_gid)
|
||||
@@ -794,7 +758,7 @@ static int copy_file (const struct path_info *src, const struct path_info *dst,
|
||||
char buf[8192];
|
||||
ssize_t cnt;
|
||||
|
||||
cnt = read (ifd, buf, sizeof buf);
|
||||
cnt = read(ifd, buf, sizeof(buf));
|
||||
if (cnt < 0) {
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
@@ -834,7 +798,7 @@ static int chown_function ## _if_needed (type_dst dst, \
|
||||
{ \
|
||||
uid_t tmpuid = (uid_t) -1; \
|
||||
gid_t tmpgid = (gid_t) -1; \
|
||||
\
|
||||
\
|
||||
/* Use new_uid if old_uid is set to -1 or if the file was \
|
||||
* owned by the user. */ \
|
||||
if (((uid_t) -1 == old_uid) || (statp->st_uid == old_uid)) { \
|
||||
@@ -845,14 +809,14 @@ static int chown_function ## _if_needed (type_dst dst, \
|
||||
if ((uid_t) -1 == tmpuid) { \
|
||||
tmpuid = statp->st_uid; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
if (((gid_t) -1 == old_gid) || (statp->st_gid == old_gid)) { \
|
||||
tmpgid = new_gid; \
|
||||
} \
|
||||
if ((gid_t) -1 == tmpgid) { \
|
||||
tmpgid = statp->st_gid; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
return chown_function (dst, tmpuid, tmpgid); \
|
||||
}
|
||||
|
||||
|
||||
45
lib/csrand.c
45
lib/csrand.c
@@ -1,21 +1,19 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: Alejandro Colomar <alx@kernel.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 2022-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#if HAVE_SYS_RANDOM_H
|
||||
#include <sys/random.h>
|
||||
#if __has_include(<sys/random.h>)
|
||||
# include <sys/random.h>
|
||||
#endif
|
||||
|
||||
#include "bit.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
@@ -23,6 +21,7 @@
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
static uint32_t csrand32(void);
|
||||
static uint32_t csrand_uniform32(uint32_t n);
|
||||
static unsigned long csrand_uniform_slow(unsigned long n);
|
||||
|
||||
@@ -33,7 +32,7 @@ static unsigned long csrand_uniform_slow(unsigned long n);
|
||||
unsigned long
|
||||
csrand(void)
|
||||
{
|
||||
FILE *fp;
|
||||
int fd;
|
||||
unsigned long r;
|
||||
|
||||
#ifdef HAVE_GETENTROPY
|
||||
@@ -55,17 +54,16 @@ csrand(void)
|
||||
#endif
|
||||
|
||||
/* Use /dev/urandom as a last resort. */
|
||||
fp = fopen("/dev/urandom", "r");
|
||||
if (NULL == fp) {
|
||||
fd = open("/dev/urandom", O_RDONLY);
|
||||
if (fd == -1)
|
||||
goto fail;
|
||||
|
||||
if (read(fd, &r, sizeof(r)) != sizeof(r)) {
|
||||
close(fd);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fread(&r, sizeof(r), 1, fp) != 1) {
|
||||
fclose(fp);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
close(fd);
|
||||
return r;
|
||||
|
||||
fail:
|
||||
@@ -97,6 +95,13 @@ csrand_interval(unsigned long min, unsigned long max)
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
csrand32(void)
|
||||
{
|
||||
return csrand();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fast Random Integer Generation in an Interval
|
||||
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
|
||||
@@ -109,12 +114,12 @@ csrand_uniform32(uint32_t n)
|
||||
uint64_t r, mult;
|
||||
|
||||
if (n == 0)
|
||||
return csrand();
|
||||
return csrand32();
|
||||
|
||||
bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`
|
||||
|
||||
do {
|
||||
r = csrand();
|
||||
r = csrand32();
|
||||
mult = r * n;
|
||||
rem = mult; // analogous to `mult % 2^32`
|
||||
} while (rem < bound); // p = (2^32 % n) / 2^32; W.C.: n=2^31+1, p=0.5
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
* crypt(3), crypt_gensalt(3), and their
|
||||
* feature test macros may be defined in here.
|
||||
*/
|
||||
#if HAVE_CRYPT_H
|
||||
#if __has_include(<crypt.h>)
|
||||
# include <crypt.h>
|
||||
#endif
|
||||
|
||||
@@ -50,24 +50,16 @@
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
/*
|
||||
* Possible cases:
|
||||
* - /usr/include/shadow.h exists and includes the shadow group stuff.
|
||||
* - /usr/include/shadow.h exists, but we use our own gshadow.h.
|
||||
*/
|
||||
#include <shadow.h>
|
||||
#if defined(SHADOWGRP) && !defined(GSHADOW)
|
||||
#include "gshadow_.h"
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef NGROUPS_MAX
|
||||
#ifdef NGROUPS
|
||||
#define NGROUPS_MAX NGROUPS
|
||||
#else
|
||||
#define NGROUPS_MAX 64
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
#include <syslog.h>
|
||||
@@ -76,11 +68,6 @@
|
||||
#define LOG_WARN LOG_WARNING
|
||||
#endif
|
||||
|
||||
/* LOG_NOWAIT is deprecated */
|
||||
#ifndef LOG_NOWAIT
|
||||
#define LOG_NOWAIT 0
|
||||
#endif
|
||||
|
||||
/* LOG_AUTH is deprecated, use LOG_AUTHPRIV instead */
|
||||
#ifndef LOG_AUTHPRIV
|
||||
#define LOG_AUTHPRIV LOG_AUTH
|
||||
@@ -94,7 +81,7 @@
|
||||
syslogd should log the current system time for each event, and not
|
||||
trust the formatted time received from the unix domain (or worse,
|
||||
UDP) socket. -MM */
|
||||
/* Avoid translated PAM error messages: Set LC_ALL to "C".
|
||||
/* Avoid translated PAM error messages: set LC_ALL to "C".
|
||||
* --Nekral */
|
||||
#define SYSLOG(x) \
|
||||
do { \
|
||||
@@ -120,7 +107,7 @@
|
||||
in just one place. */
|
||||
|
||||
#ifndef SYSLOG_OPTIONS
|
||||
/* #define SYSLOG_OPTIONS (LOG_PID | LOG_CONS | LOG_NOWAIT) */
|
||||
/* #define SYSLOG_OPTIONS (LOG_PID | LOG_CONS) */
|
||||
#define SYSLOG_OPTIONS (LOG_PID)
|
||||
#endif
|
||||
|
||||
@@ -157,10 +144,6 @@
|
||||
#define GROUP_FILE "/etc/group"
|
||||
#endif
|
||||
|
||||
#ifndef SHADOW_FILE
|
||||
#define SHADOW_FILE "/etc/shadow"
|
||||
#endif
|
||||
|
||||
#ifndef SUBUID_FILE
|
||||
#define SUBUID_FILE "/etc/subuid"
|
||||
#endif
|
||||
@@ -169,12 +152,6 @@
|
||||
#define SUBGID_FILE "/etc/subgid"
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#ifndef SGROUP_FILE
|
||||
#define SGROUP_FILE "/etc/gshadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* string to use for the pw_passwd field in /etc/passwd when using
|
||||
* shadow passwords - most systems use "x" but there are a few
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
@@ -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])
|
||||
@@ -65,7 +67,8 @@
|
||||
(void) fprintf (shadow_logfd,
|
||||
_("crypt method not supported by libcrypt? (%s)\n"),
|
||||
method);
|
||||
exit (EXIT_FAILURE);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (strlen (cp) != 13) {
|
||||
|
||||
31
lib/env.c
31
lib/env.c
@@ -7,7 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
@@ -16,11 +16,16 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "alloc/malloc.h"
|
||||
#include "alloc/realloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strdup/strdup.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -63,7 +68,7 @@ static const char *const noslash[] = {
|
||||
*/
|
||||
void initenv (void)
|
||||
{
|
||||
newenvp = XMALLOC(NEWENVP_STEP, char *);
|
||||
newenvp = xmalloc_T(NEWENVP_STEP, char *);
|
||||
*newenvp = NULL;
|
||||
}
|
||||
|
||||
@@ -74,7 +79,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);
|
||||
}
|
||||
@@ -130,7 +135,7 @@ void addenv (const char *string, /*@null@*/const char *value)
|
||||
|
||||
update_environ = (environ == newenvp);
|
||||
|
||||
newenvp = XREALLOC(newenvp, newenvc + NEWENVP_STEP, char *);
|
||||
newenvp = xrealloc_T(newenvp, newenvc + NEWENVP_STEP, char *);
|
||||
|
||||
/*
|
||||
* If this is our current environment, update
|
||||
@@ -159,20 +164,20 @@ void set_env (int argc, char *const *argv)
|
||||
char *cp;
|
||||
|
||||
for (; argc > 0; argc--, argv++) {
|
||||
if (strlen (*argv) >= sizeof variable) {
|
||||
if (strlen(*argv) >= sizeof(variable)) {
|
||||
continue; /* ignore long entries */
|
||||
}
|
||||
|
||||
cp = strchr (*argv, '=');
|
||||
if (NULL == cp) {
|
||||
assert(SNPRINTF(variable, "L%d", noname) != -1);
|
||||
assert(stprintf_a(variable, "L%d", noname) != -1);
|
||||
noname++;
|
||||
addenv (variable, *argv);
|
||||
} else {
|
||||
const char *const *p;
|
||||
|
||||
for (p = forbid; NULL != *p; p++) {
|
||||
if (strncmp (*argv, *p, strlen (*p)) == 0) {
|
||||
if (strprefix(*argv, *p)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -207,7 +212,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);
|
||||
}
|
||||
@@ -219,12 +224,12 @@ 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) {
|
||||
if (!strchr(*cur, '/'))
|
||||
continue; /* OK */
|
||||
}
|
||||
|
||||
for (move = cur; NULL != *move; move++) {
|
||||
*move = *(move + 1);
|
||||
}
|
||||
|
||||
10
lib/exit_if_null.c
Normal file
10
lib/exit_if_null.c
Normal file
@@ -0,0 +1,10 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "exit_if_null.h"
|
||||
|
||||
|
||||
extern inline void exit_if_null_(void *p);
|
||||
48
lib/exit_if_null.h
Normal file
48
lib/exit_if_null.h
Normal file
@@ -0,0 +1,48 @@
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_EXIT_IF_NULL_H_
|
||||
#define SHADOW_INCLUDE_LIB_EXIT_IF_NULL_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "shadowlog.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
|
||||
/*
|
||||
* This macro is used for implementing x*() variants of functions that
|
||||
* allocate memory, such as xstrdup() for wrapping strdup(3). The macro
|
||||
* returns the input pointer transparently, with the same type, but
|
||||
* calls exit(3) if the input is a null pointer (thus, if the allocation
|
||||
* failed).
|
||||
*/
|
||||
#define exit_if_null(p) \
|
||||
({ \
|
||||
__auto_type p_ = p; \
|
||||
\
|
||||
exit_if_null_(p_); \
|
||||
p_; \
|
||||
})
|
||||
|
||||
|
||||
inline void exit_if_null_(void *p);
|
||||
|
||||
|
||||
inline void
|
||||
exit_if_null_(void *p)
|
||||
{
|
||||
if (p == NULL) {
|
||||
fprintf(log_get_logfd(), "%s: %s\n", log_get_progname(), strerrno());
|
||||
exit(13);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -7,7 +7,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
@@ -18,10 +18,10 @@
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include "failure.h"
|
||||
#include "memzero.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/memset/memzero.h"
|
||||
#include "string/strftime.h"
|
||||
#include "string/strtcpy.h"
|
||||
#include "string/strcpy/strtcpy.h"
|
||||
|
||||
|
||||
#define YEAR (365L*DAY)
|
||||
@@ -34,7 +34,7 @@
|
||||
void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
{
|
||||
int fd;
|
||||
off_t offset_uid = (off_t) (sizeof *fl) * uid;
|
||||
off_t offset_uid = (off_t) sizeof(*fl) * uid;
|
||||
|
||||
/*
|
||||
* Don't do anything if failure logging isn't set up.
|
||||
@@ -59,7 +59,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
*/
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||
|| (read(fd, fl, sizeof(*fl)) != (ssize_t) sizeof(*fl))) {
|
||||
/* This is not necessarily a failure. The file is
|
||||
* initially zero length.
|
||||
*
|
||||
@@ -67,7 +67,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
* might reset the counter. But the new failure will be
|
||||
* logged.
|
||||
*/
|
||||
memzero (fl, sizeof *fl);
|
||||
memzero(fl, sizeof(*fl));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -81,8 +81,8 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
fl->fail_cnt++;
|
||||
}
|
||||
|
||||
STRTCPY(fl->fail_line, tty);
|
||||
(void) time (&fl->fail_time);
|
||||
strtcpy_a(fl->fail_line, tty);
|
||||
fl->fail_time = time(NULL);
|
||||
|
||||
/*
|
||||
* Seek back to the correct position in the file and write the
|
||||
@@ -92,7 +92,7 @@ void failure (uid_t uid, const char *tty, struct faillog *fl)
|
||||
*/
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (write_full(fd, fl, sizeof *fl) == -1)) {
|
||||
|| (write_full(fd, fl, sizeof(*fl)) == -1)) {
|
||||
goto err_write;
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ static bool too_many_failures (const struct faillog *fl)
|
||||
return true; /* locked until reset manually */
|
||||
}
|
||||
|
||||
(void) time (&now);
|
||||
now = time(NULL);
|
||||
if ((fl->fail_time + fl->fail_locktime) < now) {
|
||||
return false; /* enough time since last failure */
|
||||
}
|
||||
@@ -150,7 +150,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
||||
{
|
||||
int fd;
|
||||
struct faillog fail;
|
||||
off_t offset_uid = (off_t) (sizeof *fl) * uid;
|
||||
off_t offset_uid = (off_t) sizeof(*fl) * uid;
|
||||
|
||||
/*
|
||||
* Suppress the check if the log file isn't there.
|
||||
@@ -182,7 +182,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
||||
*/
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (read (fd, fl, sizeof *fl) != (ssize_t) sizeof *fl)) {
|
||||
|| (read(fd, fl, sizeof(*fl)) != (ssize_t) sizeof(*fl))) {
|
||||
(void) close (fd);
|
||||
return 1;
|
||||
}
|
||||
@@ -204,7 +204,7 @@ int failcheck (uid_t uid, struct faillog *fl, bool failed)
|
||||
fail.fail_cnt = 0;
|
||||
|
||||
if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid)
|
||||
|| (write_full(fd, &fail, sizeof fail) == -1)) {
|
||||
|| (write_full(fd, &fail, sizeof(fail)) == -1)) {
|
||||
goto err_write;
|
||||
}
|
||||
|
||||
@@ -242,19 +242,17 @@ void failprint (const struct faillog *fail)
|
||||
struct tm *tp;
|
||||
char lasttimeb[256];
|
||||
char *lasttime = lasttimeb;
|
||||
time_t NOW;
|
||||
|
||||
if (0 == fail->fail_cnt) {
|
||||
return;
|
||||
}
|
||||
|
||||
tp = localtime (&(fail->fail_time));
|
||||
(void) time (&NOW);
|
||||
|
||||
/*
|
||||
* Print all information we have.
|
||||
*/
|
||||
STRFTIME(lasttimeb, "%c", tp);
|
||||
strftime_a(lasttimeb, "%c", tp);
|
||||
|
||||
/*@-formatconst@*/
|
||||
(void) printf (ngettext ("%d failure since last login.\n"
|
||||
|
||||
89
lib/fields.c
89
lib/fields.c
@@ -7,53 +7,48 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ident "$Id$"
|
||||
#include "fields.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.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"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
/*
|
||||
* 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; '\0' != *cp; cp++) {
|
||||
unsigned char c = *cp;
|
||||
if (!isprint (c)) {
|
||||
err = 1;
|
||||
}
|
||||
if (iscntrl (c)) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
return 1; // !ASCII
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -62,44 +57,32 @@ int valid_field (const char *field, const char *illegal)
|
||||
* prompt the user with the name of the field being changed and the
|
||||
* current value.
|
||||
*/
|
||||
void change_field (char *buf, size_t maxsize, const char *prompt)
|
||||
void
|
||||
change_field(char *buf, size_t maxsize, const char *prompt)
|
||||
{
|
||||
char newf[200];
|
||||
char *cp;
|
||||
|
||||
if (maxsize > sizeof (newf)) {
|
||||
maxsize = sizeof (newf);
|
||||
if (maxsize > sizeof(newf)) {
|
||||
maxsize = sizeof(newf);
|
||||
}
|
||||
|
||||
printf ("\t%s [%s]: ", prompt, buf);
|
||||
(void) fflush (stdout);
|
||||
if (fgets (newf, maxsize, stdin) != newf) {
|
||||
if (fgets(newf, maxsize, stdin) == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
cp = strchr (newf, '\n');
|
||||
if (NULL == cp) {
|
||||
if (stpsep(newf, "\n") == NULL)
|
||||
return;
|
||||
}
|
||||
*cp = '\0';
|
||||
|
||||
if ('\0' != newf[0]) {
|
||||
if (!streq(newf, "")) {
|
||||
/*
|
||||
* Remove leading and trailing whitespace. This also
|
||||
* makes it possible to change the field to empty, by
|
||||
* entering a space. --marekm
|
||||
*/
|
||||
|
||||
while (newf < cp && isspace (cp[-1])) {
|
||||
cp--;
|
||||
}
|
||||
*cp = '\0';
|
||||
|
||||
cp = newf;
|
||||
while (isspace (*cp)) {
|
||||
cp++;
|
||||
}
|
||||
|
||||
stpcpy(stprspn(newf, " \t"), "");
|
||||
cp = stpspn(newf, " \t");
|
||||
strcpy (buf, cp);
|
||||
}
|
||||
}
|
||||
|
||||
20
lib/fields.h
Normal file
20
lib/fields.h
Normal 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
|
||||
@@ -6,27 +6,30 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "alloc/calloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "groupio.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
|
||||
/*
|
||||
* get_ranges - Get the minimum and maximum ID ranges for the search
|
||||
*
|
||||
* This function will return the minimum and maximum ranges for IDs
|
||||
*
|
||||
* 0: The function completed successfully
|
||||
* EINVAL: The provided ranges are impossible (such as maximum < minimum)
|
||||
* 0: the function completed successfully
|
||||
* EINVAL: the provided ranges are impossible (such as maximum < minimum)
|
||||
*
|
||||
* preferred_min: The special-case minimum value for a specifically-
|
||||
* preferred_min: the special-case minimum value for a specifically-
|
||||
* requested ID, which may be lower than the standard min_id
|
||||
*/
|
||||
static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
||||
@@ -53,11 +56,11 @@ static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id,
|
||||
/* Check that the ranges make sense */
|
||||
if (*max_id < *min_id) {
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: SYS_GID_MIN (%lu), "
|
||||
"GID_MIN (%lu), SYS_GID_MAX (%lu)\n"),
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
getdef_ulong ("GID_MIN", 1000UL),
|
||||
(unsigned long) *max_id);
|
||||
_("%s: Invalid configuration: SYS_GID_MIN (%lu), "
|
||||
"GID_MIN (%lu), SYS_GID_MAX (%lu)\n"),
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
getdef_ulong ("GID_MIN", 1000UL),
|
||||
(unsigned long) *max_id);
|
||||
return EINVAL;
|
||||
}
|
||||
/*
|
||||
@@ -232,11 +235,11 @@ int find_new_gid (bool sys_group,
|
||||
*/
|
||||
|
||||
/* Create an array to hold all of the discovered GIDs */
|
||||
used_gids = CALLOC (gid_max + 1, bool);
|
||||
used_gids = calloc_T(gid_max + 1, bool);
|
||||
if (NULL == used_gids) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to allocate memory: %s\n"),
|
||||
log_get_progname(), strerror (errno));
|
||||
log_get_progname(), strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -244,7 +247,7 @@ int find_new_gid (bool sys_group,
|
||||
(void) gr_rewind ();
|
||||
highest_found = gid_min;
|
||||
lowest_found = gid_max;
|
||||
while ((grp = gr_next ()) != NULL) {
|
||||
while (NULL != (grp = gr_next())) {
|
||||
/*
|
||||
* Does this entry have a lower GID than the lowest we've found
|
||||
* so far?
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
|
||||
|
||||
@@ -6,27 +6,29 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "alloc.h"
|
||||
#include "alloc/calloc.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strerrno.h"
|
||||
|
||||
/*
|
||||
* get_ranges - Get the minimum and maximum ID ranges for the search
|
||||
*
|
||||
* This function will return the minimum and maximum ranges for IDs
|
||||
*
|
||||
* 0: The function completed successfully
|
||||
* EINVAL: The provided ranges are impossible (such as maximum < minimum)
|
||||
* 0: the function completed successfully
|
||||
* EINVAL: the provided ranges are impossible (such as maximum < minimum)
|
||||
*
|
||||
* preferred_min: The special-case minimum value for a specifically-
|
||||
* preferred_min: the special-case minimum value for a specifically-
|
||||
* requested ID, which may be lower than the standard min_id
|
||||
*/
|
||||
static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
||||
@@ -53,11 +55,11 @@ static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id,
|
||||
/* Check that the ranges make sense */
|
||||
if (*max_id < *min_id) {
|
||||
(void) fprintf (log_get_logfd(),
|
||||
_("%s: Invalid configuration: SYS_UID_MIN (%lu), "
|
||||
"UID_MIN (%lu), SYS_UID_MAX (%lu)\n"),
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
getdef_ulong ("UID_MIN", 1000UL),
|
||||
(unsigned long) *max_id);
|
||||
_("%s: Invalid configuration: SYS_UID_MIN (%lu), "
|
||||
"UID_MIN (%lu), SYS_UID_MAX (%lu)\n"),
|
||||
log_get_progname(), (unsigned long) *min_id,
|
||||
getdef_ulong ("UID_MIN", 1000UL),
|
||||
(unsigned long) *max_id);
|
||||
return EINVAL;
|
||||
}
|
||||
/*
|
||||
@@ -232,11 +234,11 @@ int find_new_uid(bool sys_user,
|
||||
*/
|
||||
|
||||
/* Create an array to hold all of the discovered UIDs */
|
||||
used_uids = CALLOC(uid_max + 1, bool);
|
||||
used_uids = calloc_T(uid_max + 1, bool);
|
||||
if (NULL == used_uids) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: failed to allocate memory: %s\n"),
|
||||
log_get_progname(), strerror (errno));
|
||||
log_get_progname(), strerrno());
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -244,7 +246,7 @@ int find_new_uid(bool sys_user,
|
||||
(void) pw_rewind ();
|
||||
highest_found = uid_min;
|
||||
lowest_found = uid_max;
|
||||
while ((pwd = pw_next ()) != NULL) {
|
||||
while (NULL != (pwd = pw_next())) {
|
||||
/*
|
||||
* Does this entry have a lower UID than the lowest we've found
|
||||
* so far?
|
||||
@@ -304,7 +306,7 @@ int find_new_uid(bool sys_user,
|
||||
return 0;
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* This UID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
@@ -350,7 +352,7 @@ int find_new_uid(bool sys_user,
|
||||
return 0;
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* This UID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
@@ -413,7 +415,7 @@ int find_new_uid(bool sys_user,
|
||||
return 0;
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* This UID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
@@ -459,7 +461,7 @@ int find_new_uid(bool sys_user,
|
||||
return 0;
|
||||
} else if (result == EEXIST || result == EINVAL) {
|
||||
/*
|
||||
* This GID is in use or unusable, we'll
|
||||
* This UID is in use or unusable, we'll
|
||||
* continue to the next.
|
||||
*/
|
||||
} else {
|
||||
|
||||
68
lib/fputsx.c
68
lib/fputsx.c
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2008 , Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
|
||||
/*@null@*/char *
|
||||
fgetsx(/*@returned@*/char *restrict buf, int cnt, FILE *restrict f)
|
||||
{
|
||||
char *cp = buf;
|
||||
char *ep;
|
||||
|
||||
while (cnt > 0) {
|
||||
if (fgets (cp, cnt, f) != cp) {
|
||||
if (cp == buf) {
|
||||
return 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
ep = strrchr (cp, '\\');
|
||||
if ((NULL != ep) && (*(ep + 1) == '\n')) {
|
||||
cnt -= ep - cp;
|
||||
if (cnt > 0) {
|
||||
cp = ep;
|
||||
*cp = '\0';
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int fputsx (const char *s, FILE * stream)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; '\0' != *s; i++, s++) {
|
||||
if (putc (*s, stream) == EOF) {
|
||||
return EOF;
|
||||
}
|
||||
|
||||
#if 0 /* The standard getgr*() can't handle that. --marekm */
|
||||
if (i > (BUFSIZ / 2)) {
|
||||
if (putc ('\\', stream) == EOF ||
|
||||
putc ('\n', stream) == EOF)
|
||||
return EOF;
|
||||
|
||||
i = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
13
lib/fs/mkstemp/fmkomstemp.c
Normal file
13
lib/fs/mkstemp/fmkomstemp.c
Normal 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);
|
||||
44
lib/fs/mkstemp/fmkomstemp.h
Normal file
44
lib/fs/mkstemp/fmkomstemp.h
Normal 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
|
||||
12
lib/fs/mkstemp/mkomstemp.c
Normal file
12
lib/fs/mkstemp/mkomstemp.c
Normal 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);
|
||||
41
lib/fs/mkstemp/mkomstemp.h
Normal file
41
lib/fs/mkstemp/mkomstemp.h
Normal 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
|
||||
10
lib/fs/readlink/areadlink.c
Normal file
10
lib/fs/readlink/areadlink.c
Normal file
@@ -0,0 +1,10 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "fs/readlink/areadlink.h"
|
||||
|
||||
|
||||
extern inline char *areadlink(const char *link);
|
||||
53
lib/fs/readlink/areadlink.h
Normal file
53
lib/fs/readlink/areadlink.h
Normal file
@@ -0,0 +1,53 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_FS_READLINK_AREADLINK_H_
|
||||
#define SHADOW_INCLUDE_LIB_FS_READLINK_AREADLINK_H_
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.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"
|
||||
|
||||
|
||||
ATTR_STRING(1)
|
||||
inline char *areadlink(const char *link);
|
||||
|
||||
|
||||
// Similar to readlink(2), but allocate and terminate the string.
|
||||
inline char *
|
||||
areadlink(const char *link)
|
||||
{
|
||||
size_t size = PATH_MAX;
|
||||
|
||||
while (true) {
|
||||
int len;
|
||||
char *buf;
|
||||
|
||||
buf = malloc_T(size, char);
|
||||
if (NULL == buf)
|
||||
return NULL;
|
||||
|
||||
len = readlinknul(link, buf, size);
|
||||
if (len != -1)
|
||||
return buf;
|
||||
|
||||
free(buf);
|
||||
if (errno != E2BIG)
|
||||
return NULL;
|
||||
|
||||
size *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user