Compare commits
4 Commits
upstream/4
...
upstream/4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d5ab87d61 | ||
|
|
a9c3448878 | ||
|
|
a475f464e0 | ||
|
|
65261e28f4 |
@@ -6,7 +6,7 @@ if ENABLE_SUBIDS
|
||||
SUBDIRS += libsubid
|
||||
endif
|
||||
|
||||
SUBDIRS += src po contrib doc etc tests/unit
|
||||
SUBDIRS += src po doc etc tests/unit
|
||||
|
||||
if ENABLE_REGENERATE_MAN
|
||||
SUBDIRS += man
|
||||
|
||||
@@ -163,7 +163,7 @@ am__define_uniq_tagged_files = \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | $(am__uniquify_input)`
|
||||
DIST_SUBDIRS = lib libsubid src po contrib doc etc tests/unit man
|
||||
DIST_SUBDIRS = lib libsubid src po doc etc tests/unit man
|
||||
am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
||||
$(top_srcdir)/man/po/Makefile.in ABOUT-NLS AUTHORS.md COPYING \
|
||||
ChangeLog NEWS README compile config.guess config.rpath \
|
||||
@@ -243,6 +243,7 @@ EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
@@ -333,8 +334,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
XMLCATALOG = @XMLCATALOG@
|
||||
XML_CATALOG_FILE = @XML_CATALOG_FILE@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
@@ -389,7 +388,7 @@ target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
SUBDIRS = lib $(am__append_1) src po contrib doc etc tests/unit \
|
||||
SUBDIRS = lib $(am__append_1) src po doc etc tests/unit \
|
||||
$(am__append_2)
|
||||
CLEANFILES = man/8.out man/po/remove-potcdate.* man/*/login.defs.d man/*/*.mo
|
||||
EXTRA_DIST = NEWS README tests/
|
||||
|
||||
43
aclocal.m4
vendored
43
aclocal.m4
vendored
@@ -22,14 +22,15 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.])
|
||||
|
||||
# ltdl.m4 - Configure ltdl for the target system. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 1999-2008, 2011-2015 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1999-2008, 2011-2019, 2021-2022 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Thomas Tanner, 1999
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
# unlimited permission to copy and/or distribute it, with or without
|
||||
# modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 20 LTDL_INIT
|
||||
# serial 21 LTDL_INIT
|
||||
|
||||
# LT_CONFIG_LTDL_DIR(DIRECTORY, [LTDL-MODE])
|
||||
# ------------------------------------------
|
||||
@@ -357,7 +358,7 @@ AC_CONFIG_COMMANDS_PRE([
|
||||
if test -n "$_LT_LIBOBJS"; then
|
||||
# Remove the extension.
|
||||
_lt_sed_drop_objext='s/\.o$//;s/\.obj$//'
|
||||
for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | sed "$_lt_sed_drop_objext" | sort -u`; do
|
||||
for i in `for i in $_LT_LIBOBJS; do echo "$i"; done | $SED "$_lt_sed_drop_objext" | sort -u`; do
|
||||
_ltdl_libobjs="$_ltdl_libobjs $lt_libobj_prefix$i.$ac_objext"
|
||||
_ltdl_ltlibobjs="$_ltdl_ltlibobjs $lt_libobj_prefix$i.lo"
|
||||
done
|
||||
@@ -495,7 +496,7 @@ AC_CACHE_CHECK([whether deplibs are loaded by dlopen],
|
||||
# If you are looking for one http://www.opendarwin.org/projects/dlcompat
|
||||
lt_cv_sys_dlopen_deplibs=yes
|
||||
;;
|
||||
freebsd* | dragonfly*)
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
lt_cv_sys_dlopen_deplibs=yes
|
||||
;;
|
||||
gnu* | linux* | k*bsd*-gnu | kopensolaris*-gnu)
|
||||
@@ -930,8 +931,8 @@ AU_ALIAS([AC_LTDL_DLSYM_USCORE], [LT_FUNC_DLSYM_USCORE])
|
||||
dnl aclocal-1.4 backwards compatibility:
|
||||
dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], [])
|
||||
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 11 (pkg-config-0.29.1)
|
||||
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
|
||||
# serial 12 (pkg-config-0.29.2)
|
||||
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
@@ -973,7 +974,7 @@ dnl
|
||||
dnl See the "Since" comment for each macro you use to see what version
|
||||
dnl of the macros you require.
|
||||
m4_defun([PKG_PREREQ],
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.2])
|
||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||
])dnl PKG_PREREQ
|
||||
@@ -1018,7 +1019,7 @@ dnl Check to see whether a particular set of modules exists. Similar to
|
||||
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
dnl
|
||||
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
dnl only at the first occurence in configure.ac, so if the first place
|
||||
dnl only at the first occurrence in configure.ac, so if the first place
|
||||
dnl it's called might be skipped (such as if it is within an "if", you
|
||||
dnl have to call PKG_CHECK_EXISTS manually
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
@@ -1074,7 +1075,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $1])
|
||||
AC_MSG_CHECKING([for $2])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
@@ -1084,17 +1085,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
@@ -1105,8 +1106,8 @@ installed software in a non-standard prefix.
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
@@ -1116,10 +1117,10 @@ _PKG_TEXT
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
$3
|
||||
fi[]dnl
|
||||
])dnl PKG_CHECK_MODULES
|
||||
|
||||
|
||||
64
config.h.in
64
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,9 +244,6 @@
|
||||
/* 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
|
||||
|
||||
@@ -512,14 +457,5 @@
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Path for utmp file. */
|
||||
#undef _UTMP_FILE
|
||||
|
||||
/* Path for wtmp file. */
|
||||
#undef _WTMP_FILE
|
||||
|
||||
/* 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
|
||||
|
||||
69
configure.ac
69
configure.ac
@@ -4,7 +4,7 @@ m4_define([libsubid_abi_major], 5)
|
||||
m4_define([libsubid_abi_minor], 0)
|
||||
m4_define([libsubid_abi_micro], 0)
|
||||
m4_define([libsubid_abi], [libsubid_abi_major.libsubid_abi_minor.libsubid_abi_micro])
|
||||
AC_INIT([shadow], [4.17.1], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||
AC_INIT([shadow], [4.18.0], [pkg-shadow-devel@lists.alioth.debian.org], [],
|
||||
[https://github.com/shadow-maint/shadow])
|
||||
AM_INIT_AUTOMAKE([1.11 foreign dist-xz subdir-objects tar-pax])
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
@@ -30,26 +30,18 @@ AM_MAINTAINER_MODE
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_LN_S
|
||||
AC_PROG_YACC
|
||||
LT_INIT
|
||||
LT_LIB_DLLOAD
|
||||
|
||||
dnl Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_CHECK_HEADERS(crypt.h utmp.h \
|
||||
termio.h sgtty.h sys/ioctl.h paths.h \
|
||||
sys/capability.h sys/random.h \
|
||||
gshadow.h lastlog.h rpc/key_prot.h acl/libacl.h \
|
||||
attr/libattr.h attr/error_context.h)
|
||||
|
||||
dnl shadow now uses the libc's shadow implementation
|
||||
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
|
||||
|
||||
AC_CHECK_FUNCS(arc4random_buf futimes \
|
||||
getentropy getrandom getspnam getusershell \
|
||||
initgroups lckpwdf lutimes \
|
||||
setgroups updwtmpx innetgr \
|
||||
AC_CHECK_FUNCS(arc4random_buf \
|
||||
getentropy getrandom \
|
||||
lckpwdf lutimes \
|
||||
updwtmpx innetgr \
|
||||
getspnam_r \
|
||||
rpmatch \
|
||||
memset_explicit explicit_bzero stpecpy stpeprintf)
|
||||
@@ -66,7 +58,6 @@ AC_CHECK_MEMBERS([struct utmpx.ut_name,
|
||||
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)
|
||||
@@ -76,33 +67,6 @@ AC_CHECK_FUNC(secure_getenv, [AC_DEFINE(HAS_SECURE_GETENV,
|
||||
1,
|
||||
[Defined to 1 if you have the declaration of 'secure_getenv'])])
|
||||
|
||||
if test "$ac_cv_header_shadow_h" = "yes"; then
|
||||
AC_CACHE_CHECK(for working shadow group support,
|
||||
ac_cv_libc_shadowgrp,
|
||||
AC_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#include <shadow.h>
|
||||
#ifdef HAVE_GSHADOW_H
|
||||
#include <gshadow.h>
|
||||
#endif
|
||||
int
|
||||
main()
|
||||
{
|
||||
struct sgrp *sg = sgetsgent("test:x::");
|
||||
/* NYS libc on Red Hat 3.0.3 has broken shadow group support */
|
||||
return !sg || !sg->sg_adm || !sg->sg_mem;
|
||||
}]
|
||||
)],
|
||||
[ac_cv_libc_shadowgrp=yes],
|
||||
[ac_cv_libc_shadowgrp=no],
|
||||
[ac_cv_libc_shadowgrp=no]
|
||||
)
|
||||
)
|
||||
|
||||
if test "$ac_cv_libc_shadowgrp" = "yes"; then
|
||||
AC_DEFINE(HAVE_SHADOWGRP, 1, [Have working shadow group support in libc])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([location of shared mail directory], shadow_cv_maildir,
|
||||
[for shadow_cv_maildir in /var/mail /var/spool/mail /usr/spool/mail /usr/mail none; do
|
||||
if test -d $shadow_cv_maildir; then
|
||||
@@ -125,18 +89,6 @@ if test $shadow_cv_mailfile != none; then
|
||||
[Name of user's mail spool file if stored in user's home directory.])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([location of utmp], shadow_cv_utmpdir,
|
||||
[for shadow_cv_utmpdir in /var/run /var/adm /usr/adm /etc none; do
|
||||
if test -f $shadow_cv_utmpdir/utmp; then
|
||||
break
|
||||
fi
|
||||
done])
|
||||
if test "$shadow_cv_utmpdir" = "none"; then
|
||||
AC_MSG_WARN(utmp file not found)
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(_UTMP_FILE, "$shadow_cv_utmpdir/utmp",
|
||||
[Path for utmp file.])
|
||||
|
||||
AC_CACHE_CHECK([location of faillog/lastlog/wtmp], shadow_cv_logdir,
|
||||
[for shadow_cv_logdir in /var/log /var/adm /usr/adm /etc; do
|
||||
if test -d $shadow_cv_logdir; then
|
||||
@@ -150,13 +102,7 @@ AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$shadow_cv_logdir/lastlog",
|
||||
AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$shadow_cv_logdir/faillog",
|
||||
[Path for faillog file.])
|
||||
|
||||
AC_CACHE_CHECK([location of the passwd program], shadow_cv_passwd_dir,
|
||||
[if test -f /usr/bin/passwd; then
|
||||
shadow_cv_passwd_dir=/usr/bin
|
||||
else
|
||||
shadow_cv_passwd_dir=/bin
|
||||
fi])
|
||||
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
|
||||
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$exec_prefix/bin/passwd",
|
||||
[Path to passwd program.])
|
||||
|
||||
AC_ARG_ENABLE(shadowgrp,
|
||||
@@ -384,7 +330,7 @@ if test "$enable_lastlog" = "yes" && test "$ac_cv_header_lastlog_h" = "yes"; the
|
||||
enable_lastlog="yes"
|
||||
else
|
||||
AC_MSG_ERROR([Cannot enable support for lastlog on systems where the data structures aren't available])
|
||||
enable_subids="no"
|
||||
enable_lastlog="no"
|
||||
fi
|
||||
fi
|
||||
AM_CONDITIONAL(ENABLE_LASTLOG, test "x$enable_lastlog" != "xno")
|
||||
@@ -737,7 +683,6 @@ AC_CONFIG_FILES([
|
||||
libsubid/Makefile
|
||||
libsubid/subid.h
|
||||
src/Makefile
|
||||
contrib/Makefile
|
||||
etc/Makefile
|
||||
etc/pam.d/Makefile
|
||||
etc/shadow-maint/Makefile
|
||||
|
||||
@@ -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,503 +0,0 @@
|
||||
/****
|
||||
** 04/21/96
|
||||
** hacked even more, replaced gets() with something slightly harder to buffer
|
||||
** overflow. Added support for setting a default quota on new account, with
|
||||
** edquota -p. Other cleanups for security, I let some users run adduser suid
|
||||
** root to add new accounts. (overflow checks, clobber environment, valid
|
||||
** shell checks, restrictions on gid + home dir settings).
|
||||
|
||||
** Added max. username length. Used syslog() a bit for important events.
|
||||
** Support to immediately expire account with passwd -e.
|
||||
|
||||
** Called it version 2.0! Because I felt like it!
|
||||
|
||||
** -- Chris, chris@ferret.lmh.ox.ac.uk
|
||||
|
||||
** 03/17/96
|
||||
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
|
||||
** --marekm
|
||||
**
|
||||
** 02/26/96
|
||||
** modified to call shadow utils (useradd,chage,passwd) on shadowed
|
||||
** systems - Cristian Gafton, gafton@sorosis.ro
|
||||
**
|
||||
** 6/27/95
|
||||
** shadow-adduser 1.4:
|
||||
**
|
||||
** now it copies the /etc/skel dir into the person's dir,
|
||||
** makes the mail folders, changed some defaults and made a 'make
|
||||
** install' just for the hell of it.
|
||||
**
|
||||
** Greg Gallagher
|
||||
** CIN.Net
|
||||
**
|
||||
** 1/28/95
|
||||
** shadow-adduser 1.3:
|
||||
**
|
||||
** Basically a bug-fix on my additions in 1.2. Thanks to Terry Stewart
|
||||
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
|
||||
** It was such a stupid bug that I would have never seen it myself.
|
||||
**
|
||||
** Brandon
|
||||
*****
|
||||
** 01/27/95
|
||||
**
|
||||
** shadow-adduser 1.2:
|
||||
** I took the C source from adduser-shadow (credits are below) and made
|
||||
** it a little more worthwhile. Many small changes... Here's
|
||||
** the ones I can remember:
|
||||
**
|
||||
** Removed support for non-shadowed systems (if you don't have shadow,
|
||||
** use the original adduser, don't get this shadow version!)
|
||||
** Added support for the correct /etc/shadow fields (Min days before
|
||||
** password change, max days before password change, Warning days,
|
||||
** and how many days from expiry date does the account go invalid)
|
||||
** The previous version just left all of those fields blank.
|
||||
** There is still one field left (expiry date for the account, period)
|
||||
** which I have left blank because I do not use it and didn't want to
|
||||
** spend any more time on this. I'm sure someone will put it in and
|
||||
** tack another plethora of credits on here. :)
|
||||
** Added in the password date field, which should always reflect the last
|
||||
** date the password was changed, for expiry purposes. "passwd" always
|
||||
** updates this field, so the adduser program should set it up right
|
||||
** initially (or a user could keep their initial password forever ;)
|
||||
** The number is in days since Jan 1st, 1970.
|
||||
**
|
||||
** Have fun with it, and someone please make
|
||||
** a real version(this is still just a hack)
|
||||
** for us all to use (and Email it to me???)
|
||||
**
|
||||
** Brandon
|
||||
** photon@usis.com
|
||||
**
|
||||
*****
|
||||
** adduser 1.0: add a new user account (For systems not using shadow)
|
||||
** With a nice little interface and a will to do all the work for you.
|
||||
**
|
||||
** Craig Hagan
|
||||
** hagan@opine.cs.umass.edu
|
||||
**
|
||||
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
|
||||
** chris@slinky.cs.umass.edu
|
||||
**
|
||||
*****
|
||||
**
|
||||
** 01/19/95
|
||||
**
|
||||
** FURTHER modifications to enable shadow passwd support (kludged, but
|
||||
** no more so than the original) by Dan Crowson - dcrowson@mo.net
|
||||
**
|
||||
** Search on DAN for all changes...
|
||||
**
|
||||
*****
|
||||
**
|
||||
** cc -O -o adduser adduser.c
|
||||
** Use gcc if you have it... (political reasons beyond my control) (chris)
|
||||
**
|
||||
** I've gotten this program to work with success under Linux (without
|
||||
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
|
||||
** on any system that uses no shadow. (chris)
|
||||
**
|
||||
** If you have no crypt() then try
|
||||
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
|
||||
** I'm not sure how login operates with no crypt()... I guess
|
||||
** the same way we're doing it here.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "string/strcmp/streq.h"
|
||||
|
||||
|
||||
#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
|
||||
* immediately upon next login */
|
||||
#define HAVE_QUOTAS /* Obvious */
|
||||
#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change
|
||||
* password expiry values (if running suid root) */
|
||||
|
||||
#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */
|
||||
#define LOGGING /* If we want to log various things to syslog */
|
||||
#define MAX_USRNAME 8 /* Longer usernames seem to work on my system....
|
||||
* But they're probably a poor idea */
|
||||
|
||||
|
||||
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
|
||||
#define DEFAULT_HOME "/home"
|
||||
#define USERADD_PATH "/usr/sbin/useradd"
|
||||
#define CHAGE_PATH "/usr/bin/chage"
|
||||
#define PASSWD_PATH "/usr/bin/passwd"
|
||||
#define EDQUOTA_PATH "/usr/sbin/edquota"
|
||||
#define QUOTA_DEFAULT "defuser"
|
||||
#define DEFAULT_GROUP 100
|
||||
|
||||
#define DEFAULT_MIN_PASS 0
|
||||
#define DEFAULT_MAX_PASS 100
|
||||
#define DEFAULT_WARN_PASS 14
|
||||
#define DEFAULT_USER_DIE 366
|
||||
|
||||
void safeget (char *, int);
|
||||
|
||||
void
|
||||
main (void)
|
||||
{
|
||||
char foo[32];
|
||||
char usrname[32], person[32], dir[32], shell[32];
|
||||
unsigned int group, min_pass, max_pass, warn_pass, user_die;
|
||||
/* the group and uid of the new user */
|
||||
int bad = 0, done = 0, correct = 0, olduid;
|
||||
char cmd[255];
|
||||
struct group *grp;
|
||||
|
||||
/* flags, in order:
|
||||
* bad to see if the username is in /etc/passwd, or if strange stuff has
|
||||
* been typed if the user might be put in group 0
|
||||
* done allows the program to exit when a user has been added
|
||||
* correct loops until a username is found that isn't in /etc/passwd
|
||||
*/
|
||||
|
||||
/* The real program starts HERE! */
|
||||
|
||||
if (geteuid () != 0)
|
||||
{
|
||||
printf ("It seems you don't have access to add a new user. Try\n");
|
||||
printf ("logging in as root or su root to gain superuser access.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Sanity checks
|
||||
*/
|
||||
|
||||
#ifdef LOGGING
|
||||
openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
|
||||
syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
|
||||
#endif
|
||||
|
||||
if (!(grp = getgrgid (DEFAULT_GROUP)))
|
||||
{
|
||||
printf ("Error: the default group %d does not exist on this system!\n",
|
||||
DEFAULT_GROUP);
|
||||
printf ("adduser must be recompiled.\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: failed. no such default group\n");
|
||||
closelog ();
|
||||
#endif
|
||||
exit (1);
|
||||
};
|
||||
|
||||
while (!correct)
|
||||
{ /* loop until a "good" usrname is chosen */
|
||||
while (!done)
|
||||
{
|
||||
printf ("\nLogin to add (^C to quit): ");
|
||||
fflush (stdout);
|
||||
|
||||
safeget (usrname, sizeof (usrname));
|
||||
|
||||
if (!strlen (usrname))
|
||||
{
|
||||
printf ("Empty input.\n");
|
||||
done = 0;
|
||||
continue;
|
||||
};
|
||||
|
||||
/* what I saw here before made me think maybe I was running DOS */
|
||||
/* might this be a solution? (chris) */
|
||||
if (strlen (usrname) > MAX_USRNAME)
|
||||
{
|
||||
printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
|
||||
done = 0;
|
||||
}
|
||||
else if (getpwnam (usrname) != NULL)
|
||||
{
|
||||
printf ("That name is in use, choose another.\n");
|
||||
done = 0;
|
||||
}
|
||||
else if (strchr (usrname, ' ') != NULL)
|
||||
{
|
||||
printf ("No spaces in username!!\n");
|
||||
done = 0;
|
||||
}
|
||||
else
|
||||
done = 1;
|
||||
}; /* done, we have a valid new user name */
|
||||
|
||||
/* all set, get the rest of the stuff */
|
||||
printf ("\nEditing information for new user [%s]\n", usrname);
|
||||
|
||||
printf ("\nFull Name [%s]: ", usrname);
|
||||
fflush (stdout);
|
||||
safeget (person, sizeof (person));
|
||||
if (!strlen (person))
|
||||
{
|
||||
bzero (person, sizeof (person));
|
||||
strcpy (person, usrname);
|
||||
};
|
||||
|
||||
if (getuid () == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
bad = 0;
|
||||
printf ("GID [%d]: ", DEFAULT_GROUP);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
if (!strlen (foo))
|
||||
group = DEFAULT_GROUP;
|
||||
else if (isdigit (*foo))
|
||||
{
|
||||
group = atoi (foo);
|
||||
if (!(grp = getgrgid (group)))
|
||||
{
|
||||
printf ("unknown gid %s\n", foo);
|
||||
group = DEFAULT_GROUP;
|
||||
bad = 1;
|
||||
};
|
||||
}
|
||||
else if ((grp = getgrnam (foo)))
|
||||
group = grp->gr_gid;
|
||||
else
|
||||
{
|
||||
printf ("unknown group %s\n", foo);
|
||||
group = DEFAULT_GROUP;
|
||||
bad = 1;
|
||||
}
|
||||
if (group == 0)
|
||||
{ /* You're not allowed to make root group users! */
|
||||
printf ("Creation of root group users not allowed (must be done by hand)\n");
|
||||
group = DEFAULT_GROUP;
|
||||
bad = 1;
|
||||
};
|
||||
}
|
||||
while (bad);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("Group will be default of: %d\n", DEFAULT_GROUP);
|
||||
group = DEFAULT_GROUP;
|
||||
}
|
||||
|
||||
if (getuid () == 0)
|
||||
{
|
||||
printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
|
||||
printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
|
||||
fflush (stdout);
|
||||
safeget (dir, sizeof (dir));
|
||||
if (!strlen(dir)) /* hit return */
|
||||
sprintf(dir, "%s/%s", DEFAULT_HOME, usrname);
|
||||
else if (dir[strlen (dir) - 1] == '/')
|
||||
strcat(dir, usrname);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
|
||||
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
|
||||
}
|
||||
|
||||
printf ("\nShell [%s]: ", DEFAULT_SHELL);
|
||||
fflush (stdout);
|
||||
safeget (shell, sizeof (shell));
|
||||
if (!strlen (shell))
|
||||
strcpy(shell, DEFAULT_SHELL);
|
||||
else
|
||||
{
|
||||
char *sh;
|
||||
int ok = 0;
|
||||
#ifdef HAVE_GETUSERSHELL
|
||||
setusershell ();
|
||||
while ((sh = getusershell ()) != NULL)
|
||||
if (streq(shell, sh))
|
||||
ok = 1;
|
||||
endusershell ();
|
||||
#endif
|
||||
if (!ok)
|
||||
{
|
||||
if (getuid () == 0)
|
||||
printf ("Warning: root allowed non standard shell\n");
|
||||
else
|
||||
{
|
||||
printf ("Shell NOT in /etc/shells, DEFAULT used\n");
|
||||
strcpy(shell, DEFAULT_SHELL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXPIRE_VALS_SET
|
||||
if (getuid () == 0)
|
||||
{
|
||||
#endif
|
||||
printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
if (strlen (foo) > 1)
|
||||
min_pass = DEFAULT_MIN_PASS;
|
||||
else
|
||||
min_pass = atoi (foo);
|
||||
|
||||
printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
if (strlen (foo) > 1)
|
||||
max_pass = atoi (foo);
|
||||
else
|
||||
max_pass = DEFAULT_MAX_PASS;
|
||||
|
||||
printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
warn_pass = atoi (foo);
|
||||
if (warn_pass == 0)
|
||||
|
||||
warn_pass = DEFAULT_WARN_PASS;
|
||||
|
||||
printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
user_die = atoi (foo);
|
||||
if (user_die == 0)
|
||||
user_die = DEFAULT_USER_DIE;
|
||||
|
||||
#ifdef EXPIRE_VALS_SET
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\nSorry, account expiry values are set.\n");
|
||||
user_die = DEFAULT_USER_DIE;
|
||||
warn_pass = DEFAULT_WARN_PASS;
|
||||
max_pass = DEFAULT_MAX_PASS;
|
||||
min_pass = DEFAULT_MIN_PASS;
|
||||
}
|
||||
#endif
|
||||
|
||||
printf ("\nInformation for new user [%s] [%s]:\n", usrname, person);
|
||||
printf ("Home directory: [%s] Shell: [%s]\n", dir, shell);
|
||||
printf ("GID: [%d]\n", group);
|
||||
printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
|
||||
min_pass, max_pass, warn_pass, user_die);
|
||||
printf ("\nIs this correct? [y/N]: ");
|
||||
fflush (stdout);
|
||||
safeget (foo, sizeof (foo));
|
||||
|
||||
done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
|
||||
|
||||
if (bad != 1)
|
||||
printf ("\nUser [%s] not added\n", usrname);
|
||||
}
|
||||
|
||||
/* Clobber the environment, I run this suid root sometimes to let
|
||||
* non root privileged accounts add users --chris */
|
||||
|
||||
*environ = NULL;
|
||||
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
|
||||
USERADD_PATH, group, dir, shell, person, usrname);
|
||||
printf ("Calling useradd to add new user:\n%s\n", cmd);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("User add failed!\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "could not add new user\n");
|
||||
closelog ();
|
||||
#endif
|
||||
exit (errno);
|
||||
};
|
||||
|
||||
olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root
|
||||
*/
|
||||
setuid (0);
|
||||
|
||||
bzero (cmd, sizeof (cmd));
|
||||
|
||||
/* Chage runs suid root. => we need ruid root to run it with
|
||||
* anything other than chage -l
|
||||
*/
|
||||
|
||||
sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
|
||||
min_pass, max_pass, warn_pass, user_die, usrname);
|
||||
printf ("%s\n", cmd);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("There was an error setting password expire values\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "password expire values could not be set\n");
|
||||
#endif
|
||||
};
|
||||
|
||||
/* I want to add a user completely with one easy command --chris */
|
||||
|
||||
#ifdef HAVE_QUOTAS
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
|
||||
printf ("%s\n", cmd);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("\nWarning: error setting quota\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
|
||||
#endif /* LOGGING */
|
||||
}
|
||||
else
|
||||
printf ("\nDefault quota set.\n");
|
||||
#endif /* HAVE_QUOTAS */
|
||||
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("\nWarning: error setting password\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: password set failed!\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef IMMEDIATE_CHANGE
|
||||
bzero (cmd, sizeof (cmd));
|
||||
sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
|
||||
if (system (cmd))
|
||||
{
|
||||
printf ("\nWarning: error expiring password\n");
|
||||
#ifdef LOGGING
|
||||
syslog (LOG_ERR, "warning: password expire failed!\n");
|
||||
#endif /* LOGGING */
|
||||
}
|
||||
#endif /* IMMEDIATE_CHANGE */
|
||||
|
||||
setuid (olduid);
|
||||
|
||||
#ifdef LOGGING
|
||||
closelog ();
|
||||
#endif
|
||||
|
||||
printf ("\nDone.\n");
|
||||
}
|
||||
|
||||
void
|
||||
safeget (char *buf, int maxlen)
|
||||
{
|
||||
int c, i = 0, bad = 0;
|
||||
char *bstart = buf;
|
||||
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
|
||||
{
|
||||
bad = (!isalnum (c) && (c != '_') && (c != ' '));
|
||||
*(buf++) = c;
|
||||
}
|
||||
stpcpy(buf, "");
|
||||
|
||||
if (bad)
|
||||
{
|
||||
printf ("\nString contained banned character. Please stick to alphanumerics.\n");
|
||||
stpcpy(bstart, "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -1751,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);
|
||||
}
|
||||
|
||||
@@ -161,6 +161,7 @@ EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
@@ -251,8 +252,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
XMLCATALOG = @XMLCATALOG@
|
||||
XML_CATALOG_FILE = @XML_CATALOG_FILE@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
|
||||
@@ -250,6 +250,7 @@ EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
@@ -340,8 +341,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
XMLCATALOG = @XMLCATALOG@
|
||||
XML_CATALOG_FILE = @XML_CATALOG_FILE@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
|
||||
@@ -11,7 +11,6 @@ pamd_files = \
|
||||
passwd
|
||||
|
||||
pamd_acct_tools_files = \
|
||||
chage \
|
||||
chgpasswd \
|
||||
groupadd \
|
||||
groupdel \
|
||||
|
||||
@@ -193,6 +193,7 @@ EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
@@ -283,8 +284,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
XMLCATALOG = @XMLCATALOG@
|
||||
XML_CATALOG_FILE = @XML_CATALOG_FILE@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
@@ -342,7 +341,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
|
||||
@@ -158,6 +158,7 @@ EGREP = @EGREP@
|
||||
ETAGS = @ETAGS@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
FILECMD = @FILECMD@
|
||||
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GMSGFMT_015 = @GMSGFMT_015@
|
||||
@@ -248,8 +249,6 @@ XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
|
||||
XMLCATALOG = @XMLCATALOG@
|
||||
XML_CATALOG_FILE = @XML_CATALOG_FILE@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
YACC = @YACC@
|
||||
YFLAGS = @YFLAGS@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
|
||||
@@ -59,12 +59,8 @@ libshadow_la_SOURCES = \
|
||||
atoi/a2i/a2u_nc.h \
|
||||
atoi/getnum.c \
|
||||
atoi/getnum.h \
|
||||
atoi/str2i/str2i.c \
|
||||
atoi/str2i/str2i.h \
|
||||
atoi/str2i/str2s.c \
|
||||
atoi/str2i/str2s.h \
|
||||
atoi/str2i/str2u.c \
|
||||
atoi/str2i/str2u.h \
|
||||
atoi/str2i.c \
|
||||
atoi/str2i.h \
|
||||
atoi/strtoi/strtoi.c \
|
||||
atoi/strtoi/strtoi.h \
|
||||
atoi/strtoi/strtou.c \
|
||||
@@ -98,18 +94,21 @@ libshadow_la_SOURCES = \
|
||||
failure.h \
|
||||
fd.c \
|
||||
fields.c \
|
||||
fields.h \
|
||||
find_new_gid.c \
|
||||
find_new_uid.c \
|
||||
find_new_sub_gids.c \
|
||||
find_new_sub_uids.c \
|
||||
fputsx.c \
|
||||
fs/mkstemp/fmkomstemp.c \
|
||||
fs/mkstemp/fmkomstemp.h \
|
||||
fs/mkstemp/mkomstemp.c \
|
||||
fs/mkstemp/mkomstemp.h \
|
||||
fs/readlink/areadlink.c \
|
||||
fs/readlink/areadlink.h \
|
||||
fs/readlink/readlinknul.c \
|
||||
fs/readlink/readlinknul.h \
|
||||
get_pid.c \
|
||||
getdate.h \
|
||||
getdate.y \
|
||||
getdef.c \
|
||||
getdef.h \
|
||||
getgr_nam_gid.c \
|
||||
@@ -129,7 +128,6 @@ libshadow_la_SOURCES = \
|
||||
loginprompt.c \
|
||||
mail.c \
|
||||
motd.c \
|
||||
must_be.h \
|
||||
myname.c \
|
||||
nss.c \
|
||||
nscd.c \
|
||||
@@ -155,6 +153,14 @@ 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 \
|
||||
@@ -164,7 +170,8 @@ libshadow_la_SOURCES = \
|
||||
sgetspent.c \
|
||||
sgroupio.c \
|
||||
sgroupio.h\
|
||||
shadow.c \
|
||||
shadow/grp/agetgroups.c \
|
||||
shadow/grp/agetgroups.h \
|
||||
shadowio.c \
|
||||
shadowio.h \
|
||||
shadowlog.c \
|
||||
@@ -176,24 +183,38 @@ libshadow_la_SOURCES = \
|
||||
spawn.c \
|
||||
sssd.c \
|
||||
sssd.h \
|
||||
string/ctype/strchrisascii/strchriscntrl.c \
|
||||
string/ctype/strchrisascii/strchriscntrl.h \
|
||||
string/ctype/strisascii/strisdigit.c \
|
||||
string/ctype/strisascii/strisdigit.h \
|
||||
string/ctype/strisascii/strisprint.c \
|
||||
string/ctype/strisascii/strisprint.h \
|
||||
string/ctype/strtoascii/strtolower.c \
|
||||
string/ctype/strtoascii/strtolower.h \
|
||||
string/memset/memzero.c \
|
||||
string/memset/memzero.h \
|
||||
string/sprintf/aprintf.c \
|
||||
string/sprintf/aprintf.h \
|
||||
string/sprintf/snprintf.c \
|
||||
string/sprintf/snprintf.h \
|
||||
string/sprintf/stpeprintf.c \
|
||||
string/sprintf/stpeprintf.h \
|
||||
string/sprintf/xasprintf.c \
|
||||
string/sprintf/xasprintf.h \
|
||||
string/sprintf/xaprintf.c \
|
||||
string/sprintf/xaprintf.h \
|
||||
string/strchr/strchrcnt.c \
|
||||
string/strchr/strchrcnt.h \
|
||||
string/strchr/stpspn.c \
|
||||
string/strchr/stpspn.h \
|
||||
string/strchr/strchrscnt.c \
|
||||
string/strchr/strchrscnt.h \
|
||||
string/strchr/strnul.c \
|
||||
string/strchr/strnul.h \
|
||||
string/strchr/strrspn.c \
|
||||
string/strchr/strrspn.h \
|
||||
string/strcmp/strcaseeq.c \
|
||||
string/strcmp/strcaseeq.h \
|
||||
string/strcmp/strcaseprefix.c \
|
||||
string/strcmp/strcaseprefix.h \
|
||||
string/strcmp/streq.c \
|
||||
string/strcmp/streq.h \
|
||||
string/strcmp/strprefix.c \
|
||||
string/strcmp/strprefix.h \
|
||||
string/strcpy/stpecpy.c \
|
||||
string/strcpy/stpecpy.h \
|
||||
string/strcpy/strncat.c \
|
||||
@@ -210,8 +231,26 @@ libshadow_la_SOURCES = \
|
||||
string/strdup/xstrndup.h \
|
||||
string/strftime.c \
|
||||
string/strftime.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 \
|
||||
string/strtok/xastrsep2ls.c \
|
||||
string/strtok/xastrsep2ls.h \
|
||||
strtoday.c \
|
||||
sub.c \
|
||||
subordinateio.h \
|
||||
|
||||
839
lib/Makefile.in
839
lib/Makefile.in
File diff suppressed because it is too large
Load Diff
111
lib/addgrps.c
111
lib/addgrps.c
@@ -1,15 +1,14 @@
|
||||
/*
|
||||
* 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)
|
||||
#if !defined(USE_PAM)
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
@@ -18,12 +17,14 @@
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "alloc/malloc.h"
|
||||
#include "alloc/reallocf.h"
|
||||
#include "search/l/lsearch.h"
|
||||
#include "shadow/grp/agetgroups.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strchr/strchrscnt.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
/*
|
||||
* Add groups with names from LIST (separated by commas or colons)
|
||||
@@ -33,48 +34,25 @@
|
||||
int
|
||||
add_groups(const char *list)
|
||||
{
|
||||
GETGROUPS_T *grouplist;
|
||||
size_t i;
|
||||
int ngroups;
|
||||
bool added;
|
||||
char *g, *p;
|
||||
char buf[1024];
|
||||
int ret;
|
||||
char *g, *p, *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(gids, n + strchrscnt(list, ",:") + 1, gid_t);
|
||||
if (gids == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
added = false;
|
||||
p = buf;
|
||||
p = dup = strdup(list);
|
||||
if (dup == NULL)
|
||||
goto free_gids;
|
||||
|
||||
while (NULL != (g = strsep(&p, ",:"))) {
|
||||
struct group *grp;
|
||||
struct group *grp;
|
||||
|
||||
grp = getgrnam(g); /* local, no need for xgetgrnam */
|
||||
if (NULL == grp) {
|
||||
@@ -82,35 +60,22 @@ add_groups(const char *list)
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++);
|
||||
LSEARCH(&grp->gr_gid, gids, &n);
|
||||
}
|
||||
free(dup);
|
||||
|
||||
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 (setgroups(n, gids) == -1) {
|
||||
fprintf(shadow_logfd, "setgroups: %s\n", strerror(errno));
|
||||
goto free_gids;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
24
lib/adds.h
24
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
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
#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(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
|
||||
|
||||
@@ -106,7 +106,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)
|
||||
|
||||
@@ -8,49 +8,13 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/a2i/a2s_c.h"
|
||||
#include "atoi/a2i/a2s_nc.h"
|
||||
#include "atoi/a2i/a2i.h"
|
||||
|
||||
|
||||
#define a2sh(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2sh_c, \
|
||||
const void *: a2sh_c, \
|
||||
char *: a2sh_nc, \
|
||||
void *: a2sh_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2si(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2si_c, \
|
||||
const void *: a2si_c, \
|
||||
char *: a2si_nc, \
|
||||
void *: a2si_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2sl(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2sl_c, \
|
||||
const void *: a2sl_c, \
|
||||
char *: a2sl_nc, \
|
||||
void *: a2sl_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2sll(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2sll_c, \
|
||||
const void *: a2sll_c, \
|
||||
char *: a2sll_nc, \
|
||||
void *: a2sll_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
#define a2sh(...) a2i(short, __VA_ARGS__)
|
||||
#define a2si(...) a2i(int, __VA_ARGS__)
|
||||
#define a2sl(...) a2i(long, __VA_ARGS__)
|
||||
#define a2sll(...) a2i(long long, __VA_ARGS__)
|
||||
|
||||
|
||||
#endif // include guard
|
||||
|
||||
@@ -8,49 +8,13 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/a2i/a2u_c.h"
|
||||
#include "atoi/a2i/a2u_nc.h"
|
||||
#include "atoi/a2i/a2i.h"
|
||||
|
||||
|
||||
#define a2uh(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2uh_c, \
|
||||
const void *: a2uh_c, \
|
||||
char *: a2uh_nc, \
|
||||
void *: a2uh_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2ui(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2ui_c, \
|
||||
const void *: a2ui_c, \
|
||||
char *: a2ui_nc, \
|
||||
void *: a2ui_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2ul(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2ul_c, \
|
||||
const void *: a2ul_c, \
|
||||
char *: a2ul_nc, \
|
||||
void *: a2ul_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
|
||||
#define a2ull(n, s, ...) \
|
||||
( \
|
||||
_Generic(s, \
|
||||
const char *: a2ull_c, \
|
||||
const void *: a2ull_c, \
|
||||
char *: a2ull_nc, \
|
||||
void *: a2ull_nc \
|
||||
)(n, s, __VA_ARGS__) \
|
||||
)
|
||||
#define a2uh(...) a2i(unsigned short, __VA_ARGS__)
|
||||
#define a2ui(...) a2i(unsigned int, __VA_ARGS__)
|
||||
#define a2ul(...) a2i(unsigned long, __VA_ARGS__)
|
||||
#define a2ull(...) a2i(unsigned long long, __VA_ARGS__)
|
||||
|
||||
|
||||
#endif // include guard
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/str2i/str2i.h"
|
||||
#include "atoi/str2i.h"
|
||||
31
lib/atoi/str2i.h
Normal file
31
lib/atoi/str2i.h
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "atoi/a2i/a2i.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
|
||||
#define str2i(T, ...) a2i(T, __VA_ARGS__, NULL, 0, type_min(T), type_max(T))
|
||||
|
||||
#define str2sh(...) str2i(short, __VA_ARGS__)
|
||||
#define str2si(...) str2i(int, __VA_ARGS__)
|
||||
#define str2sl(...) str2i(long, __VA_ARGS__)
|
||||
#define str2sll(...) str2i(long long, __VA_ARGS__)
|
||||
|
||||
#define str2uh(...) str2i(unsigned short, __VA_ARGS__)
|
||||
#define str2ui(...) str2i(unsigned int, __VA_ARGS__)
|
||||
#define str2ul(...) str2i(unsigned long, __VA_ARGS__)
|
||||
#define str2ull(...) str2i(unsigned long long, __VA_ARGS__)
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,31 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2I_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/str2i/str2s.h"
|
||||
#include "atoi/str2i/str2u.h"
|
||||
|
||||
|
||||
#define str2i(TYPE, ...) \
|
||||
( \
|
||||
_Generic((TYPE) 0, \
|
||||
short: str2sh, \
|
||||
int: str2si, \
|
||||
long: str2sl, \
|
||||
long long: str2sll, \
|
||||
unsigned short: str2uh, \
|
||||
unsigned int: str2ui, \
|
||||
unsigned long: str2ul, \
|
||||
unsigned long long: str2ull \
|
||||
)(__VA_ARGS__) \
|
||||
)
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,14 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/str2i/str2s.h"
|
||||
|
||||
|
||||
extern inline int str2sh(short *restrict n, const char *restrict s);
|
||||
extern inline int str2si(int *restrict n, const char *restrict s);
|
||||
extern inline int str2sl(long *restrict n, const char *restrict s);
|
||||
extern inline int str2sll(long long *restrict n, const char *restrict s);
|
||||
@@ -1,57 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2S_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "atoi/a2i/a2s.h"
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2sh(short *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2si(int *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2sl(long *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2sll(long long *restrict n, const char *restrict s);
|
||||
|
||||
|
||||
inline int
|
||||
str2sh(short *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2sh(n, s, NULL, 0, SHRT_MIN, SHRT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2si(int *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2si(n, s, NULL, 0, INT_MIN, INT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2sl(long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2sl(n, s, NULL, 0, LONG_MIN, LONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2sll(long long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2sll(n, s, NULL, 0, LLONG_MIN, LLONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -1,14 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "atoi/str2i/str2u.h"
|
||||
|
||||
|
||||
extern inline int str2uh(unsigned short *restrict n, const char *restrict s);
|
||||
extern inline int str2ui(unsigned int *restrict n, const char *restrict s);
|
||||
extern inline int str2ul(unsigned long *restrict n, const char *restrict s);
|
||||
extern inline int str2ull(unsigned long long *restrict n, const char *restrict s);
|
||||
@@ -1,57 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2007-2009, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
|
||||
#define SHADOW_INCLUDE_LIB_ATOI_STR2I_STR2U_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "atoi/a2i/a2u.h"
|
||||
#include "attr.h"
|
||||
|
||||
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2uh(unsigned short *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2ui(unsigned int *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2ul(unsigned long *restrict n, const char *restrict s);
|
||||
ATTR_STRING(2) ATTR_ACCESS(write_only, 1)
|
||||
inline int str2ull(unsigned long long *restrict n, const char *restrict s);
|
||||
|
||||
|
||||
inline int
|
||||
str2uh(unsigned short *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2uh(n, s, NULL, 0, 0, USHRT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2ui(unsigned int *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2ui(n, s, NULL, 0, 0, UINT_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2ul(unsigned long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2ul(n, s, NULL, 0, 0, ULONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
str2ull(unsigned long long *restrict n, const char *restrict s)
|
||||
{
|
||||
return a2ull(n, s, NULL, 0, 0, ULLONG_MAX);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "config.h"
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if (__GNUC__ >= 10)
|
||||
# define MAYBE_UNUSED [[gnu::unused]]
|
||||
# define NORETURN [[gnu::__noreturn__]]
|
||||
# define format_attr(type, fmt, va) [[gnu::format(type, fmt, va)]]
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "attr.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
|
||||
int audit_fd;
|
||||
|
||||
void audit_help_open (void)
|
||||
@@ -46,10 +48,14 @@ void audit_help_open (void)
|
||||
|
||||
/*
|
||||
* This function will log a message to the audit system using a predefined
|
||||
* message format. Parameter usage is as follows:
|
||||
* message format. For additional information on the user account lifecycle
|
||||
* events check
|
||||
* <https://github.com/linux-audit/audit-documentation/wiki/SPEC-User-Account-Lifecycle-Events>
|
||||
*
|
||||
* type - type of message: AUDIT_USER_CHAUTHTOK for changing any account
|
||||
* attributes.
|
||||
* Parameter usage is as follows:
|
||||
*
|
||||
* type - type of message. A list of possible values is available in
|
||||
* "audit-records.h" file.
|
||||
* pgname - program's name
|
||||
* op - operation. "adding user", "changing finger info", "deleting group"
|
||||
* name - user's account or group name. If not available use NULL.
|
||||
@@ -68,6 +74,47 @@ void audit_logger (int type, MAYBE_UNUSED const char *pgname, const char *op,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will log a message to the audit system using a predefined
|
||||
* message format. For additional information on the group account lifecycle
|
||||
* events check
|
||||
* <https://github.com/linux-audit/audit-documentation/wiki/SPEC-User-Account-Lifecycle-Events>
|
||||
*
|
||||
* Parameter usage is as follows:
|
||||
*
|
||||
* type - type of message. A list of possible values is available in
|
||||
* "audit-records.h" file.
|
||||
* op - operation. "adding-user", "modify-group", "deleting-user-from-group"
|
||||
* name - user's account or group name. If not available use NULL.
|
||||
* id - uid or gid that the operation is being performed on. This is used
|
||||
* only when user is NULL.
|
||||
* grp_type - type of group: "grp" or "new_group"
|
||||
* grp - group name associated with event
|
||||
*/
|
||||
void
|
||||
audit_logger_with_group(int type, const char *op, const char *name,
|
||||
id_t id, const char *grp_type, const char *grp,
|
||||
shadow_audit_result result)
|
||||
{
|
||||
int len;
|
||||
char enc_group[GROUP_NAME_MAX_LENGTH * 2 + 1];
|
||||
char buf[countof(enc_group) + 100];
|
||||
|
||||
if (audit_fd < 0)
|
||||
return;
|
||||
|
||||
len = strnlen(grp, sizeof(enc_group)/2);
|
||||
if (audit_value_needs_encoding(grp, len)) {
|
||||
SNPRINTF(buf, "%s %s=%s", op, grp_type,
|
||||
audit_encode_value(enc_group, grp, len));
|
||||
} else {
|
||||
SNPRINTF(buf, "%s %s=\"%s\"", op, grp_type, grp);
|
||||
}
|
||||
|
||||
audit_log_acct_message(audit_fd, type, NULL, buf, name, id,
|
||||
NULL, NULL, NULL, result);
|
||||
}
|
||||
|
||||
void audit_logger_message (const char *message, shadow_audit_result result)
|
||||
{
|
||||
if (audit_fd < 0) {
|
||||
|
||||
@@ -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
|
||||
@@ -15,17 +13,19 @@
|
||||
|
||||
#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, "/");
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -27,15 +27,19 @@
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
#include "string/ctype/strisascii/strisdigit.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
|
||||
|
||||
#ifndef LOGIN_NAME_MAX
|
||||
# define LOGIN_NAME_MAX 256
|
||||
#endif
|
||||
|
||||
|
||||
int allow_bad_names = false;
|
||||
|
||||
|
||||
@@ -44,12 +48,11 @@ 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 MIN(conf, PTRDIFF_MAX);
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,11 +72,15 @@ is_valid_name(const char *name)
|
||||
*
|
||||
* Also do not allow fully numeric names or just "." or "..".
|
||||
*/
|
||||
int numeric;
|
||||
|
||||
if ('\0' == *name ||
|
||||
('.' == *name && (('.' == name[1] && '\0' == name[2]) ||
|
||||
'\0' == name[1])) ||
|
||||
if (strisdigit(name)) {
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (streq(name, "") ||
|
||||
streq(name, ".") ||
|
||||
streq(name, "..") ||
|
||||
!((*name >= 'a' && *name <= 'z') ||
|
||||
(*name >= 'A' && *name <= 'Z') ||
|
||||
(*name >= '0' && *name <= '9') ||
|
||||
@@ -84,8 +91,6 @@ is_valid_name(const char *name)
|
||||
return false;
|
||||
}
|
||||
|
||||
numeric = isdigit(*name);
|
||||
|
||||
while (!streq(++name, "")) {
|
||||
if (!((*name >= 'a' && *name <= 'z') ||
|
||||
(*name >= 'A' && *name <= 'Z') ||
|
||||
@@ -93,18 +98,12 @@ is_valid_name(const char *name)
|
||||
*name == '_' ||
|
||||
*name == '.' ||
|
||||
*name == '-' ||
|
||||
(*name == '$' && name[1] == '\0')
|
||||
streq(name, "$")
|
||||
))
|
||||
{
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
numeric &= isdigit(*name);
|
||||
}
|
||||
|
||||
if (numeric) {
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -62,7 +62,7 @@ void cleanup_report_mod_group (void *cleanup_info)
|
||||
gr_dbname (),
|
||||
info->action));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
|
||||
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -80,7 +80,7 @@ void cleanup_report_mod_gshadow (void *cleanup_info)
|
||||
sgr_dbname (),
|
||||
info->action));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
|
||||
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -101,7 +101,7 @@ void cleanup_report_add_group_group (void *group_name)
|
||||
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"adding group to /etc/group",
|
||||
"adding-group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -120,8 +120,8 @@ void cleanup_report_add_group_gshadow (void *group_name)
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"adding group to /etc/gshadow",
|
||||
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
|
||||
"adding-shadow-group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -143,8 +143,8 @@ void cleanup_report_del_group_group (void *group_name)
|
||||
"failed to remove group %s from %s",
|
||||
name, gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"removing group from /etc/group",
|
||||
audit_logger (AUDIT_DEL_GROUP, log_get_progname(),
|
||||
"removing-group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -166,8 +166,8 @@ void cleanup_report_del_group_gshadow (void *group_name)
|
||||
"failed to remove group %s from %s",
|
||||
name, sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_GROUP, log_get_progname(),
|
||||
"removing group from /etc/gshadow",
|
||||
audit_logger (AUDIT_GRP_MGMT, log_get_progname(),
|
||||
"removing-shadow-group",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -187,7 +187,7 @@ void cleanup_unlock_group (MAYBE_UNUSED void *arg)
|
||||
log_get_progname(), gr_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking group file",
|
||||
audit_logger_message ("unlocking-group",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
@@ -207,7 +207,7 @@ void cleanup_unlock_gshadow (MAYBE_UNUSED void *arg)
|
||||
log_get_progname(), sgr_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking gshadow file",
|
||||
audit_logger_message ("unlocking-gshadow",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ void cleanup_report_mod_passwd (void *cleanup_info)
|
||||
pw_dbname (),
|
||||
info->action));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_ACCT, log_get_progname(),
|
||||
audit_logger (AUDIT_USER_MGMT, log_get_progname(),
|
||||
info->audit_msg,
|
||||
info->name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
@@ -65,7 +65,7 @@ void cleanup_report_add_user_passwd (void *user_name)
|
||||
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, pw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, log_get_progname(),
|
||||
"adding user to /etc/passwd",
|
||||
"adding-user",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -84,8 +84,8 @@ void cleanup_report_add_user_shadow (void *user_name)
|
||||
|
||||
SYSLOG ((LOG_ERR, "failed to add user %s to %s", name, spw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, log_get_progname(),
|
||||
"adding user to /etc/shadow",
|
||||
audit_logger (AUDIT_USER_MGMT, log_get_progname(),
|
||||
"adding-shadow-user",
|
||||
name, AUDIT_NO_ID,
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
@@ -104,7 +104,7 @@ void cleanup_unlock_passwd (MAYBE_UNUSED void *arg)
|
||||
log_get_progname(), pw_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking passwd file",
|
||||
audit_logger_message ("unlocking-passwd",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
@@ -123,7 +123,7 @@ void cleanup_unlock_shadow (MAYBE_UNUSED void *arg)
|
||||
log_get_progname(), spw_dbname ());
|
||||
SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger_message ("unlocking shadow file",
|
||||
audit_logger_message ("unlocking-shadow",
|
||||
SHADOW_AUDIT_FAILURE);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -35,8 +35,10 @@
|
||||
#include "shadowlog_internal.h"
|
||||
#include "sssd.h"
|
||||
#include "string/memset/memzero.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
@@ -74,17 +76,10 @@ int lrename (const char *old, const char *new)
|
||||
{
|
||||
int res;
|
||||
char *r = NULL;
|
||||
|
||||
#ifndef __GLIBC__
|
||||
char resolved_path[PATH_MAX];
|
||||
#endif /* !__GLIBC__ */
|
||||
struct stat sb;
|
||||
|
||||
if (lstat (new, &sb) == 0 && S_ISLNK (sb.st_mode)) {
|
||||
#ifdef __GLIBC__ /* now a POSIX.1-2008 feature */
|
||||
r = realpath (new, NULL);
|
||||
#else /* !__GLIBC__ */
|
||||
r = realpath (new, resolved_path);
|
||||
#endif /* !__GLIBC__ */
|
||||
if (NULL == r) {
|
||||
perror ("realpath in lrename()");
|
||||
} else {
|
||||
@@ -94,9 +89,7 @@ int lrename (const char *old, const char *new)
|
||||
|
||||
res = rename (old, new);
|
||||
|
||||
#ifdef __GLIBC__
|
||||
free (r);
|
||||
#endif /* __GLIBC__ */
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -369,9 +362,12 @@ int commonio_lock_nowait (struct commonio_db *db, bool log)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (asprintf(&file, "%s.%ju", db->filename, (uintmax_t) getpid()) == -1)
|
||||
file = aprintf("%s.%ju", db->filename, (uintmax_t) getpid());
|
||||
if (file == NULL)
|
||||
goto cleanup_ENOMEM;
|
||||
if (asprintf(&lock, "%s.lock", db->filename) == -1)
|
||||
|
||||
lock = aprintf("%s.lock", db->filename);
|
||||
if (lock == NULL)
|
||||
goto cleanup_ENOMEM;
|
||||
|
||||
if (do_lock_file (file, lock, log) != 0) {
|
||||
@@ -524,7 +520,7 @@ static void add_one_entry (struct commonio_db *db,
|
||||
|
||||
static bool name_is_nis (const char *name)
|
||||
{
|
||||
return (('+' == name[0]) || ('-' == name[0]));
|
||||
return strprefix(name, "+") || strprefix(name, "-");
|
||||
}
|
||||
|
||||
|
||||
@@ -891,7 +887,7 @@ static int write_all (const struct commonio_db *db)
|
||||
|
||||
int commonio_close (struct commonio_db *db)
|
||||
{
|
||||
int errors = 0;
|
||||
bool errors = false;
|
||||
char buf[1024];
|
||||
struct stat sb;
|
||||
|
||||
@@ -932,25 +928,25 @@ int commonio_close (struct commonio_db *db)
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors++;
|
||||
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++;
|
||||
errors = true;
|
||||
}
|
||||
#endif
|
||||
if (errors != 0)
|
||||
if (errors)
|
||||
goto fail;
|
||||
} else {
|
||||
/*
|
||||
@@ -966,7 +962,7 @@ int commonio_close (struct commonio_db *db)
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
if (set_selinux_file_context (db->filename, S_IFREG) != 0) {
|
||||
errors++;
|
||||
errors = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -976,24 +972,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;
|
||||
}
|
||||
@@ -1011,11 +1007,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 (
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strcpy/strtcpy.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
@@ -103,9 +104,7 @@ is_listed(const char *cfgin, const char *tty, bool def)
|
||||
|
||||
bool console (const char *tty)
|
||||
{
|
||||
if (strncmp (tty, "/dev/", 5) == 0) {
|
||||
tty += 5;
|
||||
}
|
||||
tty = strprefix(tty, "/dev/") ?: tty;
|
||||
|
||||
return is_listed ("CONSOLE", tty, true);
|
||||
}
|
||||
|
||||
@@ -38,8 +38,10 @@
|
||||
#include <attr/libattr.h>
|
||||
#endif /* WITH_ATTR */
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
|
||||
|
||||
static /*@null@*/const char *src_orig;
|
||||
@@ -232,7 +234,7 @@ static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, c
|
||||
lp->ln_dev = sb->st_dev;
|
||||
lp->ln_ino = sb->st_ino;
|
||||
lp->ln_count = sb->st_nlink;
|
||||
xasprintf(&lp->ln_name, "%s%s", dst_orig, name + strlen(src_orig));
|
||||
lp->ln_name = xaprintf("%s%s", dst_orig, name + strlen(src_orig));
|
||||
lp->ln_next = links;
|
||||
links = lp;
|
||||
|
||||
@@ -321,13 +323,13 @@ static int copy_tree_impl (const struct path_info *src, const struct path_info *
|
||||
continue;
|
||||
}
|
||||
|
||||
if (asprintf(&src_name, "%s/%s", src->full_path, ent->d_name) == -1)
|
||||
{
|
||||
src_name = aprintf("%s/%s", src->full_path, ent->d_name);
|
||||
if (src_name == NULL) {
|
||||
err = -1;
|
||||
continue;
|
||||
}
|
||||
if (asprintf(&dst_name, "%s/%s", dst->full_path, ent->d_name) == -1)
|
||||
{
|
||||
dst_name = aprintf("%s/%s", dst->full_path, ent->d_name);
|
||||
if (dst_name == NULL) {
|
||||
err = -1;
|
||||
goto skip;
|
||||
}
|
||||
@@ -576,10 +578,10 @@ static int copy_symlink (const struct path_info *src, const struct path_info *ds
|
||||
* create a link to the corresponding entry in the dst_orig
|
||||
* directory.
|
||||
*/
|
||||
if (strncmp(oldlink, src_orig, strlen(src_orig)) == 0) {
|
||||
if (strprefix(oldlink, src_orig)) {
|
||||
char *dummy;
|
||||
|
||||
xasprintf(&dummy, "%s%s", dst_orig, oldlink + strlen(src_orig));
|
||||
dummy = xaprintf("%s%s", dst_orig, oldlink + strlen(src_orig));
|
||||
free(oldlink);
|
||||
oldlink = dummy;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
#include <stdint.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"
|
||||
|
||||
@@ -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,13 +50,8 @@
|
||||
|
||||
#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)
|
||||
#if defined(SHADOWGRP)
|
||||
#include "gshadow_.h"
|
||||
#endif
|
||||
|
||||
@@ -70,6 +65,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 4096
|
||||
#endif
|
||||
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 64
|
||||
#endif
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#ifndef LOG_WARN
|
||||
|
||||
@@ -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) {
|
||||
|
||||
11
lib/env.c
11
lib/env.c
@@ -22,7 +22,8 @@
|
||||
#include "defines.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strdup/xstrdup.h"
|
||||
|
||||
|
||||
@@ -77,7 +78,7 @@ void addenv (const char *string, /*@null@*/const char *value)
|
||||
size_t i, n;
|
||||
|
||||
if (NULL != value) {
|
||||
xasprintf(&newstring, "%s=%s", string, value);
|
||||
newstring = xaprintf("%s=%s", string, value);
|
||||
} else {
|
||||
newstring = xstrdup (string);
|
||||
}
|
||||
@@ -175,7 +176,7 @@ void set_env (int argc, char *const *argv)
|
||||
const char *const *p;
|
||||
|
||||
for (p = forbid; NULL != *p; p++) {
|
||||
if (strncmp (*argv, *p, strlen (*p)) == 0) {
|
||||
if (strprefix(*argv, *p)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +211,7 @@ void sanitize_env (void)
|
||||
|
||||
for (cur = envp; NULL != *cur; cur++) {
|
||||
for (bad = forbid; NULL != *bad; bad++) {
|
||||
if (strncmp (*cur, *bad, strlen (*bad)) == 0) {
|
||||
if (strprefix(*cur, *bad)) {
|
||||
for (move = cur; NULL != *move; move++) {
|
||||
*move = *(move + 1);
|
||||
}
|
||||
@@ -222,7 +223,7 @@ void sanitize_env (void)
|
||||
|
||||
for (cur = envp; NULL != *cur; cur++) {
|
||||
for (bad = noslash; NULL != *bad; bad++) {
|
||||
if (strncmp (*cur, *bad, strlen (*bad)) != 0) {
|
||||
if (!strprefix(*cur, *bad)) {
|
||||
continue;
|
||||
}
|
||||
if (strchr (*cur, '/') == NULL) {
|
||||
|
||||
54
lib/fields.c
54
lib/fields.c
@@ -9,57 +9,45 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
#include "fields.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/strchr/strrspn.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; !streq(cp, ""); cp++) {
|
||||
unsigned char c = *cp;
|
||||
if (!isprint (c)) {
|
||||
err = 1;
|
||||
}
|
||||
if (iscntrl (c)) {
|
||||
err = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
return 1; // !ASCII
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -93,7 +81,7 @@ change_field(char *buf, size_t maxsize, const char *prompt)
|
||||
* makes it possible to change the field to empty, by
|
||||
* entering a space. --marekm
|
||||
*/
|
||||
stpcpy(strrspn(newf, " \t"), "");
|
||||
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
|
||||
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
|
||||
@@ -9,11 +9,11 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "alloc/malloc.h"
|
||||
#include "attr.h"
|
||||
#include "fs/readlink/readlinknul.h"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
|
||||
#include "fs/readlink/readlinknul.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
extern inline ssize_t readlinknul(const char *restrict link, char *restrict buf,
|
||||
size_t size);
|
||||
ssize_t size);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@@ -18,35 +17,33 @@
|
||||
#include "sizeof.h"
|
||||
|
||||
|
||||
#define READLINKNUL(link, buf) readlinknul(link, buf, NITEMS(buf))
|
||||
#define READLINKNUL(link, buf) readlinknul(link, buf, countof(buf))
|
||||
|
||||
|
||||
ATTR_STRING(1)
|
||||
inline ssize_t readlinknul(const char *restrict link, char *restrict buf,
|
||||
size_t size);
|
||||
ssize_t size);
|
||||
|
||||
|
||||
// Similar to readlink(2), but terminate the string.
|
||||
inline ssize_t
|
||||
readlinknul(const char *restrict link, char *restrict buf, size_t size)
|
||||
readlinknul(const char *restrict link, char *restrict buf, ssize_t size)
|
||||
{
|
||||
size_t ulen;
|
||||
ssize_t slen;
|
||||
ssize_t len;
|
||||
|
||||
slen = readlink(link, buf, size);
|
||||
if (slen == -1)
|
||||
len = readlink(link, buf, size);
|
||||
if (len == -1)
|
||||
return -1;
|
||||
|
||||
ulen = slen;
|
||||
if (ulen == size) {
|
||||
if (len == size) {
|
||||
stpcpy(&buf[size-1], "");
|
||||
errno = E2BIG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
stpcpy(&buf[ulen], "");
|
||||
stpcpy(&buf[len], "");
|
||||
|
||||
return slen;
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "defines.h"
|
||||
#include "atoi/getnum.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
|
||||
|
||||
@@ -52,22 +52,21 @@ int get_pidfd_from_fd(const char *pidfdstr)
|
||||
int open_pidfd(const char *pidstr)
|
||||
{
|
||||
int proc_dir_fd;
|
||||
char proc_dir_name[32];
|
||||
char proc_dir_name[PATH_MAX];
|
||||
pid_t target;
|
||||
|
||||
if (get_pid(pidstr, &target) == -1)
|
||||
return -ENOENT;
|
||||
|
||||
/* max string length is 6 + 10 + 1 + 1 = 18, allocate 32 bytes */
|
||||
if (SNPRINTF(proc_dir_name, "/proc/%u/", target) == -1) {
|
||||
fprintf(stderr, "snprintf of proc path failed for %u: %s\n",
|
||||
if (SNPRINTF(proc_dir_name, "/proc/%d/", target) == -1) {
|
||||
fprintf(stderr, "snprintf of proc path failed for %d: %s\n",
|
||||
target, strerror(errno));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
|
||||
if (proc_dir_fd < 0) {
|
||||
fprintf(stderr, _("Could not open proc directory for target %u: %s\n"),
|
||||
fprintf(stderr, _("Could not open proc directory for target %d: %s\n"),
|
||||
target, strerror(errno));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
2536
lib/getdate.c
2536
lib/getdate.c
File diff suppressed because it is too large
Load Diff
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _GETDATE_H_
|
||||
#define _GETDATE_H_
|
||||
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
|
||||
time_t get_date (const char *p, /*@null@*/const time_t *now);
|
||||
#endif
|
||||
950
lib/getdate.y
950
lib/getdate.y
@@ -1,950 +0,0 @@
|
||||
%{
|
||||
/*
|
||||
** Originally written by Steven M. Bellovin <smb@research.att.com> while
|
||||
** at the University of North Carolina at Chapel Hill. Later tweaked by
|
||||
** a couple of people on Usenet. Completely overhauled by Rich $alz
|
||||
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
|
||||
**
|
||||
** This grammar has 13 shift/reduce conflicts.
|
||||
**
|
||||
** This code is in the public domain and has no copyright.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
/* Since the code of getdate.y is not included in the Emacs executable
|
||||
itself, there is no need to #define static in this file. Even if
|
||||
the code were included in the Emacs executable, it probably
|
||||
wouldn't do any harm to #undef it here; this will only cause
|
||||
problems if we try to write to a static variable, which I don't
|
||||
think this code needs to do. */
|
||||
#ifdef emacs
|
||||
# undef static
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "attr.h"
|
||||
#include "getdate.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
|
||||
|
||||
/* Some old versions of bison generate parsers that use bcopy.
|
||||
That loses on systems that don't provide the function, so we have
|
||||
to redefine it here. */
|
||||
#if !defined (HAVE_BCOPY) && !defined (bcopy)
|
||||
# define bcopy(from, to, len) memcpy ((to), (from), (len))
|
||||
#endif
|
||||
|
||||
/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
|
||||
as well as gratuitously global symbol names, so we can have multiple
|
||||
yacc generated parsers in the same program. Note that these are only
|
||||
the variables produced by yacc. If other parser generators (bison,
|
||||
byacc, etc) produce additional global names that conflict at link time,
|
||||
then those parser generators need to be fixed instead of adding those
|
||||
names to this list. */
|
||||
|
||||
#define yymaxdepth gd_maxdepth
|
||||
#define yyparse gd_parse
|
||||
#define yylex gd_lex
|
||||
#define yyerror gd_error
|
||||
#define yylval gd_lval
|
||||
#define yychar gd_char
|
||||
#define yydebug gd_debug
|
||||
#define yypact gd_pact
|
||||
#define yyr1 gd_r1
|
||||
#define yyr2 gd_r2
|
||||
#define yydef gd_def
|
||||
#define yychk gd_chk
|
||||
#define yypgo gd_pgo
|
||||
#define yyact gd_act
|
||||
#define yyexca gd_exca
|
||||
#define yyerrflag gd_errflag
|
||||
#define yynerrs gd_nerrs
|
||||
#define yyps gd_ps
|
||||
#define yypv gd_pv
|
||||
#define yys gd_s
|
||||
#define yy_yys gd_yys
|
||||
#define yystate gd_state
|
||||
#define yytmp gd_tmp
|
||||
#define yyv gd_v
|
||||
#define yy_yyv gd_yyv
|
||||
#define yyval gd_val
|
||||
#define yylloc gd_lloc
|
||||
#define yyreds gd_reds /* With YYDEBUG defined */
|
||||
#define yytoks gd_toks /* With YYDEBUG defined */
|
||||
#define yylhs gd_yylhs
|
||||
#define yylen gd_yylen
|
||||
#define yydefred gd_yydefred
|
||||
#define yydgoto gd_yydgoto
|
||||
#define yysindex gd_yysindex
|
||||
#define yyrindex gd_yyrindex
|
||||
#define yygindex gd_yygindex
|
||||
#define yytable gd_yytable
|
||||
#define yycheck gd_yycheck
|
||||
|
||||
static int yylex (void);
|
||||
static int yyerror (const char *s);
|
||||
|
||||
#define EPOCH 1970
|
||||
#define HOUR(x) ((x) * 60)
|
||||
|
||||
#define MAX_BUFF_LEN 128 /* size of buffer to read the date into */
|
||||
|
||||
/*
|
||||
** An entry in the lexical lookup table.
|
||||
*/
|
||||
typedef struct _TABLE {
|
||||
const char *name;
|
||||
int type;
|
||||
int value;
|
||||
} TABLE;
|
||||
|
||||
|
||||
/*
|
||||
** Meridian: am, pm, or 24-hour style.
|
||||
*/
|
||||
typedef enum _MERIDIAN {
|
||||
MERam, MERpm, MER24
|
||||
} MERIDIAN;
|
||||
|
||||
|
||||
/*
|
||||
** Global variables. We could get rid of most of these by using a good
|
||||
** union as the yacc stack. (This routine was originally written before
|
||||
** yacc had the %union construct.) Maybe someday; right now we only use
|
||||
** the %union very rarely.
|
||||
*/
|
||||
static const char *yyInput;
|
||||
static int yyDayOrdinal;
|
||||
static int yyDayNumber;
|
||||
static int yyHaveDate;
|
||||
static int yyHaveDay;
|
||||
static int yyHaveRel;
|
||||
static int yyHaveTime;
|
||||
static int yyHaveZone;
|
||||
static int yyTimezone;
|
||||
static int yyDay;
|
||||
static int yyHour;
|
||||
static int yyMinutes;
|
||||
static int yyMonth;
|
||||
static int yySeconds;
|
||||
static int yyYear;
|
||||
static MERIDIAN yyMeridian;
|
||||
static int yyRelDay;
|
||||
static int yyRelHour;
|
||||
static int yyRelMinutes;
|
||||
static int yyRelMonth;
|
||||
static int yyRelSeconds;
|
||||
static int yyRelYear;
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
int Number;
|
||||
enum _MERIDIAN Meridian;
|
||||
}
|
||||
|
||||
%token tAGO tDAY tDAY_UNIT tDAYZONE tDST tHOUR_UNIT tID
|
||||
%token tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
|
||||
%token tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
|
||||
|
||||
%type <Number> tDAY tDAY_UNIT tDAYZONE tHOUR_UNIT tMINUTE_UNIT
|
||||
%type <Number> tMONTH tMONTH_UNIT
|
||||
%type <Number> tSEC_UNIT tSNUMBER tUNUMBER tYEAR_UNIT tZONE
|
||||
%type <Meridian> tMERIDIAN o_merid
|
||||
|
||||
%%
|
||||
|
||||
spec : /* NULL */
|
||||
| spec item
|
||||
;
|
||||
|
||||
item : time {
|
||||
yyHaveTime++;
|
||||
}
|
||||
| zone {
|
||||
yyHaveZone++;
|
||||
}
|
||||
| date {
|
||||
yyHaveDate++;
|
||||
}
|
||||
| day {
|
||||
yyHaveDay++;
|
||||
}
|
||||
| rel {
|
||||
yyHaveRel++;
|
||||
}
|
||||
| number
|
||||
;
|
||||
|
||||
time : tUNUMBER tMERIDIAN {
|
||||
yyHour = $1;
|
||||
yyMinutes = 0;
|
||||
yySeconds = 0;
|
||||
yyMeridian = $2;
|
||||
}
|
||||
| tUNUMBER ':' tUNUMBER o_merid {
|
||||
yyHour = $1;
|
||||
yyMinutes = $3;
|
||||
yySeconds = 0;
|
||||
yyMeridian = $4;
|
||||
}
|
||||
| tUNUMBER ':' tUNUMBER tSNUMBER {
|
||||
yyHour = $1;
|
||||
yyMinutes = $3;
|
||||
yyMeridian = MER24;
|
||||
yyHaveZone++;
|
||||
yyTimezone = ($4 < 0
|
||||
? -$4 % 100 + (-$4 / 100) * 60
|
||||
: - ($4 % 100 + ($4 / 100) * 60));
|
||||
}
|
||||
| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
|
||||
yyHour = $1;
|
||||
yyMinutes = $3;
|
||||
yySeconds = $5;
|
||||
yyMeridian = $6;
|
||||
}
|
||||
| tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER {
|
||||
yyHour = $1;
|
||||
yyMinutes = $3;
|
||||
yySeconds = $5;
|
||||
yyMeridian = MER24;
|
||||
yyHaveZone++;
|
||||
yyTimezone = ($6 < 0
|
||||
? -$6 % 100 + (-$6 / 100) * 60
|
||||
: - ($6 % 100 + ($6 / 100) * 60));
|
||||
}
|
||||
;
|
||||
|
||||
zone : tZONE {
|
||||
yyTimezone = $1;
|
||||
}
|
||||
| tDAYZONE {
|
||||
yyTimezone = $1 - 60;
|
||||
}
|
||||
|
|
||||
tZONE tDST {
|
||||
yyTimezone = $1 - 60;
|
||||
}
|
||||
;
|
||||
|
||||
day : tDAY {
|
||||
yyDayOrdinal = 1;
|
||||
yyDayNumber = $1;
|
||||
}
|
||||
| tDAY ',' {
|
||||
yyDayOrdinal = 1;
|
||||
yyDayNumber = $1;
|
||||
}
|
||||
| tUNUMBER tDAY {
|
||||
yyDayOrdinal = $1;
|
||||
yyDayNumber = $2;
|
||||
}
|
||||
;
|
||||
|
||||
date : tUNUMBER '/' tUNUMBER {
|
||||
yyMonth = $1;
|
||||
yyDay = $3;
|
||||
}
|
||||
| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
|
||||
/* Interpret as YYYY/MM/DD if $1 >= 1000, otherwise as MM/DD/YY.
|
||||
The goal in recognizing YYYY/MM/DD is solely to support legacy
|
||||
machine-generated dates like those in an RCS log listing. If
|
||||
you want portability, use the ISO 8601 format. */
|
||||
if ($1 >= 1000)
|
||||
{
|
||||
yyYear = $1;
|
||||
yyMonth = $3;
|
||||
yyDay = $5;
|
||||
}
|
||||
else
|
||||
{
|
||||
yyMonth = $1;
|
||||
yyDay = $3;
|
||||
yyYear = $5;
|
||||
}
|
||||
}
|
||||
| tUNUMBER tSNUMBER tSNUMBER {
|
||||
/* ISO 8601 format. yyyy-mm-dd. */
|
||||
yyYear = $1;
|
||||
yyMonth = -$2;
|
||||
yyDay = -$3;
|
||||
}
|
||||
| tUNUMBER tMONTH tSNUMBER {
|
||||
/* e.g. 17-JUN-1992. */
|
||||
yyDay = $1;
|
||||
yyMonth = $2;
|
||||
yyYear = -$3;
|
||||
}
|
||||
| tMONTH tUNUMBER {
|
||||
yyMonth = $1;
|
||||
yyDay = $2;
|
||||
}
|
||||
| tMONTH tUNUMBER ',' tUNUMBER {
|
||||
yyMonth = $1;
|
||||
yyDay = $2;
|
||||
yyYear = $4;
|
||||
}
|
||||
| tUNUMBER tMONTH {
|
||||
yyMonth = $2;
|
||||
yyDay = $1;
|
||||
}
|
||||
| tUNUMBER tMONTH tUNUMBER {
|
||||
yyMonth = $2;
|
||||
yyDay = $1;
|
||||
yyYear = $3;
|
||||
}
|
||||
;
|
||||
|
||||
rel : relunit tAGO {
|
||||
yyRelSeconds = -yyRelSeconds;
|
||||
yyRelMinutes = -yyRelMinutes;
|
||||
yyRelHour = -yyRelHour;
|
||||
yyRelDay = -yyRelDay;
|
||||
yyRelMonth = -yyRelMonth;
|
||||
yyRelYear = -yyRelYear;
|
||||
}
|
||||
| relunit
|
||||
;
|
||||
|
||||
relunit : tUNUMBER tYEAR_UNIT {
|
||||
yyRelYear += $1 * $2;
|
||||
}
|
||||
| tSNUMBER tYEAR_UNIT {
|
||||
yyRelYear += $1 * $2;
|
||||
}
|
||||
| tYEAR_UNIT {
|
||||
yyRelYear += $1;
|
||||
}
|
||||
| tUNUMBER tMONTH_UNIT {
|
||||
yyRelMonth += $1 * $2;
|
||||
}
|
||||
| tSNUMBER tMONTH_UNIT {
|
||||
yyRelMonth += $1 * $2;
|
||||
}
|
||||
| tMONTH_UNIT {
|
||||
yyRelMonth += $1;
|
||||
}
|
||||
| tUNUMBER tDAY_UNIT {
|
||||
yyRelDay += $1 * $2;
|
||||
}
|
||||
| tSNUMBER tDAY_UNIT {
|
||||
yyRelDay += $1 * $2;
|
||||
}
|
||||
| tDAY_UNIT {
|
||||
yyRelDay += $1;
|
||||
}
|
||||
| tUNUMBER tHOUR_UNIT {
|
||||
yyRelHour += $1 * $2;
|
||||
}
|
||||
| tSNUMBER tHOUR_UNIT {
|
||||
yyRelHour += $1 * $2;
|
||||
}
|
||||
| tHOUR_UNIT {
|
||||
yyRelHour += $1;
|
||||
}
|
||||
| tUNUMBER tMINUTE_UNIT {
|
||||
yyRelMinutes += $1 * $2;
|
||||
}
|
||||
| tSNUMBER tMINUTE_UNIT {
|
||||
yyRelMinutes += $1 * $2;
|
||||
}
|
||||
| tMINUTE_UNIT {
|
||||
yyRelMinutes += $1;
|
||||
}
|
||||
| tUNUMBER tSEC_UNIT {
|
||||
yyRelSeconds += $1 * $2;
|
||||
}
|
||||
| tSNUMBER tSEC_UNIT {
|
||||
yyRelSeconds += $1 * $2;
|
||||
}
|
||||
| tSEC_UNIT {
|
||||
yyRelSeconds += $1;
|
||||
}
|
||||
;
|
||||
|
||||
number : tUNUMBER
|
||||
{
|
||||
if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0))
|
||||
yyYear = $1;
|
||||
else
|
||||
{
|
||||
if ($1>10000)
|
||||
{
|
||||
yyHaveDate++;
|
||||
yyDay= ($1)%100;
|
||||
yyMonth= ($1/100)%100;
|
||||
yyYear = $1/10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
yyHaveTime++;
|
||||
if ($1 < 100)
|
||||
{
|
||||
yyHour = $1;
|
||||
yyMinutes = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yyHour = $1 / 100;
|
||||
yyMinutes = $1 % 100;
|
||||
}
|
||||
yySeconds = 0;
|
||||
yyMeridian = MER24;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
o_merid : /* NULL */
|
||||
{
|
||||
$$ = MER24;
|
||||
}
|
||||
| tMERIDIAN
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
/* Month and day table. */
|
||||
static TABLE const MonthDayTable[] = {
|
||||
{ "january", tMONTH, 1 },
|
||||
{ "february", tMONTH, 2 },
|
||||
{ "march", tMONTH, 3 },
|
||||
{ "april", tMONTH, 4 },
|
||||
{ "may", tMONTH, 5 },
|
||||
{ "june", tMONTH, 6 },
|
||||
{ "july", tMONTH, 7 },
|
||||
{ "august", tMONTH, 8 },
|
||||
{ "september", tMONTH, 9 },
|
||||
{ "sept", tMONTH, 9 },
|
||||
{ "october", tMONTH, 10 },
|
||||
{ "november", tMONTH, 11 },
|
||||
{ "december", tMONTH, 12 },
|
||||
{ "sunday", tDAY, 0 },
|
||||
{ "monday", tDAY, 1 },
|
||||
{ "tuesday", tDAY, 2 },
|
||||
{ "tues", tDAY, 2 },
|
||||
{ "wednesday", tDAY, 3 },
|
||||
{ "wednes", tDAY, 3 },
|
||||
{ "thursday", tDAY, 4 },
|
||||
{ "thur", tDAY, 4 },
|
||||
{ "thurs", tDAY, 4 },
|
||||
{ "friday", tDAY, 5 },
|
||||
{ "saturday", tDAY, 6 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/* Time units table. */
|
||||
static TABLE const UnitsTable[] = {
|
||||
{ "year", tYEAR_UNIT, 1 },
|
||||
{ "month", tMONTH_UNIT, 1 },
|
||||
{ "fortnight", tDAY_UNIT, 14 },
|
||||
{ "week", tDAY_UNIT, 7 },
|
||||
{ "day", tDAY_UNIT, 1 },
|
||||
{ "hour", tHOUR_UNIT, 1 },
|
||||
{ "minute", tMINUTE_UNIT, 1 },
|
||||
{ "min", tMINUTE_UNIT, 1 },
|
||||
{ "second", tSEC_UNIT, 1 },
|
||||
{ "sec", tSEC_UNIT, 1 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/* Assorted relative-time words. */
|
||||
static TABLE const OtherTable[] = {
|
||||
{ "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
|
||||
{ "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
|
||||
{ "today", tMINUTE_UNIT, 0 },
|
||||
{ "now", tMINUTE_UNIT, 0 },
|
||||
{ "last", tUNUMBER, -1 },
|
||||
{ "this", tMINUTE_UNIT, 0 },
|
||||
{ "next", tUNUMBER, 2 },
|
||||
{ "first", tUNUMBER, 1 },
|
||||
/* { "second", tUNUMBER, 2 }, */
|
||||
{ "third", tUNUMBER, 3 },
|
||||
{ "fourth", tUNUMBER, 4 },
|
||||
{ "fifth", tUNUMBER, 5 },
|
||||
{ "sixth", tUNUMBER, 6 },
|
||||
{ "seventh", tUNUMBER, 7 },
|
||||
{ "eighth", tUNUMBER, 8 },
|
||||
{ "ninth", tUNUMBER, 9 },
|
||||
{ "tenth", tUNUMBER, 10 },
|
||||
{ "eleventh", tUNUMBER, 11 },
|
||||
{ "twelfth", tUNUMBER, 12 },
|
||||
{ "ago", tAGO, 1 },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/* The timezone table. */
|
||||
static TABLE const TimezoneTable[] = {
|
||||
{ "gmt", tZONE, HOUR ( 0) }, /* Greenwich Mean */
|
||||
{ "ut", tZONE, HOUR ( 0) }, /* Universal (Coordinated) */
|
||||
{ "utc", tZONE, HOUR ( 0) },
|
||||
{ "wet", tZONE, HOUR ( 0) }, /* Western European */
|
||||
{ "bst", tDAYZONE, HOUR ( 0) }, /* British Summer */
|
||||
{ "wat", tZONE, HOUR ( 1) }, /* West Africa */
|
||||
{ "at", tZONE, HOUR ( 2) }, /* Azores */
|
||||
{ "ast", tZONE, HOUR ( 4) }, /* Atlantic Standard */
|
||||
{ "adt", tDAYZONE, HOUR ( 4) }, /* Atlantic Daylight */
|
||||
{ "est", tZONE, HOUR ( 5) }, /* Eastern Standard */
|
||||
{ "edt", tDAYZONE, HOUR ( 5) }, /* Eastern Daylight */
|
||||
{ "cst", tZONE, HOUR ( 6) }, /* Central Standard */
|
||||
{ "cdt", tDAYZONE, HOUR ( 6) }, /* Central Daylight */
|
||||
{ "mst", tZONE, HOUR ( 7) }, /* Mountain Standard */
|
||||
{ "mdt", tDAYZONE, HOUR ( 7) }, /* Mountain Daylight */
|
||||
{ "pst", tZONE, HOUR ( 8) }, /* Pacific Standard */
|
||||
{ "pdt", tDAYZONE, HOUR ( 8) }, /* Pacific Daylight */
|
||||
{ "yst", tZONE, HOUR ( 9) }, /* Yukon Standard */
|
||||
{ "ydt", tDAYZONE, HOUR ( 9) }, /* Yukon Daylight */
|
||||
{ "hst", tZONE, HOUR (10) }, /* Hawaii Standard */
|
||||
{ "hdt", tDAYZONE, HOUR (10) }, /* Hawaii Daylight */
|
||||
{ "cat", tZONE, HOUR (10) }, /* Central Alaska */
|
||||
{ "ahst", tZONE, HOUR (10) }, /* Alaska-Hawaii Standard */
|
||||
{ "nt", tZONE, HOUR (11) }, /* Nome */
|
||||
{ "idlw", tZONE, HOUR (12) }, /* International Date Line West */
|
||||
{ "cet", tZONE, -HOUR (1) }, /* Central European */
|
||||
{ "met", tZONE, -HOUR (1) }, /* Middle European */
|
||||
{ "mewt", tZONE, -HOUR (1) }, /* Middle European Winter */
|
||||
{ "mest", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
|
||||
{ "mesz", tDAYZONE, -HOUR (1) }, /* Middle European Summer */
|
||||
{ "swt", tZONE, -HOUR (1) }, /* Swedish Winter */
|
||||
{ "sst", tDAYZONE, -HOUR (1) }, /* Swedish Summer */
|
||||
{ "fwt", tZONE, -HOUR (1) }, /* French Winter */
|
||||
{ "fst", tDAYZONE, -HOUR (1) }, /* French Summer */
|
||||
{ "eet", tZONE, -HOUR (2) }, /* Eastern Europe, USSR Zone 1 */
|
||||
{ "bt", tZONE, -HOUR (3) }, /* Baghdad, USSR Zone 2 */
|
||||
{ "zp4", tZONE, -HOUR (4) }, /* USSR Zone 3 */
|
||||
{ "zp5", tZONE, -HOUR (5) }, /* USSR Zone 4 */
|
||||
{ "zp6", tZONE, -HOUR (6) }, /* USSR Zone 5 */
|
||||
{ "wast", tZONE, -HOUR (7) }, /* West Australian Standard */
|
||||
{ "wadt", tDAYZONE, -HOUR (7) }, /* West Australian Daylight */
|
||||
{ "cct", tZONE, -HOUR (8) }, /* China Coast, USSR Zone 7 */
|
||||
{ "jst", tZONE, -HOUR (9) }, /* Japan Standard, USSR Zone 8 */
|
||||
{ "east", tZONE, -HOUR (10) }, /* Eastern Australian Standard */
|
||||
{ "eadt", tDAYZONE, -HOUR (10) }, /* Eastern Australian Daylight */
|
||||
{ "gst", tZONE, -HOUR (10) }, /* Guam Standard, USSR Zone 9 */
|
||||
{ "nzt", tZONE, -HOUR (12) }, /* New Zealand */
|
||||
{ "nzst", tZONE, -HOUR (12) }, /* New Zealand Standard */
|
||||
{ "nzdt", tDAYZONE, -HOUR (12) }, /* New Zealand Daylight */
|
||||
{ "idle", tZONE, -HOUR (12) }, /* International Date Line East */
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
/* Military timezone table. */
|
||||
static TABLE const MilitaryTable[] = {
|
||||
{ "a", tZONE, HOUR ( 1) },
|
||||
{ "b", tZONE, HOUR ( 2) },
|
||||
{ "c", tZONE, HOUR ( 3) },
|
||||
{ "d", tZONE, HOUR ( 4) },
|
||||
{ "e", tZONE, HOUR ( 5) },
|
||||
{ "f", tZONE, HOUR ( 6) },
|
||||
{ "g", tZONE, HOUR ( 7) },
|
||||
{ "h", tZONE, HOUR ( 8) },
|
||||
{ "i", tZONE, HOUR ( 9) },
|
||||
{ "k", tZONE, HOUR ( 10) },
|
||||
{ "l", tZONE, HOUR ( 11) },
|
||||
{ "m", tZONE, HOUR ( 12) },
|
||||
{ "n", tZONE, HOUR (- 1) },
|
||||
{ "o", tZONE, HOUR (- 2) },
|
||||
{ "p", tZONE, HOUR (- 3) },
|
||||
{ "q", tZONE, HOUR (- 4) },
|
||||
{ "r", tZONE, HOUR (- 5) },
|
||||
{ "s", tZONE, HOUR (- 6) },
|
||||
{ "t", tZONE, HOUR (- 7) },
|
||||
{ "u", tZONE, HOUR (- 8) },
|
||||
{ "v", tZONE, HOUR (- 9) },
|
||||
{ "w", tZONE, HOUR (-10) },
|
||||
{ "x", tZONE, HOUR (-11) },
|
||||
{ "y", tZONE, HOUR (-12) },
|
||||
{ "z", tZONE, HOUR ( 0) },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static int yyerror (MAYBE_UNUSED const char *s)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ToHour (int Hours, MERIDIAN Meridian)
|
||||
{
|
||||
switch (Meridian)
|
||||
{
|
||||
case MER24:
|
||||
if (Hours < 0 || Hours > 23)
|
||||
return -1;
|
||||
return Hours;
|
||||
case MERam:
|
||||
if (Hours < 1 || Hours > 12)
|
||||
return -1;
|
||||
if (Hours == 12)
|
||||
Hours = 0;
|
||||
return Hours;
|
||||
case MERpm:
|
||||
if (Hours < 1 || Hours > 12)
|
||||
return -1;
|
||||
if (Hours == 12)
|
||||
Hours = 0;
|
||||
return Hours + 12;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int ToYear (int Year)
|
||||
{
|
||||
if (Year < 0)
|
||||
Year = -Year;
|
||||
|
||||
/* XPG4 suggests that years 00-68 map to 2000-2068, and
|
||||
years 69-99 map to 1969-1999. */
|
||||
if (Year < 69)
|
||||
Year += 2000;
|
||||
else if (Year < 100)
|
||||
Year += 1900;
|
||||
|
||||
return Year;
|
||||
}
|
||||
|
||||
static int LookupWord (char *buff)
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register const TABLE *tp;
|
||||
int i;
|
||||
bool abbrev;
|
||||
|
||||
/* Make it lowercase. */
|
||||
for (p = buff; !streq(p, ""); p++)
|
||||
if (isupper (*p))
|
||||
*p = tolower (*p);
|
||||
|
||||
if (streq(buff, "am") || streq(buff, "a.m."))
|
||||
{
|
||||
yylval.Meridian = MERam;
|
||||
return tMERIDIAN;
|
||||
}
|
||||
if (streq(buff, "pm") || streq(buff, "p.m."))
|
||||
{
|
||||
yylval.Meridian = MERpm;
|
||||
return tMERIDIAN;
|
||||
}
|
||||
|
||||
/* See if we have an abbreviation for a month. */
|
||||
if (strlen (buff) == 3)
|
||||
abbrev = true;
|
||||
else if (strlen (buff) == 4 && buff[3] == '.')
|
||||
{
|
||||
abbrev = true;
|
||||
stpcpy(&buff[3], "");
|
||||
}
|
||||
else
|
||||
abbrev = false;
|
||||
|
||||
for (tp = MonthDayTable; tp->name; tp++)
|
||||
{
|
||||
if (abbrev)
|
||||
{
|
||||
if (strncmp (buff, tp->name, 3) == 0)
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
}
|
||||
else if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
}
|
||||
|
||||
for (tp = TimezoneTable; tp->name; tp++)
|
||||
if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
|
||||
if (streq(buff, "dst"))
|
||||
return tDST;
|
||||
|
||||
for (tp = UnitsTable; tp->name; tp++)
|
||||
if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
|
||||
/* Strip off any plural and try the units table again. */
|
||||
i = strlen (buff) - 1;
|
||||
if (buff[i] == 's')
|
||||
{
|
||||
stpcpy(&buff[i], "");
|
||||
for (tp = UnitsTable; tp->name; tp++)
|
||||
if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
buff[i] = 's'; /* Put back for "this" in OtherTable. */
|
||||
}
|
||||
|
||||
for (tp = OtherTable; tp->name; tp++)
|
||||
if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
|
||||
/* Military timezones. */
|
||||
if (buff[1] == '\0' && isalpha (*buff))
|
||||
{
|
||||
for (tp = MilitaryTable; tp->name; tp++)
|
||||
if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
}
|
||||
|
||||
/* Drop out any periods and try the timezone table again. */
|
||||
for (i = 0, p = q = buff; !streq(q, ""); q++)
|
||||
if (*q != '.')
|
||||
*p++ = *q;
|
||||
else
|
||||
i++;
|
||||
stpcpy(p, "");
|
||||
if (0 != i)
|
||||
for (tp = TimezoneTable; NULL != tp->name; tp++)
|
||||
if (streq(buff, tp->name))
|
||||
{
|
||||
yylval.Number = tp->value;
|
||||
return tp->type;
|
||||
}
|
||||
|
||||
return tID;
|
||||
}
|
||||
|
||||
static int
|
||||
yylex (void)
|
||||
{
|
||||
register char c;
|
||||
register char *p;
|
||||
char buff[20];
|
||||
int Count;
|
||||
int sign;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
yyInput = stpspn(yyInput, " \t");
|
||||
|
||||
if (isdigit (c = *yyInput) || c == '-' || c == '+')
|
||||
{
|
||||
if (c == '-' || c == '+')
|
||||
{
|
||||
sign = c == '-' ? -1 : 1;
|
||||
if (!isdigit (*++yyInput))
|
||||
/* skip the '-' sign */
|
||||
continue;
|
||||
}
|
||||
else
|
||||
sign = 0;
|
||||
for (yylval.Number = 0; isdigit (c = *yyInput++);)
|
||||
yylval.Number = 10 * yylval.Number + c - '0';
|
||||
yyInput--;
|
||||
if (sign < 0)
|
||||
yylval.Number = -yylval.Number;
|
||||
return (0 != sign) ? tSNUMBER : tUNUMBER;
|
||||
}
|
||||
if (isalpha (c))
|
||||
{
|
||||
for (p = buff; (c = *yyInput++, isalpha (c)) || c == '.';)
|
||||
if (p < &buff[sizeof buff - 1])
|
||||
*p++ = c;
|
||||
stpcpy(p, "");
|
||||
yyInput--;
|
||||
return LookupWord (buff);
|
||||
}
|
||||
if (c != '(')
|
||||
return *yyInput++;
|
||||
Count = 0;
|
||||
do
|
||||
{
|
||||
c = *yyInput++;
|
||||
if (c == '\0')
|
||||
return c;
|
||||
if (c == '(')
|
||||
Count++;
|
||||
else if (c == ')')
|
||||
Count--;
|
||||
}
|
||||
while (Count > 0);
|
||||
}
|
||||
}
|
||||
|
||||
#define TM_YEAR_ORIGIN 1900
|
||||
|
||||
/* Yield A - B, measured in seconds. */
|
||||
static long difftm (struct tm *a, struct tm *b)
|
||||
{
|
||||
int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
|
||||
int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
|
||||
long days = (
|
||||
/* difference in day of year */
|
||||
a->tm_yday - b->tm_yday
|
||||
/* + intervening leap days */
|
||||
+ ((ay >> 2) - (by >> 2))
|
||||
- (ay / 100 - by / 100)
|
||||
+ ((ay / 100 >> 2) - (by / 100 >> 2))
|
||||
/* + difference in years * 365 */
|
||||
+ (long) (ay - by) * 365
|
||||
);
|
||||
return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
|
||||
+ (a->tm_min - b->tm_min))
|
||||
+ (a->tm_sec - b->tm_sec));
|
||||
}
|
||||
|
||||
time_t get_date (const char *p, const time_t *now)
|
||||
{
|
||||
struct tm tm, tm0, *tmp;
|
||||
time_t Start;
|
||||
|
||||
yyInput = p;
|
||||
Start = now ? *now : time(NULL);
|
||||
tmp = localtime (&Start);
|
||||
yyYear = tmp->tm_year + TM_YEAR_ORIGIN;
|
||||
yyMonth = tmp->tm_mon + 1;
|
||||
yyDay = tmp->tm_mday;
|
||||
yyHour = tmp->tm_hour;
|
||||
yyMinutes = tmp->tm_min;
|
||||
yySeconds = tmp->tm_sec;
|
||||
yyMeridian = MER24;
|
||||
yyRelSeconds = 0;
|
||||
yyRelMinutes = 0;
|
||||
yyRelHour = 0;
|
||||
yyRelDay = 0;
|
||||
yyRelMonth = 0;
|
||||
yyRelYear = 0;
|
||||
yyHaveDate = 0;
|
||||
yyHaveDay = 0;
|
||||
yyHaveRel = 0;
|
||||
yyHaveTime = 0;
|
||||
yyHaveZone = 0;
|
||||
|
||||
if (yyparse ()
|
||||
|| yyHaveTime > 1 || yyHaveZone > 1 || yyHaveDate > 1 || yyHaveDay > 1)
|
||||
return -1;
|
||||
|
||||
tm.tm_year = ToYear (yyYear) - TM_YEAR_ORIGIN + yyRelYear;
|
||||
tm.tm_mon = yyMonth - 1 + yyRelMonth;
|
||||
tm.tm_mday = yyDay + yyRelDay;
|
||||
if ((yyHaveTime != 0) ||
|
||||
( (yyHaveRel != 0) && (yyHaveDate == 0) && (yyHaveDay == 0) ))
|
||||
{
|
||||
tm.tm_hour = ToHour (yyHour, yyMeridian);
|
||||
if (tm.tm_hour < 0)
|
||||
return -1;
|
||||
tm.tm_min = yyMinutes;
|
||||
tm.tm_sec = yySeconds;
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
|
||||
}
|
||||
tm.tm_hour += yyRelHour;
|
||||
tm.tm_min += yyRelMinutes;
|
||||
tm.tm_sec += yyRelSeconds;
|
||||
tm.tm_isdst = -1;
|
||||
tm0 = tm;
|
||||
|
||||
Start = mktime (&tm);
|
||||
|
||||
if (Start == (time_t) -1)
|
||||
{
|
||||
|
||||
/* Guard against falsely reporting errors near the time_t boundaries
|
||||
when parsing times in other time zones. For example, if the min
|
||||
time_t value is 1970-01-01 00:00:00 UTC and we are 8 hours ahead
|
||||
of UTC, then the min localtime value is 1970-01-01 08:00:00; if
|
||||
we apply mktime to 1970-01-01 00:00:00 we will get an error, so
|
||||
we apply mktime to 1970-01-02 08:00:00 instead and adjust the time
|
||||
zone by 24 hours to compensate. This algorithm assumes that
|
||||
there is no DST transition within a day of the time_t boundaries. */
|
||||
if (yyHaveZone)
|
||||
{
|
||||
tm = tm0;
|
||||
if (tm.tm_year <= EPOCH - TM_YEAR_ORIGIN)
|
||||
{
|
||||
tm.tm_mday++;
|
||||
yyTimezone -= 24 * 60;
|
||||
}
|
||||
else
|
||||
{
|
||||
tm.tm_mday--;
|
||||
yyTimezone += 24 * 60;
|
||||
}
|
||||
Start = mktime (&tm);
|
||||
}
|
||||
|
||||
if (Start == (time_t) -1)
|
||||
return Start;
|
||||
}
|
||||
|
||||
if (yyHaveDay && !yyHaveDate)
|
||||
{
|
||||
tm.tm_mday += ((yyDayNumber - tm.tm_wday + 7) % 7
|
||||
+ 7 * (yyDayOrdinal - (0 < yyDayOrdinal)));
|
||||
Start = mktime (&tm);
|
||||
if (Start == (time_t) -1)
|
||||
return Start;
|
||||
}
|
||||
|
||||
if (yyHaveZone)
|
||||
{
|
||||
long delta = yyTimezone * 60L + difftm (&tm, gmtime (&Start));
|
||||
if ((Start + delta < Start) != (delta < 0))
|
||||
return -1; /* time_t overflow */
|
||||
Start += delta;
|
||||
}
|
||||
|
||||
return Start;
|
||||
}
|
||||
|
||||
#if defined (TEST)
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char buff[MAX_BUFF_LEN + 1];
|
||||
time_t d;
|
||||
|
||||
(void) printf ("Enter date, or blank line to exit.\n\t> ");
|
||||
(void) fflush (stdout);
|
||||
|
||||
buff[MAX_BUFF_LEN] = 0;
|
||||
while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
|
||||
{
|
||||
d = get_date(buff, NULL);
|
||||
if (d == -1)
|
||||
(void) printf ("Bad format - couldn't convert.\n");
|
||||
else
|
||||
(void) printf ("%s", ctime (&d));
|
||||
(void) printf ("\t> ");
|
||||
(void) fflush (stdout);
|
||||
}
|
||||
exit (0);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif /* defined (TEST) */
|
||||
29
lib/getdef.c
29
lib/getdef.c
@@ -24,15 +24,18 @@
|
||||
|
||||
#include "atoi/a2i/a2s.h"
|
||||
#include "atoi/a2i/a2u.h"
|
||||
#include "atoi/str2i/str2u.h"
|
||||
#include "atoi/str2i.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/strchr/strrspn.h"
|
||||
#include "sizeof.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
#include "string/strcmp/strcaseeq.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strspn/stpspn.h"
|
||||
#include "string/strspn/stprspn.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
@@ -75,12 +78,12 @@ struct itemdef {
|
||||
#define FOREIGNDEFS \
|
||||
{"ALWAYS_SET_PATH", NULL}, \
|
||||
{"ENV_ROOTPATH", NULL}, \
|
||||
{"LOGIN_ENV_SAFELIST", NULL}, \
|
||||
{"LOGIN_KEEP_USERNAME", NULL}, \
|
||||
{"LOGIN_PLAIN_PROMPT", NULL}, \
|
||||
{"MOTD_FIRSTONLY", NULL}, \
|
||||
|
||||
|
||||
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
|
||||
static struct itemdef def_table[] = {
|
||||
{"CHFN_RESTRICT", NULL},
|
||||
{"CONSOLE_GROUPS", NULL},
|
||||
@@ -226,7 +229,7 @@ bool getdef_bool (const char *item)
|
||||
return false;
|
||||
}
|
||||
|
||||
return (strcasecmp (d->value, "yes") == 0);
|
||||
return strcaseeq(d->value, "yes");
|
||||
}
|
||||
|
||||
|
||||
@@ -453,13 +456,9 @@ out:
|
||||
void setdef_config_file (const char* file)
|
||||
{
|
||||
#ifdef USE_ECONF
|
||||
char *cp;
|
||||
|
||||
xasprintf(&cp, "%s/%s", file, sysconfdir);
|
||||
sysconfdir = cp;
|
||||
sysconfdir = xaprintf("%s/%s", file, sysconfdir);
|
||||
#ifdef VENDORDIR
|
||||
xasprintf(&cp, "%s/%s", file, vendordir);
|
||||
vendordir = cp;
|
||||
vendordir = xaprintf("%s/%s", file, vendordir);
|
||||
#endif
|
||||
#else
|
||||
def_fname = file;
|
||||
@@ -561,13 +560,13 @@ static void def_load (void)
|
||||
/*
|
||||
* Trim trailing whitespace.
|
||||
*/
|
||||
stpcpy(strrspn(buf, " \t\n"), "");
|
||||
stpcpy(stprspn(buf, " \t\n"), "");
|
||||
|
||||
/*
|
||||
* Break the line into two fields.
|
||||
*/
|
||||
name = stpspn(buf, " \t"); /* first nonwhite */
|
||||
if (streq(name, "") || *name == '#')
|
||||
if (streq(name, "") || strprefix(name, "#"))
|
||||
continue; /* comment or empty */
|
||||
|
||||
s = stpsep(name, " \t"); /* next field */
|
||||
@@ -608,7 +607,7 @@ int main (int argc, char **argv)
|
||||
|
||||
def_load ();
|
||||
|
||||
for (i = 0; i < NUMDEFS; ++i) {
|
||||
for (i = 0; i < countof(def_table); ++i) {
|
||||
d = def_find (def_table[i].name, NULL);
|
||||
if (NULL == d) {
|
||||
printf ("error - lookup '%s' failed\n",
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
#include "alloc/malloc.h"
|
||||
#include "commonio.h"
|
||||
#include "defines.h"
|
||||
#include "fields.h"
|
||||
#include "getdef.h"
|
||||
#include "groupio.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
|
||||
|
||||
@@ -324,7 +326,8 @@ static /*@null@*/struct commonio_entry *merge_group_entries (
|
||||
}
|
||||
|
||||
/* Concatenate the 2 lines */
|
||||
if (asprintf(&new_line, "%s\n%s", gr1->line, gr2->line) == -1)
|
||||
new_line = aprintf("%s\n%s", gr1->line, gr2->line);
|
||||
if (new_line == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Concatenate the 2 list of members */
|
||||
|
||||
@@ -9,43 +9,39 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
/* Newer versions of Linux libc already have shadow support. */
|
||||
#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{ */
|
||||
#if defined(SHADOWGRP) && !__has_include(<gshadow.h>)
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alloc/malloc.h"
|
||||
#include "alloc/realloc.h"
|
||||
#include "alloc/x/xmalloc.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strchr/strchrcnt.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
#include "string/strtok/strsep2arr.h"
|
||||
#include "string/strtok/xastrsep2ls.h"
|
||||
|
||||
|
||||
static /*@null@*/FILE *shadow;
|
||||
static struct sgrp sgroup = {};
|
||||
|
||||
#define FIELDS 4
|
||||
|
||||
|
||||
static /*@null@*/char **
|
||||
build_list(char *s)
|
||||
{
|
||||
char **l;
|
||||
size_t i;
|
||||
size_t n;
|
||||
|
||||
l = XMALLOC(strchrcnt(s, ',') + 2, char *);
|
||||
l = xastrsep2ls(s, ",", &n);
|
||||
|
||||
for (i = 0; s != NULL && !streq(s, ""); i++)
|
||||
l[i] = strsep(&s, ",");
|
||||
|
||||
l[i] = NULL;
|
||||
if (streq(l[n-1], ""))
|
||||
l[n-1] = NULL;
|
||||
|
||||
return l;
|
||||
}
|
||||
@@ -55,7 +51,7 @@ void setsgent (void)
|
||||
if (NULL != shadow) {
|
||||
rewind (shadow);
|
||||
} else {
|
||||
shadow = fopen (SGROUP_FILE, "r");
|
||||
shadow = fopen (SGROUP_FILE, "re");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,45 +65,23 @@ void endsgent (void)
|
||||
}
|
||||
|
||||
/*@observer@*//*@null@*/struct sgrp *
|
||||
sgetsgent(const char *string)
|
||||
sgetsgent(const char *s)
|
||||
{
|
||||
static char *sgrbuf = NULL;
|
||||
static size_t sgrbuflen = 0;
|
||||
static char *dup = NULL;
|
||||
|
||||
char *fields[FIELDS];
|
||||
char *cp;
|
||||
int i;
|
||||
size_t len = strlen (string) + 1;
|
||||
char *fields[4];
|
||||
|
||||
if (len > sgrbuflen) {
|
||||
char *buf = REALLOC(sgrbuf, len, char);
|
||||
if (NULL == buf)
|
||||
return NULL;
|
||||
|
||||
sgrbuf = buf;
|
||||
sgrbuflen = len;
|
||||
}
|
||||
|
||||
strcpy (sgrbuf, string);
|
||||
stpsep(sgrbuf, "\n");
|
||||
|
||||
/*
|
||||
* There should be exactly 4 colon separated fields. Find
|
||||
* all 4 of them and save the starting addresses in fields[].
|
||||
*/
|
||||
|
||||
for (cp = sgrbuf, i = 0; (i < FIELDS) && (NULL != cp); i++)
|
||||
fields[i] = strsep(&cp, ":");
|
||||
|
||||
/*
|
||||
* If there was an extra field somehow, or perhaps not enough,
|
||||
* the line is invalid.
|
||||
*/
|
||||
|
||||
if (NULL != cp || i != FIELDS)
|
||||
free(dup);
|
||||
dup = strdup(s);
|
||||
if (dup == NULL)
|
||||
return NULL;
|
||||
|
||||
sgroup.sg_name = fields[0];
|
||||
stpsep(dup, "\n");
|
||||
|
||||
if (STRSEP2ARR(dup, ":", fields) == -1)
|
||||
return NULL;
|
||||
|
||||
sgroup.sg_namp = fields[0];
|
||||
sgroup.sg_passwd = fields[1];
|
||||
|
||||
free(sgroup.sg_adm);
|
||||
@@ -193,7 +167,7 @@ sgetsgent(const char *string)
|
||||
setsgent ();
|
||||
|
||||
while ((sgrp = getsgent ()) != NULL) {
|
||||
if (streq(name, sgrp->sg_name)) {
|
||||
if (streq(name, sgrp->sg_namp)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -219,7 +193,7 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
|
||||
}
|
||||
|
||||
/* calculate the required buffer size */
|
||||
size = strlen (sgrp->sg_name) + strlen (sgrp->sg_passwd) + 10;
|
||||
size = strlen (sgrp->sg_namp) + strlen (sgrp->sg_passwd) + 10;
|
||||
for (i = 0; (NULL != sgrp->sg_adm) && (NULL != sgrp->sg_adm[i]); i++) {
|
||||
size += strlen (sgrp->sg_adm[i]) + 1;
|
||||
}
|
||||
@@ -236,7 +210,7 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
|
||||
/*
|
||||
* Copy the group name and passwd.
|
||||
*/
|
||||
cp = stpcpy(stpcpy(cp, sgrp->sg_name), ":");
|
||||
cp = stpcpy(stpcpy(cp, sgrp->sg_namp), ":");
|
||||
cp = stpcpy(stpcpy(cp, sgrp->sg_passwd), ":");
|
||||
|
||||
/*
|
||||
@@ -276,4 +250,4 @@ int putsgent (const struct sgrp *sgrp, FILE * fp)
|
||||
}
|
||||
#else
|
||||
extern int ISO_C_forbids_an_empty_translation_unit;
|
||||
#endif /*} SHADOWGRP */
|
||||
#endif // !SHADOWGRP
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1988 - 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: 1988-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
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _H_GSHADOW
|
||||
#define _H_GSHADOW
|
||||
#ifndef SHADOW_INCLUDE_LIB_GSHADOW__H_
|
||||
#define SHADOW_INCLUDE_LIB_GSHADOW__H_
|
||||
|
||||
|
||||
#if __has_include(<gshadow.h>)
|
||||
# include <gshadow.h>
|
||||
#else
|
||||
|
||||
/*
|
||||
* Shadow group security file structure
|
||||
*/
|
||||
|
||||
struct sgrp {
|
||||
char *sg_name; /* group name */
|
||||
char *sg_namp; /* group name */
|
||||
char *sg_passwd; /* group password */
|
||||
char **sg_adm; /* group administrator list */
|
||||
char **sg_mem; /* group membership list */
|
||||
@@ -39,4 +39,7 @@ void endsgent (void);
|
||||
int putsgent (const struct sgrp *, FILE *);
|
||||
|
||||
#define GSHADOW "/etc/gshadow"
|
||||
#endif /* ifndef _H_GSHADOW */
|
||||
|
||||
|
||||
#endif // !__has_include(<gshadow.h>)
|
||||
#endif // include guard
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#if HAVE_SYS_CAPABILITY_H
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/capability.h>
|
||||
#if __has_include(<sys/capability.h>)
|
||||
# include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#include "alloc/calloc.h"
|
||||
@@ -86,7 +86,7 @@ get_map_ranges(int ranges, int argc, char **argv)
|
||||
*/
|
||||
#define ULONG_DIGITS (((WIDTHOF(unsigned long) + 9)/10)*3)
|
||||
|
||||
#if HAVE_SYS_CAPABILITY_H
|
||||
#if __has_include(<sys/capability.h>)
|
||||
static inline bool maps_lower_root(int cap, int ranges, const struct map_range *mappings)
|
||||
{
|
||||
int idx;
|
||||
@@ -129,7 +129,7 @@ void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings
|
||||
char *buf, *pos, *end;
|
||||
int fd;
|
||||
|
||||
#if HAVE_SYS_CAPABILITY_H
|
||||
#if __has_include(<sys/capability.h>)
|
||||
int cap;
|
||||
struct __user_cap_header_struct hdr = {_LINUX_CAPABILITY_VERSION_3, 0};
|
||||
struct __user_cap_data_struct data[2] = {{0}};
|
||||
|
||||
36
lib/limits.c
36
lib/limits.c
@@ -32,12 +32,11 @@
|
||||
|
||||
#include "atoi/a2i/a2i.h"
|
||||
#include "atoi/a2i/a2s.h"
|
||||
#include "atoi/str2i/str2i.h"
|
||||
#include "atoi/str2i/str2s.h"
|
||||
#include "atoi/str2i/str2u.h"
|
||||
#include "atoi/str2i.h"
|
||||
#include "string/memset/memzero.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strspn/stpspn.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
|
||||
@@ -62,7 +61,7 @@ static int setrlimit_value (unsigned int resource,
|
||||
/* The "-" is special, not belonging to a strange negative limit.
|
||||
* It is infinity, in a controlled way.
|
||||
*/
|
||||
if ('-' == value[0]) {
|
||||
if (strprefix(value, "-")) {
|
||||
limit = RLIM_INFINITY;
|
||||
|
||||
} else {
|
||||
@@ -370,7 +369,7 @@ static int setup_user_limits (const char *uname)
|
||||
* FIXME: A better (smarter) checking should be done
|
||||
*/
|
||||
while (fgets (buf, 1024, fil) != NULL) {
|
||||
if (('#' == buf[0]) || ('\n' == buf[0])) {
|
||||
if (strprefix(buf, "#") || strprefix(buf, "\n")) {
|
||||
continue;
|
||||
}
|
||||
MEMZERO(tempbuf);
|
||||
@@ -401,7 +400,7 @@ static int setup_user_limits (const char *uname)
|
||||
break;
|
||||
} else if (streq(name, "*")) {
|
||||
strcpy (deflimits, tempbuf);
|
||||
} else if (name[0] == '@') {
|
||||
} else if (strprefix(name, "@")) {
|
||||
/* If the user is in the group, the group
|
||||
* limits apply unless later a line for
|
||||
* the specific user is found.
|
||||
@@ -473,14 +472,15 @@ void setup_limits (const struct passwd *info)
|
||||
}
|
||||
}
|
||||
for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) {
|
||||
if (',' == *cp) {
|
||||
cp++;
|
||||
}
|
||||
char *val;
|
||||
|
||||
if (strncmp (cp, "pri=", 4) == 0) {
|
||||
cp = strprefix(cp, ",") ?: cp;
|
||||
|
||||
val = strprefix(cp, "pri=");
|
||||
if (val != NULL) {
|
||||
int inc;
|
||||
|
||||
if (a2si(&inc, cp + 4, NULL, 0, -20, 20) == 0) {
|
||||
if (a2si(&inc, val, NULL, 0, -20, 20) == 0) {
|
||||
errno = 0;
|
||||
if ( (nice (inc) != -1)
|
||||
|| (0 != errno)) {
|
||||
@@ -495,10 +495,12 @@ void setup_limits (const struct passwd *info)
|
||||
|
||||
continue;
|
||||
}
|
||||
if (strncmp (cp, "ulimit=", 7) == 0) {
|
||||
|
||||
val = strprefix(cp, "ulimit=");
|
||||
if (val != NULL) {
|
||||
int blocks;
|
||||
|
||||
if ( (str2si(&blocks, cp + 7) == -1)
|
||||
if ( (str2si(&blocks, val) == -1)
|
||||
|| (set_filesize_limit (blocks) != 0)) {
|
||||
SYSLOG ((LOG_WARN,
|
||||
"Can't set the ulimit for user %s",
|
||||
@@ -506,10 +508,12 @@ void setup_limits (const struct passwd *info)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strncmp (cp, "umask=", 6) == 0) {
|
||||
|
||||
val = strprefix(cp, "umask=");
|
||||
if (val != NULL) {
|
||||
mode_t mask;
|
||||
|
||||
if (str2i(mode_t, &mask, cp + 6) == -1) {
|
||||
if (str2i(mode_t, &mask, val) == -1) {
|
||||
SYSLOG ((LOG_WARN,
|
||||
"Can't set umask value for user %s",
|
||||
info->pw_name));
|
||||
|
||||
21
lib/list.c
21
lib/list.c
@@ -18,6 +18,7 @@
|
||||
#include "string/strchr/strchrcnt.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strdup/xstrdup.h"
|
||||
#include "string/strtok/strsep2ls.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -186,9 +187,7 @@ comma_to_list(const char *comma)
|
||||
{
|
||||
char *members;
|
||||
char **array;
|
||||
int i;
|
||||
char *cp;
|
||||
char *cp2;
|
||||
size_t n;
|
||||
|
||||
assert (NULL != comma);
|
||||
|
||||
@@ -203,7 +202,8 @@ comma_to_list(const char *comma)
|
||||
* n: number of delimiters + last element + NULL
|
||||
*/
|
||||
|
||||
array = XMALLOC(strchrcnt(members, ',') + 2, char *);
|
||||
n = strchrcnt(members, ',') + 2;
|
||||
array = XMALLOC(n, char *);
|
||||
|
||||
/*
|
||||
* Empty list is special - 0 members, not 1 empty member. --marekm
|
||||
@@ -215,18 +215,7 @@ comma_to_list(const char *comma)
|
||||
return array;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now go walk that list all over again, this time building the
|
||||
* array of pointers.
|
||||
*/
|
||||
|
||||
for (cp = members, i = 0; cp != NULL; i++)
|
||||
array[i] = strsep(&cp, ",");
|
||||
array[i] = NULL;
|
||||
|
||||
/*
|
||||
* Return the new array of pointers
|
||||
*/
|
||||
strsep2ls(members, ",", n, array);
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/memset/memzero.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/strcpy/strtcpy.h"
|
||||
#include "string/strspn/stpspn.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "getdef.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
@@ -37,7 +37,7 @@ void mailcheck (void)
|
||||
if (NULL != mailbox) {
|
||||
char *newmail;
|
||||
|
||||
xasprintf(&newmail, "%s/new", mailbox);
|
||||
newmail = xaprintf("%s/new", mailbox);
|
||||
|
||||
if (stat (newmail, &statbuf) != -1 && statbuf.st_size != 0) {
|
||||
if (statbuf.st_mtime > statbuf.st_atime) {
|
||||
|
||||
25
lib/motd.c
25
lib/motd.c
@@ -17,7 +17,6 @@
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strdup/xstrdup.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -27,7 +26,7 @@
|
||||
* it to the user's terminal at login time. The MOTD_FILE configuration
|
||||
* option is a colon-delimited list of filenames.
|
||||
*/
|
||||
void
|
||||
int
|
||||
motd(void)
|
||||
{
|
||||
FILE *fp;
|
||||
@@ -37,24 +36,26 @@ motd(void)
|
||||
int c;
|
||||
|
||||
motdfile = getdef_str ("MOTD_FILE");
|
||||
if (NULL == motdfile) {
|
||||
return;
|
||||
}
|
||||
if (NULL == motdfile)
|
||||
return 0;
|
||||
|
||||
motdlist = xstrdup (motdfile);
|
||||
motdlist = strdup(motdfile);
|
||||
if (motdlist == NULL)
|
||||
return -1;
|
||||
|
||||
mb = motdlist;
|
||||
while (NULL != (motdfile = strsep(&mb, ":"))) {
|
||||
fp = fopen (motdfile, "r");
|
||||
if (NULL != fp) {
|
||||
while ((c = getc (fp)) != EOF) {
|
||||
putchar (c);
|
||||
}
|
||||
fclose (fp);
|
||||
if (fp == NULL)
|
||||
continue;
|
||||
|
||||
while ((c = getc(fp)) != EOF) {
|
||||
putchar(c);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
fflush (stdout);
|
||||
|
||||
free (motdlist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
117
lib/must_be.h
117
lib/must_be.h
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2023, Alejandro Colomar <alx@kernel.org>
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIBMISC_MUST_BE_H_
|
||||
#define SHADOW_INCLUDE_LIBMISC_MUST_BE_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/*
|
||||
* SYNOPSIS
|
||||
* int must_be(bool e);
|
||||
*
|
||||
* ARGUMENTS
|
||||
* e Expression to be asserted.
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This macro fails compilation if 'e' is false. If 'e' is true,
|
||||
* it returns (int) 0, so it doesn't affect the expression in which
|
||||
* it is contained.
|
||||
*
|
||||
* This macro is similar to static_assert(3). While
|
||||
* static_assert(3) can only be used where a statement is allowed,
|
||||
* this must_be() macro can be used wherever an expression is
|
||||
* allowed.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* 0
|
||||
*
|
||||
* ERRORS
|
||||
* If 'e' is false, the compilation will fail, as when using
|
||||
* static_assert(3).
|
||||
*
|
||||
* EXAMPLES
|
||||
* #define must_be_array(a) must_be(is_array(a))
|
||||
*
|
||||
* #define NITEMS(a) (sizeof(a) / sizeof(*(a)) + must_be_array(a))
|
||||
*
|
||||
* int foo[42];
|
||||
* int bar[NITEMS(foo)];
|
||||
*/
|
||||
|
||||
|
||||
#define must_be(e) \
|
||||
( \
|
||||
0 * (int) sizeof( \
|
||||
struct { \
|
||||
static_assert(e, ""); \
|
||||
int ISO_C_forbids_a_struct_with_no_members_; \
|
||||
} \
|
||||
) \
|
||||
)
|
||||
|
||||
|
||||
/*
|
||||
* SYNOPSIS
|
||||
* int must_be_array(a);
|
||||
*
|
||||
* ARGUMENTS
|
||||
* a Array.
|
||||
*
|
||||
* DESCRIPTION
|
||||
* This macro fails compilation if 'a' is not an array. It is
|
||||
* useful in macros that accept an array as a parameter, where this
|
||||
* macro can validate the macro argument. It prevent passing a
|
||||
* pointer to such macros, which would otherwise produce silent
|
||||
* bugs.
|
||||
*
|
||||
* RETURN VALUE
|
||||
* 0
|
||||
*
|
||||
* ERRORS
|
||||
* If 'a' is not an array, the compilation will fail.
|
||||
*
|
||||
* EXAMPLES
|
||||
* int a[10];
|
||||
* int *p;
|
||||
*
|
||||
* must_be_array(a); // Ok
|
||||
* must_be_array(p); // Compile-time error
|
||||
*
|
||||
* SEE ALSO
|
||||
* must_be()
|
||||
*/
|
||||
|
||||
|
||||
#define is_same_type(a, b) \
|
||||
( \
|
||||
__builtin_types_compatible_p(a, b) \
|
||||
)
|
||||
|
||||
|
||||
#define is_same_typeof(a, b) \
|
||||
( \
|
||||
is_same_type(typeof(a), typeof(b)) \
|
||||
)
|
||||
|
||||
|
||||
#define is_array(a) \
|
||||
( \
|
||||
!is_same_typeof(a, &(a)[0]) \
|
||||
)
|
||||
|
||||
|
||||
#define must_be_array(a) \
|
||||
( \
|
||||
must_be(is_array(a)) \
|
||||
)
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -15,8 +15,10 @@
|
||||
#include "shadowlog_internal.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/snprintf.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/strcmp/strcaseprefix.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strspn/stpspn.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
@@ -79,11 +81,11 @@ nss_init(const char *nsswitch_path) {
|
||||
}
|
||||
p = NULL;
|
||||
while (getline(&line, &len, nssfp) != -1) {
|
||||
if (line[0] == '#')
|
||||
if (strprefix(line, "#"))
|
||||
continue;
|
||||
if (strlen(line) < 8)
|
||||
continue;
|
||||
if (strncasecmp(line, "subid:", 6) != 0)
|
||||
if (!strcaseprefix(line, "subid:"))
|
||||
continue;
|
||||
p = &line[6];
|
||||
p = stpspn(p, " \t\n");
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh
|
||||
* SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz
|
||||
* SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko
|
||||
* SPDX-FileCopyrightText: 2007 - 2010, Nicolas François
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
// SPDX-FileCopyrightText: 1989-1994, Julianne Frances Haugh
|
||||
// SPDX-FileCopyrightText: 1996-1999, Marek Michałkiewicz
|
||||
// SPDX-FileCopyrightText: 2003-2005, Tomasz Kłoczko
|
||||
// SPDX-FileCopyrightText: 2007-2010, Nicolas François
|
||||
// SPDX-FileCopyrightText: 2025, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
@@ -19,8 +18,9 @@
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
#include "string/ctype/strtoascii/strtolower.h"
|
||||
#include "string/memset/memzero.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strdup/xstrdup.h"
|
||||
|
||||
@@ -78,15 +78,6 @@ static bool similar (/*@notnull@*/const char *old, /*@notnull@*/const char *new)
|
||||
return true;
|
||||
}
|
||||
|
||||
static char *str_lower (/*@returned@*/char *string)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
for (cp = string; !streq(cp, ""); cp++) {
|
||||
*cp = tolower (*cp);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
static /*@observer@*//*@null@*/const char *password_check (
|
||||
/*@notnull@*/const char *old,
|
||||
@@ -100,9 +91,9 @@ static /*@observer@*//*@null@*/const char *password_check (
|
||||
return _("no change");
|
||||
}
|
||||
|
||||
newmono = str_lower (xstrdup (new));
|
||||
oldmono = str_lower (xstrdup (old));
|
||||
xasprintf(&wrapped, "%s%s", oldmono, oldmono);
|
||||
newmono = strtolower(xstrdup(new));
|
||||
oldmono = strtolower(xstrdup(old));
|
||||
wrapped = xaprintf("%s%s", oldmono, oldmono);
|
||||
|
||||
if (palindrome (oldmono, newmono)) {
|
||||
msg = _("a palindrome");
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <security/pam_appl.h>
|
||||
#ifdef HAVE_SECURITY_PAM_MISC_H
|
||||
#if __has_include(<security/pam_misc.h>)
|
||||
# include <security/pam_misc.h>
|
||||
#endif
|
||||
#ifdef HAVE_SECURITY_OPENPAM_H
|
||||
#if __has_include(<security/openpam.h>)
|
||||
# include <security/openpam.h>
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
/* Copied from src/passwd.c */
|
||||
#define E_PAM_ERR 10 /* PAM returned an error */
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
|
||||
@@ -40,7 +43,7 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
|
||||
if (ret != PAM_SUCCESS) {
|
||||
fprintf (shadow_logfd,
|
||||
_("passwd: pam_start() failed, error %d\n"), ret);
|
||||
exit (10); /* XXX */
|
||||
exit (E_PAM_ERR);
|
||||
}
|
||||
|
||||
ret = pam_chauthtok (pamh, flags);
|
||||
@@ -48,7 +51,7 @@ void do_pam_passwd (const char *user, bool silent, bool change_expired)
|
||||
fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret));
|
||||
fputs (_("passwd: password unchanged\n"), shadow_logfd);
|
||||
pam_end (pamh, ret);
|
||||
exit (10); /* XXX */
|
||||
exit (E_PAM_ERR);
|
||||
}
|
||||
|
||||
fputs (_("passwd: password updated successfully\n"), shadow_logfd);
|
||||
|
||||
40
lib/port.c
40
lib/port.c
@@ -20,7 +20,9 @@
|
||||
#include "port.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
#include "string/strtok/strsep2ls.h"
|
||||
|
||||
|
||||
static FILE *ports;
|
||||
@@ -50,7 +52,7 @@ static int portcmp (const char *pattern, const char *port)
|
||||
if (streq(orig, "SU"))
|
||||
return 1;
|
||||
|
||||
return (*pattern == '*') ? 0 : 1;
|
||||
return !strprefix(pattern, "*");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -101,7 +103,8 @@ getportent(void)
|
||||
int dtime;
|
||||
int i, j;
|
||||
int saveerr;
|
||||
char *cp, *field;
|
||||
char *cp;
|
||||
char *fields[3];
|
||||
|
||||
static char buf[BUFSIZ];
|
||||
static char *ttys[PORT_TTY + 1];
|
||||
@@ -140,12 +143,13 @@ next:
|
||||
errno = saveerr;
|
||||
return NULL;
|
||||
}
|
||||
if ('#' == buf[0])
|
||||
if (strprefix(buf, "#"))
|
||||
goto next;
|
||||
|
||||
stpsep(buf, "\n");
|
||||
|
||||
field = buf;
|
||||
if (STRSEP2ARR(buf, ":", fields) == -1)
|
||||
goto next;
|
||||
|
||||
/*
|
||||
* Get the name of the TTY device. It is the first colon
|
||||
@@ -153,19 +157,8 @@ next:
|
||||
* leading "/dev". The entry '*' is used to specify all
|
||||
* TTY devices.
|
||||
*/
|
||||
|
||||
cp = strsep(&field, ":");
|
||||
if (field == NULL)
|
||||
goto next;
|
||||
|
||||
port.pt_names = ttys;
|
||||
for (j = 0; j < PORT_TTY; j++) {
|
||||
port.pt_names[j] = strsep(&cp, ",");
|
||||
if (cp == NULL)
|
||||
break;
|
||||
}
|
||||
port.pt_names[j] = NULL;
|
||||
if (cp != NULL)
|
||||
if (STRSEP2LS(fields[0], ",", ttys) == -1)
|
||||
goto next;
|
||||
|
||||
/*
|
||||
@@ -174,19 +167,8 @@ next:
|
||||
* names. The entry '*' is used to specify all usernames.
|
||||
* The last entry in the list is a NULL pointer.
|
||||
*/
|
||||
|
||||
cp = strsep(&field, ":");
|
||||
if (field == NULL)
|
||||
goto next;
|
||||
|
||||
port.pt_users = users;
|
||||
for (j = 0; j < PORT_IDS; j++) {
|
||||
port.pt_users[j] = strsep(&cp, ",");
|
||||
if (cp == NULL)
|
||||
break;
|
||||
}
|
||||
port.pt_users[j] = NULL;
|
||||
if (cp != NULL)
|
||||
if (STRSEP2LS(fields[1], ",", users) == -1)
|
||||
goto next;
|
||||
|
||||
/*
|
||||
@@ -202,7 +184,7 @@ next:
|
||||
* the starting time. Days are presumed to wrap at 0000.
|
||||
*/
|
||||
|
||||
cp = field;
|
||||
cp = fields[2];
|
||||
|
||||
if (streq(cp, "")) {
|
||||
port.pt_times = NULL;
|
||||
|
||||
@@ -28,8 +28,9 @@
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
|
||||
|
||||
static char *passwd_db_file = NULL;
|
||||
@@ -53,17 +54,15 @@ static FILE* fp_grent = NULL;
|
||||
*/
|
||||
extern const char* process_prefix_flag (const char* short_opt, int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
* Parse the command line options.
|
||||
*/
|
||||
int i;
|
||||
const char *prefix = NULL, *val;
|
||||
const char *prefix = NULL;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
const char *val;
|
||||
|
||||
val = strprefix(argv[i], "--prefix=");
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
val = NULL;
|
||||
if ( streq(argv[i], "--prefix")
|
||||
|| ((strncmp (argv[i], "--prefix=", 9) == 0)
|
||||
&& (val = argv[i] + 9))
|
||||
|| val != NULL
|
||||
|| streq(argv[i], short_opt))
|
||||
{
|
||||
if (NULL != prefix) {
|
||||
@@ -109,32 +108,32 @@ extern const char* process_prefix_flag (const char* short_opt, int argc, char **
|
||||
exit (E_BAD_ARG);
|
||||
}
|
||||
|
||||
xasprintf(&passwd_db_file, "%s/%s", prefix, PASSWD_FILE);
|
||||
passwd_db_file = xaprintf("%s/%s", prefix, PASSWD_FILE);
|
||||
pw_setdbname(passwd_db_file);
|
||||
|
||||
xasprintf(&group_db_file, "%s/%s", prefix, GROUP_FILE);
|
||||
group_db_file = xaprintf("%s/%s", prefix, GROUP_FILE);
|
||||
gr_setdbname(group_db_file);
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
xasprintf(&sgroup_db_file, "%s/%s", prefix, SGROUP_FILE);
|
||||
sgroup_db_file = xaprintf("%s/%s", prefix, SGROUP_FILE);
|
||||
sgr_setdbname(sgroup_db_file);
|
||||
#endif
|
||||
|
||||
xasprintf(&spw_db_file, "%s/%s", prefix, SHADOW_FILE);
|
||||
spw_db_file = xaprintf("%s/%s", prefix, SHADOW_FILE);
|
||||
spw_setdbname(spw_db_file);
|
||||
|
||||
#ifdef ENABLE_SUBIDS
|
||||
xasprintf(&suid_db_file, "%s/%s", prefix, SUBUID_FILE);
|
||||
suid_db_file = xaprintf("%s/%s", prefix, SUBUID_FILE);
|
||||
sub_uid_setdbname(suid_db_file);
|
||||
|
||||
xasprintf(&sgid_db_file, "%s/%s", prefix, SUBGID_FILE);
|
||||
sgid_db_file = xaprintf("%s/%s", prefix, SUBGID_FILE);
|
||||
sub_gid_setdbname(sgid_db_file);
|
||||
#endif
|
||||
|
||||
#ifdef USE_ECONF
|
||||
setdef_config_file(prefix);
|
||||
#else
|
||||
xasprintf(&def_conf_file, "%s/%s", prefix, "/etc/login.defs");
|
||||
def_conf_file = xaprintf("%s/%s", prefix, "/etc/login.defs");
|
||||
setdef_config_file(def_conf_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include "commonio.h"
|
||||
|
||||
/* addgrps.c */
|
||||
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
|
||||
#if !defined(USE_PAM)
|
||||
extern int add_groups (const char *);
|
||||
#endif
|
||||
|
||||
@@ -120,10 +120,6 @@ extern void sanitize_env (void);
|
||||
/* fd.c */
|
||||
extern void check_fds (void);
|
||||
|
||||
/* fields.c */
|
||||
extern void change_field (char *, size_t, const char *);
|
||||
extern int valid_field (const char *, const char *);
|
||||
|
||||
/* find_new_gid.c */
|
||||
extern int find_new_gid (bool sys_group,
|
||||
gid_t *gid,
|
||||
@@ -189,6 +185,9 @@ extern void audit_logger (int type, const char *pgname, const char *op,
|
||||
const char *name, unsigned int id,
|
||||
shadow_audit_result result);
|
||||
void audit_logger_message (const char *message, shadow_audit_result result);
|
||||
void audit_logger_with_group(int type, const char *op, const char *name,
|
||||
id_t id, const char *grp_type, const char *grp,
|
||||
shadow_audit_result result);
|
||||
#endif
|
||||
|
||||
/* limits.c */
|
||||
@@ -222,7 +221,7 @@ extern void login_prompt (char *, int);
|
||||
extern void mailcheck (void);
|
||||
|
||||
/* motd.c */
|
||||
extern void motd (void);
|
||||
extern int motd(void);
|
||||
|
||||
/* myname.c */
|
||||
extern /*@null@*//*@only@*/struct passwd *get_my_pwent (void);
|
||||
@@ -384,7 +383,7 @@ extern int del_seuser(const char *login_name);
|
||||
/* setugid.c */
|
||||
extern int setup_groups (const struct passwd *info);
|
||||
extern int change_uid (const struct passwd *info);
|
||||
#if (defined HAVE_INITGROUPS) && (! defined USE_PAM)
|
||||
#if !defined(USE_PAM)
|
||||
extern int setup_uid_gid (const struct passwd *info, bool is_console);
|
||||
#else
|
||||
extern int setup_uid_gid (const struct passwd *info);
|
||||
|
||||
63
lib/pwauth.c
63
lib/pwauth.c
@@ -48,16 +48,15 @@ static const char *PROMPT = gettext_noop ("%s's Password: ");
|
||||
* compared.
|
||||
*/
|
||||
|
||||
int pw_auth (const char *cipher,
|
||||
const char *user,
|
||||
int reason,
|
||||
/*@null@*/const char *input)
|
||||
int
|
||||
pw_auth(const char *cipher, const char *user)
|
||||
{
|
||||
int retval;
|
||||
char prompt[1024];
|
||||
char *clear = NULL;
|
||||
char *clear;
|
||||
const char *cp;
|
||||
const char *encrypted;
|
||||
const char *input;
|
||||
|
||||
#ifdef SKEY
|
||||
bool use_skey = false;
|
||||
@@ -65,35 +64,6 @@ int pw_auth (const char *cipher,
|
||||
struct skey skey;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There are programs for adding and deleting authentication data.
|
||||
*/
|
||||
|
||||
if ((PW_ADD == reason) || (PW_DELETE == reason)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are even programs for changing the user name ...
|
||||
*/
|
||||
|
||||
if ((PW_CHANGE == reason) && (NULL != input)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
*
|
||||
* When we change a password and we are root, we don't prompt.
|
||||
* This is so root can change any password without having to
|
||||
* know it. This is a policy decision that might have to be
|
||||
* revisited.
|
||||
*/
|
||||
|
||||
if ((PW_CHANGE == reason) && (getuid () == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
*
|
||||
@@ -128,25 +98,22 @@ int pw_auth (const char *cipher,
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prompt for the password as required. FTPD and REXECD both
|
||||
* get the cleartext password for us.
|
||||
* Prompt for the password as required.
|
||||
*/
|
||||
|
||||
if ((PW_FTP != reason) && (PW_REXEC != reason) && (NULL == input)) {
|
||||
cp = getdef_str ("LOGIN_STRING");
|
||||
if (NULL == cp) {
|
||||
cp = _(PROMPT);
|
||||
}
|
||||
cp = getdef_str ("LOGIN_STRING");
|
||||
if (NULL == cp) {
|
||||
cp = _(PROMPT);
|
||||
}
|
||||
#ifdef SKEY
|
||||
if (use_skey) {
|
||||
printf ("[%s]\n", challenge_info);
|
||||
}
|
||||
if (use_skey) {
|
||||
printf ("[%s]\n", challenge_info);
|
||||
}
|
||||
#endif
|
||||
|
||||
SNPRINTF(prompt, cp, user);
|
||||
clear = agetpass(prompt);
|
||||
input = (clear == NULL) ? "" : clear;
|
||||
}
|
||||
SNPRINTF(prompt, cp, user);
|
||||
clear = agetpass(prompt);
|
||||
input = (clear == NULL) ? "" : clear;
|
||||
|
||||
/*
|
||||
* Convert the cleartext password into a ciphertext string.
|
||||
|
||||
33
lib/pwauth.h
33
lib/pwauth.h
@@ -7,42 +7,11 @@
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _PWAUTH_H
|
||||
#define _PWAUTH_H
|
||||
|
||||
#ifndef USE_PAM
|
||||
int pw_auth (const char *cipher,
|
||||
const char *user,
|
||||
int flag,
|
||||
/*@null@*/const char *input);
|
||||
int pw_auth(const char *cipher, const char *user);
|
||||
#endif /* !USE_PAM */
|
||||
|
||||
/*
|
||||
* Local access
|
||||
*/
|
||||
|
||||
#define PW_SU 1
|
||||
#define PW_LOGIN 2
|
||||
|
||||
/*
|
||||
* Administrative functions
|
||||
*/
|
||||
|
||||
#define PW_ADD 101
|
||||
#define PW_CHANGE 102
|
||||
#define PW_DELETE 103
|
||||
|
||||
/*
|
||||
* Network access
|
||||
*/
|
||||
|
||||
#define PW_TELNET 201
|
||||
#define PW_RLOGIN 202
|
||||
#define PW_FTP 203
|
||||
#define PW_REXEC 204
|
||||
|
||||
#endif /* _PWAUTH_H */
|
||||
|
||||
@@ -28,7 +28,7 @@ void passwd_check (const char *user, const char *passwd, MAYBE_UNUSED const char
|
||||
if (NULL != sp) {
|
||||
passwd = sp->sp_pwdp;
|
||||
}
|
||||
if (pw_auth (passwd, user, PW_LOGIN, NULL) != 0) {
|
||||
if (pw_auth(passwd, user) != 0) {
|
||||
SYSLOG ((LOG_WARN, "incorrect password for `%s'", user));
|
||||
(void) sleep (1);
|
||||
fprintf (log_get_logfd(), _("Incorrect password for %s.\n"), user);
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "commonio.h"
|
||||
#include "defines.h"
|
||||
#include "fields.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
|
||||
static /*@null@*/ /*@only@*/void *passwd_dup (const void *ent)
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -34,18 +35,17 @@ static void change_root (const char* newroot);
|
||||
*/
|
||||
extern void process_root_flag (const char* short_opt, int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
* Parse the command line options.
|
||||
*/
|
||||
int i;
|
||||
const char *newroot = NULL, *val;
|
||||
const char *newroot = NULL;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
const char *val;
|
||||
|
||||
val = strprefix(argv[i], "--root=");
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
val = NULL;
|
||||
if ( streq(argv[i], "--root")
|
||||
|| ((strncmp (argv[i], "--root=", 7) == 0)
|
||||
&& (val = argv[i] + 7))
|
||||
|| streq(argv[i], short_opt)) {
|
||||
|| val != NULL
|
||||
|| streq(argv[i], short_opt))
|
||||
{
|
||||
if (NULL != newroot) {
|
||||
fprintf (log_get_logfd(),
|
||||
_("%s: multiple --root options\n"),
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "run_part.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
|
||||
|
||||
static int run_part(char *script_path, const char *name, const char *action)
|
||||
@@ -32,7 +33,7 @@ static int run_part(char *script_path, const char *name, const char *action)
|
||||
setenv("SUBJECT",name,1);
|
||||
execv(script_path,args);
|
||||
fprintf(shadow_logfd, "execv: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
pid_status = wait(&wait_status);
|
||||
@@ -60,8 +61,9 @@ int run_parts(const char *directory, const char *name, const char *action)
|
||||
char *s;
|
||||
struct stat sb;
|
||||
|
||||
if (asprintf(&s, "%s/%s", directory, namelist[n]->d_name) == -1) {
|
||||
fprintf(shadow_logfd, "asprintf: %s\n", strerror(errno));
|
||||
s = aprintf("%s/%s", directory, namelist[n]->d_name);
|
||||
if (s == NULL) {
|
||||
fprintf(shadow_logfd, "aprintf: %s\n", strerror(errno));
|
||||
for (; n<scanlist; n++) {
|
||||
free(namelist[n]);
|
||||
}
|
||||
|
||||
13
lib/search/cmp/cmp.c
Normal file
13
lib/search/cmp/cmp.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 "search/cmp/cmp.h"
|
||||
|
||||
|
||||
extern inline int cmp_int(const void *key, const void *elt);
|
||||
extern inline int cmp_long(const void *key, const void *elt);
|
||||
extern inline int cmp_uint(const void *key, const void *elt);
|
||||
extern inline int cmp_ulong(const void *key, const void *elt);
|
||||
86
lib/search/cmp/cmp.h
Normal file
86
lib/search/cmp/cmp.h
Normal file
@@ -0,0 +1,86 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_SEARCH_CMP_CMP_H_
|
||||
#define SHADOW_INCLUDE_LIB_SEARCH_CMP_CMP_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
|
||||
#define CMP(TYPE) \
|
||||
( \
|
||||
_Generic((TYPE) 0, \
|
||||
int *: cmp_int, \
|
||||
long *: cmp_long, \
|
||||
unsigned int *: cmp_uint, \
|
||||
unsigned long *: cmp_ulong \
|
||||
) \
|
||||
)
|
||||
|
||||
|
||||
/* Compatible with bsearch(3), lfind(3), and qsort(3). */
|
||||
inline int cmp_int(const void *key, const void *elt);
|
||||
inline int cmp_long(const void *key, const void *elt);
|
||||
inline int cmp_uint(const void *key, const void *elt);
|
||||
inline int cmp_ulong(const void *key, const void *elt);
|
||||
|
||||
|
||||
inline int
|
||||
cmp_int(const void *key, const void *elt)
|
||||
{
|
||||
const int *k = key;
|
||||
const int *e = elt;
|
||||
|
||||
if (*k < *e)
|
||||
return -1;
|
||||
if (*k > *e)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
cmp_long(const void *key, const void *elt)
|
||||
{
|
||||
const long *k = key;
|
||||
const long *e = elt;
|
||||
|
||||
if (*k < *e)
|
||||
return -1;
|
||||
if (*k > *e)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
cmp_uint(const void *key, const void *elt)
|
||||
{
|
||||
const unsigned int *k = key;
|
||||
const unsigned int *e = elt;
|
||||
|
||||
if (*k < *e)
|
||||
return -1;
|
||||
if (*k > *e)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
inline int
|
||||
cmp_ulong(const void *key, const void *elt)
|
||||
{
|
||||
const unsigned long *k = key;
|
||||
const unsigned long *e = elt;
|
||||
|
||||
if (*k < *e)
|
||||
return -1;
|
||||
if (*k > *e)
|
||||
return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
13
lib/search/l/lfind.c
Normal file
13
lib/search/l/lfind.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 "search/l/lfind.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
extern inline void *lfind_(const void *k, const void *a, size_t n, size_t ksize,
|
||||
typeof(int (const void *k, const void *elt)) *cmp);
|
||||
44
lib/search/l/lfind.h
Normal file
44
lib/search/l/lfind.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_SEARCH_L_LFIND_H_
|
||||
#define SHADOW_INCLUDE_LIB_SEARCH_L_LFIND_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <search.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "search/cmp/cmp.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#define LFIND(k, a, n) \
|
||||
({ \
|
||||
__auto_type k_ = k; \
|
||||
__auto_type a_ = a; \
|
||||
\
|
||||
static_assert(is_same_typeof(k_, a_), ""); \
|
||||
\
|
||||
(typeof(k_)) lfind_(k_, a_, n, sizeof(*k_), CMP(typeof(k_))); \
|
||||
})
|
||||
|
||||
|
||||
inline void *lfind_(const void *k, const void *a, size_t n, size_t ksize,
|
||||
typeof(int (const void *k, const void *elt)) *cmp);
|
||||
|
||||
|
||||
inline void *
|
||||
lfind_(const void *k, const void *a, size_t n, size_t ksize,
|
||||
typeof(int (const void *k, const void *elt)) *cmp)
|
||||
{
|
||||
// lfind(3) wants a pointer to n for historic reasons.
|
||||
return lfind(k, a, &n, ksize, cmp);
|
||||
}
|
||||
|
||||
|
||||
#endif // include guard
|
||||
7
lib/search/l/lsearch.c
Normal file
7
lib/search/l/lsearch.c
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "search/l/lsearch.h"
|
||||
30
lib/search/l/lsearch.h
Normal file
30
lib/search/l/lsearch.h
Normal file
@@ -0,0 +1,30 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_SEARCH_L_LSEARCH_H_
|
||||
#define SHADOW_INCLUDE_LIB_SEARCH_L_LSEARCH_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <search.h>
|
||||
|
||||
#include "search/cmp/cmp.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#define LSEARCH(k, a, n) \
|
||||
({ \
|
||||
__auto_type k_ = k; \
|
||||
__auto_type a_ = a; \
|
||||
\
|
||||
static_assert(is_same_typeof(k_, a_), ""); \
|
||||
\
|
||||
(typeof(k_)) lsearch(k_, a_, n, sizeof(*k_), CMP(typeof(k_)));\
|
||||
})
|
||||
|
||||
|
||||
#endif // include guard
|
||||
7
lib/search/sort/qsort.c
Normal file
7
lib/search/sort/qsort.c
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "search/sort/qsort.h"
|
||||
25
lib/search/sort/qsort.h
Normal file
25
lib/search/sort/qsort.h
Normal file
@@ -0,0 +1,25 @@
|
||||
// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
|
||||
#ifndef SHADOW_INCLUDE_LIB_SEARCH_SORT_QSORT_H_
|
||||
#define SHADOW_INCLUDE_LIB_SEARCH_SORT_QSORT_H_
|
||||
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "search/cmp/cmp.h"
|
||||
#include "typetraits.h"
|
||||
|
||||
|
||||
#define QSORT(a, n) do \
|
||||
{ \
|
||||
__auto_type p_ = a; \
|
||||
\
|
||||
qsort(p_, n, sizeof(*p_), CMP(typeof(p_))); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif // include guard
|
||||
@@ -13,9 +13,11 @@
|
||||
|
||||
#include <selinux/selinux.h>
|
||||
#include <selinux/label.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
|
||||
|
||||
static bool selinux_checked = false;
|
||||
static bool selinux_enabled;
|
||||
@@ -113,18 +115,15 @@ format_attr(printf, 2, 3)
|
||||
static int selinux_log_cb (int type, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int r;
|
||||
#ifdef WITH_AUDIT
|
||||
static int selinux_audit_fd = -2;
|
||||
#endif
|
||||
|
||||
va_start (ap, fmt);
|
||||
r = vasprintf (&buf, fmt, ap);
|
||||
buf = vaprintf(fmt, ap);
|
||||
va_end (ap);
|
||||
|
||||
if (r < 0) {
|
||||
if (buf == NULL)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
if (-2 == selinux_audit_fd) {
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
|
||||
#include "attr.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/sprintf/aprintf.h"
|
||||
|
||||
|
||||
format_attr(printf, 3, 4)
|
||||
@@ -32,18 +32,14 @@ static void semanage_error_callback (MAYBE_UNUSED void *varg,
|
||||
semanage_handle_t *handle,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
char * message = NULL;
|
||||
va_list ap;
|
||||
|
||||
|
||||
va_start (ap, fmt);
|
||||
ret = vasprintf (&message, fmt, ap);
|
||||
message = vaprintf(fmt, ap);
|
||||
va_end (ap);
|
||||
if (ret < 0) {
|
||||
/* ENOMEM */
|
||||
if (message == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (semanage_msg_get_level (handle)) {
|
||||
case SEMANAGE_MSG_ERR:
|
||||
|
||||
@@ -47,7 +47,7 @@ int setup_groups (const struct passwd *info)
|
||||
closelog ();
|
||||
return -1;
|
||||
}
|
||||
#ifdef HAVE_INITGROUPS
|
||||
|
||||
/*
|
||||
* For systems which support multiple concurrent groups, go get
|
||||
* the group set from the /etc/group file.
|
||||
@@ -60,7 +60,7 @@ int setup_groups (const struct passwd *info)
|
||||
closelog ();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ int change_uid (const struct passwd *info)
|
||||
* Returns 0 on success, or -1 on failure.
|
||||
*/
|
||||
|
||||
#if defined (HAVE_INITGROUPS) && ! (defined USE_PAM)
|
||||
#if !defined(USE_PAM)
|
||||
int setup_uid_gid (const struct passwd *info, bool is_console)
|
||||
#else
|
||||
int setup_uid_gid (const struct passwd *info)
|
||||
@@ -106,7 +106,7 @@ int setup_uid_gid (const struct passwd *info)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined (HAVE_INITGROUPS) && ! defined (USE_PAM)
|
||||
#if !defined(USE_PAM)
|
||||
if (is_console) {
|
||||
const char *cp = getdef_str ("CONSOLE_GROUPS");
|
||||
|
||||
@@ -114,7 +114,7 @@ int setup_uid_gid (const struct passwd *info)
|
||||
perror ("Warning: add_groups");
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INITGROUPS && !USE_PAM*/
|
||||
#endif // !USE_PAM
|
||||
|
||||
if (change_uid (info) < 0) {
|
||||
return -1;
|
||||
|
||||
@@ -26,10 +26,11 @@
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
#include "shadowlog.h"
|
||||
#include "string/sprintf/xasprintf.h"
|
||||
#include "string/strchr/stpspn.h"
|
||||
#include "string/sprintf/xaprintf.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strcmp/strprefix.h"
|
||||
#include "string/strdup/xstrdup.h"
|
||||
#include "string/strspn/stpspn.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
|
||||
|
||||
@@ -39,7 +40,7 @@ addenv_path(const char *varname, const char *dirname, const char *filename)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
xasprintf(&buf, "%s/%s", dirname, filename);
|
||||
buf = xaprintf("%s/%s", dirname, filename);
|
||||
addenv(varname, buf);
|
||||
free(buf);
|
||||
}
|
||||
@@ -61,7 +62,7 @@ static void read_env_file (const char *filename)
|
||||
cp = buf;
|
||||
/* ignore whitespace and comments */
|
||||
cp = stpspn(cp, " \t");
|
||||
if (streq(cp, "") || ('#' == *cp)) {
|
||||
if (streq(cp, "") || strprefix(cp, "#")) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@@ -72,7 +73,7 @@ static void read_env_file (const char *filename)
|
||||
val = stpsep(cp, "=");
|
||||
if (val == NULL)
|
||||
continue;
|
||||
if (strpbrk(name, " \t") != NULL)
|
||||
if (strpbrk(name, " \t"))
|
||||
continue;
|
||||
#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
|
||||
/*
|
||||
|
||||
@@ -11,22 +11,22 @@
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "alloc/malloc.h"
|
||||
#include "alloc/reallocf.h"
|
||||
#include "atoi/getnum.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
#include "string/strtok/strsep2arr.h"
|
||||
#include "string/strtok/astrsep2ls.h"
|
||||
|
||||
|
||||
#define NFIELDS 4
|
||||
|
||||
/*
|
||||
* list - turn a comma-separated string into an array of (char *)'s
|
||||
*
|
||||
@@ -40,69 +40,52 @@ static char **
|
||||
list(char *s)
|
||||
{
|
||||
static char **members = NULL;
|
||||
static size_t size = 0; /* max members + 1 */
|
||||
size_t i;
|
||||
|
||||
i = 0;
|
||||
for (;;) {
|
||||
/* check if there is room for another pointer (to a group
|
||||
member name, or terminating NULL). */
|
||||
if (i >= size) {
|
||||
size = i + 100; /* at least: i + 1 */
|
||||
members = REALLOCF(members, size, char *);
|
||||
if (!members) {
|
||||
size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (!s || streq(s, ""))
|
||||
break;
|
||||
members[i++] = strsep(&s, ",");
|
||||
}
|
||||
members[i] = NULL;
|
||||
size_t n;
|
||||
|
||||
free(members);
|
||||
|
||||
members = astrsep2ls(s, ",", &n);
|
||||
if (members == NULL)
|
||||
return NULL;
|
||||
|
||||
if (streq(members[n-1], ""))
|
||||
members[n-1] = NULL;
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
|
||||
struct group *sgetgrent (const char *buf)
|
||||
struct group *
|
||||
sgetgrent(const char *s)
|
||||
{
|
||||
static char *grpbuf = NULL;
|
||||
static size_t size = 0;
|
||||
static char *grpfields[NFIELDS];
|
||||
static char *dup = NULL;
|
||||
static struct group grent;
|
||||
int i;
|
||||
char *cp;
|
||||
|
||||
if (strlen (buf) + 1 > size) {
|
||||
/* no need to use realloc() here - just free it and
|
||||
allocate a larger block */
|
||||
free (grpbuf);
|
||||
size = strlen (buf) + 1000; /* at least: strlen(buf) + 1 */
|
||||
grpbuf = MALLOC(size, char);
|
||||
if (grpbuf == NULL) {
|
||||
size = 0;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
strcpy (grpbuf, buf);
|
||||
stpsep(grpbuf, "\n");
|
||||
char *fields[4];
|
||||
|
||||
for (cp = grpbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++)
|
||||
grpfields[i] = strsep(&cp, ":");
|
||||
free(dup);
|
||||
dup = strdup(s);
|
||||
if (dup == NULL)
|
||||
return NULL;
|
||||
|
||||
if (i < NFIELDS || streq(grpfields[2], "") || cp != NULL) {
|
||||
stpsep(dup, "\n");
|
||||
|
||||
if (STRSEP2ARR(dup, ":", fields) == -1)
|
||||
return NULL;
|
||||
|
||||
if (streq(fields[2], ""))
|
||||
return NULL;
|
||||
|
||||
grent.gr_name = fields[0];
|
||||
grent.gr_passwd = fields[1];
|
||||
if (get_gid(fields[2], &grent.gr_gid) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
grent.gr_name = grpfields[0];
|
||||
grent.gr_passwd = grpfields[1];
|
||||
if (get_gid(grpfields[2], &grent.gr_gid) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
grent.gr_mem = list (grpfields[3]);
|
||||
grent.gr_mem = list(fields[3]);
|
||||
if (NULL == grent.gr_mem) {
|
||||
return NULL; /* out of memory */
|
||||
}
|
||||
|
||||
return &grent;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,20 +11,21 @@
|
||||
|
||||
#ident "$Id$"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "atoi/getnum.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
#include "string/strtok/strsep2arr.h"
|
||||
|
||||
|
||||
#define NFIELDS 7
|
||||
|
||||
/*
|
||||
* sgetpwent - convert a string to a (struct passwd)
|
||||
*
|
||||
@@ -38,47 +39,26 @@
|
||||
* compilation glarp to improve on this in the future.
|
||||
*/
|
||||
struct passwd *
|
||||
sgetpwent(const char *buf)
|
||||
sgetpwent(const char *s)
|
||||
{
|
||||
static char *dup = NULL;
|
||||
static struct passwd pwent;
|
||||
static char pwdbuf[PASSWD_ENTRY_MAX_LENGTH];
|
||||
int i;
|
||||
char *cp;
|
||||
char *fields[NFIELDS];
|
||||
|
||||
/*
|
||||
* Copy the string to a static buffer so the pointers into
|
||||
* the password structure remain valid.
|
||||
*/
|
||||
char *fields[7];
|
||||
|
||||
if (strlen (buf) >= sizeof pwdbuf) {
|
||||
fprintf (shadow_logfd,
|
||||
"%s: Too long passwd entry encountered, file corruption?\n",
|
||||
shadow_progname);
|
||||
return NULL; /* fail if too long */
|
||||
}
|
||||
strcpy (pwdbuf, buf);
|
||||
|
||||
/*
|
||||
* Save a pointer to the start of each colon separated
|
||||
* field. The fields are converted into NUL terminated strings.
|
||||
*/
|
||||
|
||||
for (cp = pwdbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++)
|
||||
fields[i] = strsep(&cp, ":");
|
||||
|
||||
/* something at the end, columns over shot */
|
||||
if ( cp != NULL ) {
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
/*
|
||||
* There must be exactly NFIELDS colon separated fields or
|
||||
* the entry is invalid. Also, the UID and GID must be non-blank.
|
||||
*/
|
||||
|
||||
if (i != NFIELDS)
|
||||
free(dup);
|
||||
dup = strdup(s);
|
||||
if (dup == NULL)
|
||||
return NULL;
|
||||
|
||||
stpsep(dup, "\n");
|
||||
|
||||
if (STRSEP2ARR(dup, ":", fields) == -1)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* The UID and GID must be non-blank.
|
||||
*/
|
||||
if (streq(fields[2], ""))
|
||||
return NULL;
|
||||
if (streq(fields[3], ""))
|
||||
|
||||
@@ -16,16 +16,19 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "atoi/a2i/a2s.h"
|
||||
#include "atoi/str2i/str2u.h"
|
||||
#include "atoi/str2i.h"
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "shadowlog_internal.h"
|
||||
#include "sizeof.h"
|
||||
#include "string/strcmp/streq.h"
|
||||
#include "string/strtok/stpsep.h"
|
||||
#include "string/strtok/strsep2arr.h"
|
||||
|
||||
|
||||
#define FIELDS 9
|
||||
@@ -36,40 +39,25 @@
|
||||
* sgetspent - convert string in shadow file format to (struct spwd *)
|
||||
*/
|
||||
struct spwd *
|
||||
sgetspent(const char *string)
|
||||
sgetspent(const char *s)
|
||||
{
|
||||
static char spwbuf[PASSWD_ENTRY_MAX_LENGTH];
|
||||
static char *dup = NULL;
|
||||
static struct spwd spwd;
|
||||
|
||||
char *fields[FIELDS];
|
||||
char *cp;
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
/*
|
||||
* Copy string to local buffer. It has to be tokenized and we
|
||||
* have to do that to our private copy.
|
||||
*/
|
||||
free(dup);
|
||||
dup = strdup(s);
|
||||
if (dup == NULL)
|
||||
return NULL;
|
||||
|
||||
if (strlen (string) >= sizeof spwbuf) {
|
||||
fprintf (shadow_logfd,
|
||||
"%s: Too long passwd entry encountered, file corruption?\n",
|
||||
shadow_progname);
|
||||
return NULL; /* fail if too long */
|
||||
}
|
||||
strcpy (spwbuf, string);
|
||||
stpsep(spwbuf, "\n");
|
||||
stpsep(dup, "\n");
|
||||
|
||||
/*
|
||||
* Tokenize the string into colon separated fields. Allow up to
|
||||
* FIELDS different fields.
|
||||
*/
|
||||
|
||||
for (cp = spwbuf, i = 0; cp != NULL && i < FIELDS; i++)
|
||||
fields[i] = strsep(&cp, ":");
|
||||
|
||||
if (i == (FIELDS - 1))
|
||||
i = strsep2arr(dup, ":", countof(fields), fields);
|
||||
if (i == countof(fields) - 1)
|
||||
fields[i++] = "";
|
||||
|
||||
if (cp != NULL || (i != FIELDS && i != OFIELDS))
|
||||
if (i != countof(fields) && i != OFIELDS)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "commonio.h"
|
||||
#include "fields.h"
|
||||
#include "getdef.h"
|
||||
#include "sgroupio.h"
|
||||
#include "string/memset/memzero.h"
|
||||
@@ -36,9 +37,9 @@
|
||||
/* Do the same as the other _dup function, even if we know the
|
||||
* structure. */
|
||||
/*@-mustfreeonly@*/
|
||||
sg->sg_name = strdup (sgent->sg_name);
|
||||
sg->sg_namp = strdup (sgent->sg_namp);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == sg->sg_name) {
|
||||
if (NULL == sg->sg_namp) {
|
||||
free (sg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -46,7 +47,7 @@
|
||||
sg->sg_passwd = strdup (sgent->sg_passwd);
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == sg->sg_passwd) {
|
||||
free (sg->sg_name);
|
||||
free (sg->sg_namp);
|
||||
free (sg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -57,7 +58,7 @@
|
||||
/*@=mustfreeonly@*/
|
||||
if (NULL == sg->sg_adm) {
|
||||
free (sg->sg_passwd);
|
||||
free (sg->sg_name);
|
||||
free (sg->sg_namp);
|
||||
free (sg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -69,7 +70,7 @@
|
||||
}
|
||||
free (sg->sg_adm);
|
||||
free (sg->sg_passwd);
|
||||
free (sg->sg_name);
|
||||
free (sg->sg_namp);
|
||||
free (sg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -86,7 +87,7 @@
|
||||
}
|
||||
free (sg->sg_adm);
|
||||
free (sg->sg_passwd);
|
||||
free (sg->sg_name);
|
||||
free (sg->sg_namp);
|
||||
free (sg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -102,7 +103,7 @@
|
||||
}
|
||||
free (sg->sg_adm);
|
||||
free (sg->sg_passwd);
|
||||
free (sg->sg_name);
|
||||
free (sg->sg_namp);
|
||||
free (sg);
|
||||
return NULL;
|
||||
}
|
||||
@@ -131,7 +132,7 @@ void
|
||||
sgr_free(/*@only@*/struct sgrp *sgent)
|
||||
{
|
||||
size_t i;
|
||||
free (sgent->sg_name);
|
||||
free (sgent->sg_namp);
|
||||
if (NULL != sgent->sg_passwd)
|
||||
free(strzero(sgent->sg_passwd));
|
||||
|
||||
@@ -150,7 +151,7 @@ static const char *gshadow_getname (const void *ent)
|
||||
{
|
||||
const struct sgrp *gr = ent;
|
||||
|
||||
return gr->sg_name;
|
||||
return gr->sg_namp;
|
||||
}
|
||||
|
||||
static void *gshadow_parse (const char *line)
|
||||
@@ -163,7 +164,7 @@ static int gshadow_put (const void *ent, FILE * file)
|
||||
const struct sgrp *sg = ent;
|
||||
|
||||
if ( (NULL == sg)
|
||||
|| (valid_field (sg->sg_name, ":\n") == -1)
|
||||
|| (valid_field (sg->sg_namp, ":\n") == -1)
|
||||
|| (valid_field (sg->sg_passwd, ":\n") == -1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user