diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-26 16:18:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-26 16:18:39 +0000 |
commit | 5242eef8fc54636a41701fd9d7083ba6e4a4e0b3 (patch) | |
tree | e6a0980092957865a937cc0f34446df3d5194e99 /libmisc | |
parent | Releasing progress-linux version 1:4.13+dfsg1-5~progress7.99u1. (diff) | |
download | shadow-5242eef8fc54636a41701fd9d7083ba6e4a4e0b3.tar.xz shadow-5242eef8fc54636a41701fd9d7083ba6e4a4e0b3.zip |
Merging upstream version 1:4.15.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libmisc')
74 files changed, 0 insertions, 14891 deletions
diff --git a/libmisc/.indent.pro b/libmisc/.indent.pro deleted file mode 100644 index fe572bb..0000000 --- a/libmisc/.indent.pro +++ /dev/null @@ -1,5 +0,0 @@ --kr --i8 --bad --pcs --l80 diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am deleted file mode 100644 index 3d319cd..0000000 --- a/libmisc/Makefile.am +++ /dev/null @@ -1,80 +0,0 @@ - -EXTRA_DIST = .indent.pro xgetXXbyYY.c - -AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) $(ECONF_CPPFLAGS) - -noinst_LTLIBRARIES = libmisc.la - -libmisc_la_SOURCES = \ - addgrps.c \ - age.c \ - audit_help.c \ - basename.c \ - chkname.c \ - chkname.h \ - chowndir.c \ - chowntty.c \ - cleanup.c \ - cleanup_group.c \ - cleanup_user.c \ - console.c \ - copydir.c \ - date_to_str.c \ - entry.c \ - env.c \ - failure.c \ - failure.h \ - find_new_gid.c \ - find_new_uid.c \ - find_new_sub_gids.c \ - find_new_sub_uids.c \ - getdate.h \ - getdate.y \ - getgr_nam_gid.c \ - getrange.c \ - gettime.c \ - hushed.c \ - idmapping.h \ - idmapping.c \ - isexpired.c \ - limits.c \ - list.c log.c \ - loginprompt.c \ - mail.c \ - motd.c \ - myname.c \ - obscure.c \ - pam_pass.c \ - pam_pass_non_interactive.c \ - prefix_flag.c \ - pwd2spwd.c \ - pwdcheck.c \ - pwd_init.c \ - remove_tree.c \ - rlogin.c \ - root_flag.c \ - salt.c \ - setugid.c \ - setupenv.c \ - shell.c \ - strtoday.c \ - sub.c \ - sulog.c \ - ttytype.c \ - tz.c \ - ulimit.c \ - user_busy.c \ - utmp.c \ - valid.c \ - xgetpwnam.c \ - xgetpwuid.c \ - xgetgrnam.c \ - xgetgrgid.c \ - xgetspnam.c \ - xmalloc.c \ - yesno.c - -if WITH_BTRFS -libmisc_la_SOURCES += btrfs.c -endif - diff --git a/libmisc/Makefile.in b/libmisc/Makefile.in deleted file mode 100644 index 2defd8e..0000000 --- a/libmisc/Makefile.in +++ /dev/null @@ -1,927 +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@ - -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@ -@WITH_BTRFS_TRUE@am__append_1 = btrfs.c -subdir = libmisc -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 = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libmisc_la_LIBADD = -am__libmisc_la_SOURCES_DIST = addgrps.c age.c audit_help.c basename.c \ - chkname.c chkname.h chowndir.c chowntty.c cleanup.c \ - cleanup_group.c cleanup_user.c console.c copydir.c \ - date_to_str.c entry.c env.c failure.c failure.h find_new_gid.c \ - find_new_uid.c find_new_sub_gids.c find_new_sub_uids.c \ - getdate.h getdate.y getgr_nam_gid.c getrange.c gettime.c \ - hushed.c idmapping.h idmapping.c isexpired.c limits.c list.c \ - log.c loginprompt.c mail.c motd.c myname.c obscure.c \ - pam_pass.c pam_pass_non_interactive.c prefix_flag.c pwd2spwd.c \ - pwdcheck.c pwd_init.c remove_tree.c rlogin.c root_flag.c \ - salt.c setugid.c setupenv.c shell.c strtoday.c sub.c sulog.c \ - ttytype.c tz.c ulimit.c user_busy.c utmp.c valid.c xgetpwnam.c \ - xgetpwuid.c xgetgrnam.c xgetgrgid.c xgetspnam.c xmalloc.c \ - yesno.c btrfs.c -@WITH_BTRFS_TRUE@am__objects_1 = btrfs.lo -am_libmisc_la_OBJECTS = addgrps.lo age.lo audit_help.lo basename.lo \ - chkname.lo chowndir.lo chowntty.lo cleanup.lo cleanup_group.lo \ - cleanup_user.lo console.lo copydir.lo date_to_str.lo entry.lo \ - env.lo failure.lo find_new_gid.lo find_new_uid.lo \ - find_new_sub_gids.lo find_new_sub_uids.lo getdate.lo \ - getgr_nam_gid.lo getrange.lo gettime.lo hushed.lo idmapping.lo \ - isexpired.lo limits.lo list.lo log.lo loginprompt.lo mail.lo \ - motd.lo myname.lo obscure.lo pam_pass.lo \ - pam_pass_non_interactive.lo prefix_flag.lo pwd2spwd.lo \ - pwdcheck.lo pwd_init.lo remove_tree.lo rlogin.lo root_flag.lo \ - salt.lo setugid.lo setupenv.lo shell.lo strtoday.lo sub.lo \ - sulog.lo ttytype.lo tz.lo ulimit.lo user_busy.lo utmp.lo \ - valid.lo xgetpwnam.lo xgetpwuid.lo xgetgrnam.lo xgetgrgid.lo \ - xgetspnam.lo xmalloc.lo yesno.lo $(am__objects_1) -libmisc_la_OBJECTS = $(am_libmisc_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -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 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__maybe_remake_depfiles = depfiles -am__depfiles_remade = ./$(DEPDIR)/addgrps.Plo ./$(DEPDIR)/age.Plo \ - ./$(DEPDIR)/audit_help.Plo ./$(DEPDIR)/basename.Plo \ - ./$(DEPDIR)/btrfs.Plo ./$(DEPDIR)/chkname.Plo \ - ./$(DEPDIR)/chowndir.Plo ./$(DEPDIR)/chowntty.Plo \ - ./$(DEPDIR)/cleanup.Plo ./$(DEPDIR)/cleanup_group.Plo \ - ./$(DEPDIR)/cleanup_user.Plo ./$(DEPDIR)/console.Plo \ - ./$(DEPDIR)/copydir.Plo ./$(DEPDIR)/date_to_str.Plo \ - ./$(DEPDIR)/entry.Plo ./$(DEPDIR)/env.Plo \ - ./$(DEPDIR)/failure.Plo ./$(DEPDIR)/find_new_gid.Plo \ - ./$(DEPDIR)/find_new_sub_gids.Plo \ - ./$(DEPDIR)/find_new_sub_uids.Plo ./$(DEPDIR)/find_new_uid.Plo \ - ./$(DEPDIR)/getdate.Plo ./$(DEPDIR)/getgr_nam_gid.Plo \ - ./$(DEPDIR)/getrange.Plo ./$(DEPDIR)/gettime.Plo \ - ./$(DEPDIR)/hushed.Plo ./$(DEPDIR)/idmapping.Plo \ - ./$(DEPDIR)/isexpired.Plo ./$(DEPDIR)/limits.Plo \ - ./$(DEPDIR)/list.Plo ./$(DEPDIR)/log.Plo \ - ./$(DEPDIR)/loginprompt.Plo ./$(DEPDIR)/mail.Plo \ - ./$(DEPDIR)/motd.Plo ./$(DEPDIR)/myname.Plo \ - ./$(DEPDIR)/obscure.Plo ./$(DEPDIR)/pam_pass.Plo \ - ./$(DEPDIR)/pam_pass_non_interactive.Plo \ - ./$(DEPDIR)/prefix_flag.Plo ./$(DEPDIR)/pwd2spwd.Plo \ - ./$(DEPDIR)/pwd_init.Plo ./$(DEPDIR)/pwdcheck.Plo \ - ./$(DEPDIR)/remove_tree.Plo ./$(DEPDIR)/rlogin.Plo \ - ./$(DEPDIR)/root_flag.Plo ./$(DEPDIR)/salt.Plo \ - ./$(DEPDIR)/setugid.Plo ./$(DEPDIR)/setupenv.Plo \ - ./$(DEPDIR)/shell.Plo ./$(DEPDIR)/strtoday.Plo \ - ./$(DEPDIR)/sub.Plo ./$(DEPDIR)/sulog.Plo \ - ./$(DEPDIR)/ttytype.Plo ./$(DEPDIR)/tz.Plo \ - ./$(DEPDIR)/ulimit.Plo ./$(DEPDIR)/user_busy.Plo \ - ./$(DEPDIR)/utmp.Plo ./$(DEPDIR)/valid.Plo \ - ./$(DEPDIR)/xgetgrgid.Plo ./$(DEPDIR)/xgetgrnam.Plo \ - ./$(DEPDIR)/xgetpwnam.Plo ./$(DEPDIR)/xgetpwuid.Plo \ - ./$(DEPDIR)/xgetspnam.Plo ./$(DEPDIR)/xmalloc.Plo \ - ./$(DEPDIR)/yesno.Plo -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -@MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ || -am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \ - -e s/c++$$/h++/ -e s/c$$/h/ -YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) -LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) -AM_V_YACC = $(am__v_YACC_@AM_V@) -am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) -am__v_YACC_0 = @echo " YACC " $@; -am__v_YACC_1 = -YLWRAP = $(top_srcdir)/ylwrap -SOURCES = $(libmisc_la_SOURCES) -DIST_SOURCES = $(am__libmisc_la_SOURCES_DIST) -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) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp \ - $(top_srcdir)/ylwrap getdate.c -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@ -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@ -LIBATTR = @LIBATTR@ -LIBAUDIT = @LIBAUDIT@ -LIBCRACK = @LIBCRACK@ -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@ -LIBTCB = @LIBTCB@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LIYESCRYPT = @LIYESCRYPT@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -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@ -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 = .indent.pro xgetXXbyYY.c -AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir) $(ECONF_CPPFLAGS) -noinst_LTLIBRARIES = libmisc.la -libmisc_la_SOURCES = addgrps.c age.c audit_help.c basename.c chkname.c \ - chkname.h chowndir.c chowntty.c cleanup.c cleanup_group.c \ - cleanup_user.c console.c copydir.c date_to_str.c entry.c env.c \ - failure.c failure.h find_new_gid.c find_new_uid.c \ - find_new_sub_gids.c find_new_sub_uids.c getdate.h getdate.y \ - getgr_nam_gid.c getrange.c gettime.c hushed.c idmapping.h \ - idmapping.c isexpired.c limits.c list.c log.c loginprompt.c \ - mail.c motd.c myname.c obscure.c pam_pass.c \ - pam_pass_non_interactive.c prefix_flag.c pwd2spwd.c pwdcheck.c \ - pwd_init.c remove_tree.c rlogin.c root_flag.c salt.c setugid.c \ - setupenv.c shell.c strtoday.c sub.c sulog.c ttytype.c tz.c \ - ulimit.c user_busy.c utmp.c valid.c xgetpwnam.c xgetpwuid.c \ - xgetgrnam.c xgetgrgid.c xgetspnam.c xmalloc.c yesno.c \ - $(am__append_1) -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj .y -$(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 libmisc/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign libmisc/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): - -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libmisc.la: $(libmisc_la_OBJECTS) $(libmisc_la_DEPENDENCIES) $(EXTRA_libmisc_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libmisc_la_OBJECTS) $(libmisc_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/addgrps.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/age.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audit_help.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basename.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/btrfs.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chkname.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chowndir.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chowntty.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanup.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanup_group.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cleanup_user.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copydir.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/date_to_str.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entry.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/env.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/failure.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_new_gid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_new_sub_gids.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_new_sub_uids.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/find_new_uid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdate.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getgr_nam_gid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getrange.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gettime.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hushed.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/idmapping.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/isexpired.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/limits.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/list.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loginprompt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mail.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/motd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myname.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/obscure.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pass.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pass_non_interactive.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefix_flag.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwd2spwd.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwd_init.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwdcheck.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/remove_tree.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rlogin.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/root_flag.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salt.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setugid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/setupenv.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shell.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strtoday.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sub.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sulog.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttytype.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tz.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ulimit.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/user_busy.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utmp.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/valid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetgrgid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetgrnam.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetpwnam.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetpwuid.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xgetspnam.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yesno.Plo@am__quote@ # am--include-marker - -$(am__depfiles_remade): - @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ - -am--depfiles: $(am__depfiles_remade) - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -.y.c: - $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -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 $(LTLIBRARIES) -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." - -rm -f getdate.c -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -f ./$(DEPDIR)/addgrps.Plo - -rm -f ./$(DEPDIR)/age.Plo - -rm -f ./$(DEPDIR)/audit_help.Plo - -rm -f ./$(DEPDIR)/basename.Plo - -rm -f ./$(DEPDIR)/btrfs.Plo - -rm -f ./$(DEPDIR)/chkname.Plo - -rm -f ./$(DEPDIR)/chowndir.Plo - -rm -f ./$(DEPDIR)/chowntty.Plo - -rm -f ./$(DEPDIR)/cleanup.Plo - -rm -f ./$(DEPDIR)/cleanup_group.Plo - -rm -f ./$(DEPDIR)/cleanup_user.Plo - -rm -f ./$(DEPDIR)/console.Plo - -rm -f ./$(DEPDIR)/copydir.Plo - -rm -f ./$(DEPDIR)/date_to_str.Plo - -rm -f ./$(DEPDIR)/entry.Plo - -rm -f ./$(DEPDIR)/env.Plo - -rm -f ./$(DEPDIR)/failure.Plo - -rm -f ./$(DEPDIR)/find_new_gid.Plo - -rm -f ./$(DEPDIR)/find_new_sub_gids.Plo - -rm -f ./$(DEPDIR)/find_new_sub_uids.Plo - -rm -f ./$(DEPDIR)/find_new_uid.Plo - -rm -f ./$(DEPDIR)/getdate.Plo - -rm -f ./$(DEPDIR)/getgr_nam_gid.Plo - -rm -f ./$(DEPDIR)/getrange.Plo - -rm -f ./$(DEPDIR)/gettime.Plo - -rm -f ./$(DEPDIR)/hushed.Plo - -rm -f ./$(DEPDIR)/idmapping.Plo - -rm -f ./$(DEPDIR)/isexpired.Plo - -rm -f ./$(DEPDIR)/limits.Plo - -rm -f ./$(DEPDIR)/list.Plo - -rm -f ./$(DEPDIR)/log.Plo - -rm -f ./$(DEPDIR)/loginprompt.Plo - -rm -f ./$(DEPDIR)/mail.Plo - -rm -f ./$(DEPDIR)/motd.Plo - -rm -f ./$(DEPDIR)/myname.Plo - -rm -f ./$(DEPDIR)/obscure.Plo - -rm -f ./$(DEPDIR)/pam_pass.Plo - -rm -f ./$(DEPDIR)/pam_pass_non_interactive.Plo - -rm -f ./$(DEPDIR)/prefix_flag.Plo - -rm -f ./$(DEPDIR)/pwd2spwd.Plo - -rm -f ./$(DEPDIR)/pwd_init.Plo - -rm -f ./$(DEPDIR)/pwdcheck.Plo - -rm -f ./$(DEPDIR)/remove_tree.Plo - -rm -f ./$(DEPDIR)/rlogin.Plo - -rm -f ./$(DEPDIR)/root_flag.Plo - -rm -f ./$(DEPDIR)/salt.Plo - -rm -f ./$(DEPDIR)/setugid.Plo - -rm -f ./$(DEPDIR)/setupenv.Plo - -rm -f ./$(DEPDIR)/shell.Plo - -rm -f ./$(DEPDIR)/strtoday.Plo - -rm -f ./$(DEPDIR)/sub.Plo - -rm -f ./$(DEPDIR)/sulog.Plo - -rm -f ./$(DEPDIR)/ttytype.Plo - -rm -f ./$(DEPDIR)/tz.Plo - -rm -f ./$(DEPDIR)/ulimit.Plo - -rm -f ./$(DEPDIR)/user_busy.Plo - -rm -f ./$(DEPDIR)/utmp.Plo - -rm -f ./$(DEPDIR)/valid.Plo - -rm -f ./$(DEPDIR)/xgetgrgid.Plo - -rm -f ./$(DEPDIR)/xgetgrnam.Plo - -rm -f ./$(DEPDIR)/xgetpwnam.Plo - -rm -f ./$(DEPDIR)/xgetpwuid.Plo - -rm -f ./$(DEPDIR)/xgetspnam.Plo - -rm -f ./$(DEPDIR)/xmalloc.Plo - -rm -f ./$(DEPDIR)/yesno.Plo - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -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 ./$(DEPDIR)/addgrps.Plo - -rm -f ./$(DEPDIR)/age.Plo - -rm -f ./$(DEPDIR)/audit_help.Plo - -rm -f ./$(DEPDIR)/basename.Plo - -rm -f ./$(DEPDIR)/btrfs.Plo - -rm -f ./$(DEPDIR)/chkname.Plo - -rm -f ./$(DEPDIR)/chowndir.Plo - -rm -f ./$(DEPDIR)/chowntty.Plo - -rm -f ./$(DEPDIR)/cleanup.Plo - -rm -f ./$(DEPDIR)/cleanup_group.Plo - -rm -f ./$(DEPDIR)/cleanup_user.Plo - -rm -f ./$(DEPDIR)/console.Plo - -rm -f ./$(DEPDIR)/copydir.Plo - -rm -f ./$(DEPDIR)/date_to_str.Plo - -rm -f ./$(DEPDIR)/entry.Plo - -rm -f ./$(DEPDIR)/env.Plo - -rm -f ./$(DEPDIR)/failure.Plo - -rm -f ./$(DEPDIR)/find_new_gid.Plo - -rm -f ./$(DEPDIR)/find_new_sub_gids.Plo - -rm -f ./$(DEPDIR)/find_new_sub_uids.Plo - -rm -f ./$(DEPDIR)/find_new_uid.Plo - -rm -f ./$(DEPDIR)/getdate.Plo - -rm -f ./$(DEPDIR)/getgr_nam_gid.Plo - -rm -f ./$(DEPDIR)/getrange.Plo - -rm -f ./$(DEPDIR)/gettime.Plo - -rm -f ./$(DEPDIR)/hushed.Plo - -rm -f ./$(DEPDIR)/idmapping.Plo - -rm -f ./$(DEPDIR)/isexpired.Plo - -rm -f ./$(DEPDIR)/limits.Plo - -rm -f ./$(DEPDIR)/list.Plo - -rm -f ./$(DEPDIR)/log.Plo - -rm -f ./$(DEPDIR)/loginprompt.Plo - -rm -f ./$(DEPDIR)/mail.Plo - -rm -f ./$(DEPDIR)/motd.Plo - -rm -f ./$(DEPDIR)/myname.Plo - -rm -f ./$(DEPDIR)/obscure.Plo - -rm -f ./$(DEPDIR)/pam_pass.Plo - -rm -f ./$(DEPDIR)/pam_pass_non_interactive.Plo - -rm -f ./$(DEPDIR)/prefix_flag.Plo - -rm -f ./$(DEPDIR)/pwd2spwd.Plo - -rm -f ./$(DEPDIR)/pwd_init.Plo - -rm -f ./$(DEPDIR)/pwdcheck.Plo - -rm -f ./$(DEPDIR)/remove_tree.Plo - -rm -f ./$(DEPDIR)/rlogin.Plo - -rm -f ./$(DEPDIR)/root_flag.Plo - -rm -f ./$(DEPDIR)/salt.Plo - -rm -f ./$(DEPDIR)/setugid.Plo - -rm -f ./$(DEPDIR)/setupenv.Plo - -rm -f ./$(DEPDIR)/shell.Plo - -rm -f ./$(DEPDIR)/strtoday.Plo - -rm -f ./$(DEPDIR)/sub.Plo - -rm -f ./$(DEPDIR)/sulog.Plo - -rm -f ./$(DEPDIR)/ttytype.Plo - -rm -f ./$(DEPDIR)/tz.Plo - -rm -f ./$(DEPDIR)/ulimit.Plo - -rm -f ./$(DEPDIR)/user_busy.Plo - -rm -f ./$(DEPDIR)/utmp.Plo - -rm -f ./$(DEPDIR)/valid.Plo - -rm -f ./$(DEPDIR)/xgetgrgid.Plo - -rm -f ./$(DEPDIR)/xgetgrnam.Plo - -rm -f ./$(DEPDIR)/xgetpwnam.Plo - -rm -f ./$(DEPDIR)/xgetpwuid.Plo - -rm -f ./$(DEPDIR)/xgetspnam.Plo - -rm -f ./$(DEPDIR)/xmalloc.Plo - -rm -f ./$(DEPDIR)/yesno.Plo - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ - clean-generic clean-libtool clean-noinstLTLIBRARIES \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags 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-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags 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: diff --git a/libmisc/addgrps.c b/libmisc/addgrps.c deleted file mode 100644 index 845d383..0000000 --- a/libmisc/addgrps.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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 - */ - -#include <config.h> - -#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM) - -#include "prototypes.h" -#include "defines.h" - -#include <stdio.h> -#include <grp.h> -#include <errno.h> -#include "shadowlog.h" - -#ident "$Id$" - -#define SEP ",:" -/* - * Add groups with names from LIST (separated by commas or colons) - * to the supplementary group set. Silently ignore groups which are - * already there. Warning: uses strtok(). - */ -int add_groups (const char *list) -{ - GETGROUPS_T *grouplist, *tmp; - size_t i; - int ngroups; - bool added; - char *token; - char buf[1024]; - int ret; - FILE *shadow_logfd = log_get_logfd(); - - if (strlen (list) >= sizeof (buf)) { - errno = EINVAL; - return -1; - } - strcpy (buf, list); - - i = 16; - for (;;) { - grouplist = (gid_t *) malloc (i * sizeof (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); - return -1; - } - - added = false; - for (token = strtok (buf, SEP); NULL != token; token = strtok (NULL, SEP)) { - struct group *grp; - - grp = getgrnam (token); /* local, no need for xgetgrnam */ - if (NULL == grp) { - fprintf (shadow_logfd, _("Warning: unknown group %s\n"), - token); - continue; - } - - for (i = 0; i < (size_t)ngroups && grouplist[i] != grp->gr_gid; i++); - - if (i < (size_t)ngroups) { - continue; - } - - if (ngroups >= sysconf (_SC_NGROUPS_MAX)) { - fputs (_("Warning: too many groups\n"), shadow_logfd); - break; - } - tmp = (gid_t *) realloc (grouplist, (size_t)(ngroups + 1) * sizeof (GETGROUPS_T)); - if (NULL == tmp) { - free (grouplist); - return -1; - } - tmp[ngroups] = grp->gr_gid; - ngroups++; - grouplist = tmp; - added = true; - } - - if (added) { - ret = setgroups ((size_t)ngroups, grouplist); - free (grouplist); - return ret; - } - - free (grouplist); - return 0; -} -#else /* HAVE_SETGROUPS && !USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* HAVE_SETGROUPS && !USE_PAM */ - diff --git a/libmisc/age.c b/libmisc/age.c deleted file mode 100644 index d10f71b..0000000 --- a/libmisc/age.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include <sys/types.h> -#include <stdio.h> -#include <time.h> -#include <errno.h> -#include "prototypes.h" -#include "defines.h" -#include "exitcodes.h" -#include <pwd.h> -#include <grp.h> - -#ident "$Id$" - -#ifndef PASSWD_PROGRAM -#define PASSWD_PROGRAM "/bin/passwd" -#endif -/* - * expire - force password change if password expired - * - * expire() calls /bin/passwd to change the user's password - * if it has expired. - */ -int expire (const struct passwd *pw, /*@null@*/const struct spwd *sp) -{ - int status; - pid_t child; - pid_t pid; - - if (NULL == sp) { - return 0; - } - - /* - * See if the user's password has expired, and if so - * force them to change their password. - */ - - status = isexpired (pw, sp); - switch (status) { - case 0: - return 0; - case 1: - (void) fputs (_("Your password has expired."), stdout); - break; - case 2: - (void) fputs (_("Your password is inactive."), stdout); - break; - case 3: - (void) fputs (_("Your login has expired."), stdout); - break; - } - - /* - * Setting the maximum valid period to less than the minimum - * valid period means that the minimum period will never - * occur while the password is valid, so the user can never - * change that password. - */ - - if ((status > 1) || (sp->sp_max < sp->sp_min)) { - (void) puts (_(" Contact the system administrator.")); - exit (EXIT_FAILURE); - } - (void) puts (_(" Choose a new password.")); - (void) fflush (stdout); - - /* - * Close all the files so that unauthorized access won't - * occur. This needs to be done anyway because those files - * might become stale after "passwd" is executed. - */ - - endspent (); - endpwent (); -#ifdef SHADOWGRP - endsgent (); -#endif - endgrent (); - - /* - * Execute the /bin/passwd command. The exit status will be - * examined to see what the result is. If there are any - * errors the routine will exit. This forces the user to - * change their password before being able to use the account. - */ - - pid = fork (); - if (0 == pid) { - int err; - - /* - * Set the UID to be that of the user. This causes - * 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 (setup_uid_gid (pw, false) != 0) -#else - if (setup_uid_gid (pw) != 0) -#endif - { - _exit (126); - } - - (void) execl (PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *) 0); - err = errno; - perror ("Can't execute " PASSWD_PROGRAM); - _exit ((ENOENT == err) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); - } else if ((pid_t) -1 == pid) { - perror ("fork"); - exit (EXIT_FAILURE); - } - - while (((child = wait (&status)) != pid) && (child != (pid_t)-1)); - - if ((child == pid) && (0 == status)) { - return 1; - } - - exit (EXIT_FAILURE); - /*@notreached@*/} - -/* - * agecheck - see if warning is needed for password expiration - * - * agecheck sees how many days until the user's password is going - * to expire and warns the user of the pending password expiration. - */ - -void agecheck (/*@null@*/const struct spwd *sp) -{ - long now = (long) time ((time_t *) 0) / SCALE; - long remain; - - if (NULL == sp) { - return; - } - - /* - * The last, max, and warn fields must be supported or the - * warning period cannot be calculated. - */ - - if ( (-1 == sp->sp_lstchg) - || (-1 == sp->sp_max) - || (-1 == sp->sp_warn)) { - return; - } - - if (0 == sp->sp_lstchg) { - (void) puts (_("You must change your password.")); - return; - } - - remain = sp->sp_lstchg + sp->sp_max - now; - if (remain <= sp->sp_warn) { - remain /= DAY / SCALE; - if (remain > 1) { - (void) printf (_("Your password will expire in %ld days.\n"), - remain); - } else if (1 == remain) { - (void) puts (_("Your password will expire tomorrow.")); - } else if (remain == 0) { - (void) puts (_("Your password will expire today.")); - } - } -} - diff --git a/libmisc/audit_help.c b/libmisc/audit_help.c deleted file mode 100644 index e6c2006..0000000 --- a/libmisc/audit_help.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2005 , Red Hat, Inc. - * SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Audit helper functions used throughout shadow - * - */ - -#include <config.h> - -#ifdef WITH_AUDIT - -#include <stdlib.h> -#include <syslog.h> -#include <stdarg.h> -#include <libaudit.h> -#include <errno.h> -#include <stdio.h> -#include "prototypes.h" -#include "shadowlog.h" -int audit_fd; - -void audit_help_open (void) -{ - audit_fd = audit_open (); - if (audit_fd < 0) { - /* You get these only when the kernel doesn't have - * audit compiled in. */ - if ( (errno == EINVAL) - || (errno == EPROTONOSUPPORT) - || (errno == EAFNOSUPPORT)) { - return; - } - (void) fputs (_("Cannot open audit interface - aborting.\n"), - log_get_logfd()); - exit (EXIT_FAILURE); - } -} - -/* - * This function will log a message to the audit system using a predefined - * message format. Parameter usage is as follows: - * - * type - type of message: AUDIT_USER_CHAUTHTOK for changing any account - * attributes. - * 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. - * id - uid or gid that the operation is being performed on. This is used - * only when user is NULL. - */ -void audit_logger (int type, unused const char *pgname, const char *op, - const char *name, unsigned int id, - shadow_audit_result result) -{ - if (audit_fd < 0) { - return; - } else { - audit_log_acct_message (audit_fd, type, NULL, op, name, id, - NULL, NULL, NULL, (int) result); - } -} - -void audit_logger_message (const char *message, shadow_audit_result result) -{ - if (audit_fd < 0) { - return; - } else { - audit_log_user_message (audit_fd, - AUDIT_USYS_CONFIG, - message, - NULL, /* hostname */ - NULL, /* addr */ - NULL, /* tty */ - (int) result); - } -} - -#else /* WITH_AUDIT */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* WITH_AUDIT */ - diff --git a/libmisc/basename.c b/libmisc/basename.c deleted file mode 100644 index fe91653..0000000 --- a/libmisc/basename.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 - */ - -/* - * basename.c - not worth copyrighting :-). Some versions of Linux libc - * already have basename(), other versions don't. To avoid confusion, - * we will not use the function from libc and use a different name here. - * --marekm - */ - -#include <config.h> - -#ident "$Id$" - -#include "defines.h" -#include "prototypes.h" -/*@observer@*/const char *Basename (const char *str) -{ - char *cp = strrchr (str, '/'); - - return (NULL != cp) ? cp + 1 : str; -} diff --git a/libmisc/btrfs.c b/libmisc/btrfs.c deleted file mode 100644 index a2563f7..0000000 --- a/libmisc/btrfs.c +++ /dev/null @@ -1,110 +0,0 @@ -#include <linux/btrfs_tree.h> -#include <linux/magic.h> -#include <sys/statfs.h> -#include <stdbool.h> - -#include "prototypes.h" - -static bool path_exists(const char *p) -{ - struct stat sb; - - return stat(p, &sb) == 0; -} - -static const char *btrfs_cmd(void) -{ - const char *const btrfs_paths[] = {"/sbin/btrfs", - "/bin/btrfs", "/usr/sbin/btrfs", "/usr/bin/btrfs", NULL}; - const char *p; - int i; - - for (i = 0, p = btrfs_paths[i]; p; i++, p = btrfs_paths[i]) - if (path_exists(p)) - return p; - - return NULL; -} - -static int run_btrfs_subvolume_cmd(const char *subcmd, const char *arg1, const char *arg2) -{ - int status = 0; - const char *cmd = btrfs_cmd(); - const char *argv[] = { - "btrfs", - "subvolume", - subcmd, - arg1, - arg2, - NULL - }; - - if (access(cmd, X_OK)) { - return 1; - } - - if (run_command(cmd, argv, NULL, &status)) - return -1; - return status; -} - - -int btrfs_create_subvolume(const char *path) -{ - return run_btrfs_subvolume_cmd("create", path, NULL); -} - - -int btrfs_remove_subvolume(const char *path) -{ - return run_btrfs_subvolume_cmd("delete", "-C", path); -} - - -/* Adapted from btrfsprogs */ -/* - * This intentionally duplicates btrfs_util_is_subvolume_fd() instead of opening - * a file descriptor and calling it, because fstat() and fstatfs() don't accept - * file descriptors opened with O_PATH on old kernels (before v3.6 and before - * v3.12, respectively), but stat() and statfs() can be called on a path that - * the user doesn't have read or write permissions to. - * - * returns: - * 1 - btrfs subvolume - * 0 - not btrfs subvolume - * -1 - error - */ -int btrfs_is_subvolume(const char *path) -{ - struct stat st; - int ret; - - ret = is_btrfs(path); - if (ret <= 0) - return ret; - - ret = stat(path, &st); - if (ret == -1) - return -1; - - if (st.st_ino != BTRFS_FIRST_FREE_OBJECTID || !S_ISDIR(st.st_mode)) { - return 0; - } - - return 1; -} - - -/* Adapted from btrfsprogs */ -int is_btrfs(const char *path) -{ - struct statfs sfs; - int ret; - - ret = statfs(path, &sfs); - if (ret == -1) - return -1; - - return sfs.f_type == BTRFS_SUPER_MAGIC; -} - diff --git a/libmisc/chkname.c b/libmisc/chkname.c deleted file mode 100644 index e31ee8c..0000000 --- a/libmisc/chkname.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2005 - 2008, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * is_valid_user_name(), is_valid_group_name() - check the new user/group - * name for validity; - * return values: - * true - OK - * false - bad name - */ - -#include <config.h> - -#ident "$Id$" - -#include <ctype.h> -#include "defines.h" -#include "chkname.h" - -int allow_bad_names = false; - -static bool is_valid_name (const char *name) -{ - if (allow_bad_names) { - return true; - } - - /* - * User/group names must match gnu e-regex: - * [a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,30}[a-zA-Z0-9_.$-]? - * - * as a non-POSIX, extension, allow "$" as the last char for - * sake of Samba 3.x "add machine script" - * - * Also do not allow fully numeric names or just "." or "..". - */ - int numeric; - - if ('\0' == *name || - ('.' == *name && (('.' == name[1] && '\0' == name[2]) || - '\0' == name[1])) || - !((*name >= 'a' && *name <= 'z') || - (*name >= 'A' && *name <= 'Z') || - (*name >= '0' && *name <= '9') || - *name == '_' || - *name == '.')) { - return false; - } - - numeric = isdigit(*name); - - while ('\0' != *++name) { - if (!((*name >= 'a' && *name <= 'z') || - (*name >= 'A' && *name <= 'Z') || - (*name >= '0' && *name <= '9') || - *name == '_' || - *name == '.' || - *name == '-' || - (*name == '$' && name[1] == '\0') - )) { - return false; - } - numeric &= isdigit(*name); - } - - return !numeric; -} - -bool is_valid_user_name (const char *name) -{ - /* - * User names are limited by whatever utmp can - * handle. - */ - if (strlen (name) > USER_NAME_MAX_LENGTH) { - return false; - } - - return is_valid_name (name); -} - -bool is_valid_group_name (const char *name) -{ - /* - * Arbitrary limit for group names. - * HP-UX 10 limits to 16 characters - */ - if ( (GROUP_NAME_MAX_LENGTH > 0) - && (strlen (name) > GROUP_NAME_MAX_LENGTH)) { - return false; - } - - return is_valid_name (name); -} - diff --git a/libmisc/chkname.h b/libmisc/chkname.h deleted file mode 100644 index 0771347..0000000 --- a/libmisc/chkname.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* $Id$ */ -#ifndef _CHKNAME_H_ -#define _CHKNAME_H_ - -/* - * is_valid_user_name(), is_valid_group_name() - check the new user/group - * name for validity; - * return values: - * true - OK - * false - bad name - */ - -#include "defines.h" - -extern bool is_valid_user_name (const char *name); -extern bool is_valid_group_name (const char *name); - -#endif diff --git a/libmisc/chowndir.c b/libmisc/chowndir.c deleted file mode 100644 index d31618a..0000000 --- a/libmisc/chowndir.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1992 - 1993, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2010 - , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <sys/stat.h> -#include "prototypes.h" -#include "defines.h" -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> - -static int chown_tree_at (int at_fd, - const char *path, - uid_t old_uid, - uid_t new_uid, - gid_t old_gid, - gid_t new_gid) -{ - DIR *dir; - const struct dirent *ent; - struct stat dir_sb; - int dir_fd, rc = 0; - - dir_fd = openat (at_fd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (dir_fd < 0) { - return -1; - } - - dir = fdopendir (dir_fd); - if (!dir) { - (void) close (dir_fd); - return -1; - } - - /* - * Open the directory and read each entry. Every entry is tested - * to see if it is a directory, and if so this routine is called - * recursively. If not, it is checked to see if an ownership - * shall be changed. - */ - while ((ent = readdir (dir))) { - uid_t tmpuid = (uid_t) -1; - gid_t tmpgid = (gid_t) -1; - struct stat ent_sb; - - /* - * Skip the "." and ".." entries - */ - if ( (strcmp (ent->d_name, ".") == 0) - || (strcmp (ent->d_name, "..") == 0)) { - continue; - } - - rc = fstatat (dirfd(dir), ent->d_name, &ent_sb, AT_SYMLINK_NOFOLLOW); - if (rc < 0) { - break; - } - - if (S_ISDIR (ent_sb.st_mode)) { - /* - * Do the entire subdirectory. - */ - rc = chown_tree_at (dirfd(dir), ent->d_name, old_uid, new_uid, old_gid, new_gid); - if (0 != rc) { - break; - } - } - - /* - * By default, the IDs are not changed (-1). - * - * If the file is not owned by the user, the owner is not - * changed. - * - * If the file is not group-owned by the group, the - * group-owner is not changed. - */ - if (((uid_t) -1 == old_uid) || (ent_sb.st_uid == old_uid)) { - tmpuid = new_uid; - } - if (((gid_t) -1 == old_gid) || (ent_sb.st_gid == old_gid)) { - tmpgid = new_gid; - } - if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) { - rc = fchownat (dirfd(dir), ent->d_name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW); - if (0 != rc) { - break; - } - } - } - - /* - * Now do the root of the tree - */ - if ((0 == rc) && (fstat (dirfd(dir), &dir_sb) == 0)) { - uid_t tmpuid = (uid_t) -1; - gid_t tmpgid = (gid_t) -1; - if (((uid_t) -1 == old_uid) || (dir_sb.st_uid == old_uid)) { - tmpuid = new_uid; - } - if (((gid_t) -1 == old_gid) || (dir_sb.st_gid == old_gid)) { - tmpgid = new_gid; - } - if (((uid_t) -1 != tmpuid) || ((gid_t) -1 != tmpgid)) { - rc = fchown (dirfd(dir), tmpuid, tmpgid); - } - } else { - rc = -1; - } - - (void) closedir (dir); - - return rc; -} - -/* - * chown_tree - change ownership of files in a directory tree - * - * chown_dir() walks a directory tree and changes the ownership - * of all files owned by the provided user ID. - * - * Only files owned (resp. group-owned) by old_uid (resp. by old_gid) - * will have their ownership (resp. group-ownership) modified, unless - * old_uid (resp. old_gid) is set to -1. - * - * new_uid and new_gid can be set to -1 to indicate that no owner or - * group-owner shall be changed. - */ -int chown_tree (const char *root, - uid_t old_uid, - uid_t new_uid, - gid_t old_gid, - gid_t new_gid) -{ - return chown_tree_at (AT_FDCWD, root, old_uid, new_uid, old_gid, new_gid); -} diff --git a/libmisc/chowntty.c b/libmisc/chowntty.c deleted file mode 100644 index 8043d8c..0000000 --- a/libmisc/chowntty.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <errno.h> -#include <grp.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> -#include "getdef.h" -#include "shadowlog.h" - -/* - * chown_tty() sets the login tty to be owned by the new user ID - * with TTYPERM modes - */ - -void chown_tty (const struct passwd *info) -{ - struct group *grent; - gid_t gid; - - /* - * See if login.defs has some value configured for the port group - * ID. Otherwise, use the user's primary group ID. - */ - - grent = getgr_nam_gid (getdef_str ("TTYGROUP")); - if (NULL != grent) { - gid = grent->gr_gid; - gr_free (grent); - } else { - gid = info->pw_gid; - } - - /* - * Change the permissions on the TTY to be owned by the user with - * the group as determined above. - */ - - if ( (fchown (STDIN_FILENO, info->pw_uid, gid) != 0) - || (fchmod (STDIN_FILENO, (mode_t)getdef_num ("TTYPERM", 0600)) != 0)) { - int err = errno; - FILE *shadow_logfd = log_get_logfd(); - - fprintf (shadow_logfd, - _("Unable to change owner or mode of tty stdin: %s"), - strerror (err)); - SYSLOG ((LOG_WARN, - "unable to change owner or mode of tty stdin for user `%s': %s\n", - info->pw_name, strerror (err))); - if (EROFS != err) { - closelog (); - exit (EXIT_FAILURE); - } - } -#ifdef __linux__ - /* - * Please don't add code to chown /dev/vcs* to the user logging in - - * it's a potential security hole. I wouldn't like the previous user - * to hold the file descriptor open and watch my screen. We don't - * have the *BSD revoke() system call yet, and vhangup() only works - * for tty devices (which vcs* is not). --marekm - */ -#endif -} - diff --git a/libmisc/cleanup.c b/libmisc/cleanup.c deleted file mode 100644 index c16f1bc..0000000 --- a/libmisc/cleanup.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 - 2011, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include <assert.h> -#include <stdio.h> - -#include "prototypes.h" - -/* - * The cleanup_functions stack. - */ -#define CLEANUP_FUNCTIONS 10 - -typedef /*@null@*/void * parg_t; - -static cleanup_function cleanup_functions[CLEANUP_FUNCTIONS]; -static parg_t cleanup_function_args[CLEANUP_FUNCTIONS]; -static pid_t cleanup_pid = 0; - -/* - * - Cleanup functions shall not fail. - * - You should register do_cleanups with atexit. - * - You should add cleanup functions to the stack with add_cleanup when - * an operation is expected to be executed later, and remove it from the - * stack with del_cleanup when it has been executed. - * - **/ - -/* - * do_cleanups - perform the actions stored in the cleanup_functions stack. - * - * Cleanup action are not executed on exit of the processes started by the - * parent (first caller of add_cleanup). - * - * It is intended to be used as: - * atexit (do_cleanups); - */ -void do_cleanups (void) -{ - unsigned int i; - - /* Make sure there were no overflow */ - assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-1]); - - if (getpid () != cleanup_pid) { - return; - } - - i = CLEANUP_FUNCTIONS; - do { - i--; - if (cleanup_functions[i] != NULL) { - cleanup_functions[i] (cleanup_function_args[i]); - } - } while (i>0); -} - -/* - * add_cleanup - Add a cleanup_function to the cleanup_functions stack. - */ -void add_cleanup (/*@notnull@*/cleanup_function pcf, /*@null@*/void *arg) -{ - unsigned int i; - assert (NULL != pcf); - - assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-2]); - - if (0 == cleanup_pid) { - cleanup_pid = getpid (); - } - - /* Add the cleanup_function at the end of the stack */ - for (i=0; NULL != cleanup_functions[i]; i++); - cleanup_functions[i] = pcf; - cleanup_function_args[i] = arg; -} - -/* - * del_cleanup - Remove a cleanup_function from the cleanup_functions stack. - */ -void del_cleanup (/*@notnull@*/cleanup_function pcf) -{ - unsigned int i; - assert (NULL != pcf); - - /* Find the pcf cleanup function */ - for (i=0; i<CLEANUP_FUNCTIONS; i++) { - if (cleanup_functions[i] == pcf) { - break; - } - } - - /* Make sure the cleanup function was found */ - assert (i<CLEANUP_FUNCTIONS); - - /* Move the rest of the cleanup functions */ - for (; i<CLEANUP_FUNCTIONS; i++) { - /* Make sure the cleanup function was specified only once */ - assert ( (i == (CLEANUP_FUNCTIONS -1)) - || (cleanup_functions[i+1] != pcf)); - - if (i == (CLEANUP_FUNCTIONS -1)) { - cleanup_functions[i] = NULL; - cleanup_function_args[i] = NULL; - } else { - cleanup_functions[i] = cleanup_functions[i+1]; - cleanup_function_args[i] = cleanup_function_args[i+1]; - } - - /* A NULL indicates the end of the stack */ - if (NULL == cleanup_functions[i]) { - break; - } - } -} - diff --git a/libmisc/cleanup_group.c b/libmisc/cleanup_group.c deleted file mode 100644 index df3ebfd..0000000 --- a/libmisc/cleanup_group.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include <assert.h> -#include <stdio.h> - -#include "defines.h" -#include "groupio.h" -#include "sgroupio.h" -#include "prototypes.h" -#include "shadowlog.h" - -/* - * cleanup_report_add_group - Report failure to add a group to the system - * - * It should be registered when it is decided to add a group to the system. - */ -void cleanup_report_add_group (void *group_name) -{ - const char *name = (const char *)group_name; - - SYSLOG ((LOG_ERR, "failed to add group %s", name)); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -/* - * cleanup_report_del_group - Report failure to remove a group from the system - * - * It should be registered when it is decided to remove a group from the system. - */ -void cleanup_report_del_group (void *group_name) -{ - const char *name = (const char *)group_name; - - SYSLOG ((LOG_ERR, "failed to remove group %s", name)); -#ifdef WITH_AUDIT - audit_logger (AUDIT_DEL_GROUP, log_get_progname(), - "", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -void cleanup_report_mod_group (void *cleanup_info) -{ - const struct cleanup_info_mod *info; - info = (const struct cleanup_info_mod *)cleanup_info; - - SYSLOG ((LOG_ERR, - "failed to change %s (%s)", - gr_dbname (), - info->action)); -#ifdef WITH_AUDIT - audit_logger (AUDIT_USER_ACCT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -#ifdef SHADOWGRP -void cleanup_report_mod_gshadow (void *cleanup_info) -{ - const struct cleanup_info_mod *info; - info = (const struct cleanup_info_mod *)cleanup_info; - - SYSLOG ((LOG_ERR, - "failed to change %s (%s)", - sgr_dbname (), - info->action)); -#ifdef WITH_AUDIT - audit_logger (AUDIT_USER_ACCT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} -#endif - -/* - * cleanup_report_add_group_group - Report failure to add a group to group - * - * It should be registered when it is decided to add a group to the - * group database. - */ -void cleanup_report_add_group_group (void *group_name) -{ - const char *name = (const char *)group_name; - - SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, gr_dbname ())); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "adding group to /etc/group", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -#ifdef SHADOWGRP -/* - * cleanup_report_add_group_gshadow - Report failure to add a group to gshadow - * - * It should be registered when it is decided to add a group to the - * gshadow database. - */ -void cleanup_report_add_group_gshadow (void *group_name) -{ - const char *name = (const char *)group_name; - - SYSLOG ((LOG_ERR, "failed to add group %s to %s", name, sgr_dbname ())); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_GROUP, log_get_progname(), - "adding group to /etc/gshadow", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} -#endif - -/* - * cleanup_report_del_group_group - Report failure to remove a group from the - * regular group database - * - * It should be registered when it is decided to remove a group from the - * regular group database. - */ -void cleanup_report_del_group_group (void *group_name) -{ - const char *name = (const char *)group_name; - - SYSLOG ((LOG_ERR, - "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", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -#ifdef SHADOWGRP -/* - * cleanup_report_del_group_gshadow - Report failure to remove a group from - * gshadow - * - * It should be registered when it is decided to remove a group from the - * gshadow database. - */ -void cleanup_report_del_group_gshadow (void *group_name) -{ - const char *name = (const char *)group_name; - - SYSLOG ((LOG_ERR, - "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", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} -#endif - -/* - * cleanup_unlock_group - Unlock the group file - * - * It should be registered after the group file is successfully locked. - */ -void cleanup_unlock_group (unused void *arg) -{ - if (gr_unlock () == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), gr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", gr_dbname ())); -#ifdef WITH_AUDIT - audit_logger_message ("unlocking group file", - SHADOW_AUDIT_FAILURE); -#endif - } -} - -#ifdef SHADOWGRP -/* - * cleanup_unlock_gshadow - Unlock the gshadow file - * - * It should be registered after the gshadow file is successfully locked. - */ -void cleanup_unlock_gshadow (unused void *arg) -{ - if (sgr_unlock () == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), sgr_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", sgr_dbname ())); -#ifdef WITH_AUDIT - audit_logger_message ("unlocking gshadow file", - SHADOW_AUDIT_FAILURE); -#endif - } -} -#endif - diff --git a/libmisc/cleanup_user.c b/libmisc/cleanup_user.c deleted file mode 100644 index 26675c6..0000000 --- a/libmisc/cleanup_user.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include <assert.h> -#include <stdio.h> - -#include "defines.h" -#include "pwio.h" -#include "shadowio.h" -#include "prototypes.h" -#include "shadowlog.h" - -/* - * cleanup_report_add_user - Report failure to add an user to the system - * - * It should be registered when it is decided to add an user to the system. - */ -void cleanup_report_add_user (void *user_name) -{ - const char *name = (const char *)user_name; - - SYSLOG ((LOG_ERR, "failed to add user %s", name)); -#ifdef WITH_AUDIT - audit_logger (AUDIT_ADD_USER, log_get_progname(), - "", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -void cleanup_report_mod_passwd (void *cleanup_info) -{ - const struct cleanup_info_mod *info; - info = (const struct cleanup_info_mod *)cleanup_info; - - SYSLOG ((LOG_ERR, - "failed to change %s (%s)", - pw_dbname (), - info->action)); -#ifdef WITH_AUDIT - audit_logger (AUDIT_USER_ACCT, log_get_progname(), - info->audit_msg, - info->name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -/* - * cleanup_report_add_user_passwd - Report failure to add an user to - * /etc/passwd - * - * It should be registered when it is decided to add an user to the - * /etc/passwd database. - */ -void cleanup_report_add_user_passwd (void *user_name) -{ - const char *name = (const char *)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", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -/* - * cleanup_report_add_user_shadow - Report failure to add an user to - * /etc/shadow - * - * It should be registered when it is decided to add an user to the - * /etc/shadow database. - */ -void cleanup_report_add_user_shadow (void *user_name) -{ - const char *name = (const char *)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", - name, AUDIT_NO_ID, - SHADOW_AUDIT_FAILURE); -#endif -} - -/* - * cleanup_unlock_passwd - Unlock the /etc/passwd database - * - * It should be registered after the passwd database is successfully locked. - */ -void cleanup_unlock_passwd (unused void *arg) -{ - if (pw_unlock () == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), pw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", pw_dbname ())); -#ifdef WITH_AUDIT - audit_logger_message ("unlocking passwd file", - SHADOW_AUDIT_FAILURE); -#endif - } -} - -/* - * cleanup_unlock_shadow - Unlock the /etc/shadow database - * - * It should be registered after the shadow database is successfully locked. - */ -void cleanup_unlock_shadow (unused void *arg) -{ - if (spw_unlock () == 0) { - fprintf (log_get_logfd(), - _("%s: failed to unlock %s\n"), - log_get_progname(), spw_dbname ()); - SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ())); -#ifdef WITH_AUDIT - audit_logger_message ("unlocking shadow file", - SHADOW_AUDIT_FAILURE); -#endif - } -} - diff --git a/libmisc/console.c b/libmisc/console.c deleted file mode 100644 index c475aa2..0000000 --- a/libmisc/console.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 , Julianne Frances Haugh - * SPDX-FileCopyrightText: 1991 , Chip Rosenthal - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> -#include "defines.h" -#include <stdio.h> -#include "getdef.h" -#include "prototypes.h" - -#ident "$Id$" - -/* - * This is now rather generic function which decides if "tty" is listed - * under "cfgin" in config (directly or indirectly). Fallback to default if - * something is bad. - */ -static bool is_listed (const char *cfgin, const char *tty, bool def) -{ - FILE *fp; - char buf[1024], *s; - const char *cons; - - /* - * If the CONSOLE configuration definition isn't given, - * fallback to default. - */ - - cons = getdef_str (cfgin); - if (NULL == cons) { - return def; - } - - /* - * If this isn't a filename, then it is a ":" delimited list of - * console devices upon which root logins are allowed. - */ - - if (*cons != '/') { - char *pbuf; - strncpy (buf, cons, sizeof (buf)); - buf[sizeof (buf) - 1] = '\0'; - pbuf = &buf[0]; - while ((s = strtok (pbuf, ":")) != NULL) { - if (strcmp (s, tty) == 0) { - return true; - } - - pbuf = NULL; - } - return false; - } - - /* - * If we can't open the console list, then call everything a - * console - otherwise root will never be allowed to login. - */ - - fp = fopen (cons, "r"); - if (NULL == fp) { - return def; - } - - /* - * See if this tty is listed in the console file. - */ - - while (fgets (buf, (int) sizeof (buf), fp) != NULL) { - buf[strlen (buf) - 1] = '\0'; - if (strcmp (buf, tty) == 0) { - (void) fclose (fp); - return true; - } - } - - /* - * This tty isn't a console. - */ - - (void) fclose (fp); - return false; -} - -/* - * console - return 1 if the "tty" is a console device, else 0. - * - * Note - we need to take extreme care here to avoid locking out root logins - * if something goes awry. That's why we do things like call everything a - * console if the consoles file can't be opened. Because of this, we must - * warn the user to protect against the remove of the consoles file since - * that would allow an unauthorized root login. - */ - -bool console (const char *tty) -{ - if (strncmp (tty, "/dev/", 5) == 0) { - tty += 5; - } - - return is_listed ("CONSOLE", tty, true); -} - diff --git a/libmisc/copydir.c b/libmisc/copydir.c deleted file mode 100644 index b692aa9..0000000 --- a/libmisc/copydir.c +++ /dev/null @@ -1,968 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <assert.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <fcntl.h> -#include <stdio.h> -#include "prototypes.h" -#include "defines.h" -#ifdef WITH_SELINUX -#include <selinux/selinux.h> -#endif /* WITH_SELINUX */ -#if defined(WITH_ACL) || defined(WITH_ATTR) -#include <stdarg.h> -#include <attr/error_context.h> -#endif /* WITH_ACL || WITH_ATTR */ -#ifdef WITH_ACL -#include <acl/libacl.h> -#endif /* WITH_ACL */ -#ifdef WITH_ATTR -#include <attr/libattr.h> -#endif /* WITH_ATTR */ -#include "shadowlog.h" - - -static /*@null@*/const char *src_orig; -static /*@null@*/const char *dst_orig; - -struct link_name { - dev_t ln_dev; - ino_t ln_ino; - nlink_t ln_count; - char *ln_name; - /*@dependent@*/struct link_name *ln_next; -}; -static /*@exposed@*/struct link_name *links; - -struct path_info { - const char *full_path; - int dirfd; - const char *name; -}; - -static int copy_entry (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); -static int copy_dir (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); -static /*@null@*/char *readlink_malloc (const char *filename); -static int copy_symlink (const struct path_info *src, const struct path_info *dst, - unused bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); -static int copy_hardlink (const struct path_info *dst, - unused bool reset_selinux, - struct link_name *lp); -static int copy_special (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); -static int copy_file (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); -static int chownat_if_needed (const struct path_info *dst, const struct stat *statp, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); -static int fchown_if_needed (int fdst, const struct stat *statp, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid); - -#if defined(WITH_ACL) || defined(WITH_ATTR) -/* - * error_acl - format the error messages for the ACL and EQ libraries. - */ -format_attr(printf, 2, 3) -static void error_acl (unused struct error_context *ctx, const char *fmt, ...) -{ - va_list ap; - FILE *shadow_logfd = log_get_logfd(); - - /* ignore the case when destination does not support ACLs - * or extended attributes */ - if (ENOTSUP == errno) { - errno = 0; - return; - } - - va_start (ap, fmt); - (void) fprintf (shadow_logfd, _("%s: "), log_get_progname()); - if (vfprintf (shadow_logfd, fmt, ap) != 0) { - (void) fputs (_(": "), shadow_logfd); - } - (void) fprintf (shadow_logfd, "%s\n", strerror (errno)); - va_end (ap); -} - -static struct error_context ctx = { - error_acl, NULL, NULL -}; -#endif /* WITH_ACL || WITH_ATTR */ - -#ifdef WITH_ACL -static int perm_copy_path(const struct path_info *src, - const struct path_info *dst, - struct error_context *errctx) -{ - int src_fd, dst_fd, ret; - - src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC); - if (src_fd < 0) { - return -1; - } - - dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC); - if (dst_fd < 0) { - (void) close (src_fd); - return -1; - } - - ret = perm_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, errctx); - (void) close (src_fd); - (void) close (dst_fd); - return ret; -} -#endif /* WITH_ACL */ - -#ifdef WITH_ATTR -static int attr_copy_path(const struct path_info *src, - const struct path_info *dst, - int (*callback) (const char *, struct error_context *), - struct error_context *errctx) -{ - int src_fd, dst_fd, ret; - - src_fd = openat(src->dirfd, src->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC); - if (src_fd < 0) { - return -1; - } - - dst_fd = openat(dst->dirfd, dst->name, O_RDONLY | O_NOFOLLOW | O_NONBLOCK | O_CLOEXEC); - if (dst_fd < 0) { - (void) close (src_fd); - return -1; - } - - ret = attr_copy_fd(src->full_path, src_fd, dst->full_path, dst_fd, callback, errctx); - (void) close (src_fd); - (void) close (dst_fd); - return ret; -} -#endif /* WITH_ATTR */ - -/* - * remove_link - delete a link from the linked list - */ -static void remove_link (/*@only@*/struct link_name *ln) -{ - struct link_name *lp; - - if (links == ln) { - links = ln->ln_next; - free (ln->ln_name); - free (ln); - return; - } - for (lp = links; NULL !=lp; lp = lp->ln_next) { - if (lp->ln_next == ln) { - break; - } - } - - if (NULL == lp) { - free (ln->ln_name); - free (ln); - return; - } - - lp->ln_next = lp->ln_next->ln_next; - free (ln->ln_name); - free (ln); -} - -/* - * check_link - see if a file is really a link - */ - -static /*@exposed@*/ /*@null@*/struct link_name *check_link (const char *name, const struct stat *sb) -{ - struct link_name *lp; - size_t src_len; - size_t dst_len; - size_t name_len; - size_t len; - - /* copy_tree () must be the entry point */ - assert (NULL != src_orig); - assert (NULL != dst_orig); - - for (lp = links; NULL != lp; lp = lp->ln_next) { - if ((lp->ln_dev == sb->st_dev) && (lp->ln_ino == sb->st_ino)) { - return lp; - } - } - - if (sb->st_nlink == 1) { - return NULL; - } - - lp = (struct link_name *) xmalloc (sizeof *lp); - src_len = strlen (src_orig); - dst_len = strlen (dst_orig); - name_len = strlen (name); - lp->ln_dev = sb->st_dev; - lp->ln_ino = sb->st_ino; - lp->ln_count = sb->st_nlink; - len = name_len - src_len + dst_len + 1; - lp->ln_name = (char *) xmalloc (len); - (void) snprintf (lp->ln_name, len, "%s%s", dst_orig, name + src_len); - lp->ln_next = links; - links = lp; - - return NULL; -} - -static int copy_tree_impl (const struct path_info *src, const struct path_info *dst, - bool copy_root, bool reset_selinux, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - int dst_fd, src_fd, err = 0; - bool set_orig = false; - const struct dirent *ent; - DIR *dir; - - if (copy_root) { - struct stat sb; - - if ( fstatat (dst->dirfd, dst->name, &sb, 0) == 0 - || errno != ENOENT) { - return -1; - } - - if (fstatat (src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) { - return -1; - } - - if (!S_ISDIR (sb.st_mode)) { - fprintf (log_get_logfd(), - "%s: %s is not a directory", - log_get_progname(), src->full_path); - return -1; - } - - return copy_entry (src, dst, reset_selinux, - old_uid, new_uid, old_gid, new_gid); - } - - /* - * Make certain both directories exist. This routine is called - * after the home directory is created, or recursively after the - * target is created. It assumes the target directory exists. - */ - - src_fd = openat (src->dirfd, src->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC); - if (src_fd < 0) { - return -1; - } - - dst_fd = openat (dst->dirfd, dst->name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_CLOEXEC); - if (dst_fd < 0) { - (void) close (src_fd); - return -1; - } - - /* - * Open the source directory and read each entry. Every file - * entry in the directory is copied with the UID and GID set - * to the provided values. As an added security feature only - * regular files (and directories ...) are copied, and no file - * is made set-ID. - */ - dir = fdopendir (src_fd); - if (NULL == dir) { - (void) close (src_fd); - (void) close (dst_fd); - return -1; - } - - if (src_orig == NULL) { - src_orig = src->full_path; - dst_orig = dst->full_path; - set_orig = true; - } - while ((0 == err) && (ent = readdir (dir)) != NULL) { - /* - * Skip the "." and ".." entries - */ - if ((strcmp (ent->d_name, ".") != 0) && - (strcmp (ent->d_name, "..") != 0)) { - char *src_name; - char *dst_name; - size_t src_len = strlen (ent->d_name) + 2; - size_t dst_len = strlen (ent->d_name) + 2; - src_len += strlen (src->full_path); - dst_len += strlen (dst->full_path); - - src_name = (char *) malloc (src_len); - dst_name = (char *) malloc (dst_len); - - if ((NULL == src_name) || (NULL == dst_name)) { - err = -1; - } else { - /* - * Build the filename for both the source and - * the destination files. - */ - struct path_info src_entry, dst_entry; - - (void) snprintf (src_name, src_len, "%s/%s", - src->full_path, ent->d_name); - (void) snprintf (dst_name, dst_len, "%s/%s", - dst->full_path, ent->d_name); - - src_entry.full_path = src_name; - src_entry.dirfd = dirfd(dir); - src_entry.name = ent->d_name; - - dst_entry.full_path = dst_name; - dst_entry.dirfd = dst_fd; - dst_entry.name = ent->d_name; - - err = copy_entry (&src_entry, &dst_entry, - reset_selinux, - old_uid, new_uid, - old_gid, new_gid); - } - free (src_name); - free (dst_name); - } - } - (void) closedir (dir); - (void) close (dst_fd); - - if (set_orig) { - src_orig = NULL; - dst_orig = NULL; - /* FIXME: clean links - * Since there can be hardlinks elsewhere on the device, - * we cannot check that all the hardlinks were found: - assert (NULL == links); - */ - } - -#ifdef WITH_SELINUX - /* Reset SELinux to create files with default contexts. - * Note that the context is only reset on exit of copy_tree (it is - * assumed that the program would quit without needing a restored - * context if copy_tree failed previously), and that copy_tree can - * be called recursively (hence the context is set on the - * sub-functions of copy_entry). - */ - if (reset_selinux_file_context () != 0) { - err = -1; - } -#endif /* WITH_SELINUX */ - - return err; -} - -/* - * copy_entry - copy the entry of a directory - * - * Copy the entry src to dst. - * Depending on the type of entry, this function will forward the - * request to copy_dir(), copy_symlink(), copy_hardlink(), - * copy_special(), or copy_file(). - * - * The access and modification time will not be modified. - * - * The permissions will be set to new_uid/new_gid. - * - * If new_uid (resp. new_gid) is equal to -1, the user (resp. group) will - * not be modified. - * - * Only the files owned (resp. group-owned) by old_uid (resp. - * old_gid) will be modified, unless old_uid (resp. old_gid) is set - * to -1. - */ -static int copy_entry (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - int err = 0; - struct stat sb; - struct link_name *lp; - struct timespec mt[2]; - - if (fstatat(src->dirfd, src->name, &sb, AT_SYMLINK_NOFOLLOW) == -1) { - /* If we cannot stat the file, do not care. */ - } else { -#ifdef HAVE_STRUCT_STAT_ST_ATIM - mt[0].tv_sec = sb.st_atim.tv_sec; - mt[0].tv_nsec = sb.st_atim.tv_nsec; -#else /* !HAVE_STRUCT_STAT_ST_ATIM */ - mt[0].tv_sec = sb.st_atime; -# ifdef HAVE_STRUCT_STAT_ST_ATIMENSEC - mt[0].tv_nsec = sb.st_atimensec; -# else /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */ - mt[0].tv_nsec = 0; -# endif /* !HAVE_STRUCT_STAT_ST_ATIMENSEC */ -#endif /* !HAVE_STRUCT_STAT_ST_ATIM */ - -#ifdef HAVE_STRUCT_STAT_ST_MTIM - mt[1].tv_sec = sb.st_mtim.tv_sec; - mt[1].tv_nsec = sb.st_mtim.tv_nsec; -#else /* !HAVE_STRUCT_STAT_ST_MTIM */ - mt[1].tv_sec = sb.st_mtime; -# ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC - mt[1].tv_nsec = sb.st_mtimensec; -# else /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */ - mt[1].tv_nsec = 0; -# endif /* !HAVE_STRUCT_STAT_ST_MTIMENSEC */ -#endif /* !HAVE_STRUCT_STAT_ST_MTIM */ - - if (S_ISDIR (sb.st_mode)) { - err = copy_dir (src, dst, reset_selinux, &sb, mt, - old_uid, new_uid, old_gid, new_gid); - } - - /* - * Copy any symbolic links - */ - - else if (S_ISLNK (sb.st_mode)) { - err = copy_symlink (src, dst, reset_selinux, &sb, mt, - old_uid, new_uid, old_gid, new_gid); - } - - /* - * See if this is a previously copied link - */ - - else if ((lp = check_link (src->full_path, &sb)) != NULL) { - err = copy_hardlink (dst, reset_selinux, lp); - } - - /* - * Deal with FIFOs and special files. The user really - * shouldn't have any of these, but it seems like it - * would be nice to copy everything ... - */ - - else if (!S_ISREG (sb.st_mode)) { - err = copy_special (src, dst, reset_selinux, &sb, mt, - old_uid, new_uid, old_gid, new_gid); - } - - /* - * Create the new file and copy the contents. The new - * file will be owned by the provided UID and GID values. - */ - - else { - err = copy_file (src, dst, reset_selinux, &sb, mt, - old_uid, new_uid, old_gid, new_gid); - } - } - - return err; -} - -/* - * copy_dir - copy a directory - * - * Copy a directory (recursively) from src to dst. - * - * statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set - * the access and modification and the access rights. - * - * Return 0 on success, -1 on error. - */ -static int copy_dir (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - int err = 0; - - /* - * Create a new target directory, make it owned by - * the user and then recursively copy that directory. - */ - -#ifdef WITH_SELINUX - if (set_selinux_file_context (dst->full_path, S_IFDIR) != 0) { - return -1; - } -#endif /* WITH_SELINUX */ - if ( (mkdirat (dst->dirfd, dst->name, 0700) != 0) - || (chownat_if_needed (dst, statp, - old_uid, new_uid, old_gid, new_gid) != 0) - || (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0) -#ifdef WITH_ACL - || ( (perm_copy_path (src, dst, &ctx) != 0) - && (errno != 0)) -#endif /* WITH_ACL */ -#ifdef WITH_ATTR - /* - * If the third parameter is NULL, all extended attributes - * except those that define Access Control Lists are copied. - * ACLs are excluded by default because copying them between - * file systems with and without ACL support needs some - * additional logic so that no unexpected permissions result. - */ - || ( !reset_selinux - && (attr_copy_path (src, dst, NULL, &ctx) != 0) - && (errno != 0)) -#endif /* WITH_ATTR */ - || (copy_tree_impl (src, dst, false, reset_selinux, - old_uid, new_uid, old_gid, new_gid) != 0) - || (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) { - err = -1; - } - - return err; -} - -/* - * readlink_malloc - wrapper for readlink - * - * return NULL on error. - * The return string shall be freed by the caller. - */ -static /*@null@*/char *readlink_malloc (const char *filename) -{ - size_t size = 1024; - - while (true) { - ssize_t nchars; - char *buffer = (char *) malloc (size); - if (NULL == buffer) { - return NULL; - } - - nchars = readlink (filename, buffer, size); - - if (nchars < 0) { - free(buffer); - return NULL; - } - - if ((size_t) nchars < size) { /* The buffer was large enough */ - /* readlink does not nul-terminate */ - buffer[nchars] = '\0'; - return buffer; - } - - /* Try again with a bigger buffer */ - free (buffer); - size *= 2; - } -} - -/* - * copy_symlink - copy a symlink - * - * Copy a symlink from src to dst. - * - * statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set - * the access and modification and the access rights. - * - * Return 0 on success, -1 on error. - */ -static int copy_symlink (const struct path_info *src, const struct path_info *dst, - unused bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - char *oldlink; - - /* copy_tree () must be the entry point */ - assert (NULL != src_orig); - assert (NULL != dst_orig); - - /* - * Get the name of the file which the link points - * to. If that name begins with the original - * source directory name, that part of the link - * name will be replaced with the original - * destination directory name. - */ - - oldlink = readlink_malloc (src->full_path); - if (NULL == oldlink) { - return -1; - } - - /* If src was a link to an entry of the src_orig directory itself, - * create a link to the corresponding entry in the dst_orig - * directory. - */ - if (strncmp (oldlink, src_orig, strlen (src_orig)) == 0) { - size_t len = strlen (dst_orig) + strlen (oldlink) - strlen (src_orig) + 1; - char *dummy = (char *) xmalloc (len); - (void) snprintf (dummy, len, "%s%s", - dst_orig, - oldlink + strlen (src_orig)); - free (oldlink); - oldlink = dummy; - } - -#ifdef WITH_SELINUX - if (set_selinux_file_context (dst->full_path, S_IFLNK) != 0) { - free (oldlink); - return -1; - } -#endif /* WITH_SELINUX */ - if ( (symlinkat (oldlink, dst->dirfd, dst->name) != 0) - || (chownat_if_needed (dst, statp, - old_uid, new_uid, old_gid, new_gid) != 0)) { - /* FIXME: there are no modes on symlinks, right? - * ACL could be copied, but this would be much more - * complex than calling perm_copy_file. - * Ditto for Extended Attributes. - * We currently only document that ACL and Extended - * Attributes are not copied. - */ - free (oldlink); - return -1; - } - free (oldlink); - - if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) { - return -1; - } - - return 0; -} - -/* - * copy_hardlink - copy a hardlink - * - * Copy a hardlink from src to dst. - * - * Return 0 on success, -1 on error. - */ -static int copy_hardlink (const struct path_info *dst, - unused bool reset_selinux, - struct link_name *lp) -{ - /* FIXME: selinux, ACL, Extended Attributes needed? */ - - if (linkat (AT_FDCWD, lp->ln_name, dst->dirfd, dst->name, 0) != 0) { - return -1; - } - - /* If the file could be unlinked, decrement the links counter, - * and forget about this link if it was the last reference */ - lp->ln_count--; - if (lp->ln_count <= 0) { - remove_link (lp); - } - - return 0; -} - -/* - * copy_special - copy a special file - * - * Copy a special file from src to dst. - * - * statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set - * the access and modification and the access rights. - * - * Return 0 on success, -1 on error. - */ -static int copy_special (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - int err = 0; - -#ifdef WITH_SELINUX - if (set_selinux_file_context (dst->full_path, statp->st_mode & S_IFMT) != 0) { - return -1; - } -#endif /* WITH_SELINUX */ - - if ( (mknodat (dst->dirfd, dst->name, statp->st_mode & ~07777U, statp->st_rdev) != 0) - || (chownat_if_needed (dst, statp, - old_uid, new_uid, old_gid, new_gid) != 0) - || (fchmodat (dst->dirfd, dst->name, statp->st_mode & 07777, AT_SYMLINK_NOFOLLOW) != 0) -#ifdef WITH_ACL - || ( (perm_copy_path (src, dst, &ctx) != 0) - && (errno != 0)) -#endif /* WITH_ACL */ -#ifdef WITH_ATTR - /* - * If the third parameter is NULL, all extended attributes - * except those that define Access Control Lists are copied. - * ACLs are excluded by default because copying them between - * file systems with and without ACL support needs some - * additional logic so that no unexpected permissions result. - */ - || ( !reset_selinux - && (attr_copy_path (src, dst, NULL, &ctx) != 0) - && (errno != 0)) -#endif /* WITH_ATTR */ - || (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0)) { - err = -1; - } - - return err; -} - -/* - * full_write - write entire buffer - * - * Write up to count bytes from the buffer starting at buf to the - * file referred to by the file descriptor fd. - * Retry in case of a short write. - * - * Returns the number of bytes written on success, -1 on error. - */ -static ssize_t full_write(int fd, const void *buf, size_t count) { - ssize_t written = 0; - - while (count > 0) { - ssize_t res; - - res = write(fd, buf, count); - if (res < 0) { - if (errno == EINTR) { - continue; - } - - return res; - } - - if (res == 0) { - break; - } - - written += res; - buf = (const unsigned char*)buf + res; - count -= (size_t)res; - } - - return written; -} - -/* - * copy_file - copy a file - * - * Copy a file from src to dst. - * - * statp, mt, old_uid, new_uid, old_gid, and new_gid are used to set - * the access and modification and the access rights. - * - * Return 0 on success, -1 on error. - */ -static int copy_file (const struct path_info *src, const struct path_info *dst, - bool reset_selinux, - const struct stat *statp, const struct timespec mt[], - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - int err = 0; - int ifd; - int ofd; - - ifd = openat (src->dirfd, src->name, O_RDONLY|O_NOFOLLOW|O_CLOEXEC); - if (ifd < 0) { - return -1; - } -#ifdef WITH_SELINUX - if (set_selinux_file_context (dst->full_path, S_IFREG) != 0) { - (void) close (ifd); - return -1; - } -#endif /* WITH_SELINUX */ - ofd = openat (dst->dirfd, dst->name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_NOFOLLOW | O_CLOEXEC, 0600); - if ( (ofd < 0) - || (fchown_if_needed (ofd, statp, - old_uid, new_uid, old_gid, new_gid) != 0) - || (fchmod (ofd, statp->st_mode & 07777) != 0) -#ifdef WITH_ACL - || ( (perm_copy_fd (src->full_path, ifd, dst->full_path, ofd, &ctx) != 0) - && (errno != 0)) -#endif /* WITH_ACL */ -#ifdef WITH_ATTR - /* - * If the third parameter is NULL, all extended attributes - * except those that define Access Control Lists are copied. - * ACLs are excluded by default because copying them between - * file systems with and without ACL support needs some - * additional logic so that no unexpected permissions result. - */ - || ( !reset_selinux - && (attr_copy_fd (src->full_path, ifd, dst->full_path, ofd, NULL, &ctx) != 0) - && (errno != 0)) -#endif /* WITH_ATTR */ - ) { - if (ofd >= 0) { - (void) close (ofd); - } - (void) close (ifd); - return -1; - } - - while (true) { - char buf[8192]; - ssize_t cnt; - - cnt = read (ifd, buf, sizeof buf); - if (cnt < 0) { - if (errno == EINTR) { - continue; - } - (void) close (ofd); - (void) close (ifd); - return -1; - } - if (cnt == 0) { - break; - } - - if (full_write (ofd, buf, (size_t)cnt) < 0) { - (void) close (ofd); - (void) close (ifd); - return -1; - } - } - - (void) close (ifd); - if (close (ofd) != 0) { - return -1; - } - - if (utimensat (dst->dirfd, dst->name, mt, AT_SYMLINK_NOFOLLOW) != 0) { - return -1; - } - - return err; -} - -#define def_chown_if_needed(chown_function, type_dst) \ -static int chown_function ## _if_needed (type_dst dst, \ - const struct stat *statp, \ - uid_t old_uid, uid_t new_uid, \ - gid_t old_gid, gid_t new_gid) \ -{ \ - uid_t tmpuid = (uid_t) -1; \ - gid_t tmpgid = (gid_t) -1; \ - \ - /* Use new_uid if old_uid is set to -1 or if the file was \ - * owned by the user. */ \ - if (((uid_t) -1 == old_uid) || (statp->st_uid == old_uid)) { \ - tmpuid = new_uid; \ - } \ - /* Otherwise, or if new_uid was set to -1, we keep the same \ - * owner. */ \ - if ((uid_t) -1 == tmpuid) { \ - tmpuid = statp->st_uid; \ - } \ - \ - if (((gid_t) -1 == old_gid) || (statp->st_gid == old_gid)) { \ - tmpgid = new_gid; \ - } \ - if ((gid_t) -1 == tmpgid) { \ - tmpgid = statp->st_gid; \ - } \ - \ - return chown_function (dst, tmpuid, tmpgid); \ -} - -def_chown_if_needed (fchown, int) - -static int chownat_if_needed (const struct path_info *dst, - const struct stat *statp, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - uid_t tmpuid = (uid_t) -1; - gid_t tmpgid = (gid_t) -1; - - /* Use new_uid if old_uid is set to -1 or if the file was - * owned by the user. */ - if (((uid_t) -1 == old_uid) || (statp->st_uid == old_uid)) { - tmpuid = new_uid; - } - /* Otherwise, or if new_uid was set to -1, we keep the same - * owner. */ - if ((uid_t) -1 == tmpuid) { - tmpuid = statp->st_uid; - } - - if (((gid_t) -1 == old_gid) || (statp->st_gid == old_gid)) { - tmpgid = new_gid; - } - if ((gid_t) -1 == tmpgid) { - tmpgid = statp->st_gid; - } - - return fchownat (dst->dirfd, dst->name, tmpuid, tmpgid, AT_SYMLINK_NOFOLLOW); -} - -/* - * copy_tree - copy files in a directory tree - * - * copy_tree() walks a directory tree and copies ordinary files - * as it goes. - * - * When reset_selinux is enabled, extended attributes (and thus - * SELinux attributes) are not copied. - * - * old_uid and new_uid are used to set the ownership of the copied - * files. Unless old_uid is set to -1, only the files owned by - * old_uid have their ownership changed to new_uid. In addition, if - * new_uid is set to -1, no ownership will be changed. - * - * The same logic applies for the group-ownership and - * old_gid/new_gid. - */ -int copy_tree (const char *src_root, const char *dst_root, - bool copy_root, bool reset_selinux, - uid_t old_uid, uid_t new_uid, - gid_t old_gid, gid_t new_gid) -{ - const struct path_info src = { - .full_path = src_root, - .dirfd = AT_FDCWD, - .name = src_root - }; - const struct path_info dst = { - .full_path = dst_root, - .dirfd = AT_FDCWD, - .name = dst_root - }; - - return copy_tree_impl(&src, &dst, copy_root, reset_selinux, - old_uid, new_uid, old_gid, new_gid); -} diff --git a/libmisc/date_to_str.c b/libmisc/date_to_str.c deleted file mode 100644 index 07e99f1..0000000 --- a/libmisc/date_to_str.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2021, Alejandro Colomar <alx.manpages@gmail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the copyright holders or contributors may not be used to - * endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <string.h> -#include <time.h> - -#ident "$Id$" - -#include "prototypes.h" - -void date_to_str (size_t size, char buf[size], long date) -{ - time_t t; - - t = date; - if (date < 0) - (void) strncpy (buf, "never", size); - else - (void) strftime (buf, size, "%Y-%m-%d", gmtime (&t)); - buf[size - 1] = '\0'; -} diff --git a/libmisc/entry.c b/libmisc/entry.c deleted file mode 100644 index 87f5754..0000000 --- a/libmisc/entry.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <stdio.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> - -void pw_entry (const char *name, struct passwd *pwent) -{ - struct passwd *passwd; - - struct spwd *spwd; - - if (!(passwd = getpwnam (name))) { /* local, no need for xgetpwnam */ - pwent->pw_name = (char *) 0; - return; - } else { - pwent->pw_name = xstrdup (passwd->pw_name); - pwent->pw_uid = passwd->pw_uid; - pwent->pw_gid = passwd->pw_gid; - pwent->pw_gecos = xstrdup (passwd->pw_gecos); - pwent->pw_dir = xstrdup (passwd->pw_dir); - pwent->pw_shell = xstrdup (passwd->pw_shell); -#if !defined(AUTOSHADOW) - /* local, no need for xgetspnam */ - if ((spwd = getspnam (name))) { - pwent->pw_passwd = xstrdup (spwd->sp_pwdp); - return; - } -#endif - pwent->pw_passwd = xstrdup (passwd->pw_passwd); - } -} diff --git a/libmisc/env.c b/libmisc/env.c deleted file mode 100644 index fc6dbce..0000000 --- a/libmisc/env.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1992, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "prototypes.h" -#include "defines.h" -#include "shadowlog.h" -/* - * NEWENVP_STEP must be a power of two. This is the number - * of (char *) pointers to allocate at a time, to avoid using - * realloc() too often. - */ -#define NEWENVP_STEP 16 -size_t newenvc = 0; -/*@null@*/char **newenvp = NULL; -extern char **environ; - -static const char *const forbid[] = { - "_RLD_=", - "BASH_ENV=", /* GNU creeping featurism strikes again... */ - "ENV=", - "HOME=", - "IFS=", - "KRB_CONF=", - "LD_", /* anything with the LD_ prefix */ - "LIBPATH=", - "MAIL=", - "NLSPATH=", - "PATH=", - "SHELL=", - "SHLIB_PATH=", - (char *) 0 -}; - -/* these are allowed, but with no slashes inside - (to work around security problems in GNU gettext) */ -static const char *const noslash[] = { - "LANG=", - "LANGUAGE=", - "LC_", /* anything with the LC_ prefix */ - (char *) 0 -}; - -/* - * initenv() must be called once before using addenv(). - */ -void initenv (void) -{ - newenvp = (char **) xmalloc (NEWENVP_STEP * sizeof (char *)); - *newenvp = NULL; -} - - -void addenv (const char *string, /*@null@*/const char *value) -{ - char *cp, *newstring; - size_t i; - size_t n; - - if (NULL != value) { - size_t len = strlen (string) + strlen (value) + 2; - int wlen; - newstring = xmalloc (len); - wlen = snprintf (newstring, len, "%s=%s", string, value); - assert (wlen == (int) len -1); - } else { - newstring = xstrdup (string); - } - - /* - * Search for a '=' character within the string and if none is found - * just ignore the whole string. - */ - - cp = strchr (newstring, '='); - if (NULL == cp) { - free (newstring); - return; - } - - n = (size_t) (cp - newstring); - - /* - * If this environment variable is already set, change its value. - */ - for (i = 0; i < newenvc; i++) { - if ( (strncmp (newstring, newenvp[i], n) == 0) - && (('=' == newenvp[i][n]) || ('\0' == newenvp[i][n]))) { - break; - } - } - - if (i < newenvc) { - free (newenvp[i]); - newenvp[i] = newstring; - return; - } - - /* - * Otherwise, save the new environment variable - */ - newenvp[newenvc++] = newstring; - - /* - * And extend the environment if needed. - */ - - /* - * Check whether newenvc is a multiple of NEWENVP_STEP. - * If so we have to resize the vector. - * the expression (newenvc & (NEWENVP_STEP - 1)) == 0 - * is equal to (newenvc % NEWENVP_STEP) == 0 - * as long as NEWENVP_STEP is a power of 2. - */ - - if ((newenvc & (NEWENVP_STEP - 1)) == 0) { - char **__newenvp; - size_t newsize; - - /* - * If the resize operation succeeds we can - * happily go on, else print a message. - */ - - newsize = (newenvc + NEWENVP_STEP) * sizeof (char *); - __newenvp = (char **) realloc (newenvp, newsize); - - if (NULL != __newenvp) { - /* - * If this is our current environment, update - * environ so that it doesn't point to some - * free memory area (realloc() could move it). - */ - if (environ == newenvp) { - environ = __newenvp; - } - newenvp = __newenvp; - } else { - (void) fputs (_("Environment overflow\n"), log_get_logfd()); - newenvc--; - free (newenvp[newenvc]); - } - } - - /* - * The last entry of newenvp must be NULL - */ - - newenvp[newenvc] = NULL; -} - - -/* - * set_env - copy command line arguments into the environment - */ -void set_env (int argc, char *const *argv) -{ - int noname = 1; - char variable[1024]; - char *cp; - - for (; argc > 0; argc--, argv++) { - if (strlen (*argv) >= sizeof variable) { - continue; /* ignore long entries */ - } - - cp = strchr (*argv, '='); - if (NULL == cp) { - int wlen; - wlen = snprintf (variable, sizeof variable, "L%d", noname); - assert (wlen < (int) sizeof(variable)); - noname++; - addenv (variable, *argv); - } else { - const char *const *p; - - for (p = forbid; NULL != *p; p++) { - if (strncmp (*argv, *p, strlen (*p)) == 0) { - break; - } - } - - if (NULL != *p) { - strncpy (variable, *argv, (size_t)(cp - *argv)); - variable[cp - *argv] = '\0'; - printf (_("You may not change $%s\n"), - variable); - continue; - } - - addenv (*argv, NULL); - } - } -} - -/* - * sanitize_env - remove some nasty environment variables - * If you fall into a total paranoia, you should call this - * function for any root-setuid program or anything the user - * might change the environment with. 99% useless as almost - * all modern Unixes will handle setuid executables properly, - * but... I feel better with that silly precaution. -j. - */ - -void sanitize_env (void) -{ - char **envp = environ; - const char *const *bad; - char **cur; - char **move; - - for (cur = envp; NULL != *cur; cur++) { - for (bad = forbid; NULL != *bad; bad++) { - if (strncmp (*cur, *bad, strlen (*bad)) == 0) { - for (move = cur; NULL != *move; move++) { - *move = *(move + 1); - } - cur--; - break; - } - } - } - - for (cur = envp; NULL != *cur; cur++) { - for (bad = noslash; NULL != *bad; bad++) { - if (strncmp (*cur, *bad, strlen (*bad)) != 0) { - continue; - } - if (strchr (*cur, '/') == NULL) { - continue; /* OK */ - } - for (move = cur; NULL != *move; move++) { - *move = *(move + 1); - } - cur--; - break; - } - } -} - diff --git a/libmisc/failure.c b/libmisc/failure.c deleted file mode 100644 index 1aab299..0000000 --- a/libmisc/failure.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2002 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> -#include "defines.h" -#include "faillog.h" -#include "getdef.h" -#include "failure.h" -#define YEAR (365L*DAY) -/* - * failure - make failure entry - * - * failure() creates a new (struct faillog) entry or updates an - * existing one with the current failed login information. - */ -void failure (uid_t uid, const char *tty, struct faillog *fl) -{ - int fd; - off_t offset_uid = (off_t) (sizeof *fl) * uid; - - /* - * Don't do anything if failure logging isn't set up. - */ - - if (access (FAILLOG_FILE, F_OK) != 0) { - return; - } - - fd = open (FAILLOG_FILE, O_RDWR); - if (fd < 0) { - SYSLOG ((LOG_WARN, - "Can't write faillog entry for UID %lu in %s.", - (unsigned long) uid, FAILLOG_FILE)); - return; - } - - /* - * The file is indexed by UID value meaning that shared UID's - * share failure log records. That's OK since they really - * share just about everything else ... - */ - - if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) { - /* This is not necessarily a failure. The file is - * initially zero length. - * - * If lseek() or read() failed for any other reason, this - * might reset the counter. But the new failure will be - * logged. - */ - memzero (fl, sizeof *fl); - } - - /* - * Update the record. We increment the failure count to log the - * latest failure. The only concern here is overflow, and we'll - * check for that. The line name and time of day are both - * updated as well. - */ - - if (fl->fail_cnt + 1 > 0) { - fl->fail_cnt++; - } - - strncpy (fl->fail_line, tty, sizeof (fl->fail_line) - 1); - (void) time (&fl->fail_time); - - /* - * Seek back to the correct position in the file and write the - * record out. Ideally we should lock the file in case the same - * account is being logged simultaneously. But the risk doesn't - * seem that great. - */ - - if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't write faillog entry for UID %lu in %s.", - (unsigned long) uid, FAILLOG_FILE)); - (void) close (fd); - } -} - -static bool too_many_failures (const struct faillog *fl) -{ - time_t now; - - if ((0 == fl->fail_max) || (fl->fail_cnt < fl->fail_max)) { - return false; - } - - if (0 == fl->fail_locktime) { - return true; /* locked until reset manually */ - } - - (void) time (&now); - if ((fl->fail_time + fl->fail_locktime) < now) { - return false; /* enough time since last failure */ - } - - return true; -} - -/* - * failcheck - check for failures > allowable - * - * failcheck() is called AFTER the password has been validated. If the - * account has been "attacked" with too many login failures, failcheck() - * returns 0 to indicate that the login should be denied even though - * the password is valid. - * - * failed indicates if the login failed AFTER the password has been - * validated. - */ - -int failcheck (uid_t uid, struct faillog *fl, bool failed) -{ - int fd; - struct faillog fail; - off_t offset_uid = (off_t) (sizeof *fl) * uid; - - /* - * Suppress the check if the log file isn't there. - */ - - if (access (FAILLOG_FILE, F_OK) != 0) { - return 1; - } - - fd = open (FAILLOG_FILE, failed?O_RDONLY:O_RDWR); - if (fd < 0) { - SYSLOG ((LOG_WARN, - "Can't open the faillog file (%s) to check UID %lu. " - "User access authorized.", - FAILLOG_FILE, (unsigned long) uid)); - return 1; - } - - /* - * Get the record from the file and determine if the user has - * exceeded the failure limit. If "max" is zero, any number - * of failures are permitted. Only when "max" is non-zero and - * "cnt" is greater than or equal to "max" is the account - * considered to be locked. - * - * If read fails, there is no record for this user yet (the - * file is initially zero length and extended by writes), so - * no need to reset the count. - */ - - if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (read (fd, (char *) fl, sizeof *fl) != (ssize_t) sizeof *fl)) { - (void) close (fd); - return 1; - } - - if (too_many_failures (fl)) { - (void) close (fd); - return 0; - } - - /* - * The record is updated if this is not a failure. The count will - * be reset to zero, but the rest of the information will be left - * in the record in case someone wants to see where the failed - * login originated. - */ - - if (!failed) { - fail = *fl; - fail.fail_cnt = 0; - - if ( (lseek (fd, offset_uid, SEEK_SET) != offset_uid) - || (write (fd, (const void *) &fail, sizeof fail) != (ssize_t) sizeof fail) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't reset faillog entry for UID %lu in %s.", - (unsigned long) uid, FAILLOG_FILE)); - (void) close (fd); - } - } else { - (void) close (fd); - } - - return 1; -} - -/* - * failprint - print line of failure information - * - * failprint takes a (struct faillog) entry and formats it into a - * message which is displayed at login time. - */ - -void failprint (const struct faillog *fail) -{ - struct tm *tp; - char lasttimeb[256]; - char *lasttime = lasttimeb; - time_t NOW; - - if (0 == fail->fail_cnt) { - return; - } - - tp = localtime (&(fail->fail_time)); - (void) time (&NOW); - - /* - * Print all information we have. - */ - (void) strftime (lasttimeb, sizeof lasttimeb, "%c", tp); - - /*@-formatconst@*/ - (void) printf (ngettext ("%d failure since last login.\n" - "Last was %s on %s.\n", - "%d failures since last login.\n" - "Last was %s on %s.\n", - (unsigned long) fail->fail_cnt), - fail->fail_cnt, lasttime, fail->fail_line); - /*@=formatconst@*/ -} - -/* - * failtmp - update the cumulative failure log - * - * failtmp updates the (struct utmp) formatted failure log which - * maintains a record of all login failures. - */ - -void failtmp (const char *username, -#ifdef USE_UTMPX - const struct utmpx *failent -#else /* !USE_UTMPX */ - const struct utmp *failent -#endif /* !USE_UTMPX */ - ) -{ - const char *ftmp; - int fd; - - /* - * Get the name of the failure file. If no file has been defined - * in login.defs, don't do this. - */ - - ftmp = getdef_str ("FTMP_FILE"); - if (NULL == ftmp) { - return; - } - - /* - * Open the file for append. It must already exist for this - * feature to be used. - */ - - if (access (ftmp, F_OK) != 0) { - return; - } - - fd = open (ftmp, O_WRONLY | O_APPEND); - if (-1 == fd) { - SYSLOG ((LOG_WARN, - "Can't append failure of user %s to %s.", - username, ftmp)); - return; - } - - /* - * Append the new failure record and close the log file. - */ - - if ( (write (fd, (const void *) failent, sizeof *failent) != (ssize_t) sizeof *failent) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't append failure of user %s to %s.", - username, ftmp)); - (void) close (fd); - } -} - diff --git a/libmisc/failure.h b/libmisc/failure.h deleted file mode 100644 index 2ac30d7..0000000 --- a/libmisc/failure.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1997 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2005 , Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* $Id$ */ -#ifndef _FAILURE_H_ -#define _FAILURE_H_ - -#include "defines.h" -#include "faillog.h" -#ifdef USE_UTMPX -#include <utmpx.h> -#else /* !USE_UTMPX */ -#include <utmp.h> -#endif /* !USE_UTMPX */ - -/* - * failure - make failure entry - * - * failure() creates a new (struct faillog) entry or updates an - * existing one with the current failed login information. - */ -extern void failure (uid_t, const char *, struct faillog *); - -/* - * failcheck - check for failures > allowable - * - * failcheck() is called AFTER the password has been validated. If the - * account has been "attacked" with too many login failures, failcheck() - * returns FALSE to indicate that the login should be denied even though - * the password is valid. - */ -extern int failcheck (uid_t uid, struct faillog *fl, bool failed); - -/* - * failprint - print line of failure information - * - * failprint takes a (struct faillog) entry and formats it into a - * message which is displayed at login time. - */ -extern void failprint (const struct faillog *); - -/* - * failtmp - update the cumulative failure log - * - * failtmp updates the (struct utmp) formatted failure log which - * maintains a record of all login failures. - */ -#ifdef USE_UTMPX -extern void failtmp (const char *username, const struct utmpx *); -#else /* !USE_UTMPX */ -extern void failtmp (const char *username, const struct utmp *); -#endif /* !USE_UTMPX */ - -#endif - diff --git a/libmisc/find_new_gid.c b/libmisc/find_new_gid.c deleted file mode 100644 index 65ab5d0..0000000 --- a/libmisc/find_new_gid.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 2008 - 2011, Nicolas François - * SPDX-FileCopyrightText: 2014, Red Hat, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include <assert.h> -#include <stdio.h> -#include <errno.h> - -#include "prototypes.h" -#include "groupio.h" -#include "getdef.h" -#include "shadowlog.h" - -/* - * get_ranges - Get the minimum and maximum ID ranges for the search - * - * This function will return the minimum and maximum ranges for IDs - * - * 0: The function completed successfully - * EINVAL: The provided ranges are impossible (such as maximum < minimum) - * - * preferred_min: The special-case minimum value for a specifically- - * requested ID, which may be lower than the standard min_id - */ -static int get_ranges (bool sys_group, gid_t *min_id, gid_t *max_id, - gid_t *preferred_min) -{ - gid_t gid_def_max = 0; - - if (sys_group) { - /* System groups */ - - /* A requested ID is allowed to be below the autoselect range */ - *preferred_min = (gid_t) 1; - - /* Get the minimum ID range from login.defs or default to 101 */ - *min_id = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL); - - /* - * If SYS_GID_MAX is unspecified, we should assume it to be one - * less than the GID_MIN (which is reserved for non-system accounts) - */ - gid_def_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1; - *max_id = (gid_t) getdef_ulong ("SYS_GID_MAX", - (unsigned long) gid_def_max); - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { - (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SYS_GID_MIN (%lu), " - "GID_MIN (%lu), SYS_GID_MAX (%lu)\n"), - log_get_progname(), (unsigned long) *min_id, - getdef_ulong ("GID_MIN", 1000UL), - (unsigned long) *max_id); - return EINVAL; - } - /* - * Zero is reserved for root and the allocation algorithm does not - * work right with it. - */ - if (*min_id == 0) { - *min_id = (gid_t) 1; - } - } else { - /* Non-system groups */ - - /* Get the values from login.defs or use reasonable defaults */ - *min_id = (gid_t) getdef_ulong ("GID_MIN", 1000UL); - *max_id = (gid_t) getdef_ulong ("GID_MAX", 60000UL); - - /* - * The preferred minimum should match the standard ID minimum - * for non-system groups. - */ - *preferred_min = *min_id; - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { - (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: GID_MIN (%lu), " - "GID_MAX (%lu)\n"), - log_get_progname(), (unsigned long) *min_id, - (unsigned long) *max_id); - return EINVAL; - } - } - - return 0; -} - -/* - * check_gid - See if the requested GID is available - * - * On success, return 0 - * If the ID is in use, return EEXIST - * If the ID is outside the range, return ERANGE - * In other cases, return errno from getgrgid() - */ -static int check_gid (const gid_t gid, - const gid_t gid_min, - const gid_t gid_max, - const bool *used_gids) -{ - /* First test that the preferred ID is in the range */ - if (gid < gid_min || gid > gid_max) { - return ERANGE; - } - - /* - * Check whether we already detected this GID - * using the gr_next() loop - */ - if (used_gids != NULL && used_gids[gid]) { - return EEXIST; - } - /* Check if the GID exists according to NSS */ - errno = 0; - if (prefix_getgrgid (gid) != NULL) { - return EEXIST; - } else { - /* getgrgid() was NULL - * we have to ignore errors as temporary - * failures of remote user identity services - * would completely block user/group creation - */ - } - - /* If we've made it here, the GID must be available */ - return 0; -} - -/* - * find_new_gid - Find a new unused GID. - * - * If successful, find_new_gid provides an unused group ID in the - * [GID_MIN:GID_MAX] range. - * This ID should be higher than all the used GID, but if not possible, - * the lowest unused ID in the range will be returned. - * - * Return 0 on success, -1 if no unused GIDs are available. - */ -int find_new_gid (bool sys_group, - gid_t *gid, - /*@null@*/gid_t const *preferred_gid) -{ - bool *used_gids; - const struct group *grp; - gid_t gid_min, gid_max, preferred_min; - gid_t id; - gid_t lowest_found, highest_found; - int result; - int nospam = 0; - - assert(gid != NULL); - - /* - * First, figure out what ID range is appropriate for - * automatic assignment - */ - result = get_ranges (sys_group, &gid_min, &gid_max, &preferred_min); - if (result == EINVAL) { - return -1; - } - - /* Check if the preferred GID is available */ - if (preferred_gid) { - result = check_gid (*preferred_gid, preferred_min, gid_max, NULL); - if (result == 0) { - /* - * Make sure the GID isn't queued for use already - */ - if (gr_locate_gid (*preferred_gid) == NULL) { - *gid = *preferred_gid; - return 0; - } - /* - * gr_locate_gid() found the GID in an as-yet uncommitted - * entry. We'll proceed below and auto-set a GID. - */ - } else if (result == EEXIST || result == ERANGE) { - /* - * Continue on below. At this time, we won't - * treat these two cases differently. - */ - } else { - /* - * An unexpected error occurred. We should report - * this and fail the group creation. - * This differs from the automatic creation - * behavior below, since if a specific GID was - * requested and generated an error, the user is - * more likely to want to stop and address the - * issue. - */ - fprintf (log_get_logfd(), - _("%s: Encountered error attempting to use " - "preferred GID: %s\n"), - log_get_progname(), strerror (result)); - return -1; - } - } - - /* - * Search the entire group file, - * looking for the next unused value. - * - * We first check the local database with gr_rewind/gr_next to find - * all local values that are in use. - * - * We then compare the next free value to all databases (local and - * remote) and iterate until we find a free one. If there are free - * values beyond the lowest (system groups) or highest (non-system - * groups), we will prefer those and avoid potentially reclaiming a - * deleted group (which can be a security issue, since it may grant - * access to files belonging to that former group). - * - * If there are no GIDs available at the end of the search, we will - * have no choice but to iterate through the range looking for gaps. - * - */ - - /* Create an array to hold all of the discovered GIDs */ - used_gids = malloc (sizeof (bool) * (gid_max +1)); - if (NULL == used_gids) { - fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), - log_get_progname(), strerror (errno)); - return -1; - } - memset (used_gids, false, sizeof (bool) * (gid_max + 1)); - - /* First look for the lowest and highest value in the local database */ - (void) gr_rewind (); - highest_found = gid_min; - lowest_found = gid_max; - while ((grp = gr_next ()) != NULL) { - /* - * Does this entry have a lower GID than the lowest we've found - * so far? - */ - if ((grp->gr_gid <= lowest_found) && (grp->gr_gid >= gid_min)) { - lowest_found = grp->gr_gid - 1; - } - - /* - * Does this entry have a higher GID than the highest we've found - * so far? - */ - if ((grp->gr_gid >= highest_found) && (grp->gr_gid <= gid_max)) { - highest_found = grp->gr_gid + 1; - } - - /* create index of used GIDs */ - if (grp->gr_gid >= gid_min - && grp->gr_gid <= gid_max) { - - used_gids[grp->gr_gid] = true; - } - } - - if (sys_group) { - /* - * For system groups, we want to start from the - * top of the range and work downwards. - */ - - /* - * At the conclusion of the gr_next() search, we will either - * have a presumed-free GID or we will be at GID_MIN - 1. - */ - if (lowest_found < gid_min) { - /* - * In this case, a GID is in use at GID_MIN. - * - * We will reset the search to GID_MAX and proceed down - * through all the GIDs (skipping those we detected with - * used_gids) for a free one. It is a known issue that - * this may result in reusing a previously-deleted GID, - * so administrators should be instructed to use this - * auto-detection with care (and prefer to assign GIDs - * explicitly). - */ - lowest_found = gid_max; - } - - /* Search through all of the IDs in the range */ - for (id = lowest_found; id >= gid_min; id--) { - result = check_gid (id, gid_min, gid_max, used_gids); - if (result == 0) { - /* This GID is available. Return it. */ - *gid = id; - free (used_gids); - return 0; - } else if (result == EEXIST) { - /* This GID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique system GID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later GID - * will work properly. - */ - } - } - - /* - * If we get all the way through the loop, try again from GID_MAX, - * unless that was where we previously started. (NOTE: the worst-case - * scenario here is that we will run through (GID_MAX - GID_MIN - 1) - * cycles *again* if we fall into this case with lowest_found as - * GID_MAX - 1, all groups in the range in use and maintained by - * network services such as LDAP.) - */ - if (lowest_found != gid_max) { - for (id = gid_max; id >= gid_min; id--) { - result = check_gid (id, gid_min, gid_max, used_gids); - if (result == 0) { - /* This GID is available. Return it. */ - *gid = id; - free (used_gids); - return 0; - } else if (result == EEXIST) { - /* This GID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique system GID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later GID - * will work properly. - */ - } - } - } - } else { /* !sys_group */ - /* - * For non-system groups, we want to start from the - * bottom of the range and work upwards. - */ - - /* - * At the conclusion of the gr_next() search, we will either - * have a presumed-free GID or we will be at GID_MAX + 1. - */ - if (highest_found > gid_max) { - /* - * In this case, a GID is in use at GID_MAX. - * - * We will reset the search to GID_MIN and proceed up - * through all the GIDs (skipping those we detected with - * used_gids) for a free one. It is a known issue that - * this may result in reusing a previously-deleted GID, - * so administrators should be instructed to use this - * auto-detection with care (and prefer to assign GIDs - * explicitly). - */ - highest_found = gid_min; - } - - /* Search through all of the IDs in the range */ - for (id = highest_found; id <= gid_max; id++) { - result = check_gid (id, gid_min, gid_max, used_gids); - if (result == 0) { - /* This GID is available. Return it. */ - *gid = id; - free (used_gids); - return 0; - } else if (result == EEXIST) { - /* This GID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique GID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later GID - * will work properly. - */ - } - } - - /* - * If we get all the way through the loop, try again from GID_MIN, - * unless that was where we previously started. (NOTE: the worst-case - * scenario here is that we will run through (GID_MAX - GID_MIN - 1) - * cycles *again* if we fall into this case with highest_found as - * GID_MIN + 1, all groups in the range in use and maintained by - * network services such as LDAP.) - */ - if (highest_found != gid_min) { - for (id = gid_min; id <= gid_max; id++) { - result = check_gid (id, gid_min, gid_max, used_gids); - if (result == 0) { - /* This GID is available. Return it. */ - *gid = id; - free (used_gids); - return 0; - } else if (result == EEXIST) { - /* This GID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique GID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available GIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later GID - * will work properly. - */ - } - } - } - } - - /* The code reached here and found no available IDs in the range */ - fprintf (log_get_logfd(), - _("%s: Can't get unique GID (no more available GIDs)\n"), - log_get_progname()); - SYSLOG ((LOG_WARN, "no more available GIDs on the system")); - free (used_gids); - return -1; -} - diff --git a/libmisc/find_new_sub_gids.c b/libmisc/find_new_sub_gids.c deleted file mode 100644 index bbd4570..0000000 --- a/libmisc/find_new_sub_gids.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2012 Eric Biederman - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ifdef ENABLE_SUBIDS - -#include <assert.h> -#include <stdio.h> -#include <errno.h> - -#include "prototypes.h" -#include "subordinateio.h" -#include "getdef.h" -#include "shadowlog.h" - -/* - * find_new_sub_gids - Find a new unused range of GIDs. - * - * If successful, find_new_sub_gids provides a range of unused - * user IDs in the [SUB_GID_MIN:SUB_GID_MAX] range. - * - * Return 0 on success, -1 if no unused GIDs are available. - */ -int find_new_sub_gids (gid_t *range_start, unsigned long *range_count) -{ - unsigned long min, max; - unsigned long count; - gid_t start; - - assert (range_start != NULL); - assert (range_count != NULL); - - min = getdef_ulong ("SUB_GID_MIN", 100000UL); - max = getdef_ulong ("SUB_GID_MAX", 600100000UL); - count = getdef_ulong ("SUB_GID_COUNT", 65536); - - if (min > max || count >= max || (min + count - 1) > max) { - (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SUB_GID_MIN (%lu)," - " SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"), - log_get_progname(), min, max, count); - return -1; - } - - start = sub_gid_find_free_range(min, max, count); - if (start == (gid_t)-1) { - fprintf (log_get_logfd(), - _("%s: Can't get unique subordinate GID range\n"), - log_get_progname()); - SYSLOG ((LOG_WARN, "no more available subordinate GIDs on the system")); - return -1; - } - *range_start = start; - *range_count = count; - return 0; -} -#else /* !ENABLE_SUBIDS */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !ENABLE_SUBIDS */ - diff --git a/libmisc/find_new_sub_uids.c b/libmisc/find_new_sub_uids.c deleted file mode 100644 index a86b311..0000000 --- a/libmisc/find_new_sub_uids.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2012 Eric Biederman - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ifdef ENABLE_SUBIDS - -#include <assert.h> -#include <stdio.h> -#include <errno.h> - -#include "prototypes.h" -#include "subordinateio.h" -#include "getdef.h" -#include "shadowlog.h" - -/* - * find_new_sub_uids - Find a new unused range of UIDs. - * - * If successful, find_new_sub_uids provides a range of unused - * user IDs in the [SUB_UID_MIN:SUB_UID_MAX] range. - * - * Return 0 on success, -1 if no unused UIDs are available. - */ -int find_new_sub_uids (uid_t *range_start, unsigned long *range_count) -{ - unsigned long min, max; - unsigned long count; - uid_t start; - - assert (range_start != NULL); - assert (range_count != NULL); - - min = getdef_ulong ("SUB_UID_MIN", 100000UL); - max = getdef_ulong ("SUB_UID_MAX", 600100000UL); - count = getdef_ulong ("SUB_UID_COUNT", 65536); - - if (min > max || count >= max || (min + count - 1) > max) { - (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SUB_UID_MIN (%lu)," - " SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"), - log_get_progname(), min, max, count); - return -1; - } - - start = sub_uid_find_free_range(min, max, count); - if (start == (uid_t)-1) { - fprintf (log_get_logfd(), - _("%s: Can't get unique subordinate UID range\n"), - log_get_progname()); - SYSLOG ((LOG_WARN, "no more available subordinate UIDs on the system")); - return -1; - } - *range_start = start; - *range_count = count; - return 0; -} -#else /* !ENABLE_SUBIDS */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !ENABLE_SUBIDS */ - diff --git a/libmisc/find_new_uid.c b/libmisc/find_new_uid.c deleted file mode 100644 index 5f7e74b..0000000 --- a/libmisc/find_new_uid.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 2008 - 2011, Nicolas François - * SPDX-FileCopyrightText: 2014, Red Hat, Inc. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include <assert.h> -#include <stdio.h> -#include <errno.h> - -#include "prototypes.h" -#include "pwio.h" -#include "getdef.h" -#include "shadowlog.h" - -/* - * get_ranges - Get the minimum and maximum ID ranges for the search - * - * This function will return the minimum and maximum ranges for IDs - * - * 0: The function completed successfully - * EINVAL: The provided ranges are impossible (such as maximum < minimum) - * - * preferred_min: The special-case minimum value for a specifically- - * requested ID, which may be lower than the standard min_id - */ -static int get_ranges (bool sys_user, uid_t *min_id, uid_t *max_id, - uid_t *preferred_min) -{ - uid_t uid_def_max = 0; - - if (sys_user) { - /* System users */ - - /* A requested ID is allowed to be below the autoselect range */ - *preferred_min = (uid_t) 1; - - /* Get the minimum ID range from login.defs or default to 101 */ - *min_id = (uid_t) getdef_ulong ("SYS_UID_MIN", 101UL); - - /* - * If SYS_UID_MAX is unspecified, we should assume it to be one - * less than the UID_MIN (which is reserved for non-system accounts) - */ - uid_def_max = (uid_t) getdef_ulong ("UID_MIN", 1000UL) - 1; - *max_id = (uid_t) getdef_ulong ("SYS_UID_MAX", - (unsigned long) uid_def_max); - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { - (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: SYS_UID_MIN (%lu), " - "UID_MIN (%lu), SYS_UID_MAX (%lu)\n"), - log_get_progname(), (unsigned long) *min_id, - getdef_ulong ("UID_MIN", 1000UL), - (unsigned long) *max_id); - return EINVAL; - } - /* - * Zero is reserved for root and the allocation algorithm does not - * work right with it. - */ - if (*min_id == 0) { - *min_id = (uid_t) 1; - } - } else { - /* Non-system users */ - - /* Get the values from login.defs or use reasonable defaults */ - *min_id = (uid_t) getdef_ulong ("UID_MIN", 1000UL); - *max_id = (uid_t) getdef_ulong ("UID_MAX", 60000UL); - - /* - * The preferred minimum should match the standard ID minimum - * for non-system users. - */ - *preferred_min = *min_id; - - /* Check that the ranges make sense */ - if (*max_id < *min_id) { - (void) fprintf (log_get_logfd(), - _("%s: Invalid configuration: UID_MIN (%lu), " - "UID_MAX (%lu)\n"), - log_get_progname(), (unsigned long) *min_id, - (unsigned long) *max_id); - return EINVAL; - } - } - - return 0; -} - -/* - * check_uid - See if the requested UID is available - * - * On success, return 0 - * If the ID is in use, return EEXIST - * If the ID is outside the range, return ERANGE - * In other cases, return errno from getpwuid() - */ -static int check_uid(const uid_t uid, - const uid_t uid_min, - const uid_t uid_max, - const bool *used_uids) -{ - /* First test that the preferred ID is in the range */ - if (uid < uid_min || uid > uid_max) { - return ERANGE; - } - - /* - * Check whether we already detected this UID - * using the pw_next() loop - */ - if (used_uids != NULL && used_uids[uid]) { - return EEXIST; - } - /* Check if the UID exists according to NSS */ - errno = 0; - if (prefix_getpwuid(uid) != NULL) { - return EEXIST; - } else { - /* getpwuid() was NULL - * we have to ignore errors as temporary - * failures of remote user identity services - * would completely block user/group creation - */ - } - - /* If we've made it here, the UID must be available */ - return 0; -} - -/* - * find_new_uid - Find a new unused UID. - * - * If successful, find_new_uid provides an unused user ID in the - * [UID_MIN:UID_MAX] range. - * This ID should be higher than all the used UID, but if not possible, - * the lowest unused ID in the range will be returned. - * - * Return 0 on success, -1 if no unused UIDs are available. - */ -int find_new_uid(bool sys_user, - uid_t *uid, - /*@null@*/uid_t const *preferred_uid) -{ - bool *used_uids; - const struct passwd *pwd; - uid_t uid_min, uid_max, preferred_min; - uid_t id; - uid_t lowest_found, highest_found; - int result; - int nospam = 0; - - assert (uid != NULL); - - /* - * First, figure out what ID range is appropriate for - * automatic assignment - */ - result = get_ranges (sys_user, &uid_min, &uid_max, &preferred_min); - if (result == EINVAL) { - return -1; - } - - /* Check if the preferred UID is available */ - if (preferred_uid) { - result = check_uid (*preferred_uid, preferred_min, uid_max, NULL); - if (result == 0) { - /* - * Make sure the UID isn't queued for use already - */ - if (pw_locate_uid (*preferred_uid) == NULL) { - *uid = *preferred_uid; - return 0; - } - /* - * pw_locate_uid() found the UID in an as-yet uncommitted - * entry. We'll proceed below and auto-set an UID. - */ - } else if (result == EEXIST || result == ERANGE) { - /* - * Continue on below. At this time, we won't - * treat these two cases differently. - */ - } else { - /* - * An unexpected error occurred. We should report - * this and fail the user creation. - * This differs from the automatic creation - * behavior below, since if a specific UID was - * requested and generated an error, the user is - * more likely to want to stop and address the - * issue. - */ - fprintf (log_get_logfd(), - _("%s: Encountered error attempting to use " - "preferred UID: %s\n"), - log_get_progname(), strerror (result)); - return -1; - } - } - - /* - * Search the entire passwd file, - * looking for the next unused value. - * - * We first check the local database with pw_rewind/pw_next to find - * all local values that are in use. - * - * We then compare the next free value to all databases (local and - * remote) and iterate until we find a free one. If there are free - * values beyond the lowest (system users) or highest (non-system - * users), we will prefer those and avoid potentially reclaiming a - * deleted user (which can be a security issue, since it may grant - * access to files belonging to that former user). - * - * If there are no UIDs available at the end of the search, we will - * have no choice but to iterate through the range looking for gaps. - * - */ - - /* Create an array to hold all of the discovered UIDs */ - used_uids = malloc (sizeof (bool) * (uid_max +1)); - if (NULL == used_uids) { - fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), - log_get_progname(), strerror (errno)); - return -1; - } - memset (used_uids, false, sizeof (bool) * (uid_max + 1)); - - /* First look for the lowest and highest value in the local database */ - (void) pw_rewind (); - highest_found = uid_min; - lowest_found = uid_max; - while ((pwd = pw_next ()) != NULL) { - /* - * Does this entry have a lower UID than the lowest we've found - * so far? - */ - if ((pwd->pw_uid <= lowest_found) && (pwd->pw_uid >= uid_min)) { - lowest_found = pwd->pw_uid - 1; - } - - /* - * Does this entry have a higher UID than the highest we've found - * so far? - */ - if ((pwd->pw_uid >= highest_found) && (pwd->pw_uid <= uid_max)) { - highest_found = pwd->pw_uid + 1; - } - - /* create index of used UIDs */ - if (pwd->pw_uid >= uid_min - && pwd->pw_uid <= uid_max) { - - used_uids[pwd->pw_uid] = true; - } - } - - if (sys_user) { - /* - * For system users, we want to start from the - * top of the range and work downwards. - */ - - /* - * At the conclusion of the pw_next() search, we will either - * have a presumed-free UID or we will be at UID_MIN - 1. - */ - if (lowest_found < uid_min) { - /* - * In this case, an UID is in use at UID_MIN. - * - * We will reset the search to UID_MAX and proceed down - * through all the UIDs (skipping those we detected with - * used_uids) for a free one. It is a known issue that - * this may result in reusing a previously-deleted UID, - * so administrators should be instructed to use this - * auto-detection with care (and prefer to assign UIDs - * explicitly). - */ - lowest_found = uid_max; - } - - /* Search through all of the IDs in the range */ - for (id = lowest_found; id >= uid_min; id--) { - result = check_uid (id, uid_min, uid_max, used_uids); - if (result == 0) { - /* This UID is available. Return it. */ - *uid = id; - free (used_uids); - return 0; - } else if (result == EEXIST) { - /* This UID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique system UID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later UID - * will work properly. - */ - } - } - - /* - * If we get all the way through the loop, try again from UID_MAX, - * unless that was where we previously started. (NOTE: the worst-case - * scenario here is that we will run through (UID_MAX - UID_MIN - 1) - * cycles *again* if we fall into this case with lowest_found as - * UID_MAX - 1, all users in the range in use and maintained by - * network services such as LDAP.) - */ - if (lowest_found != uid_max) { - for (id = uid_max; id >= uid_min; id--) { - result = check_uid (id, uid_min, uid_max, used_uids); - if (result == 0) { - /* This UID is available. Return it. */ - *uid = id; - free (used_uids); - return 0; - } else if (result == EEXIST) { - /* This UID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique system UID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later UID - * will work properly. - */ - } - } - } - } else { /* !sys_user */ - /* - * For non-system users, we want to start from the - * bottom of the range and work upwards. - */ - - /* - * At the conclusion of the pw_next() search, we will either - * have a presumed-free UID or we will be at UID_MAX + 1. - */ - if (highest_found > uid_max) { - /* - * In this case, a UID is in use at UID_MAX. - * - * We will reset the search to UID_MIN and proceed up - * through all the UIDs (skipping those we detected with - * used_uids) for a free one. It is a known issue that - * this may result in reusing a previously-deleted UID, - * so administrators should be instructed to use this - * auto-detection with care (and prefer to assign UIDs - * explicitly). - */ - highest_found = uid_min; - } - - /* Search through all of the IDs in the range */ - for (id = highest_found; id <= uid_max; id++) { - result = check_uid (id, uid_min, uid_max, used_uids); - if (result == 0) { - /* This UID is available. Return it. */ - *uid = id; - free (used_uids); - return 0; - } else if (result == EEXIST) { - /* This UID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique UID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later UID - * will work properly. - */ - } - } - - /* - * If we get all the way through the loop, try again from UID_MIN, - * unless that was where we previously started. (NOTE: the worst-case - * scenario here is that we will run through (UID_MAX - UID_MIN - 1) - * cycles *again* if we fall into this case with highest_found as - * UID_MIN + 1, all users in the range in use and maintained by - * network services such as LDAP.) - */ - if (highest_found != uid_min) { - for (id = uid_min; id <= uid_max; id++) { - result = check_uid (id, uid_min, uid_max, used_uids); - if (result == 0) { - /* This UID is available. Return it. */ - *uid = id; - free (used_uids); - return 0; - } else if (result == EEXIST) { - /* This UID is in use, we'll continue to the next */ - } else { - /* - * An unexpected error occurred. - * - * Only report it the first time to avoid spamming - * the logs - * - */ - if (!nospam) { - fprintf (log_get_logfd(), - _("%s: Can't get unique UID (%s). " - "Suppressing additional messages.\n"), - log_get_progname(), strerror (result)); - SYSLOG ((LOG_ERR, - "Error checking available UIDs: %s", - strerror (result))); - nospam = 1; - } - /* - * We will continue anyway. Hopefully a later UID - * will work properly. - */ - } - } - } - } - - /* The code reached here and found no available IDs in the range */ - fprintf (log_get_logfd(), - _("%s: Can't get unique UID (no more available UIDs)\n"), - log_get_progname()); - SYSLOG ((LOG_WARN, "no more available UIDs on the system")); - free (used_uids); - return -1; -} - diff --git a/libmisc/getdate.c b/libmisc/getdate.c deleted file mode 100644 index fc17c18..0000000 --- a/libmisc/getdate.c +++ /dev/null @@ -1,2540 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - 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 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <https://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output, and Bison version. */ -#define YYBISON 30802 - -/* Bison version string. */ -#define YYBISON_VERSION "3.8.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* First part of user prologue. */ -#line 1 "getdate.y" - -/* -** 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> -# ifdef FORCE_ALLOCA_H -# include <alloca.h> -# endif -#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 <stdio.h> -#include <ctype.h> -#include <time.h> - -#include "getdate.h" - -#include <string.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; - - -#line 219 "getdate.c" - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast<Type> (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - - -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - tAGO = 258, /* tAGO */ - tDAY = 259, /* tDAY */ - tDAY_UNIT = 260, /* tDAY_UNIT */ - tDAYZONE = 261, /* tDAYZONE */ - tDST = 262, /* tDST */ - tHOUR_UNIT = 263, /* tHOUR_UNIT */ - tID = 264, /* tID */ - tMERIDIAN = 265, /* tMERIDIAN */ - tMINUTE_UNIT = 266, /* tMINUTE_UNIT */ - tMONTH = 267, /* tMONTH */ - tMONTH_UNIT = 268, /* tMONTH_UNIT */ - tSEC_UNIT = 269, /* tSEC_UNIT */ - tSNUMBER = 270, /* tSNUMBER */ - tUNUMBER = 271, /* tUNUMBER */ - tYEAR_UNIT = 272, /* tYEAR_UNIT */ - tZONE = 273 /* tZONE */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif -/* Token kinds. */ -#define YYEMPTY -2 -#define YYEOF 0 -#define YYerror 256 -#define YYUNDEF 257 -#define tAGO 258 -#define tDAY 259 -#define tDAY_UNIT 260 -#define tDAYZONE 261 -#define tDST 262 -#define tHOUR_UNIT 263 -#define tID 264 -#define tMERIDIAN 265 -#define tMINUTE_UNIT 266 -#define tMONTH 267 -#define tMONTH_UNIT 268 -#define tSEC_UNIT 269 -#define tSNUMBER 270 -#define tUNUMBER 271 -#define tYEAR_UNIT 272 -#define tZONE 273 - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 149 "getdate.y" - - int Number; - enum _MERIDIAN Meridian; - -#line 310 "getdate.c" - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - - -int yyparse (void); - - - -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_tAGO = 3, /* tAGO */ - YYSYMBOL_tDAY = 4, /* tDAY */ - YYSYMBOL_tDAY_UNIT = 5, /* tDAY_UNIT */ - YYSYMBOL_tDAYZONE = 6, /* tDAYZONE */ - YYSYMBOL_tDST = 7, /* tDST */ - YYSYMBOL_tHOUR_UNIT = 8, /* tHOUR_UNIT */ - YYSYMBOL_tID = 9, /* tID */ - YYSYMBOL_tMERIDIAN = 10, /* tMERIDIAN */ - YYSYMBOL_tMINUTE_UNIT = 11, /* tMINUTE_UNIT */ - YYSYMBOL_tMONTH = 12, /* tMONTH */ - YYSYMBOL_tMONTH_UNIT = 13, /* tMONTH_UNIT */ - YYSYMBOL_tSEC_UNIT = 14, /* tSEC_UNIT */ - YYSYMBOL_tSNUMBER = 15, /* tSNUMBER */ - YYSYMBOL_tUNUMBER = 16, /* tUNUMBER */ - YYSYMBOL_tYEAR_UNIT = 17, /* tYEAR_UNIT */ - YYSYMBOL_tZONE = 18, /* tZONE */ - YYSYMBOL_19_ = 19, /* ':' */ - YYSYMBOL_20_ = 20, /* ',' */ - YYSYMBOL_21_ = 21, /* '/' */ - YYSYMBOL_YYACCEPT = 22, /* $accept */ - YYSYMBOL_spec = 23, /* spec */ - YYSYMBOL_item = 24, /* item */ - YYSYMBOL_time = 25, /* time */ - YYSYMBOL_zone = 26, /* zone */ - YYSYMBOL_day = 27, /* day */ - YYSYMBOL_date = 28, /* date */ - YYSYMBOL_rel = 29, /* rel */ - YYSYMBOL_relunit = 30, /* relunit */ - YYSYMBOL_number = 31, /* number */ - YYSYMBOL_o_merid = 32 /* o_merid */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - <limits.h> and (if available) <stdint.h> are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include <limits.h> /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include <stdint.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -/* Work around bug in HP-UX 11.23, which defines these macros - incorrectly for preprocessor constants. This workaround can likely - be removed in 2023, as HPE has promised support for HP-UX 11.23 - (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of - <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */ -#ifdef __hpux -# undef UINT_LEAST8_MAX -# undef UINT_LEAST16_MAX -# define UINT_LEAST8_MAX 255 -# define UINT_LEAST16_MAX 65535 -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_int8 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YY_USE(E) ((void) (E)) -#else -# define YY_USE(E) /* empty */ -#endif - -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ -# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") -# else -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# endif -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if !defined yyoverflow - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* !defined yyoverflow */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 2 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 50 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 22 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 11 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 51 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 61 - -/* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 273 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_int8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 20, 2, 2, 21, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 19, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18 -}; - -#if YYDEBUG -/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_int16 yyrline[] = -{ - 0, 165, 165, 166, 169, 172, 175, 178, 181, 184, - 187, 193, 199, 208, 214, 226, 229, 233, 238, 242, - 246, 252, 256, 274, 280, 286, 290, 295, 299, 306, - 314, 317, 320, 323, 326, 329, 332, 335, 338, 341, - 344, 347, 350, 353, 356, 359, 362, 365, 368, 373, - 407, 410 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if YYDEBUG || 0 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "\"end of file\"", "error", "\"invalid token\"", "tAGO", "tDAY", - "tDAY_UNIT", "tDAYZONE", "tDST", "tHOUR_UNIT", "tID", "tMERIDIAN", - "tMINUTE_UNIT", "tMONTH", "tMONTH_UNIT", "tSEC_UNIT", "tSNUMBER", - "tUNUMBER", "tYEAR_UNIT", "tZONE", "':'", "','", "'/'", "$accept", - "spec", "item", "time", "zone", "day", "date", "rel", "relunit", - "number", "o_merid", YY_NULLPTR -}; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - return yytname[yysymbol]; -} -#endif - -#define YYPACT_NINF (-20) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-1) - -#define yytable_value_is_error(Yyn) \ - 0 - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int8 yypact[] = -{ - -20, 0, -20, -19, -20, -20, -20, -20, -13, -20, - -20, 30, 15, -20, 14, -20, -20, -20, -20, -20, - -20, 19, -20, -20, 4, -20, -20, -20, -20, -20, - -20, -20, -20, -20, -20, -20, -6, -20, -20, 16, - -20, 17, 23, -20, -20, 24, -20, -20, -20, 27, - 28, -20, -20, -20, 29, -20, 32, -8, -20, -20, - -20 -}; - -/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_int8 yydefact[] = -{ - 2, 0, 1, 18, 39, 16, 42, 45, 0, 36, - 48, 0, 49, 33, 15, 3, 4, 5, 7, 6, - 8, 30, 9, 19, 25, 38, 41, 44, 35, 47, - 32, 20, 37, 40, 10, 43, 27, 34, 46, 0, - 31, 0, 0, 17, 29, 0, 24, 28, 23, 50, - 21, 26, 51, 12, 0, 11, 0, 50, 22, 14, - 13 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -20, -20, -20, -20, -20, -20, -20, -20, -20, -20, - -7 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - 0, 1, 15, 16, 17, 18, 19, 20, 21, 22, - 55 -}; - -/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int8 yytable[] = -{ - 2, 23, 52, 24, 3, 4, 5, 59, 6, 46, - 47, 7, 8, 9, 10, 11, 12, 13, 14, 31, - 32, 43, 44, 33, 45, 34, 35, 36, 37, 38, - 39, 48, 40, 49, 41, 25, 42, 52, 26, 50, - 51, 27, 53, 28, 29, 57, 54, 30, 58, 56, - 60 -}; - -static const yytype_int8 yycheck[] = -{ - 0, 20, 10, 16, 4, 5, 6, 15, 8, 15, - 16, 11, 12, 13, 14, 15, 16, 17, 18, 4, - 5, 7, 3, 8, 20, 10, 11, 12, 13, 14, - 15, 15, 17, 16, 19, 5, 21, 10, 8, 16, - 16, 11, 15, 13, 14, 16, 19, 17, 16, 21, - 57 -}; - -/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of - state STATE-NUM. */ -static const yytype_int8 yystos[] = -{ - 0, 23, 0, 4, 5, 6, 8, 11, 12, 13, - 14, 15, 16, 17, 18, 24, 25, 26, 27, 28, - 29, 30, 31, 20, 16, 5, 8, 11, 13, 14, - 17, 4, 5, 8, 10, 11, 12, 13, 14, 15, - 17, 19, 21, 7, 3, 20, 15, 16, 15, 16, - 16, 16, 10, 15, 19, 32, 21, 16, 16, 15, - 32 -}; - -/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr1[] = -{ - 0, 22, 23, 23, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 26, 26, 26, 27, 27, - 27, 28, 28, 28, 28, 28, 28, 28, 28, 29, - 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, - 32, 32 -}; - -/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 0, 2, 1, 1, 1, 1, 1, 1, - 2, 4, 4, 6, 6, 1, 1, 2, 1, 2, - 2, 3, 5, 3, 3, 2, 4, 2, 3, 2, - 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, - 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, - 0, 1 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab -#define YYNOMEM goto yyexhaustedlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - FILE *yyoutput = yyo; - YY_USE (yyoutput); - if (!yyvaluep) - return; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - yy_symbol_value_print (yyo, yykind, yyvaluep); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, - int yyrule) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)]); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - - - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep) -{ - YY_USE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* Lookahead token kind. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - yy_state_fast_t yystate = 0; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; - - /* Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; - - /* The state stack: array, bottom, top. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; - - /* The semantic value stack: array, bottom, top. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; - - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead symbol kind. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - YYNOMEM; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - YYNOMEM; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - YYNOMEM; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - /* Discard the shifted token. */ - yychar = YYEMPTY; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 4: /* item: time */ -#line 169 "getdate.y" - { - yyHaveTime++; - } -#line 1360 "getdate.c" - break; - - case 5: /* item: zone */ -#line 172 "getdate.y" - { - yyHaveZone++; - } -#line 1368 "getdate.c" - break; - - case 6: /* item: date */ -#line 175 "getdate.y" - { - yyHaveDate++; - } -#line 1376 "getdate.c" - break; - - case 7: /* item: day */ -#line 178 "getdate.y" - { - yyHaveDay++; - } -#line 1384 "getdate.c" - break; - - case 8: /* item: rel */ -#line 181 "getdate.y" - { - yyHaveRel++; - } -#line 1392 "getdate.c" - break; - - case 10: /* time: tUNUMBER tMERIDIAN */ -#line 187 "getdate.y" - { - yyHour = (yyvsp[-1].Number); - yyMinutes = 0; - yySeconds = 0; - yyMeridian = (yyvsp[0].Meridian); - } -#line 1403 "getdate.c" - break; - - case 11: /* time: tUNUMBER ':' tUNUMBER o_merid */ -#line 193 "getdate.y" - { - yyHour = (yyvsp[-3].Number); - yyMinutes = (yyvsp[-1].Number); - yySeconds = 0; - yyMeridian = (yyvsp[0].Meridian); - } -#line 1414 "getdate.c" - break; - - case 12: /* time: tUNUMBER ':' tUNUMBER tSNUMBER */ -#line 199 "getdate.y" - { - yyHour = (yyvsp[-3].Number); - yyMinutes = (yyvsp[-1].Number); - yyMeridian = MER24; - yyHaveZone++; - yyTimezone = ((yyvsp[0].Number) < 0 - ? -(yyvsp[0].Number) % 100 + (-(yyvsp[0].Number) / 100) * 60 - : - ((yyvsp[0].Number) % 100 + ((yyvsp[0].Number) / 100) * 60)); - } -#line 1428 "getdate.c" - break; - - case 13: /* time: tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid */ -#line 208 "getdate.y" - { - yyHour = (yyvsp[-5].Number); - yyMinutes = (yyvsp[-3].Number); - yySeconds = (yyvsp[-1].Number); - yyMeridian = (yyvsp[0].Meridian); - } -#line 1439 "getdate.c" - break; - - case 14: /* time: tUNUMBER ':' tUNUMBER ':' tUNUMBER tSNUMBER */ -#line 214 "getdate.y" - { - yyHour = (yyvsp[-5].Number); - yyMinutes = (yyvsp[-3].Number); - yySeconds = (yyvsp[-1].Number); - yyMeridian = MER24; - yyHaveZone++; - yyTimezone = ((yyvsp[0].Number) < 0 - ? -(yyvsp[0].Number) % 100 + (-(yyvsp[0].Number) / 100) * 60 - : - ((yyvsp[0].Number) % 100 + ((yyvsp[0].Number) / 100) * 60)); - } -#line 1454 "getdate.c" - break; - - case 15: /* zone: tZONE */ -#line 226 "getdate.y" - { - yyTimezone = (yyvsp[0].Number); - } -#line 1462 "getdate.c" - break; - - case 16: /* zone: tDAYZONE */ -#line 229 "getdate.y" - { - yyTimezone = (yyvsp[0].Number) - 60; - } -#line 1470 "getdate.c" - break; - - case 17: /* zone: tZONE tDST */ -#line 233 "getdate.y" - { - yyTimezone = (yyvsp[-1].Number) - 60; - } -#line 1478 "getdate.c" - break; - - case 18: /* day: tDAY */ -#line 238 "getdate.y" - { - yyDayOrdinal = 1; - yyDayNumber = (yyvsp[0].Number); - } -#line 1487 "getdate.c" - break; - - case 19: /* day: tDAY ',' */ -#line 242 "getdate.y" - { - yyDayOrdinal = 1; - yyDayNumber = (yyvsp[-1].Number); - } -#line 1496 "getdate.c" - break; - - case 20: /* day: tUNUMBER tDAY */ -#line 246 "getdate.y" - { - yyDayOrdinal = (yyvsp[-1].Number); - yyDayNumber = (yyvsp[0].Number); - } -#line 1505 "getdate.c" - break; - - case 21: /* date: tUNUMBER '/' tUNUMBER */ -#line 252 "getdate.y" - { - yyMonth = (yyvsp[-2].Number); - yyDay = (yyvsp[0].Number); - } -#line 1514 "getdate.c" - break; - - case 22: /* date: tUNUMBER '/' tUNUMBER '/' tUNUMBER */ -#line 256 "getdate.y" - { - /* 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 ((yyvsp[-4].Number) >= 1000) - { - yyYear = (yyvsp[-4].Number); - yyMonth = (yyvsp[-2].Number); - yyDay = (yyvsp[0].Number); - } - else - { - yyMonth = (yyvsp[-4].Number); - yyDay = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } - } -#line 1537 "getdate.c" - break; - - case 23: /* date: tUNUMBER tSNUMBER tSNUMBER */ -#line 274 "getdate.y" - { - /* ISO 8601 format. yyyy-mm-dd. */ - yyYear = (yyvsp[-2].Number); - yyMonth = -(yyvsp[-1].Number); - yyDay = -(yyvsp[0].Number); - } -#line 1548 "getdate.c" - break; - - case 24: /* date: tUNUMBER tMONTH tSNUMBER */ -#line 280 "getdate.y" - { - /* e.g. 17-JUN-1992. */ - yyDay = (yyvsp[-2].Number); - yyMonth = (yyvsp[-1].Number); - yyYear = -(yyvsp[0].Number); - } -#line 1559 "getdate.c" - break; - - case 25: /* date: tMONTH tUNUMBER */ -#line 286 "getdate.y" - { - yyMonth = (yyvsp[-1].Number); - yyDay = (yyvsp[0].Number); - } -#line 1568 "getdate.c" - break; - - case 26: /* date: tMONTH tUNUMBER ',' tUNUMBER */ -#line 290 "getdate.y" - { - yyMonth = (yyvsp[-3].Number); - yyDay = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } -#line 1578 "getdate.c" - break; - - case 27: /* date: tUNUMBER tMONTH */ -#line 295 "getdate.y" - { - yyMonth = (yyvsp[0].Number); - yyDay = (yyvsp[-1].Number); - } -#line 1587 "getdate.c" - break; - - case 28: /* date: tUNUMBER tMONTH tUNUMBER */ -#line 299 "getdate.y" - { - yyMonth = (yyvsp[-1].Number); - yyDay = (yyvsp[-2].Number); - yyYear = (yyvsp[0].Number); - } -#line 1597 "getdate.c" - break; - - case 29: /* rel: relunit tAGO */ -#line 306 "getdate.y" - { - yyRelSeconds = -yyRelSeconds; - yyRelMinutes = -yyRelMinutes; - yyRelHour = -yyRelHour; - yyRelDay = -yyRelDay; - yyRelMonth = -yyRelMonth; - yyRelYear = -yyRelYear; - } -#line 1610 "getdate.c" - break; - - case 31: /* relunit: tUNUMBER tYEAR_UNIT */ -#line 317 "getdate.y" - { - yyRelYear += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1618 "getdate.c" - break; - - case 32: /* relunit: tSNUMBER tYEAR_UNIT */ -#line 320 "getdate.y" - { - yyRelYear += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1626 "getdate.c" - break; - - case 33: /* relunit: tYEAR_UNIT */ -#line 323 "getdate.y" - { - yyRelYear++; - } -#line 1634 "getdate.c" - break; - - case 34: /* relunit: tUNUMBER tMONTH_UNIT */ -#line 326 "getdate.y" - { - yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1642 "getdate.c" - break; - - case 35: /* relunit: tSNUMBER tMONTH_UNIT */ -#line 329 "getdate.y" - { - yyRelMonth += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1650 "getdate.c" - break; - - case 36: /* relunit: tMONTH_UNIT */ -#line 332 "getdate.y" - { - yyRelMonth++; - } -#line 1658 "getdate.c" - break; - - case 37: /* relunit: tUNUMBER tDAY_UNIT */ -#line 335 "getdate.y" - { - yyRelDay += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1666 "getdate.c" - break; - - case 38: /* relunit: tSNUMBER tDAY_UNIT */ -#line 338 "getdate.y" - { - yyRelDay += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1674 "getdate.c" - break; - - case 39: /* relunit: tDAY_UNIT */ -#line 341 "getdate.y" - { - yyRelDay++; - } -#line 1682 "getdate.c" - break; - - case 40: /* relunit: tUNUMBER tHOUR_UNIT */ -#line 344 "getdate.y" - { - yyRelHour += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1690 "getdate.c" - break; - - case 41: /* relunit: tSNUMBER tHOUR_UNIT */ -#line 347 "getdate.y" - { - yyRelHour += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1698 "getdate.c" - break; - - case 42: /* relunit: tHOUR_UNIT */ -#line 350 "getdate.y" - { - yyRelHour++; - } -#line 1706 "getdate.c" - break; - - case 43: /* relunit: tUNUMBER tMINUTE_UNIT */ -#line 353 "getdate.y" - { - yyRelMinutes += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1714 "getdate.c" - break; - - case 44: /* relunit: tSNUMBER tMINUTE_UNIT */ -#line 356 "getdate.y" - { - yyRelMinutes += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1722 "getdate.c" - break; - - case 45: /* relunit: tMINUTE_UNIT */ -#line 359 "getdate.y" - { - yyRelMinutes++; - } -#line 1730 "getdate.c" - break; - - case 46: /* relunit: tUNUMBER tSEC_UNIT */ -#line 362 "getdate.y" - { - yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1738 "getdate.c" - break; - - case 47: /* relunit: tSNUMBER tSEC_UNIT */ -#line 365 "getdate.y" - { - yyRelSeconds += (yyvsp[-1].Number) * (yyvsp[0].Number); - } -#line 1746 "getdate.c" - break; - - case 48: /* relunit: tSEC_UNIT */ -#line 368 "getdate.y" - { - yyRelSeconds++; - } -#line 1754 "getdate.c" - break; - - case 49: /* number: tUNUMBER */ -#line 374 "getdate.y" - { - if ((yyHaveTime != 0) && (yyHaveDate != 0) && (yyHaveRel == 0)) - yyYear = (yyvsp[0].Number); - else - { - if ((yyvsp[0].Number)>10000) - { - yyHaveDate++; - yyDay= ((yyvsp[0].Number))%100; - yyMonth= ((yyvsp[0].Number)/100)%100; - yyYear = (yyvsp[0].Number)/10000; - } - else - { - yyHaveTime++; - if ((yyvsp[0].Number) < 100) - { - yyHour = (yyvsp[0].Number); - yyMinutes = 0; - } - else - { - yyHour = (yyvsp[0].Number) / 100; - yyMinutes = (yyvsp[0].Number) % 100; - } - yySeconds = 0; - yyMeridian = MER24; - } - } - } -#line 1789 "getdate.c" - break; - - case 50: /* o_merid: %empty */ -#line 407 "getdate.y" - { - (yyval.Meridian) = MER24; - } -#line 1797 "getdate.c" - break; - - case 51: /* o_merid: tMERIDIAN */ -#line 411 "getdate.y" - { - (yyval.Meridian) = (yyvsp[0].Meridian); - } -#line 1805 "getdate.c" - break; - - -#line 1809 "getdate.c" - - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - yyerror (YY_("syntax error")); - } - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - ++yynerrs; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturnlab; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturnlab; - - -/*-----------------------------------------------------------. -| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | -`-----------------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - goto yyreturnlab; - - -/*----------------------------------------------------------. -| yyreturnlab -- parsing is finished, clean up and return. | -`----------------------------------------------------------*/ -yyreturnlab: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - - return yyresult; -} - -#line 416 "getdate.y" - - -/* 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 (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; '\0' != *p; p++) - if (isupper (*p)) - *p = tolower (*p); - - if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) - { - yylval.Meridian = MERam; - return tMERIDIAN; - } - if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0) - { - 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; - buff[3] = '\0'; - } - 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 (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - } - - for (tp = TimezoneTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - - if (strcmp (buff, "dst") == 0) - return tDST; - - for (tp = UnitsTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - 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') - { - buff[i] = '\0'; - for (tp = UnitsTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - buff[i] = 's'; /* Put back for "this" in OtherTable. */ - } - - for (tp = OtherTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - - /* Military timezones. */ - if (buff[1] == '\0' && isalpha (*buff)) - { - for (tp = MilitaryTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - } - - /* Drop out any periods and try the timezone table again. */ - for (i = 0, p = q = buff; '\0' != *q; q++) - if (*q != '.') - *p++ = *q; - else - i++; - *p = '\0'; - if (0 != i) - for (tp = TimezoneTable; NULL != tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - 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 (;;) - { - while (isspace (*yyInput)) - yyInput++; - - 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; - *p = '\0'; - 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 ((time_t *) 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) - -/* ARGSUSED */ -int -main (ac, av) - int ac; - char *av[]; -{ - 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, (time_t *) 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) */ diff --git a/libmisc/getdate.h b/libmisc/getdate.h deleted file mode 100644 index eae56f6..0000000 --- a/libmisc/getdate.h +++ /dev/null @@ -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 diff --git a/libmisc/getdate.y b/libmisc/getdate.y deleted file mode 100644 index 0c07f74..0000000 --- a/libmisc/getdate.y +++ /dev/null @@ -1,954 +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> -# ifdef FORCE_ALLOCA_H -# include <alloca.h> -# endif -#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 <stdio.h> -#include <ctype.h> -#include <time.h> - -#include "getdate.h" - -#include <string.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++; - } - | tUNUMBER tMONTH_UNIT { - yyRelMonth += $1 * $2; - } - | tSNUMBER tMONTH_UNIT { - yyRelMonth += $1 * $2; - } - | tMONTH_UNIT { - yyRelMonth++; - } - | tUNUMBER tDAY_UNIT { - yyRelDay += $1 * $2; - } - | tSNUMBER tDAY_UNIT { - yyRelDay += $1 * $2; - } - | tDAY_UNIT { - yyRelDay++; - } - | tUNUMBER tHOUR_UNIT { - yyRelHour += $1 * $2; - } - | tSNUMBER tHOUR_UNIT { - yyRelHour += $1 * $2; - } - | tHOUR_UNIT { - yyRelHour++; - } - | tUNUMBER tMINUTE_UNIT { - yyRelMinutes += $1 * $2; - } - | tSNUMBER tMINUTE_UNIT { - yyRelMinutes += $1 * $2; - } - | tMINUTE_UNIT { - yyRelMinutes++; - } - | tUNUMBER tSEC_UNIT { - yyRelSeconds += $1 * $2; - } - | tSNUMBER tSEC_UNIT { - yyRelSeconds += $1 * $2; - } - | tSEC_UNIT { - yyRelSeconds++; - } - ; - -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 (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; '\0' != *p; p++) - if (isupper (*p)) - *p = tolower (*p); - - if (strcmp (buff, "am") == 0 || strcmp (buff, "a.m.") == 0) - { - yylval.Meridian = MERam; - return tMERIDIAN; - } - if (strcmp (buff, "pm") == 0 || strcmp (buff, "p.m.") == 0) - { - 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; - buff[3] = '\0'; - } - 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 (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - } - - for (tp = TimezoneTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - - if (strcmp (buff, "dst") == 0) - return tDST; - - for (tp = UnitsTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - 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') - { - buff[i] = '\0'; - for (tp = UnitsTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - buff[i] = 's'; /* Put back for "this" in OtherTable. */ - } - - for (tp = OtherTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - - /* Military timezones. */ - if (buff[1] == '\0' && isalpha (*buff)) - { - for (tp = MilitaryTable; tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - yylval.Number = tp->value; - return tp->type; - } - } - - /* Drop out any periods and try the timezone table again. */ - for (i = 0, p = q = buff; '\0' != *q; q++) - if (*q != '.') - *p++ = *q; - else - i++; - *p = '\0'; - if (0 != i) - for (tp = TimezoneTable; NULL != tp->name; tp++) - if (strcmp (buff, tp->name) == 0) - { - 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 (;;) - { - while (isspace (*yyInput)) - yyInput++; - - 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; - *p = '\0'; - 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 ((time_t *) 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) - -/* ARGSUSED */ -int -main (ac, av) - int ac; - char *av[]; -{ - 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, (time_t *) 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) */ diff --git a/libmisc/getgr_nam_gid.c b/libmisc/getgr_nam_gid.c deleted file mode 100644 index 5294f50..0000000 --- a/libmisc/getgr_nam_gid.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdlib.h> -#include <errno.h> -#include <grp.h> -#include "prototypes.h" - -/* - * getgr_nam_gid - Return a pointer to the group specified by a string. - * The string may be a valid GID or a valid groupname. - * If the group does not exist on the system, NULL is returned. - */ -extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname) -{ - long long int gid; - char *endptr; - - if (NULL == grname) { - return NULL; - } - - errno = 0; - gid = strtoll (grname, &endptr, 10); - if ( ('\0' != *grname) - && ('\0' == *endptr) - && (ERANGE != errno) - && (/*@+longintegral@*/gid == (gid_t)gid)/*@=longintegral@*/) { - return xgetgrgid ((gid_t) gid); - } - return xgetgrnam (grname); -} - diff --git a/libmisc/getrange.c b/libmisc/getrange.c deleted file mode 100644 index 82f2edf..0000000 --- a/libmisc/getrange.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id: $" - -#include <ctype.h> -#include <stdlib.h> - -#include "defines.h" -#include "prototypes.h" - -/* - * Parse a range and indicate if the range is valid. - * Valid ranges are in the form: - * <long> -> min=max=long has_min has_max - * -<long> -> max=long !has_min has_max - * <long>- -> min=long has_min !has_max - * <long1>-<long2> -> min=long1 max=long2 has_min has_max - * - * If the range is valid, getrange returns 1. - * If the range is not valid, getrange returns 0. - */ -int getrange (const char *range, - unsigned long *min, bool *has_min, - unsigned long *max, bool *has_max) -{ - char *endptr; - unsigned long n; - - if (NULL == range) { - return 0; - } - - if ('-' == range[0]) { - if (!isdigit(range[1])) { - /* invalid */ - return 0; - } - errno = 0; - n = strtoul (&range[1], &endptr, 10); - if (('\0' != *endptr) || (ERANGE == errno)) { - /* invalid */ - return 0; - } - /* -<long> */ - *has_min = false; - *has_max = true; - *max = n; - } else { - errno = 0; - n = strtoul (range, &endptr, 10); - if (ERANGE == errno) { - /* invalid */ - return 0; - } - switch (*endptr) { - case '\0': - /* <long> */ - *has_min = true; - *has_max = true; - *min = n; - *max = n; - break; - case '-': - endptr++; - if ('\0' == *endptr) { - /* <long>- */ - *has_min = true; - *has_max = false; - *min = n; - } else if (!isdigit (*endptr)) { - /* invalid */ - return 0; - } else { - *has_min = true; - *min = n; - errno = 0; - n = strtoul (endptr, &endptr, 10); - if ( ('\0' != *endptr) - || (ERANGE == errno)) { - /* invalid */ - return 0; - } - /* <long>-<long> */ - *has_max = true; - *max = n; - } - break; - default: - return 0; - } - } - - return 1; -} - diff --git a/libmisc/gettime.c b/libmisc/gettime.c deleted file mode 100644 index b288402..0000000 --- a/libmisc/gettime.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2017, Chris Lamb - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include "defines.h" -#include "prototypes.h" -#include "shadowlog.h" - -/* - * gettime() returns the time as the number of seconds since the Epoch - * - * Like time(), gettime() returns the time as the number of seconds since the - * Epoch, 1970-01-01 00:00:00 +0000 (UTC), except that if the SOURCE_DATE_EPOCH - * environment variable is exported it will use that instead. - */ -/*@observer@*/time_t gettime () -{ - char *endptr; - char *source_date_epoch; - time_t fallback; - unsigned long long epoch; - FILE *shadow_logfd = log_get_logfd(); - - fallback = time (NULL); - source_date_epoch = shadow_getenv ("SOURCE_DATE_EPOCH"); - - if (!source_date_epoch) - return fallback; - - errno = 0; - epoch = strtoull (source_date_epoch, &endptr, 10); - if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) - || (errno != 0 && epoch == 0)) { - fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"), - strerror(errno)); - } else if (endptr == source_date_epoch) { - fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n"), - endptr); - } else if (*endptr != '\0') { - fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n"), - endptr); - } else if (epoch > ULONG_MAX) { - fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"), - ULONG_MAX, epoch); - } else if (epoch > fallback) { - fprintf (shadow_logfd, - _("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"), - fallback, epoch); - } else { - /* Valid */ - return (time_t)epoch; - } - - return fallback; -} diff --git a/libmisc/hushed.c b/libmisc/hushed.c deleted file mode 100644 index 84b2f55..0000000 --- a/libmisc/hushed.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1993, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1991 - 1993, Chip Rosenthal - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <stdio.h> -#include <pwd.h> -#include "defines.h" -#include "prototypes.h" -#include "getdef.h" -/* - * hushed - determine if a user receives login messages - * - * Look in the hushed-logins file (or user's home directory) to see - * if the user is to receive the login-time messages. - */ -bool hushed (const char *username) -{ - struct passwd *pw; - const char *hushfile; - char buf[BUFSIZ]; - bool found; - FILE *fp; - - /* - * Get the name of the file to use. If this option is not - * defined, default to a noisy login. - */ - - hushfile = getdef_str ("HUSHLOGIN_FILE"); - if (NULL == hushfile) { - return false; - } - - pw = getpwnam (username); - if (NULL == pw) { - return false; - } - - /* - * If this is not a fully rooted path then see if the - * file exists in the user's home directory. - */ - - if (hushfile[0] != '/') { - (void) snprintf (buf, sizeof (buf), "%s/%s", pw->pw_dir, hushfile); - return (access (buf, F_OK) == 0); - } - - /* - * If this is a fully rooted path then go through the file - * and see if this user, or its shell is in there. - */ - - fp = fopen (hushfile, "r"); - if (NULL == fp) { - return false; - } - for (found = false; !found && (fgets (buf, (int) sizeof buf, fp) == buf);) { - buf[strcspn (buf, "\n")] = '\0'; - found = (strcmp (buf, pw->pw_shell) == 0) || - (strcmp (buf, pw->pw_name) == 0); - } - (void) fclose (fp); - return found; -} - diff --git a/libmisc/idmapping.c b/libmisc/idmapping.c deleted file mode 100644 index 30eb89f..0000000 --- a/libmisc/idmapping.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2013 Eric Biederman - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <limits.h> -#include <stdlib.h> -#include <stdio.h> -#include "prototypes.h" -#include "idmapping.h" -#if HAVE_SYS_CAPABILITY_H -#include <sys/prctl.h> -#include <sys/capability.h> -#endif -#include "shadowlog.h" - -struct map_range *get_map_ranges(int ranges, int argc, char **argv) -{ - struct map_range *mappings, *mapping; - int idx, argidx; - - if (ranges < 0 || argc < 0) { - fprintf(log_get_logfd(), "%s: error calculating number of arguments\n", log_get_progname()); - return NULL; - } - - if (ranges != ((argc + 2) / 3)) { - fprintf(log_get_logfd(), "%s: ranges: %u is wrong for argc: %d\n", log_get_progname(), ranges, argc); - return NULL; - } - - if ((ranges * 3) > argc) { - fprintf(log_get_logfd(), "ranges: %u argc: %d\n", - ranges, argc); - fprintf(log_get_logfd(), - _( "%s: Not enough arguments to form %u mappings\n"), - log_get_progname(), ranges); - return NULL; - } - - mappings = calloc(ranges, sizeof(*mappings)); - if (!mappings) { - fprintf(log_get_logfd(), _( "%s: Memory allocation failure\n"), - log_get_progname()); - exit(EXIT_FAILURE); - } - - /* Gather up the ranges from the command line */ - mapping = mappings; - for (idx = 0, argidx = 0; idx < ranges; idx++, argidx += 3, mapping++) { - if (!getulong(argv[argidx + 0], &mapping->upper)) { - free(mappings); - return NULL; - } - if (!getulong(argv[argidx + 1], &mapping->lower)) { - free(mappings); - return NULL; - } - if (!getulong(argv[argidx + 2], &mapping->count)) { - free(mappings); - return NULL; - } - if (ULONG_MAX - mapping->upper <= mapping->count || ULONG_MAX - mapping->lower <= mapping->count) { - fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - if (mapping->upper > UINT_MAX || - mapping->lower > UINT_MAX || - mapping->count > UINT_MAX) { - fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - if (mapping->lower + mapping->count > UINT_MAX || - mapping->upper + mapping->count > UINT_MAX) { - fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - if (mapping->lower + mapping->count < mapping->lower || - mapping->upper + mapping->count < mapping->upper) { - /* this one really shouldn't be possible given previous checks */ - fprintf(log_get_logfd(), _( "%s: subuid overflow detected.\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - } - return mappings; -} - -/* Number of ascii digits needed to print any unsigned long in decimal. - * There are approximately 10 bits for every 3 decimal digits. - * So from bits to digits the formula is roundup((Number of bits)/10) * 3. - * For common sizes of integers this works out to: - * 2bytes --> 6 ascii estimate -> 65536 (5 real) - * 4bytes --> 12 ascii estimated -> 4294967296 (10 real) - * 8bytes --> 21 ascii estimated -> 18446744073709551616 (20 real) - * 16bytes --> 39 ascii estimated -> 340282366920938463463374607431768211456 (39 real) - */ -#define ULONG_DIGITS ((((sizeof(unsigned long) * CHAR_BIT) + 9)/10)*3) - -#if HAVE_SYS_CAPABILITY_H -static inline bool maps_lower_root(int cap, int ranges, const struct map_range *mappings) -{ - int idx; - const struct map_range *mapping; - - if (cap != CAP_SETUID) - return false; - - mapping = mappings; - for (idx = 0; idx < ranges; idx++, mapping++) { - if (mapping->lower == 0) - return true; - } - - return false; -} -#endif - -/* - * The ruid refers to the caller's uid and is used to reset the effective uid - * back to the callers real uid. - * This clutch mainly exists for setuid-based new{g,u}idmap binaries that are - * called in contexts where all capabilities other than the necessary - * CAP_SET{G,U}ID capabilities are dropped. Since the kernel will require - * assurance that the caller holds CAP_SYS_ADMIN over the target user namespace - * the only way it can confirm is in this case is if the effective uid is - * equivalent to the uid owning the target user namespace. - * Note, we only support this when a) new{g,u}idmap is not called by root and - * b) if the caller's uid and the uid retrieved via system appropriate means - * (shadow file or other) are identical. Specifically, this does not support - * when the root user calls the new{g,u}idmap binary for an unprivileged user. - * If this is wanted: use file capabilities! - */ -void write_mapping(int proc_dir_fd, int ranges, const struct map_range *mappings, - const char *map_file, uid_t ruid) -{ - int idx; - const struct map_range *mapping; - size_t bufsize; - char *buf, *pos; - int fd; - -#if HAVE_SYS_CAPABILITY_H - int cap; - struct __user_cap_header_struct hdr = {_LINUX_CAPABILITY_VERSION_3, 0}; - struct __user_cap_data_struct data[2] = {{0}}; - - if (strcmp(map_file, "uid_map") == 0) { - cap = CAP_SETUID; - } else if (strcmp(map_file, "gid_map") == 0) { - cap = CAP_SETGID; - } else { - fprintf(log_get_logfd(), _("%s: Invalid map file %s specified\n"), log_get_progname(), map_file); - exit(EXIT_FAILURE); - } - - /* Align setuid- and fscaps-based new{g,u}idmap behavior. */ - if (geteuid() == 0 && geteuid() != ruid) { - if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) { - fprintf(log_get_logfd(), _("%s: Could not prctl(PR_SET_KEEPCAPS)\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - - if (seteuid(ruid) < 0) { - fprintf(log_get_logfd(), _("%s: Could not seteuid to %d\n"), log_get_progname(), ruid); - exit(EXIT_FAILURE); - } - } - - /* Lockdown new{g,u}idmap by dropping all unneeded capabilities. */ - memset(data, 0, sizeof(data)); - data[0].effective = CAP_TO_MASK(cap); - /* - * When uid 0 from the ancestor userns is supposed to be mapped into - * the child userns we need to retain CAP_SETFCAP. - */ - if (maps_lower_root(cap, ranges, mappings)) - data[0].effective |= CAP_TO_MASK(CAP_SETFCAP); - data[0].permitted = data[0].effective; - if (capset(&hdr, data) < 0) { - fprintf(log_get_logfd(), _("%s: Could not set caps\n"), log_get_progname()); - exit(EXIT_FAILURE); - } -#endif - - bufsize = ranges * ((ULONG_DIGITS + 1) * 3); - pos = buf = xmalloc(bufsize); - - /* Build the mapping command */ - mapping = mappings; - for (idx = 0; idx < ranges; idx++, mapping++) { - /* Append this range to the string that will be written */ - int written = snprintf(pos, bufsize - (pos - buf), - "%lu %lu %lu\n", - mapping->upper, - mapping->lower, - mapping->count); - if ((written <= 0) || (written >= (bufsize - (pos - buf)))) { - fprintf(log_get_logfd(), _("%s: snprintf failed!\n"), log_get_progname()); - exit(EXIT_FAILURE); - } - pos += written; - } - - /* Write the mapping to the mapping file */ - fd = openat(proc_dir_fd, map_file, O_WRONLY); - if (fd < 0) { - fprintf(log_get_logfd(), _("%s: open of %s failed: %s\n"), - log_get_progname(), map_file, strerror(errno)); - exit(EXIT_FAILURE); - } - if (write(fd, buf, pos - buf) != (pos - buf)) { - fprintf(log_get_logfd(), _("%s: write to %s failed: %s\n"), - log_get_progname(), map_file, strerror(errno)); - exit(EXIT_FAILURE); - } - close(fd); - free(buf); -} diff --git a/libmisc/idmapping.h b/libmisc/idmapping.h deleted file mode 100644 index 46d4631..0000000 --- a/libmisc/idmapping.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2013 Eric Biederman - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef _IDMAPPING_H_ -#define _IDMAPPING_H_ - -#include <sys/types.h> - -struct map_range { - unsigned long upper; /* first ID inside the namespace */ - unsigned long lower; /* first ID outside the namespace */ - unsigned long count; /* Length of the inside and outside ranges */ -}; - -extern struct map_range *get_map_ranges(int ranges, int argc, char **argv); -extern void write_mapping(int proc_dir_fd, int ranges, - const struct map_range *mappings, const char *map_file, uid_t ruid); - -#endif /* _ID_MAPPING_H_ */ - diff --git a/libmisc/isexpired.c b/libmisc/isexpired.c deleted file mode 100644 index ff20396..0000000 --- a/libmisc/isexpired.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Extracted from age.c and made part of libshadow.a - may be useful - * in other shadow-aware programs. --marekm - */ - -#include <config.h> - -#include <sys/types.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> -#include <time.h> - -#ident "$Id$" - - -/* - * isexpired - determine if account is expired yet - * - * isexpired calculates the expiration date based on the - * password expiration criteria. - * - * Return value: - * 0: The password is still valid - * 1: The password has expired, it must be changed - * 2: The password has expired since a long time and the account is - * now disabled. (password cannot be changed) - * 3: The account has expired - */ -int isexpired (const struct passwd *pw, /*@null@*/const struct spwd *sp) -{ - long now; - - now = (long) time ((time_t *) 0) / SCALE; - - if (NULL == sp) { - return 0; - } - - /* - * Quick and easy - there is an expired account field - * along with an inactive account field. Do the expired - * one first since it is worse. - */ - - if ((sp->sp_expire > 0) && (now >= sp->sp_expire)) { - return 3; - } - - /* - * Last changed date 1970-01-01 (not very likely) means that - * the password must be changed on next login (passwd -e). - * - * The check for "x" is a workaround for RedHat NYS libc bug - - * if /etc/shadow doesn't exist, getspnam() still succeeds and - * returns sp_lstchg==0 (must change password) instead of -1! - */ - if ( (0 == sp->sp_lstchg) - && (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0)) { - return 1; - } - - if ( (sp->sp_lstchg > 0) - && (sp->sp_max >= 0) - && (sp->sp_inact >= 0) - && (now >= (sp->sp_lstchg + sp->sp_max + sp->sp_inact))) { - return 2; - } - - /* - * The last and max fields must be present for an account - * to have an expired password. A maximum of >10000 days - * is considered to be infinite. - */ - - if ( (-1 == sp->sp_lstchg) - || (-1 == sp->sp_max) - || (sp->sp_max >= ((10000L * DAY) / SCALE))) { - return 0; - } - - /* - * Calculate today's day and the day on which the password - * is going to expire. If that date has already passed, - * the password has expired. - */ - - if (now >= (sp->sp_lstchg + sp->sp_max)) { - return 1; - } - return 0; -} - diff --git a/libmisc/limits.c b/libmisc/limits.c deleted file mode 100644 index fea85fe..0000000 --- a/libmisc/limits.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Separated from setup.c. --marekm - * Resource limits thanks to Cristian Gafton. - * Enhancements of resource limit code by Thomas Orgis <thomas@orgis.org> - */ - -#include <config.h> - -#ifndef USE_PAM - -#ident "$Id$" - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <ctype.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> -#include "getdef.h" -#include "shadowlog.h" -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#define LIMITS -#endif -#ifdef LIMITS -#ifndef LIMITS_FILE -#define LIMITS_FILE "/etc/limits" -#endif -#define LOGIN_ERROR_RLIMIT 1 -#define LOGIN_ERROR_LOGIN 2 -/* Set a limit on a resource */ -/* - * rlimit - RLIMIT_XXXX - * value - string value to be read - * multiplier - value*multiplier is the actual limit - */ -static int setrlimit_value (unsigned int resource, - const char *value, - unsigned int multiplier) -{ - struct rlimit rlim; - rlim_t limit; - - /* The "-" is special, not belonging to a strange negative limit. - * It is infinity, in a controlled way. - */ - if ('-' == value[0]) { - limit = RLIM_INFINITY; - } - else { - /* We cannot use getlong here because it fails when there - * is more to the value than just this number! - * Also, we are limited to base 10 here (hex numbers will not - * work with the limit string parser as is anyway) - */ - char *endptr; - long longlimit = strtol (value, &endptr, 10); - if ((0 == longlimit) && (value == endptr)) { - /* No argument at all. No-op. - * FIXME: We could instead throw an error, though. - */ - return 0; - } - longlimit *= multiplier; - limit = (rlim_t)longlimit; - if (longlimit != limit) - { - /* FIXME: Again, silent error handling... - * Wouldn't screaming make more sense? - */ - return 0; - } - } - - rlim.rlim_cur = limit; - rlim.rlim_max = limit; - if (setrlimit (resource, &rlim) != 0) { - return LOGIN_ERROR_RLIMIT; - } - return 0; -} - - -static int set_prio (const char *value) -{ - long prio; - - if ( (getlong (value, &prio) == 0) - || (prio != (int) prio)) { - return 0; - } - if (setpriority (PRIO_PROCESS, 0, (int) prio) != 0) { - return LOGIN_ERROR_RLIMIT; - } - return 0; -} - - -static int set_umask (const char *value) -{ - unsigned long int mask; - - if ( (getulong (value, &mask) == 0) - || (mask != (mode_t) mask)) { - return 0; - } - - (void) umask ((mode_t) mask); - return 0; -} - - -/* Counts the number of user logins and check against the limit */ -static int check_logins (const char *name, const char *maxlogins) -{ -#ifdef USE_UTMPX - struct utmpx *ut; -#else /* !USE_UTMPX */ - struct utmp *ut; -#endif /* !USE_UTMPX */ - unsigned long limit, count; - - if (getulong (maxlogins, &limit) == 0) { - return 0; - } - - if (0 == limit) { /* maximum 0 logins ? */ - SYSLOG ((LOG_WARN, "No logins allowed for `%s'\n", name)); - return LOGIN_ERROR_LOGIN; - } - - count = 0; -#ifdef USE_UTMPX - setutxent (); - while ((ut = getutxent ())) -#else /* !USE_UTMPX */ - setutent (); - while ((ut = getutent ())) -#endif /* !USE_UTMPX */ - { - if (USER_PROCESS != ut->ut_type) { - continue; - } - if ('\0' == ut->ut_user[0]) { - continue; - } - if (strncmp (name, ut->ut_user, sizeof (ut->ut_user)) != 0) { - continue; - } - count++; - if (count > limit) { - break; - } - } -#ifdef USE_UTMPX - endutxent (); -#else /* !USE_UTMPX */ - endutent (); -#endif /* !USE_UTMPX */ - /* - * This is called after setutmp(), so the number of logins counted - * includes the user who is currently trying to log in. - */ - if (count > limit) { - SYSLOG ((LOG_WARN, - "Too many logins (max %lu) for %s\n", - limit, name)); - return LOGIN_ERROR_LOGIN; - } - return 0; -} - -/* Function setup_user_limits - checks/set limits for the current login - * Original idea from Joel Katz's lshell. Ported to shadow-login - * by Cristian Gafton - gafton@sorosis.ro - * - * We are passed a string of the form ('BASH' constants for ulimit) - * [Aa][Cc][Dd][Ff][Mm][Nn][Rr][Ss][Tt][Uu][Ll][Pp][Ii][Oo] - * (eg. 'C2F256D2048N5' or 'C2 F256 D2048 N5') - * where: - * [Aa]: a = RLIMIT_AS max address space (KB) - * [Cc]: c = RLIMIT_CORE max core file size (KB) - * [Dd]: d = RLIMIT_DATA max data size (KB) - * [Ff]: f = RLIMIT_FSIZE max file size (KB) - * [Ii]: i = RLIMIT_NICE max nice value (0..39 translates to 20..-19) - * [Kk]: k = file creation masK (umask) - * [Ll]: l = max number of logins for this user - * [Mm]: m = RLIMIT_MEMLOCK max locked-in-memory address space (KB) - * [Nn]: n = RLIMIT_NOFILE max number of open files - * [Oo]: o = RLIMIT_RTPRIO max real time priority (linux/sched.h 0..MAX_RT_PRIO) - * [Pp]: p = process priority -20..20 (negative = high, positive = low) - * [Rr]: r = RLIMIT_RSS max resident set size (KB) - * [Ss]: s = RLIMIT_STACK max stack size (KB) - * [Tt]: t = RLIMIT_CPU max CPU time (MIN) - * [Uu]: u = RLIMIT_NPROC max number of processes - * - * NOTE: Remember to extend the "no-limits" string below when adding a new - * limit... - * - * Return value: - * 0 = okay, of course - * LOGIN_ERROR_RLIMIT = error setting some RLIMIT - * LOGIN_ERROR_LOGIN = error - too many logins for this user - * - * buf - the limits string - * name - the username - */ -static int do_user_limits (const char *buf, const char *name) -{ - const char *pp; - int retval = 0; - bool reported = false; - - pp = buf; - /* Skip leading whitespace. */ - while ((' ' == *pp) || ('\t' == *pp)) { - pp++; - } - - /* The special limit string "-" results in no limit for all known - * limits. - * We achieve that by parsing a full limit string, parts of it - * being ignored if a limit type is not known to the system. - * Though, there will be complaining for unknown limit types. - */ - if (strcmp (pp, "-") == 0) { - /* Remember to extend this, too, when adding new limits! - * Oh... but "unlimited" does not make sense for umask, - * or does it? (K-) - */ - pp = "A- C- D- F- I- L- M- N- O- P- R- S- T- U-"; - } - - while ('\0' != *pp) { - switch (*pp++) { -#ifdef RLIMIT_AS - case 'a': - case 'A': - /* RLIMIT_AS - max address space (KB) */ - retval |= setrlimit_value (RLIMIT_AS, pp, 1024); - break; -#endif -#ifdef RLIMIT_CORE - case 'c': - case 'C': - /* RLIMIT_CORE - max core file size (KB) */ - retval |= setrlimit_value (RLIMIT_CORE, pp, 1024); - break; -#endif -#ifdef RLIMIT_DATA - case 'd': - case 'D': - /* RLIMIT_DATA - max data size (KB) */ - retval |= setrlimit_value (RLIMIT_DATA, pp, 1024); - break; -#endif -#ifdef RLIMIT_FSIZE - case 'f': - case 'F': - /* RLIMIT_FSIZE - Maximum filesize (KB) */ - retval |= setrlimit_value (RLIMIT_FSIZE, pp, 1024); - break; -#endif -#ifdef RLIMIT_NICE - case 'i': - case 'I': - /* RLIMIT_NICE - max scheduling priority (0..39) */ - retval |= setrlimit_value (RLIMIT_NICE, pp, 1); - break; -#endif - case 'k': - case 'K': - retval |= set_umask (pp); - break; - case 'l': - case 'L': - /* LIMIT the number of concurrent logins */ - retval |= check_logins (name, pp); - break; -#ifdef RLIMIT_MEMLOCK - case 'm': - case 'M': - /* RLIMIT_MEMLOCK - max locked-in-memory address space (KB) */ - retval |= setrlimit_value (RLIMIT_MEMLOCK, pp, 1024); - break; -#endif -#ifdef RLIMIT_NOFILE - case 'n': - case 'N': - /* RLIMIT_NOFILE - max number of open files */ - retval |= setrlimit_value (RLIMIT_NOFILE, pp, 1); - break; -#endif -#ifdef RLIMIT_RTPRIO - case 'o': - case 'O': - /* RLIMIT_RTPRIO - max real time priority (0..MAX_RT_PRIO) */ - retval |= setrlimit_value (RLIMIT_RTPRIO, pp, 1); - break; -#endif - case 'p': - case 'P': - retval |= set_prio (pp); - break; -#ifdef RLIMIT_RSS - case 'r': - case 'R': - /* RLIMIT_RSS - max resident set size (KB) */ - retval |= setrlimit_value (RLIMIT_RSS, pp, 1024); - break; -#endif -#ifdef RLIMIT_STACK - case 's': - case 'S': - /* RLIMIT_STACK - max stack size (KB) */ - retval |= setrlimit_value (RLIMIT_STACK, pp, 1024); - break; -#endif -#ifdef RLIMIT_CPU - case 't': - case 'T': - /* RLIMIT_CPU - max CPU time (MIN) */ - retval |= setrlimit_value (RLIMIT_CPU, pp, 60); - break; -#endif -#ifdef RLIMIT_NPROC - case 'u': - case 'U': - /* RLIMIT_NPROC - max number of processes */ - retval |= setrlimit_value (RLIMIT_NPROC, pp, 1); - break; -#endif - default: - /* Only report invalid strings once */ - /* Note: A string can be invalid just because a - * specific (theoretically valid) setting is not - * supported by this build. - * It is just a warning in syslog anyway. The line - * is still processed - */ - if (!reported) { - SYSLOG ((LOG_WARN, - "Invalid limit string: '%s'", - pp-1)); - reported = true; - retval |= LOGIN_ERROR_RLIMIT; - } - } - /* After parsing one limit setting (or just complaining - * about it), one still needs to skip its argument to - * prevent a bogus warning on trying to parse that as - * limit specification. - * So, let's skip all digits, "-" and our limited set of - * whitespace. - */ - while ( isdigit (*pp) - || ('-' == *pp) - || (' ' == *pp) - || ('\t' ==*pp)) { - pp++; - } - } - return retval; -} - -/* Check if user uname is in the group gname. - * Can I be sure that gr_mem contains no UID as string? - * Returns true when user is in the group, false when not. - * Any error is treated as false. - */ -static bool user_in_group (const char *uname, const char *gname) -{ - struct group *groupdata; - - if (uname == NULL || gname == NULL) { - return false; - } - - /* We are not claiming to be re-entrant! - * In case of paranoia or a multithreaded login program, - * one needs to add some mess for getgrnam_r. */ - groupdata = getgrnam (gname); - if (NULL == groupdata) { - SYSLOG ((LOG_WARN, "Nonexisting group `%s' in limits file.", - gname)); - return false; - } - - return is_on_list (groupdata->gr_mem, uname); -} - -static int setup_user_limits (const char *uname) -{ - FILE *fil; - char buf[1024]; - char name[1024]; - char limits[1024]; - char deflimits[1024]; - char tempbuf[1024]; - - /* init things */ - memzero (buf, sizeof (buf)); - memzero (name, sizeof (name)); - memzero (limits, sizeof (limits)); - memzero (deflimits, sizeof (deflimits)); - memzero (tempbuf, sizeof (tempbuf)); - - /* start the checks */ - fil = fopen (LIMITS_FILE, "r"); - if (fil == NULL) { - return 0; - } - /* The limits file have the following format: - * - '#' (comment) chars only as first chars on a line; - * - username must start on first column (or *, or @group) - * - * FIXME: A better (smarter) checking should be done - */ - while (fgets (buf, 1024, fil) != NULL) { - if (('#' == buf[0]) || ('\n' == buf[0])) { - continue; - } - memzero (tempbuf, sizeof (tempbuf)); - /* a valid line should have a username, then spaces, - * then limits - * we allow the format: - * username L2 D2048 R4096 - * where spaces={' ',\t}. Also, we reject invalid limits. - * Imposing a limit should be done with care, so a wrong - * entry means no care anyway :-). - * - * A '-' as a limits strings means no limits - * - * The username can also be: - * '*': the default limits (only the last is taken into - * account) - * @group: the limit applies to the members of the group - * - * To clarify: The first entry with matching user name rules, - * everything after it is ignored. If there is no user entry, - * the last encountered entry for a matching group rules. - * If there is no matching group entry, the default limits rule. - */ - if (sscanf (buf, "%s%[ACDFIKLMNOPRSTUacdfiklmnoprstu0-9 \t-]", - name, tempbuf) == 2) { - if (strcmp (name, uname) == 0) { - strcpy (limits, tempbuf); - break; - } else if (strcmp (name, "*") == 0) { - strcpy (deflimits, tempbuf); - } else if (name[0] == '@') { - /* If the user is in the group, the group - * limits apply unless later a line for - * the specific user is found. - */ - if (user_in_group (uname, name+1)) { - strcpy (limits, tempbuf); - } - } - } - } - (void) fclose (fil); - if (limits[0] == '\0') { - /* no user specific limits */ - if (deflimits[0] == '\0') { /* no default limits */ - return 0; - } - strcpy (limits, deflimits); /* use the default limits */ - } - return do_user_limits (limits, uname); -} -#endif /* LIMITS */ - - -static void setup_usergroups (const struct passwd *info) -{ - const struct group *grp; - -/* - * if not root, and UID == GID, and username is the same as primary - * group name, set umask group bits to be the same as owner bits - * (examples: 022 -> 002, 077 -> 007). - */ - if ((0 != info->pw_uid) && (info->pw_uid == info->pw_gid)) { - /* local, no need for xgetgrgid */ - grp = getgrgid (info->pw_gid); - if ( (NULL != grp) - && (strcmp (info->pw_name, grp->gr_name) == 0)) { - mode_t tmpmask; - tmpmask = umask (0777); - tmpmask = (tmpmask & ~070) | ((tmpmask >> 3) & 070); - (void) umask (tmpmask); - } - } -} - -/* - * set the process nice, ulimit, and umask from the password file entry - */ - -void setup_limits (const struct passwd *info) -{ - char *cp; - - if (getdef_bool ("USERGROUPS_ENAB")) { - setup_usergroups (info); - } - - /* - * See if the GECOS field contains values for NICE, UMASK or ULIMIT. - * If this feature is enabled in /etc/login.defs, we make those - * values the defaults for this login session. - */ - - if (getdef_bool ("QUOTAS_ENAB")) { -#ifdef LIMITS - if (info->pw_uid != 0) { - if ((setup_user_limits (info->pw_name) & LOGIN_ERROR_LOGIN) != 0) { - (void) fputs (_("Too many logins.\n"), log_get_logfd()); - (void) sleep (2); /* XXX: Should be FAIL_DELAY */ - exit (EXIT_FAILURE); - } - } -#endif - for (cp = info->pw_gecos; cp != NULL; cp = strchr (cp, ',')) { - if (',' == *cp) { - cp++; - } - - if (strncmp (cp, "pri=", 4) == 0) { - long int inc; - if ( (getlong (cp + 4, &inc) == 1) - && (inc >= -20) && (inc <= 20)) { - errno = 0; - if ( (nice ((int) inc) != -1) - || (0 != errno)) { - continue; - } - } - - /* Failed to parse or failed to nice() */ - SYSLOG ((LOG_WARN, - "Can't set the nice value for user %s", - info->pw_name)); - - continue; - } - if (strncmp (cp, "ulimit=", 7) == 0) { - long int blocks; - if ( (getlong (cp + 7, &blocks) == 0) - || (blocks != (int) blocks) - || (set_filesize_limit ((int) blocks) != 0)) { - SYSLOG ((LOG_WARN, - "Can't set the ulimit for user %s", - info->pw_name)); - } - continue; - } - if (strncmp (cp, "umask=", 6) == 0) { - unsigned long int mask; - if ( (getulong (cp + 6, &mask) == 0) - || (mask != (mode_t) mask)) { - SYSLOG ((LOG_WARN, - "Can't set umask value for user %s", - info->pw_name)); - } else { - (void) umask ((mode_t) mask); - } - - continue; - } - } - } -} - -#else /* !USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !USE_PAM */ - diff --git a/libmisc/list.c b/libmisc/list.c deleted file mode 100644 index 9d7ec77..0000000 --- a/libmisc/list.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <assert.h> -#include "prototypes.h" -#include "defines.h" -/* - * add_list - add a member to a list of group members - * - * the array of member names is searched for the new member - * name, and if not present it is added to a freshly allocated - * list of users. - */ -/*@only@*/ /*@out@*/char **add_list (/*@returned@*/ /*@only@*/char **list, const char *member) -{ - int i; - char **tmp; - - assert (NULL != member); - assert (NULL != list); - - /* - * Scan the list for the new name. Return the original list - * pointer if it is present. - */ - - for (i = 0; list[i] != (char *) 0; i++) { - if (strcmp (list[i], member) == 0) { - return list; - } - } - - /* - * Allocate a new list pointer large enough to hold all the - * old entries, and the new entries as well. - */ - - tmp = (char **) xmalloc ((i + 2) * sizeof member); - - /* - * Copy the original list to the new list, then append the - * new member and NULL terminate the result. This new list - * is returned to the invoker. - */ - - for (i = 0; list[i] != (char *) 0; i++) { - tmp[i] = list[i]; - } - - tmp[i] = xstrdup (member); - tmp[i+1] = (char *) 0; - - return tmp; -} - -/* - * del_list - delete a member from a list of group members - * - * the array of member names is searched for the old member - * name, and if present it is deleted from a freshly allocated - * list of users. - */ - -/*@only@*/ /*@out@*/char **del_list (/*@returned@*/ /*@only@*/char **list, const char *member) -{ - int i, j; - char **tmp; - - assert (NULL != member); - assert (NULL != list); - - /* - * Scan the list for the old name. Return the original list - * pointer if it is not present. - */ - - for (i = j = 0; list[i] != (char *) 0; i++) { - if (strcmp (list[i], member) != 0) { - j++; - } - } - - if (j == i) { - return list; - } - - /* - * Allocate a new list pointer large enough to hold all the - * old entries. - */ - - tmp = (char **) xmalloc ((j + 1) * sizeof member); - - /* - * Copy the original list except the deleted members to the - * new list, then NULL terminate the result. This new list - * is returned to the invoker. - */ - - for (i = j = 0; list[i] != (char *) 0; i++) { - if (strcmp (list[i], member) != 0) { - tmp[j] = list[i]; - j++; - } - } - - tmp[j] = (char *) 0; - - return tmp; -} - -/* - * Duplicate a list. - * The input list is not modified, but in order to allow the use of this - * function with list of members, the list elements are not enforced to be - * constant strings here. - */ -/*@only@*/ /*@out@*/char **dup_list (char *const *list) -{ - int i; - char **tmp; - - assert (NULL != list); - - for (i = 0; NULL != list[i]; i++); - - tmp = (char **) xmalloc ((i + 1) * sizeof (char *)); - - i = 0; - while (NULL != *list) { - tmp[i] = xstrdup (*list); - i++; - list++; - } - - tmp[i] = (char *) 0; - return tmp; -} - -/* - * Check if member is part of the input list - * The input list is not modified, but in order to allow the use of this - * function with list of members, the list elements are not enforced to be - * constant strings here. - */ -bool is_on_list (char *const *list, const char *member) -{ - assert (NULL != member); - assert (NULL != list); - - while (NULL != *list) { - if (strcmp (*list, member) == 0) { - return true; - } - list++; - } - - return false; -} - -/* - * comma_to_list - convert comma-separated list to (char *) array - */ - -/*@only@*/char **comma_to_list (const char *comma) -{ - char *members; - char **array; - int i; - char *cp; - char *cp2; - - assert (NULL != comma); - - /* - * Make a copy since we are going to be modifying the list - */ - - members = xstrdup (comma); - - /* - * Count the number of commas in the list - */ - - for (cp = members, i = 0;; i++) { - cp2 = strchr (cp, ','); - if (NULL != cp2) { - cp = cp2 + 1; - } else { - break; - } - } - - /* - * Add 2 - one for the ending NULL, the other for the last item - */ - - i += 2; - - /* - * Allocate the array we're going to store the pointers into. - */ - - array = (char **) xmalloc (sizeof (char *) * i); - - /* - * Empty list is special - 0 members, not 1 empty member. --marekm - */ - - if ('\0' == *members) { - *array = (char *) 0; - free (members); - return array; - } - - /* - * Now go walk that list all over again, this time building the - * array of pointers. - */ - - for (cp = members, i = 0;; i++) { - array[i] = cp; - cp2 = strchr (cp, ','); - if (NULL != cp2) { - *cp2 = '\0'; - cp2++; - cp = cp2; - } else { - array[i + 1] = (char *) 0; - break; - } - } - - /* - * Return the new array of pointers - */ - - return array; -} - diff --git a/libmisc/log.c b/libmisc/log.c deleted file mode 100644 index a220be0..0000000 --- a/libmisc/log.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <pwd.h> -#include <fcntl.h> -#include <time.h> -#include "defines.h" -#include <lastlog.h> -#include "prototypes.h" - -/* - * dolastlog - create lastlog entry - * - * A "last login" entry is created for the user being logged in. The - * UID is extracted from the global (struct passwd) entry and the - * TTY information is gotten from the (struct utmp). - */ -void dolastlog ( - struct lastlog *ll, - const struct passwd *pw, - /*@unique@*/const char *line, - /*@unique@*/const char *host) -{ - int fd; - off_t offset; - struct lastlog newlog; - time_t ll_time; - - /* - * If the file does not exist, don't create it. - */ - - fd = open (LASTLOG_FILE, O_RDWR); - if (-1 == fd) { - return; - } - - /* - * The file is indexed by UID number. Seek to the record - * for this UID. Negative UID's will create problems, but ... - */ - - offset = (off_t) pw->pw_uid * sizeof newlog; - - if (lseek (fd, offset, SEEK_SET) != offset) { - SYSLOG ((LOG_WARN, - "Can't read last lastlog entry for UID %lu in %s. Entry not updated.", - (unsigned long) pw->pw_uid, LASTLOG_FILE)); - (void) close (fd); - return; - } - - /* - * Read the old entry so we can tell the user when they last - * logged in. Then construct the new entry and write it out - * the way we read the old one in. - */ - - if (read (fd, (void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) { - memzero (&newlog, sizeof newlog); - } - if (NULL != ll) { - *ll = newlog; - } - - ll_time = newlog.ll_time; - (void) time (&ll_time); - newlog.ll_time = ll_time; - strncpy (newlog.ll_line, line, sizeof (newlog.ll_line) - 1); -#if HAVE_LL_HOST - strncpy (newlog.ll_host, host, sizeof (newlog.ll_host) - 1); -#endif - if ( (lseek (fd, offset, SEEK_SET) != offset) - || (write (fd, (const void *) &newlog, sizeof newlog) != (ssize_t) sizeof newlog) - || (close (fd) != 0)) { - SYSLOG ((LOG_WARN, - "Can't write lastlog entry for UID %lu in %s.", - (unsigned long) pw->pw_uid, LASTLOG_FILE)); - (void) close (fd); - } -} - diff --git a/libmisc/loginprompt.c b/libmisc/loginprompt.c deleted file mode 100644 index 0a67f46..0000000 --- a/libmisc/loginprompt.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1993, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2011, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <assert.h> -#include <stdio.h> -#include <signal.h> -#include <ctype.h> -#include "prototypes.h" -#include "defines.h" -#include "getdef.h" - -static void login_exit (unused int sig) -{ - exit (EXIT_FAILURE); -} - -/* - * login_prompt - prompt the user for their login name - * - * login_prompt() displays the standard login prompt. If ISSUE_FILE - * is set in login.defs, this file is displayed before the prompt. - */ - -void login_prompt (const char *prompt, char *name, int namesize) -{ - char buf[1024]; - -#define MAX_ENV 32 - char *envp[MAX_ENV]; - char *cp; - int i; - FILE *fp; - - sighandler_t sigquit; -#ifdef SIGTSTP - sighandler_t sigtstp; -#endif - - /* - * There is a small chance that a QUIT character will be part of - * some random noise during a prompt. Deal with this by exiting - * instead of core dumping. If SIGTSTP is defined, do the same - * thing for that signal. - */ - - sigquit = signal (SIGQUIT, login_exit); -#ifdef SIGTSTP - sigtstp = signal (SIGTSTP, login_exit); -#endif - - /* - * See if the user has configured the issue file to - * be displayed and display it before the prompt. - */ - - if (NULL != prompt) { - const char *fname = getdef_str ("ISSUE_FILE"); - if (NULL != fname) { - fp = fopen (fname, "r"); - if (NULL != fp) { - while ((i = getc (fp)) != EOF) { - (void) putc (i, stdout); - } - - (void) fclose (fp); - } - } - (void) gethostname (buf, sizeof buf); - printf (prompt, buf); - (void) fflush (stdout); - } - - /* - * Read the user's response. The trailing newline will be - * removed. - */ - - memzero (buf, sizeof buf); - if (fgets (buf, (int) sizeof buf, stdin) != buf) { - exit (EXIT_FAILURE); - } - - cp = strchr (buf, '\n'); - if (NULL == cp) { - exit (EXIT_FAILURE); - } - *cp = '\0'; /* remove \n [ must be there ] */ - - /* - * Skip leading whitespace. This makes " username" work right. - * Then copy the rest (up to the end or the first "non-graphic" - * character into the username. - */ - - for (cp = buf; *cp == ' ' || *cp == '\t'; cp++); - - for (i = 0; i < namesize - 1 && isgraph (*cp); name[i++] = *cp++); - while (isgraph (*cp)) { - cp++; - } - - if ('\0' != *cp) { - cp++; - } - - name[i] = '\0'; - - /* - * This is a disaster, at best. The user may have entered extra - * environmental variables at the prompt. There are several ways - * to do this, and I just take the easy way out. - */ - - if ('\0' != *cp) { /* process new variables */ - char *nvar; - int count = 1; - int envc; - - for (envc = 0; envc < MAX_ENV; envc++) { - nvar = strtok ((0 != envc) ? (char *) 0 : cp, " \t,"); - if (NULL == nvar) { - break; - } - if (strchr (nvar, '=') != NULL) { - envp[envc] = nvar; - } else { - size_t len = strlen (nvar) + 32; - envp[envc] = xmalloc (len); - (void) snprintf (envp[envc], len, - "L%d=%s", count++, nvar); - } - } - set_env (envc, envp); - } - - /* - * Set the SIGQUIT handler back to its original value - */ - - (void) signal (SIGQUIT, sigquit); -#ifdef SIGTSTP - (void) signal (SIGTSTP, sigtstp); -#endif -} - diff --git a/libmisc/mail.c b/libmisc/mail.c deleted file mode 100644 index 647f879..0000000 --- a/libmisc/mail.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1991, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> -#include "prototypes.h" -#include "defines.h" -#include <assert.h> -#include <sys/stat.h> -#include <stdio.h> -#include <string.h> - -#include "getdef.h" - -#ident "$Id$" - - -void mailcheck (void) -{ - struct stat statbuf; - char *mailbox; - - if (!getdef_bool ("MAIL_CHECK_ENAB")) { - return; - } - - /* - * Check incoming mail in Maildir format - J. - */ - mailbox = getenv ("MAILDIR"); - if (NULL != mailbox) { - char *newmail; - size_t len = strlen (mailbox) + 5; - int wlen; - - newmail = xmalloc (len); - wlen = snprintf (newmail, len, "%s/new", mailbox); - assert (wlen == (int) len - 1); - - if (stat (newmail, &statbuf) != -1 && statbuf.st_size != 0) { - if (statbuf.st_mtime > statbuf.st_atime) { - free (newmail); - (void) puts (_("You have new mail.")); - return; - } - } - free (newmail); - } - - mailbox = getenv ("MAIL"); - if (NULL == mailbox) { - return; - } - - if ( (stat (mailbox, &statbuf) == -1) - || (statbuf.st_size == 0)) { - (void) puts (_("No mail.")); - } else if (statbuf.st_atime > statbuf.st_mtime) { - (void) puts (_("You have mail.")); - } else { - (void) puts (_("You have new mail.")); - } -} - diff --git a/libmisc/motd.c b/libmisc/motd.c deleted file mode 100644 index 7f7e523..0000000 --- a/libmisc/motd.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1991, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2010 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include "prototypes.h" -#include "defines.h" -#include "getdef.h" -/* - * motd -- output the /etc/motd file - * - * motd() determines the name of a login announcement file and outputs - * it to the user's terminal at login time. The MOTD_FILE configuration - * option is a colon-delimited list of filenames. - */ -void motd (void) -{ - FILE *fp; - char *motdlist; - const char *motdfile; - char *mb; - int c; - - motdfile = getdef_str ("MOTD_FILE"); - if (NULL == motdfile) { - return; - } - - motdlist = xstrdup (motdfile); - - for (mb = motdlist; ;mb = NULL) { - motdfile = strtok (mb, ":"); - if (NULL == motdfile) { - break; - } - - fp = fopen (motdfile, "r"); - if (NULL != fp) { - while ((c = getc (fp)) != EOF) { - putchar (c); - } - fclose (fp); - } - } - fflush (stdout); - - free (motdlist); -} - diff --git a/libmisc/myname.c b/libmisc/myname.c deleted file mode 100644 index 1b02617..0000000 --- a/libmisc/myname.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * myname.c - determine the current username and get the passwd entry - * - */ - -#include <config.h> - -#ident "$Id$" - -#include "defines.h" -#include <pwd.h> -#include "prototypes.h" -/*@null@*/ /*@only@*/struct passwd *get_my_pwent (void) -{ - struct passwd *pw; - const char *cp = getlogin (); - uid_t ruid = getuid (); - - /* - * Try getlogin() first - if it fails or returns a non-existent - * username, or a username which doesn't match the real UID, fall - * back to getpwuid(getuid()). This should work reasonably with - * usernames longer than the utmp limit (8 characters), as well as - * shared UIDs - but not both at the same time... - * - * XXX - when running from su, will return the current user (not - * the original user, like getlogin() does). Does this matter? - */ - if ((NULL != cp) && ('\0' != *cp)) { - pw = xgetpwnam (cp); - if ((NULL != pw) && (pw->pw_uid == ruid)) { - return pw; - } - if (NULL != pw) { - pw_free (pw); - } - } - - return xgetpwuid (ruid); -} - diff --git a/libmisc/obscure.c b/libmisc/obscure.c deleted file mode 100644 index 3daaa95..0000000 --- a/libmisc/obscure.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * 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 - */ - -#include <config.h> - -#ifndef USE_PAM - -#ident "$Id$" - - -/* - * This version of obscure.c contains modifications to support "cracklib" - * by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib - * library source code for this function to operate. - */ -#include <ctype.h> -#include <stdio.h> -#include "prototypes.h" -#include "defines.h" -#include "getdef.h" -/* - * can't be a palindrome - like `R A D A R' or `M A D A M' - */ -static bool palindrome (unused const char *old, const char *new) -{ - size_t i, j; - - i = strlen (new); - - for (j = 0; j < i; j++) { - if (new[i - j - 1] != new[j]) { - return false; - } - } - - return true; -} - -/* - * more than half of the characters are different ones. - */ - -static bool similar (/*@notnull@*/const char *old, /*@notnull@*/const char *new) -{ - int i, j; - - /* - * XXX - sometimes this fails when changing from a simple password - * to a really long one (MD5). For now, I just return success if - * the new password is long enough. Please feel free to suggest - * something better... --marekm - */ - if (strlen (new) >= 8) { - return false; - } - - for (i = j = 0; ('\0' != new[i]) && ('\0' != old[i]); i++) { - if (strchr (new, old[i]) != NULL) { - j++; - } - } - - if (i >= j * 2) { - return false; - } - - return true; -} - -/* - * a nice mix of characters. - */ - -static bool simple (unused const char *old, const char *new) -{ - bool digits = false; - bool uppers = false; - bool lowers = false; - bool others = false; - int size; - int i; - - for (i = 0; '\0' != new[i]; i++) { - if (isdigit (new[i])) { - digits = true; - } else if (isupper (new[i])) { - uppers = true; - } else if (islower (new[i])) { - lowers = true; - } else { - others = true; - } - } - - /* - * The scam is this - a password of only one character type - * must be 8 letters long. Two types, 7, and so on. - */ - - size = 9; - if (digits) { - size--; - } - if (uppers) { - size--; - } - if (lowers) { - size--; - } - if (others) { - size--; - } - - if (size <= i) { - return false; - } - - return true; -} - -static char *str_lower (/*@returned@*/char *string) -{ - char *cp; - - for (cp = string; '\0' != *cp; cp++) { - *cp = tolower (*cp); - } - return string; -} - -static /*@observer@*//*@null@*/const char *password_check ( - /*@notnull@*/const char *old, - /*@notnull@*/const char *new, - /*@notnull@*/const struct passwd *pwdp) -{ - const char *msg = NULL; - char *oldmono, *newmono, *wrapped; - -#ifdef HAVE_LIBCRACK - char *dictpath; - -#ifdef HAVE_LIBCRACK_PW - char *FascistCheckPw (); -#else - char *FascistCheck (); -#endif -#endif - - if (strcmp (new, old) == 0) { - return _("no change"); - } - - newmono = str_lower (xstrdup (new)); - oldmono = str_lower (xstrdup (old)); - wrapped = xmalloc (strlen (oldmono) * 2 + 1); - strcpy (wrapped, oldmono); - strcat (wrapped, oldmono); - - if (palindrome (oldmono, newmono)) { - msg = _("a palindrome"); - } else if (strcmp (oldmono, newmono) == 0) { - msg = _("case changes only"); - } else if (similar (oldmono, newmono)) { - msg = _("too similar"); - } else if (simple (old, new)) { - msg = _("too simple"); - } else if (strstr (wrapped, newmono) != NULL) { - msg = _("rotated"); - } else { -#ifdef HAVE_LIBCRACK - /* - * Invoke Alec Muffett's cracklib routines. - */ - - dictpath = getdef_str ("CRACKLIB_DICTPATH"); - if (NULL != dictpath) { -#ifdef HAVE_LIBCRACK_PW - msg = FascistCheckPw (new, dictpath, pwdp); -#else - msg = FascistCheck (new, dictpath); -#endif - } -#endif - } - strzero (newmono); - strzero (oldmono); - strzero (wrapped); - free (newmono); - free (oldmono); - free (wrapped); - - return msg; -} - -static /*@observer@*//*@null@*/const char *obscure_msg ( - /*@notnull@*/const char *old, - /*@notnull@*/const char *new, - /*@notnull@*/const struct passwd *pwdp) -{ - size_t maxlen, oldlen, newlen; - char *new1, *old1; - const char *msg; - const char *result; - - oldlen = strlen (old); - newlen = strlen (new); - - if (newlen < (size_t) getdef_num ("PASS_MIN_LEN", 0)) { - return _("too short"); - } - - /* - * Remaining checks are optional. - */ - if (!getdef_bool ("OBSCURE_CHECKS_ENAB")) { - return NULL; - } - - msg = password_check (old, new, pwdp); - if (NULL != msg) { - return msg; - } - - result = getdef_str ("ENCRYPT_METHOD"); - if (NULL == result) { - /* The traditional crypt() truncates passwords to 8 chars. It is - possible to circumvent the above checks by choosing an easy - 8-char password and adding some random characters to it... - Example: "password$%^&*123". So check it again, this time - truncated to the maximum length. Idea from npasswd. --marekm */ - - if (getdef_bool ("MD5_CRYPT_ENAB")) { - return NULL; - } - - } else { - - if ( (strcmp (result, "MD5") == 0) -#ifdef USE_SHA_CRYPT - || (strcmp (result, "SHA256") == 0) - || (strcmp (result, "SHA512") == 0) -#endif -#ifdef USE_BCRYPT - || (strcmp (result, "BCRYPT") == 0) -#endif -#ifdef USE_YESCRYPT - || (strcmp (result, "YESCRYPT") == 0) -#endif - ) { - return NULL; - } - - } - maxlen = (size_t) getdef_num ("PASS_MAX_LEN", 8); - if ( (oldlen <= maxlen) - && (newlen <= maxlen)) { - return NULL; - } - - new1 = xstrdup (new); - old1 = xstrdup (old); - if (newlen > maxlen) { - new1[maxlen] = '\0'; - } - if (oldlen > maxlen) { - old1[maxlen] = '\0'; - } - - msg = password_check (old1, new1, pwdp); - - memzero (new1, newlen); - memzero (old1, oldlen); - free (new1); - free (old1); - - return msg; -} - -/* - * Obscure - see if password is obscure enough. - * - * The programmer is encouraged to add as much complexity to this - * routine as desired. Included are some of my favorite ways to - * check passwords. - */ - -bool obscure (const char *old, const char *new, const struct passwd *pwdp) -{ - const char *msg = obscure_msg (old, new, pwdp); - - if (NULL != msg) { - printf (_("Bad password: %s. "), msg); - return false; - } - return true; -} - -#else /* !USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !USE_PAM */ diff --git a/libmisc/pam_pass.c b/libmisc/pam_pass.c deleted file mode 100644 index 166a42e..0000000 --- a/libmisc/pam_pass.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1997 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ifdef USE_PAM - -#ident "$Id$" - - -/* - * Change the user's password using PAM. - */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include "defines.h" -#include "pam_defs.h" -#include "prototypes.h" -#include "shadowlog.h" - -void do_pam_passwd (const char *user, bool silent, bool change_expired) -{ - pam_handle_t *pamh = NULL; - int flags = 0, ret; - FILE *shadow_logfd = log_get_logfd(); - - if (silent) - flags |= PAM_SILENT; - if (change_expired) - flags |= PAM_CHANGE_EXPIRED_AUTHTOK; - - ret = pam_start ("passwd", user, &conv, &pamh); - if (ret != PAM_SUCCESS) { - fprintf (shadow_logfd, - _("passwd: pam_start() failed, error %d\n"), ret); - exit (10); /* XXX */ - } - - ret = pam_chauthtok (pamh, flags); - if (ret != PAM_SUCCESS) { - fprintf (shadow_logfd, _("passwd: %s\n"), pam_strerror (pamh, ret)); - fputs (_("passwd: password unchanged\n"), shadow_logfd); - pam_end (pamh, ret); - exit (10); /* XXX */ - } - - fputs (_("passwd: password updated successfully\n"), shadow_logfd); - (void) pam_end (pamh, PAM_SUCCESS); -} -#else /* !USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !USE_PAM */ diff --git a/libmisc/pam_pass_non_interactive.c b/libmisc/pam_pass_non_interactive.c deleted file mode 100644 index 34cdc1f..0000000 --- a/libmisc/pam_pass_non_interactive.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2009 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id:$" - -#ifdef USE_PAM -#include <assert.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include <security/pam_appl.h> -#include "prototypes.h" -#include "shadowlog.h" - -/*@null@*/ /*@only@*/static const char *non_interactive_password = NULL; -static int ni_conv (int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - unused void *appdata_ptr); -static const struct pam_conv non_interactive_pam_conv = { - ni_conv, - NULL -}; - - - -static int ni_conv (int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - unused void *appdata_ptr) -{ - struct pam_response *responses; - int count; - - assert (NULL != non_interactive_password); - - if (num_msg <= 0) { - return PAM_CONV_ERR; - } - - responses = (struct pam_response *) calloc ((size_t) num_msg, - sizeof (*responses)); - if (NULL == responses) { - return PAM_CONV_ERR; - } - - for (count=0; count < num_msg; count++) { - responses[count].resp_retcode = 0; - - switch (msg[count]->msg_style) { - case PAM_PROMPT_ECHO_ON: - fprintf (log_get_logfd(), - _("%s: PAM modules requesting echoing are not supported.\n"), - log_get_progname()); - goto failed_conversation; - case PAM_PROMPT_ECHO_OFF: - responses[count].resp = strdup (non_interactive_password); - if (NULL == responses[count].resp) { - goto failed_conversation; - } - break; - case PAM_ERROR_MSG: - if ( (NULL == msg[count]->msg) - || (fprintf (log_get_logfd(), "%s\n", msg[count]->msg) <0)) { - goto failed_conversation; - } - responses[count].resp = NULL; - break; - case PAM_TEXT_INFO: - if ( (NULL == msg[count]->msg) - || (fprintf (stdout, "%s\n", msg[count]->msg) <0)) { - goto failed_conversation; - } - responses[count].resp = NULL; - break; - default: - (void) fprintf (log_get_logfd(), - _("%s: conversation type %d not supported.\n"), - log_get_progname(), msg[count]->msg_style); - goto failed_conversation; - } - } - - *resp = responses; - - return PAM_SUCCESS; - -failed_conversation: - for (count=0; count < num_msg; count++) { - if (NULL != responses[count].resp) { - memset (responses[count].resp, 0, - strlen (responses[count].resp)); - free (responses[count].resp); - responses[count].resp = NULL; - } - } - - free (responses); - *resp = NULL; - - return PAM_CONV_ERR; -} - - -/* - * Change non interactively the user's password using PAM. - * - * Return 0 on success, 1 on failure. - */ -int do_pam_passwd_non_interactive (const char *pam_service, - const char *username, - const char* password) -{ - pam_handle_t *pamh = NULL; - int ret; - - ret = pam_start (pam_service, username, &non_interactive_pam_conv, &pamh); - if (ret != PAM_SUCCESS) { - fprintf (log_get_logfd(), - _("%s: (user %s) pam_start failure %d\n"), - log_get_progname(), username, ret); - return 1; - } - - non_interactive_password = password; - ret = pam_chauthtok (pamh, 0); - if (ret != PAM_SUCCESS) { - fprintf (log_get_logfd(), - _("%s: (user %s) pam_chauthtok() failed, error:\n" - "%s\n"), - log_get_progname(), username, pam_strerror (pamh, ret)); - } - - (void) pam_end (pamh, PAM_SUCCESS); - - return ((PAM_SUCCESS == ret) ? 0 : 1); -} -#else /* !USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !USE_PAM */ diff --git a/libmisc/prefix_flag.c b/libmisc/prefix_flag.c deleted file mode 100644 index 4eb5154..0000000 --- a/libmisc/prefix_flag.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2011 , Julian Pidancet - * SPDX-FileCopyrightText: 2011 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include <assert.h> -#include "defines.h" -#include "prototypes.h" -/*@-exitarg@*/ -#include "exitcodes.h" -#include "groupio.h" -#include "pwio.h" -#ifdef SHADOWGRP -#include "sgroupio.h" -#endif -#include "shadowio.h" -#ifdef ENABLE_SUBIDS -#include "subordinateio.h" -#endif /* ENABLE_SUBIDS */ -#include "getdef.h" -#include "shadowlog.h" - -static char *passwd_db_file = NULL; -static char *spw_db_file = NULL; -static char *group_db_file = NULL; -static char *sgroup_db_file = NULL; -static char *suid_db_file = NULL; -static char *sgid_db_file = NULL; -static char *def_conf_file = NULL; -static FILE* fp_pwent = NULL; -static FILE* fp_grent = NULL; - -/* - * process_prefix_flag - prefix all paths if given the --prefix option - * - * This shall be called before accessing the passwd, group, shadow, - * gshadow, useradd's default, login.defs files (non exhaustive list) - * or authenticating the caller. - * - * The audit, syslog, or locale files shall be open before - */ -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; - - for (i = 0; i < argc; i++) { - val = NULL; - if ( (strcmp (argv[i], "--prefix") == 0) - || ((strncmp (argv[i], "--prefix=", 9) == 0) - && (val = argv[i] + 9)) - || (strcmp (argv[i], short_opt) == 0)) { - if (NULL != prefix) { - fprintf (log_get_logfd(), - _("%s: multiple --prefix options\n"), - log_get_progname()); - exit (E_BAD_ARG); - } - - if (val) { - prefix = val; - } else if (i + 1 == argc) { - fprintf (log_get_logfd(), - _("%s: option '%s' requires an argument\n"), - log_get_progname(), argv[i]); - exit (E_BAD_ARG); - } else { - prefix = argv[++ i]; - } - } - } - - - - if (prefix != NULL) { - if ( prefix[0] == '\0' || !strcmp(prefix, "/")) - return ""; /* if prefix is "/" then we ignore the flag option */ - /* should we prevent symbolic link from being used as a prefix? */ - - if ( prefix[0] != '/') { - fprintf (log_get_logfd(), - _("%s: prefix must be an absolute path\n"), - log_get_progname()); - exit (E_BAD_ARG); - } - size_t len; - len = strlen(prefix) + strlen(PASSWD_FILE) + 2; - passwd_db_file = xmalloc(len); - snprintf(passwd_db_file, len, "%s/%s", prefix, PASSWD_FILE); - pw_setdbname(passwd_db_file); - - len = strlen(prefix) + strlen(GROUP_FILE) + 2; - group_db_file = xmalloc(len); - snprintf(group_db_file, len, "%s/%s", prefix, GROUP_FILE); - gr_setdbname(group_db_file); - -#ifdef SHADOWGRP - len = strlen(prefix) + strlen(SGROUP_FILE) + 2; - sgroup_db_file = xmalloc(len); - snprintf(sgroup_db_file, len, "%s/%s", prefix, SGROUP_FILE); - sgr_setdbname(sgroup_db_file); -#endif -#ifdef USE_NIS - __setspNIS(0); /* disable NIS for now, at least until it is properly supporting a "prefix" */ -#endif - - len = strlen(prefix) + strlen(SHADOW_FILE) + 2; - spw_db_file = xmalloc(len); - snprintf(spw_db_file, len, "%s/%s", prefix, SHADOW_FILE); - spw_setdbname(spw_db_file); - -#ifdef ENABLE_SUBIDS - len = strlen(prefix) + strlen("/etc/subuid") + 2; - suid_db_file = xmalloc(len); - snprintf(suid_db_file, len, "%s/%s", prefix, "/etc/subuid"); - sub_uid_setdbname(suid_db_file); - - len = strlen(prefix) + strlen("/etc/subgid") + 2; - sgid_db_file = xmalloc(len); - snprintf(sgid_db_file, len, "%s/%s", prefix, "/etc/subgid"); - sub_gid_setdbname(sgid_db_file); -#endif - -#ifdef USE_ECONF - setdef_config_file(prefix); -#else - len = strlen(prefix) + strlen("/etc/login.defs") + 2; - def_conf_file = xmalloc(len); - snprintf(def_conf_file, len, "%s/%s", prefix, "/etc/login.defs"); - setdef_config_file(def_conf_file); -#endif - } - - if (prefix == NULL) - return ""; - return prefix; -} - - -extern struct group *prefix_getgrnam(const char *name) -{ - if (group_db_file) { - FILE* fg; - struct group * grp = NULL; - - fg = fopen(group_db_file, "rt"); - if (!fg) - return NULL; - while ((grp = fgetgrent(fg)) != NULL) { - if (!strcmp(name, grp->gr_name)) - break; - } - fclose(fg); - return grp; - } - - return getgrnam(name); -} - -extern struct group *prefix_getgrgid(gid_t gid) -{ - if (group_db_file) { - FILE* fg; - struct group * grp = NULL; - - fg = fopen(group_db_file, "rt"); - if (!fg) - return NULL; - while ((grp = fgetgrent(fg)) != NULL) { - if (gid == grp->gr_gid) - break; - } - fclose(fg); - return grp; - } - - return getgrgid(gid); -} - -extern struct passwd *prefix_getpwuid(uid_t uid) -{ - if (passwd_db_file) { - FILE* fg; - struct passwd *pwd = NULL; - - fg = fopen(passwd_db_file, "rt"); - if (!fg) - return NULL; - while ((pwd = fgetpwent(fg)) != NULL) { - if (uid == pwd->pw_uid) - break; - } - fclose(fg); - return pwd; - } - else { - return getpwuid(uid); - } -} -extern struct passwd *prefix_getpwnam(const char* name) -{ - if (passwd_db_file) { - FILE* fg; - struct passwd *pwd = NULL; - - fg = fopen(passwd_db_file, "rt"); - if (!fg) - return NULL; - while ((pwd = fgetpwent(fg)) != NULL) { - if (!strcmp(name, pwd->pw_name)) - break; - } - fclose(fg); - return pwd; - } - else { - return getpwnam(name); - } -} -extern struct spwd *prefix_getspnam(const char* name) -{ - if (spw_db_file) { - FILE* fg; - struct spwd *sp = NULL; - - fg = fopen(spw_db_file, "rt"); - if (!fg) - return NULL; - while ((sp = fgetspent(fg)) != NULL) { - if (!strcmp(name, sp->sp_namp)) - break; - } - fclose(fg); - return sp; - } - else { - return getspnam(name); - } -} - -extern void prefix_setpwent(void) -{ - if (!passwd_db_file) { - setpwent(); - return; - } - if (fp_pwent) - fclose (fp_pwent); - - fp_pwent = fopen(passwd_db_file, "rt"); - if (!fp_pwent) - return; -} -extern struct passwd* prefix_getpwent(void) -{ - if (!passwd_db_file) { - return getpwent(); - } - if (!fp_pwent) { - return NULL; - } - return fgetpwent(fp_pwent); -} -extern void prefix_endpwent(void) -{ - if (!passwd_db_file) { - endpwent(); - return; - } - if (fp_pwent) - fclose(fp_pwent); - fp_pwent = NULL; -} - -extern void prefix_setgrent(void) -{ - if (!group_db_file) { - setgrent(); - return; - } - if (fp_grent) - fclose (fp_grent); - - fp_grent = fopen(group_db_file, "rt"); - if (!fp_grent) - return; -} -extern struct group* prefix_getgrent(void) -{ - if (!group_db_file) { - return getgrent(); - } - return fgetgrent(fp_grent); -} -extern void prefix_endgrent(void) -{ - if (!group_db_file) { - endgrent(); - return; - } - if (fp_grent) - fclose(fp_grent); - fp_grent = NULL; -} - -extern struct group *prefix_getgr_nam_gid(const char *grname) -{ - long long int gid; - char *endptr; - struct group *g; - - if (NULL == grname) { - return NULL; - } - - if (group_db_file) { - errno = 0; - gid = strtoll (grname, &endptr, 10); - if ( ('\0' != *grname) - && ('\0' == *endptr) - && (ERANGE != errno) - && (gid == (gid_t)gid)) { - return prefix_getgrgid ((gid_t) gid); - } - g = prefix_getgrnam (grname); - return g ? __gr_dup(g) : NULL; - } - else - return getgr_nam_gid(grname); -} diff --git a/libmisc/pwd2spwd.c b/libmisc/pwd2spwd.c deleted file mode 100644 index 139a024..0000000 --- a/libmisc/pwd2spwd.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#ifndef USE_PAM - -#include <sys/types.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> - -/* - * pwd_to_spwd - create entries for new spwd structure - * - * pwd_to_spwd() creates a new (struct spwd) containing the - * information in the pointed-to (struct passwd). - */ - -struct spwd *pwd_to_spwd (const struct passwd *pw) -{ - static struct spwd sp; - - /* - * Nice, easy parts first. The name and passwd map directly - * from the old password structure to the new one. - */ - sp.sp_namp = pw->pw_name; - sp.sp_pwdp = pw->pw_passwd; - - { - /* - * Defaults used if there is no pw_age information. - */ - sp.sp_min = 0; - sp.sp_max = (10000L * DAY) / SCALE; - sp.sp_lstchg = (long) gettime () / SCALE; - if (0 == sp.sp_lstchg) { - /* Better disable aging than requiring a password - * change */ - sp.sp_lstchg = -1; - } - } - - /* - * These fields have no corresponding information in the password - * file. They are set to uninitialized values. - */ - sp.sp_warn = -1; - sp.sp_expire = -1; - sp.sp_inact = -1; - sp.sp_flag = SHADOW_SP_FLAG_UNSET; - - return &sp; -} -#else /* USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !USE_PAM */ - diff --git a/libmisc/pwd_init.c b/libmisc/pwd_init.c deleted file mode 100644 index 63c71e2..0000000 --- a/libmisc/pwd_init.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1997 , Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include "defines.h" -#include <signal.h> -#include <sys/types.h> -#include <sys/stat.h> -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif - -#include "prototypes.h" - -/* - * pwd_init - ignore signals, and set resource limits to safe - * values. Call this before modifying password files, so that - * it is less likely to fail in the middle of operation. - */ -void pwd_init (void) -{ -#ifdef HAVE_SYS_RESOURCE_H - struct rlimit rlim; - -#ifdef RLIMIT_CORE - rlim.rlim_cur = rlim.rlim_max = 0; - setrlimit (RLIMIT_CORE, &rlim); -#endif - rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; -#ifdef RLIMIT_AS - setrlimit (RLIMIT_AS, &rlim); -#endif -#ifdef RLIMIT_CPU - setrlimit (RLIMIT_CPU, &rlim); -#endif -#ifdef RLIMIT_DATA - setrlimit (RLIMIT_DATA, &rlim); -#endif -#ifdef RLIMIT_FSIZE - setrlimit (RLIMIT_FSIZE, &rlim); -#endif -#ifdef RLIMIT_NOFILE - setrlimit (RLIMIT_NOFILE, &rlim); -#endif -#ifdef RLIMIT_RSS - setrlimit (RLIMIT_RSS, &rlim); -#endif -#ifdef RLIMIT_STACK - setrlimit (RLIMIT_STACK, &rlim); -#endif -#else /* !HAVE_SYS_RESOURCE_H */ - set_filesize_limit (30000); - /* don't know how to set the other limits... */ -#endif /* !HAVE_SYS_RESOURCE_H */ - - signal (SIGALRM, SIG_IGN); - signal (SIGHUP, SIG_IGN); - signal (SIGINT, SIG_IGN); - signal (SIGPIPE, SIG_IGN); - signal (SIGQUIT, SIG_IGN); - signal (SIGTERM, SIG_IGN); -#ifdef SIGTSTP - signal (SIGTSTP, SIG_IGN); -#endif -#ifdef SIGTTOU - signal (SIGTTOU, SIG_IGN); -#endif - - umask (077); -} diff --git a/libmisc/pwdcheck.c b/libmisc/pwdcheck.c deleted file mode 100644 index 15fc3a3..0000000 --- a/libmisc/pwdcheck.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2000 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#ifndef USE_PAM - -#include <stdio.h> -#include <shadow.h> -#include "prototypes.h" -#include "defines.h" -#include "pwauth.h" -#include "shadowlog.h" - -void passwd_check (const char *user, const char *passwd, unused const char *progname) -{ - struct spwd *sp; - - sp = getspnam (user); /* !USE_PAM, no need for xgetspnam */ - if (NULL != sp) { - passwd = sp->sp_pwdp; - } - if (pw_auth (passwd, user, PW_LOGIN, (char *) 0) != 0) { - SYSLOG ((LOG_WARN, "incorrect password for `%s'", user)); - (void) sleep (1); - fprintf (log_get_logfd(), _("Incorrect password for %s.\n"), user); - exit (EXIT_FAILURE); - } -} -#else /* USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* USE_PAM */ diff --git a/libmisc/remove_tree.c b/libmisc/remove_tree.c deleted file mode 100644 index 3d76b95..0000000 --- a/libmisc/remove_tree.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2001, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <unistd.h> -#include "prototypes.h" -#include "defines.h" - -static int remove_tree_at (int at_fd, const char *path, bool remove_root) -{ - DIR *dir; - const struct dirent *ent; - int dir_fd, rc = 0; - - dir_fd = openat (at_fd, path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); - if (dir_fd < 0) { - return -1; - } - - dir = fdopendir (dir_fd); - if (!dir) { - (void) close (dir_fd); - return -1; - } - - /* - * Open the source directory and delete each entry. - */ - while ((ent = readdir (dir))) { - struct stat ent_sb; - - /* - * Skip the "." and ".." entries - */ - if (strcmp (ent->d_name, ".") == 0 || - strcmp (ent->d_name, "..") == 0) { - continue; - } - - rc = fstatat (dirfd(dir), ent->d_name, &ent_sb, AT_SYMLINK_NOFOLLOW); - if (rc < 0) { - break; - } - - if (S_ISDIR (ent_sb.st_mode)) { - /* - * Recursively delete this directory. - */ - if (remove_tree_at (dirfd(dir), ent->d_name, true) != 0) { - rc = -1; - break; - } - } else { - /* - * Delete the file. - */ - if (unlinkat (dirfd(dir), ent->d_name, 0) != 0) { - rc = -1; - break; - } - } - } - - (void) closedir (dir); - - if (remove_root && (0 == rc)) { - if (unlinkat (at_fd, path, AT_REMOVEDIR) != 0) { - rc = -1; - } - } - - return rc; -} - -/* - * remove_tree - delete a directory tree - * - * remove_tree() walks a directory tree and deletes all the files - * and directories. - * At the end, it deletes the root directory itself. - */ -int remove_tree (const char *root, bool remove_root) -{ - return remove_tree_at (AT_FDCWD, root, remove_root); -} diff --git a/libmisc/rlogin.c b/libmisc/rlogin.c deleted file mode 100644 index fa67dc3..0000000 --- a/libmisc/rlogin.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ifdef RLOGIN - -#ident "$Id$" - -#include "prototypes.h" -#include "defines.h" -#include <stdio.h> -#include <pwd.h> -#include <netdb.h> -static struct { - int spd_name; - int spd_baud; -} speed_table[] = -{ -#ifdef B50 - { - B50, 50}, -#endif -#ifdef B75 - { - B75, 75}, -#endif -#ifdef B110 - { - B110, 110}, -#endif -#ifdef B134 - { - B134, 134}, -#endif -#ifdef B150 - { - B150, 150}, -#endif -#ifdef B200 - { - B200, 200}, -#endif -#ifdef B300 - { - B300, 300}, -#endif -#ifdef B600 - { - B600, 600}, -#endif -#ifdef B1200 - { - B1200, 1200}, -#endif -#ifdef B1800 - { - B1800, 1800}, -#endif -#ifdef B2400 - { - B2400, 2400}, -#endif -#ifdef B4800 - { - B4800, 4800}, -#endif -#ifdef B9600 - { - B9600, 9600}, -#endif -#ifdef B19200 - { - B19200, 19200}, -#endif -#ifdef B38400 - { - B38400, 38400}, -#endif - { - -1, -1} -}; - -static void get_remote_string (char *buf, size_t size) -{ - for (;;) { - if (read (0, buf, 1) != 1) { - exit (EXIT_FAILURE); - } - if ('\0' == *buf) { - return; - } - --size; - if (size > 0) { - ++buf; - } - } - /*NOTREACHED*/} - -int -do_rlogin (const char *remote_host, char *name, size_t namelen, char *term, - size_t termlen) -{ - struct passwd *pwd; - char remote_name[32]; - char *cp; - unsigned long remote_speed = 9600; - int speed_name = B9600; - int i; - TERMIO termio; - - get_remote_string (remote_name, sizeof remote_name); - get_remote_string (name, namelen); - get_remote_string (term, termlen); - - cp = strchr (term, '/'); - if (NULL != cp) { - *cp = '\0'; - cp++; - - if (getulong (cp, &remote_speed) == 0) { - remote_speed = 9600; - } - } - for (i = 0; - ( (speed_table[i].spd_baud != remote_speed) - && (speed_table[i].spd_name != -1)); - i++); - - if (-1 != speed_table[i].spd_name) { - speed_name = speed_table[i].spd_name; - } - - /* - * Put the terminal in cooked mode with echo turned on. - */ - - GTTY (0, &termio); - termio.c_iflag |= ICRNL | IXON; - termio.c_oflag |= OPOST | ONLCR; - termio.c_lflag |= ICANON | ECHO | ECHOE; -#ifdef CBAUD - termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name; -#else - termio.c_cflag = (termio.c_cflag) | speed_name; -#endif - STTY (0, &termio); - - pwd = getpwnam (name); /* local, no need for xgetpwnam */ - if (NULL == pwd) { - return 0; - } - - /* - * ruserok() returns 0 for success on modern systems, and 1 on - * older ones. If you are having trouble with people logging - * in without giving a required password, THIS is the culprit - - * go fix the #define in config.h. - */ - -#ifndef RUSEROK - return 0; -#else - return ruserok (remote_host, pwd->pw_uid == 0, - remote_name, name) == RUSEROK; -#endif -} -#endif /* RLOGIN */ - diff --git a/libmisc/root_flag.c b/libmisc/root_flag.c deleted file mode 100644 index 62915b0..0000000 --- a/libmisc/root_flag.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2011 , Julian Pidancet - * SPDX-FileCopyrightText: 2011 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include <assert.h> -#include "defines.h" -#include "prototypes.h" -/*@-exitarg@*/ -#include "exitcodes.h" -#include "shadowlog.h" - -static void change_root (const char* newroot); - -/* - * process_root_flag - chroot if given the --root option - * - * This shall be called before accessing the passwd, group, shadow, - * gshadow, useradd's default, login.defs files (non exhaustive list) - * or authenticating the caller. - * - * The audit, syslog, or locale files shall be open before - */ -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; - - for (i = 0; i < argc; i++) { - val = NULL; - if ( (strcmp (argv[i], "--root") == 0) - || ((strncmp (argv[i], "--root=", 7) == 0) - && (val = argv[i] + 7)) - || (strcmp (argv[i], short_opt) == 0)) { - if (NULL != newroot) { - fprintf (log_get_logfd(), - _("%s: multiple --root options\n"), - log_get_progname()); - exit (E_BAD_ARG); - } - - if (val) { - newroot = val; - } else if (i + 1 == argc) { - fprintf (log_get_logfd(), - _("%s: option '%s' requires an argument\n"), - log_get_progname(), argv[i]); - exit (E_BAD_ARG); - } else { - newroot = argv[++ i]; - } - } - } - - if (NULL != newroot) { - change_root (newroot); - } -} - -static void change_root (const char* newroot) -{ - /* Drop privileges */ - if ( (setregid (getgid (), getgid ()) != 0) - || (setreuid (getuid (), getuid ()) != 0)) { - fprintf (log_get_logfd(), _("%s: failed to drop privileges (%s)\n"), - log_get_progname(), strerror (errno)); - exit (EXIT_FAILURE); - } - - if ('/' != newroot[0]) { - fprintf (log_get_logfd(), - _("%s: invalid chroot path '%s', only absolute paths are supported.\n"), - log_get_progname(), newroot); - exit (E_BAD_ARG); - } - - if (access (newroot, F_OK) != 0) { - fprintf(log_get_logfd(), - _("%s: cannot access chroot directory %s: %s\n"), - log_get_progname(), newroot, strerror (errno)); - exit (E_BAD_ARG); - } - - if (chdir (newroot) != 0) { - fprintf(log_get_logfd(), - _("%s: cannot chdir to chroot directory %s: %s\n"), - log_get_progname(), newroot, strerror (errno)); - exit (E_BAD_ARG); - } - - if (chroot (newroot) != 0) { - fprintf(log_get_logfd(), - _("%s: unable to chroot to directory %s: %s\n"), - log_get_progname(), newroot, strerror (errno)); - exit (E_BAD_ARG); - } -} - diff --git a/libmisc/salt.c b/libmisc/salt.c deleted file mode 100644 index e5f633a..0000000 --- a/libmisc/salt.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * SPDX-FileCopyrightText: Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl> - * SPDX-FileCopyrightText: J.T. Conklin <jtc@netbsd.org> - * - * SPDX-License-Identifier: Unlicense - */ - -/* - * salt.c - generate a random salt string for crypt() - * - * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>, - * it is in the public domain. - * - * l64a was Written by J.T. Conklin <jtc@netbsd.org>. Public domain. - */ - -#include <config.h> - -#ident "$Id$" - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#if HAVE_SYS_RANDOM_H -#include <sys/random.h> -#endif -#include "prototypes.h" -#include "defines.h" -#include "getdef.h" -#include "shadowlog.h" - -#if (defined CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY && \ - CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) -#define USE_XCRYPT_GENSALT 1 -#else -#define USE_XCRYPT_GENSALT 0 -#endif - -/* Add the salt prefix. */ -#define MAGNUM(array,ch) (array)[0]=(array)[2]='$',(array)[1]=(ch),(array)[3]='\0' - -#ifdef USE_BCRYPT -/* Use $2b$ as prefix for compatibility with OpenBSD's bcrypt. */ -#define BCRYPTMAGNUM(array) (array)[0]=(array)[3]='$',(array)[1]='2',(array)[2]='b',(array)[4]='\0' -#define BCRYPT_SALT_SIZE 22 -/* Default number of rounds if not explicitly specified. */ -#define B_ROUNDS_DEFAULT 13 -/* Minimum number of rounds. */ -#define B_ROUNDS_MIN 4 -/* Maximum number of rounds. */ -#define B_ROUNDS_MAX 31 -#endif /* USE_BCRYPT */ - -#ifdef USE_SHA_CRYPT -/* Fixed salt len for sha{256,512}crypt. */ -#define SHA_CRYPT_SALT_SIZE 16 -/* Default number of rounds if not explicitly specified. */ -#define SHA_ROUNDS_DEFAULT 5000 -/* Minimum number of rounds. */ -#define SHA_ROUNDS_MIN 1000 -/* Maximum number of rounds. */ -#define SHA_ROUNDS_MAX 999999999 -#endif - -#ifdef USE_YESCRYPT -/* - * Default number of base64 characters used for the salt. - * 24 characters gives a 144 bits (18 bytes) salt. Unlike the more - * traditional 128 bits (16 bytes) salt, this 144 bits salt is always - * represented by the same number of base64 characters without padding - * issue, even with a non-standard base64 encoding scheme. - */ -#define YESCRYPT_SALT_SIZE 24 -/* Default cost if not explicitly specified. */ -#define Y_COST_DEFAULT 5 -/* Minimum cost. */ -#define Y_COST_MIN 1 -/* Maximum cost. */ -#define Y_COST_MAX 11 -#endif - -/* Fixed salt len for md5crypt. */ -#define MD5_CRYPT_SALT_SIZE 8 - -/* Generate salt of size salt_size. */ -#define MAX_SALT_SIZE 44 -#define MIN_SALT_SIZE 8 - -/* Maximum size of the generated salt string. */ -#define GENSALT_SETTING_SIZE 100 - -/* local function prototypes */ -static long read_random_bytes (void); -#if !USE_XCRYPT_GENSALT -static /*@observer@*/const char *gensalt (size_t salt_size); -#endif /* !USE_XCRYPT_GENSALT */ -#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -static long shadow_random (long min, long max); -#endif /* USE_SHA_CRYPT || USE_BCRYPT */ -#ifdef USE_SHA_CRYPT -static /*@observer@*/unsigned long SHA_get_salt_rounds (/*@null@*/const int *prefered_rounds); -static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds); -#endif /* USE_SHA_CRYPT */ -#ifdef USE_BCRYPT -static /*@observer@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds); -static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds); -#endif /* USE_BCRYPT */ -#ifdef USE_YESCRYPT -static /*@observer@*/unsigned long YESCRYPT_get_salt_cost (/*@null@*/const int *prefered_cost); -static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost); -#endif /* USE_YESCRYPT */ - -#if !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) -static /*@observer@*/char *l64a (long value) -{ - static char buf[8]; - char *s = buf; - int digit; - int i; - - if (value < 0) { - errno = EINVAL; - return(NULL); - } - - for (i = 0; value != 0 && i < 6; i++) { - digit = value & 0x3f; - - if (digit < 2) { - *s = digit + '.'; - } else if (digit < 12) { - *s = digit + '0' - 2; - } else if (digit < 38) { - *s = digit + 'A' - 12; - } else { - *s = digit + 'a' - 38; - } - - value >>= 6; - s++; - } - - *s = '\0'; - - return buf; -} -#endif /* !USE_XCRYPT_GENSALT && !defined(HAVE_L64A) */ - -/* Read sizeof (long) random bytes from /dev/urandom. */ -static long read_random_bytes (void) -{ - long randval = 0; - -#ifdef HAVE_ARC4RANDOM_BUF - /* arc4random_buf, if it exists, can never fail. */ - arc4random_buf (&randval, sizeof (randval)); - goto end; -#endif - -#ifdef HAVE_GETENTROPY - /* getentropy may exist but lack kernel support. */ - if (getentropy (&randval, sizeof (randval)) == 0) { - goto end; - } -#endif - -#ifdef HAVE_GETRANDOM - /* Likewise getrandom. */ - if ((size_t) getrandom (&randval, sizeof (randval), 0) == sizeof (randval)) { - goto end; - } -#endif - - /* Use /dev/urandom as a last resort. */ - FILE *f = fopen ("/dev/urandom", "r"); - if (NULL == f) { - goto fail; - } - - if (fread (&randval, sizeof (randval), 1, f) != 1) { - fclose(f); - goto fail; - } - - fclose(f); - goto end; - -fail: - fprintf (log_get_logfd(), - _("Unable to obtain random bytes.\n")); - exit (1); - -end: - return randval; -} - -#if defined(USE_SHA_CRYPT) || defined(USE_BCRYPT) -/* - * Return a random number between min and max (both included). - * - * It favors slightly the higher numbers. - */ -static long shadow_random (long min, long max) -{ - double drand; - long ret; - - drand = (double) (read_random_bytes () & RAND_MAX) / (double) RAND_MAX; - drand *= (double) (max - min + 1); - /* On systems were this is not random() range is lower, we favor - * higher numbers of salt. */ - ret = (long) (max + 1 - drand); - /* And we catch limits, and use the highest number */ - if ((ret < min) || (ret > max)) { - ret = max; - } - return ret; -} -#endif /* USE_SHA_CRYPT || USE_BCRYPT */ - -#ifdef USE_SHA_CRYPT -/* Return the the rounds number for the SHA crypt methods. */ -static /*@observer@*/unsigned long SHA_get_salt_rounds (/*@null@*/const int *prefered_rounds) -{ - unsigned long rounds; - - if (NULL == prefered_rounds) { - long min_rounds = getdef_long ("SHA_CRYPT_MIN_ROUNDS", -1); - long max_rounds = getdef_long ("SHA_CRYPT_MAX_ROUNDS", -1); - - if ((-1 == min_rounds) && (-1 == max_rounds)) { - rounds = SHA_ROUNDS_DEFAULT; - } - else { - if (-1 == min_rounds) { - min_rounds = max_rounds; - } - - if (-1 == max_rounds) { - max_rounds = min_rounds; - } - - if (min_rounds > max_rounds) { - max_rounds = min_rounds; - } - - rounds = (unsigned long) shadow_random (min_rounds, max_rounds); - } - } else if (0 == *prefered_rounds) { - rounds = SHA_ROUNDS_DEFAULT; - } else { - rounds = (unsigned long) *prefered_rounds; - } - - /* Sanity checks. The libc should also check this, but this - * protects against a rounds_prefix overflow. */ - if (rounds < SHA_ROUNDS_MIN) { - rounds = SHA_ROUNDS_MIN; - } - - if (rounds > SHA_ROUNDS_MAX) { - rounds = SHA_ROUNDS_MAX; - } - - return rounds; -} - -/* - * Fill a salt prefix specifying the rounds number for the SHA crypt methods - * to a buffer. - */ -static /*@observer@*/void SHA_salt_rounds_to_buf (char *buf, unsigned long rounds) -{ - const size_t buf_begin = strlen (buf); - - /* Nothing to do here if SHA_ROUNDS_DEFAULT is used. */ - if (rounds == SHA_ROUNDS_DEFAULT) { - return; - } - - /* - * Check if the result buffer is long enough. - * We are going to write a maximum of 17 bytes, - * plus one byte for the terminator. - * rounds=XXXXXXXXX$ - * 00000000011111111 - * 12345678901234567 - */ - assert (GENSALT_SETTING_SIZE > buf_begin + 17); - - (void) snprintf (buf + buf_begin, 18, "rounds=%lu$", rounds); -} -#endif /* USE_SHA_CRYPT */ - -#ifdef USE_BCRYPT -/* Return the the rounds number for the BCRYPT method. */ -static /*@observer@*/unsigned long BCRYPT_get_salt_rounds (/*@null@*/const int *prefered_rounds) -{ - unsigned long rounds; - - if (NULL == prefered_rounds) { - long min_rounds = getdef_long ("BCRYPT_MIN_ROUNDS", -1); - long max_rounds = getdef_long ("BCRYPT_MAX_ROUNDS", -1); - - if ((-1 == min_rounds) && (-1 == max_rounds)) { - rounds = B_ROUNDS_DEFAULT; - } else { - if (-1 == min_rounds) { - min_rounds = max_rounds; - } - - if (-1 == max_rounds) { - max_rounds = min_rounds; - } - - if (min_rounds > max_rounds) { - max_rounds = min_rounds; - } - - rounds = (unsigned long) shadow_random (min_rounds, max_rounds); - } - } else if (0 == *prefered_rounds) { - rounds = B_ROUNDS_DEFAULT; - } else { - rounds = (unsigned long) *prefered_rounds; - } - - /* Sanity checks. */ - if (rounds < B_ROUNDS_MIN) { - rounds = B_ROUNDS_MIN; - } - -#if USE_XCRYPT_GENSALT - if (rounds > B_ROUNDS_MAX) { - rounds = B_ROUNDS_MAX; - } -#else /* USE_XCRYPT_GENSALT */ - /* - * Use 19 as an upper bound for now, - * because musl doesn't allow rounds >= 20. - * If musl ever supports > 20 rounds, - * rounds should be set to B_ROUNDS_MAX. - */ - if (rounds > 19) { - rounds = 19; - } -#endif /* USE_XCRYPT_GENSALT */ - - return rounds; -} - -/* - * Fill a salt prefix specifying the rounds number for the BCRYPT method - * to a buffer. - */ -static /*@observer@*/void BCRYPT_salt_rounds_to_buf (char *buf, unsigned long rounds) -{ - const size_t buf_begin = strlen (buf); - - /* - * Check if the result buffer is long enough. - * We are going to write three bytes, - * plus one byte for the terminator. - * XX$ - * 000 - * 123 - */ - assert (GENSALT_SETTING_SIZE > buf_begin + 3); - - (void) snprintf (buf + buf_begin, 4, "%2.2lu$", rounds); -} -#endif /* USE_BCRYPT */ - -#ifdef USE_YESCRYPT -/* Return the the cost number for the YESCRYPT method. */ -static /*@observer@*/unsigned long YESCRYPT_get_salt_cost (/*@null@*/const int *prefered_cost) -{ - unsigned long cost; - - if (NULL == prefered_cost) { - cost = getdef_num ("YESCRYPT_COST_FACTOR", Y_COST_DEFAULT); - } else if (0 == *prefered_cost) { - cost = Y_COST_DEFAULT; - } else { - cost = (unsigned long) *prefered_cost; - } - - /* Sanity checks. */ - if (cost < Y_COST_MIN) { - cost = Y_COST_MIN; - } - - if (cost > Y_COST_MAX) { - cost = Y_COST_MAX; - } - - return cost; -} - -/* - * Fill a salt prefix specifying the cost for the YESCRYPT method - * to a buffer. - */ -static /*@observer@*/void YESCRYPT_salt_cost_to_buf (char *buf, unsigned long cost) -{ - const size_t buf_begin = strlen (buf); - - /* - * Check if the result buffer is long enough. - * We are going to write four bytes, - * plus one byte for the terminator. - * jXX$ - * 0000 - * 1234 - */ - assert (GENSALT_SETTING_SIZE > buf_begin + 4); - - buf[buf_begin + 0] = 'j'; - if (cost < 3) { - buf[buf_begin + 1] = 0x36 + cost; - } else if (cost < 6) { - buf[buf_begin + 1] = 0x34 + cost; - } else { - buf[buf_begin + 1] = 0x3b + cost; - } - buf[buf_begin + 2] = cost >= 3 ? 'T' : '5'; - buf[buf_begin + 3] = '$'; - buf[buf_begin + 4] = '\0'; -} -#endif /* USE_YESCRYPT */ - -#if !USE_XCRYPT_GENSALT -static /*@observer@*/const char *gensalt (size_t salt_size) -{ - static char salt[MAX_SALT_SIZE + 6]; - - memset (salt, '\0', MAX_SALT_SIZE + 6); - - assert (salt_size >= MIN_SALT_SIZE && - salt_size <= MAX_SALT_SIZE); - strcat (salt, l64a (read_random_bytes ())); - do { - strcat (salt, l64a (read_random_bytes ())); - } while (strlen (salt) < salt_size); - - salt[salt_size] = '\0'; - - return salt; -} -#endif /* !USE_XCRYPT_GENSALT */ - -/* - * Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB - * in /etc/login.defs is "yes", the salt string will be prefixed by "$1$" - * (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible - * version of crypt() instead of the standard one. - * Other methods can be set with ENCRYPT_METHOD - * - * The method can be forced with the meth parameter. - * If NULL, the method will be defined according to the ENCRYPT_METHOD - * variable, and if not set according to the MD5_CRYPT_ENAB variable, - * which can both be set inside the login.defs file. - * - * If meth is specified, an additional parameter can be provided. - * * For the SHA256 and SHA512 method, this specifies the number of rounds - * (if not NULL). - * * For the YESCRYPT method, this specifies the cost factor (if not NULL). - */ -/*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg) -{ - static char result[GENSALT_SETTING_SIZE]; - size_t salt_len = MAX_SALT_SIZE; - const char *method; - unsigned long rounds = 0; - - memset (result, '\0', GENSALT_SETTING_SIZE); - - if (NULL != meth) - method = meth; - else { - method = getdef_str ("ENCRYPT_METHOD"); - if (NULL == method) { - method = getdef_bool ("MD5_CRYPT_ENAB") ? "MD5" : "DES"; - } - } - - if (0 == strcmp (method, "MD5")) { - MAGNUM(result, '1'); - salt_len = MD5_CRYPT_SALT_SIZE; - rounds = 0; -#ifdef USE_BCRYPT - } else if (0 == strcmp (method, "BCRYPT")) { - BCRYPTMAGNUM(result); - salt_len = BCRYPT_SALT_SIZE; - rounds = BCRYPT_get_salt_rounds ((int *) arg); - BCRYPT_salt_rounds_to_buf (result, rounds); -#endif /* USE_BCRYPT */ -#ifdef USE_YESCRYPT - } else if (0 == strcmp (method, "YESCRYPT")) { - MAGNUM(result, 'y'); - salt_len = YESCRYPT_SALT_SIZE; - rounds = YESCRYPT_get_salt_cost ((int *) arg); - YESCRYPT_salt_cost_to_buf (result, rounds); -#endif /* USE_YESCRYPT */ -#ifdef USE_SHA_CRYPT - } else if (0 == strcmp (method, "SHA256")) { - MAGNUM(result, '5'); - salt_len = SHA_CRYPT_SALT_SIZE; - rounds = SHA_get_salt_rounds ((int *) arg); - SHA_salt_rounds_to_buf (result, rounds); - } else if (0 == strcmp (method, "SHA512")) { - MAGNUM(result, '6'); - salt_len = SHA_CRYPT_SALT_SIZE; - rounds = SHA_get_salt_rounds ((int *) arg); - SHA_salt_rounds_to_buf (result, rounds); -#endif /* USE_SHA_CRYPT */ - } else if (0 != strcmp (method, "DES")) { - fprintf (log_get_logfd(), - _("Invalid ENCRYPT_METHOD value: '%s'.\n" - "Defaulting to DES.\n"), - method); - salt_len = MAX_SALT_SIZE; - rounds = 0; - memset (result, '\0', GENSALT_SETTING_SIZE); - } - -#if USE_XCRYPT_GENSALT - /* - * Prepare DES setting for crypt_gensalt(), if result - * has not been filled with anything previously. - */ - if ('\0' == result[0]) { - /* Avoid -Wunused-but-set-variable. */ - salt_len = GENSALT_SETTING_SIZE - 1; - rounds = 0; - memset (result, '.', salt_len); - result[salt_len] = '\0'; - } - - char *retval = crypt_gensalt (result, rounds, NULL, 0); - - /* Should not happen, but... */ - if (NULL == retval) { - fprintf (log_get_logfd(), - _("Unable to generate a salt from setting " - "\"%s\", check your settings in " - "ENCRYPT_METHOD and the corresponding " - "configuration for your selected hash " - "method.\n"), result); - - exit (1); - } - - return retval; -#else /* USE_XCRYPT_GENSALT */ - /* Check if the result buffer is long enough. */ - assert (GENSALT_SETTING_SIZE > strlen (result) + salt_len); - - /* Concatenate a pseudo random salt. */ - strncat (result, gensalt (salt_len), - GENSALT_SETTING_SIZE - strlen (result) - 1); - - return result; -#endif /* USE_XCRYPT_GENSALT */ -} diff --git a/libmisc/setugid.c b/libmisc/setugid.c deleted file mode 100644 index 6dbe38e..0000000 --- a/libmisc/setugid.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Separated from setup.c. --marekm - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include <grp.h> -#include <errno.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> -#include "getdef.h" - -/* - * setup_groups - set the group credentials - * set the group ID to the value from the password file entry - * set the supplementary group IDs - * - * In case of PAM enabled configurations, this shall be called before - * pam_setcred. - * - * Returns 0 on success, or -1 on failure. - */ -int setup_groups (const struct passwd *info) -{ - /* - * Set the real group ID to the primary group ID in the password - * file. - */ - if (setgid (info->pw_gid) == -1) { - int err = errno; - perror ("setgid"); - SYSLOG ((LOG_ERR, "bad group ID `%d' for user `%s': %s\n", - info->pw_gid, info->pw_name, strerror (err))); - closelog (); - return -1; - } -#ifdef HAVE_INITGROUPS - /* - * For systems which support multiple concurrent groups, go get - * the group set from the /etc/group file. - */ - if (initgroups (info->pw_name, info->pw_gid) == -1) { - int err = errno; - perror ("initgroups"); - SYSLOG ((LOG_ERR, "initgroups failed for user `%s': %s\n", - info->pw_name, strerror (err))); - closelog (); - return -1; - } -#endif - return 0; -} - -/* - * change_uid - Set the real UID - * - * Returns 0 on success, or -1 on failure. - */ -int change_uid (const struct passwd *info) -{ - /* - * Set the real UID to the UID value in the password file. - */ - if (setuid (info->pw_uid) != 0) { - int err = errno; - perror ("setuid"); - SYSLOG ((LOG_ERR, "bad user ID `%d' for user `%s': %s\n", - (int) info->pw_uid, info->pw_name, strerror (err))); - closelog (); - return -1; - } - return 0; -} - -/* - * setup_uid_gid() performs the following steps - - * - * set the group ID to the value from the password file entry - * set the supplementary group IDs - * optionally call specified function which may add more groups - * set the user ID to the value from the password file entry - * - * Returns 0 on success, or -1 on failure. - */ - -#if defined (HAVE_INITGROUPS) && ! (defined USE_PAM) -int setup_uid_gid (const struct passwd *info, bool is_console) -#else -int setup_uid_gid (const struct passwd *info) -#endif -{ - if (setup_groups (info) < 0) { - return -1; - } - -#if defined (HAVE_INITGROUPS) && ! defined (USE_PAM) - if (is_console) { - const char *cp = getdef_str ("CONSOLE_GROUPS"); - - if ((NULL != cp) && (add_groups (cp) != 0)) { - perror ("Warning: add_groups"); - } - } -#endif /* HAVE_INITGROUPS && !USE_PAM*/ - - if (change_uid (info) < 0) { - return -1; - } - - return 0; -} - diff --git a/libmisc/setupenv.c b/libmisc/setupenv.c deleted file mode 100644 index 5d7aefa..0000000 --- a/libmisc/setupenv.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Separated from setup.c. --marekm - */ - -#include <config.h> - -#ident "$Id$" - -#include <assert.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <ctype.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> -#include "getdef.h" -#include "shadowlog.h" - -#ifndef USE_PAM -static void -addenv_path (const char *varname, const char *dirname, const char *filename) -{ - char *buf; - size_t len = strlen (dirname) + strlen (filename) + 2; - int wlen; - - buf = xmalloc (len); - wlen = snprintf (buf, len, "%s/%s", dirname, filename); - assert (wlen == (int) len - 1); - - addenv (varname, buf); - free (buf); -} - -static void read_env_file (const char *filename) -{ - FILE *fp; - char buf[1024]; - char *cp, *name, *val; - - fp = fopen (filename, "r"); - if (NULL == fp) { - return; - } - while (fgets (buf, (int)(sizeof buf), fp) == buf) { - cp = strrchr (buf, '\n'); - if (NULL == cp) { - break; - } - *cp = '\0'; - - cp = buf; - /* ignore whitespace and comments */ - while (('\0' != *cp) && isspace (*cp)) { - cp++; - } - if (('\0' == *cp) || ('#' == *cp)) { - continue; - } - /* - * ignore lines which don't follow the name=value format - * (for example, the "export NAME" shell commands) - */ - name = cp; - while (('\0' != *cp) && !isspace (*cp) && ('=' != *cp)) { - cp++; - } - if ('=' != *cp) { - continue; - } - /* NUL-terminate the name */ - *cp = '\0'; - cp++; - val = cp; -#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */ -/* - (state, char_type) -> (state, action) - - state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped - char_type: normal, white, backslash, single, double - action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX -*/ - no_quote: - if (*cp == '\\') { - /* remove the backslash */ - remove_char (cp); - /* skip over the next character */ - if (*cp) - cp++; - goto no_quote; - } else if (*cp == '\'') { - /* remove the quote */ - remove_char (cp); - /* now within single quotes */ - goto s_quote; - } else if (*cp == '"') { - /* remove the quote */ - remove_char (cp); - /* now within double quotes */ - goto d_quote; - } else if (*cp == '\0') { - /* end of string */ - goto finished; - } else if (isspace (*cp)) { - /* unescaped whitespace - end of string */ - *cp = '\0'; - goto finished; - } else { - cp++; - goto no_quote; - } - s_quote: - if (*cp == '\'') { - /* remove the quote */ - remove_char (cp); - /* unquoted again */ - goto no_quote; - } else if (*cp == '\0') { - /* end of string */ - goto finished; - } else { - /* preserve everything within single quotes */ - cp++; - goto s_quote; - } - d_quote: - if (*cp == '\"') { - /* remove the quote */ - remove_char (cp); - /* unquoted again */ - goto no_quote; - } else if (*cp == '\\') { - cp++; - /* if backslash followed by double quote, remove backslash - else skip over the backslash and following char */ - if (*cp == '"') - remove_char (cp - 1); - else if (*cp) - cp++; - goto d_quote; - } - else if (*cp == '\0') { - /* end of string */ - goto finished; - } else { - /* preserve everything within double quotes */ - goto d_quote; - } - finished: -#endif /* 0 */ - /* - * XXX - should handle quotes, backslash escapes, etc. - * like the shell does. - */ - addenv (name, val); - } - (void) fclose (fp); -} -#endif /* USE_PAM */ - - -/* - * change to the user's home directory - * set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental - * variables. - */ - -void setup_env (struct passwd *info) -{ -#ifndef USE_PAM - const char *envf; -#endif - const char *cp; - - /* - * Change the current working directory to be the home directory - * of the user. It is a fatal error for this process to be unable - * to change to that directory. There is no "default" home - * directory. - * - * We no longer do it as root - should work better on NFS-mounted - * home directories. Some systems default to HOME=/, so we make - * this a configurable option. --marekm - */ - - if (chdir (info->pw_dir) == -1) { - static char temp_pw_dir[] = "/"; - - if (!getdef_bool ("DEFAULT_HOME") || chdir ("/") == -1) { - fprintf (log_get_logfd(), _("Unable to cd to '%s'\n"), - info->pw_dir); - SYSLOG ((LOG_WARN, - "unable to cd to `%s' for user `%s'\n", - info->pw_dir, info->pw_name)); - closelog (); - exit (EXIT_FAILURE); - } - (void) puts (_("No directory, logging in with HOME=/")); - free (info->pw_dir); - info->pw_dir = xstrdup (temp_pw_dir); - } - - /* - * Create the HOME environmental variable and export it. - */ - - addenv ("HOME", info->pw_dir); - - /* - * Create the SHELL environmental variable and export it. - */ - - if ((NULL == info->pw_shell) || ('\0' == *info->pw_shell)) { - static char temp_pw_shell[] = SHELL; - - free (info->pw_shell); - info->pw_shell = xstrdup (temp_pw_shell); - } - - addenv ("SHELL", info->pw_shell); - - /* - * Export the user name. For BSD derived systems, it's "USER", for - * all others it's "LOGNAME". We set both of them. - */ - - addenv ("USER", info->pw_name); - addenv ("LOGNAME", info->pw_name); - - /* - * Create the PATH environmental variable and export it. - */ - - cp = getdef_str ((info->pw_uid == 0) ? "ENV_SUPATH" : "ENV_PATH"); - - if (NULL == cp) { - /* not specified, use a minimal default */ - addenv ((info->pw_uid == 0) ? "PATH=/sbin:/bin:/usr/sbin:/usr/bin" : "PATH=/bin:/usr/bin", NULL); - } else if (strchr (cp, '=')) { - /* specified as name=value (PATH=...) */ - addenv (cp, NULL); - } else { - /* only value specified without "PATH=" */ - addenv ("PATH", cp); - } - -#ifndef USE_PAM - /* - * Create the MAIL environmental variable and export it. login.defs - * knows the prefix. - */ - - if (getdef_bool ("MAIL_CHECK_ENAB")) { - cp = getdef_str ("MAIL_DIR"); - if (NULL != cp) { - addenv_path ("MAIL", cp, info->pw_name); - } else { - cp = getdef_str ("MAIL_FILE"); - if (NULL != cp) { - addenv_path ("MAIL", info->pw_dir, cp); - } else { -#if defined(MAIL_SPOOL_FILE) - addenv_path ("MAIL", info->pw_dir, MAIL_SPOOL_FILE); -#elif defined(MAIL_SPOOL_DIR) - addenv_path ("MAIL", MAIL_SPOOL_DIR, info->pw_name); -#endif - } - } - } - - /* - * Read environment from optional config file. --marekm - */ - envf = getdef_str ("ENVIRON_FILE"); - if (NULL != envf) { - read_env_file (envf); - } -#endif /* !USE_PAM */ -} - diff --git a/libmisc/shell.c b/libmisc/shell.c deleted file mode 100644 index 7c67500..0000000 --- a/libmisc/shell.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1991, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2009 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include <errno.h> -#include "prototypes.h" -#include "defines.h" -extern char **newenvp; -extern size_t newenvc; - -/* - * shell - execute the named program - * - * shell begins by trying to figure out what argv[0] is going to - * be for the named process. The user may pass in that argument, - * or it will be the last pathname component of the file with a - * '-' prepended. - * Then, it executes the named file. - */ - -int shell (const char *file, /*@null@*/const char *arg, char *const envp[]) -{ - char arg0[1024]; - int err; - - if (file == (char *) 0) { - errno = EINVAL; - return errno; - } - - /* - * The argv[0]'th entry is usually the path name, but - * for various reasons the invoker may want to override - * that. So, we determine the 0'th entry only if they - * don't want to tell us what it is themselves. - */ - if (arg == (char *) 0) { - (void) snprintf (arg0, sizeof arg0, "-%s", Basename (file)); - arg0[sizeof arg0 - 1] = '\0'; - arg = arg0; - } - - /* - * First we try the direct approach. The system should be - * able to figure out what we are up to without too much - * grief. - */ - (void) execle (file, arg, (char *) 0, envp); - err = errno; - - if (access (file, R_OK|X_OK) == 0) { - /* - * Assume this is a shell script (with no shebang). - * Interpret it with /bin/sh - */ - (void) execle (SHELL, "sh", "-", file, (char *)0, envp); - err = errno; - } - - /* - * Obviously something is really wrong - I can't figure out - * how to execute this stupid shell, so I might as well give - * up in disgust ... - */ - (void) snprintf (arg0, sizeof arg0, _("Cannot execute %s"), file); - errno = err; - perror (arg0); - return err; -} - diff --git a/libmisc/strtoday.c b/libmisc/strtoday.c deleted file mode 100644 index d321873..0000000 --- a/libmisc/strtoday.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#if !defined(__GLIBC__) -#define _XOPEN_SOURCE 500 -#endif - -#include <config.h> - -#include <ctype.h> - -#ident "$Id$" - -#include "defines.h" -#include "prototypes.h" - -#ifndef USE_GETDATE -#define USE_GETDATE 1 -#endif - -#if USE_GETDATE -#include "getdate.h" -/* - * strtoday() now uses get_date() (borrowed from GNU shellutils) - * which can handle many date formats, for example: - * 1970-09-17 # ISO 8601. - * 70-9-17 # This century assumed by default. - * 70-09-17 # Leading zeros are ignored. - * 9/17/72 # Common U.S. writing. - * 24 September 1972 - * 24 Sept 72 # September has a special abbreviation. - * 24 Sep 72 # Three-letter abbreviations always allowed. - * Sep 24, 1972 - * 24-sep-72 - * 24sep72 - */ -long strtoday (const char *str) -{ - time_t t; - bool isnum = true; - const char *s = str; - - /* - * get_date() interprets an empty string as the current date, - * which is not what we expect, unless you're a BOFH :-). - * (useradd sets sp_expire = current date for new lusers) - */ - if ((NULL == str) || ('\0' == *str)) { - return -1; - } - - /* If a numerical value is provided, this is already a number of - * days since EPOCH. - */ - if ('-' == *s) { - s++; - } - while (' ' == *s) { - s++; - } - while (isnum && ('\0' != *s)) { - if (!isdigit (*s)) { - isnum = false; - } - s++; - } - if (isnum) { - long retdate; - if (getlong (str, &retdate) == 0) { - return -2; - } - return retdate; - } - - t = get_date (str, NULL); - if ((time_t) - 1 == t) { - return -2; - } - /* convert seconds to days since 1970-01-01 */ - return (long) (t + DAY / 2) / DAY; -} - -#else /* !USE_GETDATE */ -/* - * Old code, just in case get_date() doesn't work as expected... - */ -#include <stdio.h> -#ifdef HAVE_STRPTIME -/* - * for now we allow just one format, but we can define more later - * (we try them all until one succeeds). --marekm - */ -static const char *const date_formats[] = { - "%Y-%m-%d", - (char *) 0 -}; -#else -/* - * days and juldays are used to compute the number of days in the - * current month, and the cumulative number of days in the preceding - * months. they are declared so that january is 1, not 0. - */ -static const short days[13] = { 0, - 31, 28, 31, 30, 31, 30, /* JAN - JUN */ - 31, 31, 30, 31, 30, 31 -}; /* JUL - DEC */ - -static const short juldays[13] = { 0, - 0, 31, 59, 90, 120, 151, /* JAN - JUN */ - 181, 212, 243, 273, 304, 334 -}; /* JUL - DEC */ -#endif - -/* - * strtoday - compute the number of days since 1970. - * - * the total number of days prior to the current date is - * computed. january 1, 1970 is used as the origin with - * it having a day number of 0. - */ - -long strtoday (const char *str) -{ -#ifdef HAVE_STRPTIME - struct tm tp; - const char *const *fmt; - char *cp; - time_t result; - - memzero (&tp, sizeof tp); - for (fmt = date_formats; *fmt; fmt++) { - cp = strptime ((char *) str, *fmt, &tp); - if ((NULL == cp) || ('\0' != *cp)) { - continue; - } - - result = mktime (&tp); - if ((time_t) - 1 == result) { - continue; - } - - return (long) (result / DAY); /* success */ - } - return -1; -#else - char slop[2]; - int month; - int day; - int year; - long total; - - /* - * start by separating the month, day and year. the order - * is compiled in ... - */ - - if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3) { - return -1; - } - - /* - * the month, day of the month, and year are checked for - * correctness and the year adjusted so it falls between - * 1970 and 2069. - */ - - if ((month < 1) || (month > 12)) { - return -1; - } - - if (day < 1) { - return -1; - } - - if ( ((2 != month) || ((year % 4) != 0)) - && (day > days[month])) { - return -1; - } else if ((month == 2) && ((year % 4) == 0) && (day > 29)) { - return -1; - } - - if (year < 0) { - return -1; - } else if (year <= 69) { - year += 2000; - } else if (year <= 99) { - year += 1900; - } - - /* - * On systems with 32-bit signed time_t, time wraps around in 2038 - * - for now we just limit the year to 2037 (instead of 2069). - * This limit can be removed once no one is using 32-bit systems - * anymore :-). --marekm - */ - if ((year < 1970) || (year > 2037)) { - return -1; - } - - /* - * the total number of days is the total number of days in all - * the whole years, plus the number of leap days, plus the - * number of days in the whole months preceding, plus the number - * of days so far in the month. - */ - - total = (long) ((year - 1970) * 365L) + (((year + 1) - 1970) / 4); - total += (long) juldays[month] + (month > 2 && (year % 4) == 0 ? 1 : 0); - total += (long) day - 1; - - return total; -#endif /* HAVE_STRPTIME */ -} -#endif /* !USE_GETDATE */ diff --git a/libmisc/sub.c b/libmisc/sub.c deleted file mode 100644 index d30c4c7..0000000 --- a/libmisc/sub.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1991, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <pwd.h> -#include <stdio.h> -#include <sys/types.h> -#include "prototypes.h" -#include "defines.h" -#define BAD_SUBROOT2 "invalid root `%s' for user `%s'\n" -#define NO_SUBROOT2 "no subsystem root `%s' for user `%s'\n" -/* - * subsystem - change to subsystem root - * - * A subsystem login is indicated by the presence of a "*" as - * the first character of the login shell. The given home - * directory will be used as the root of a new filesystem which - * the user is actually logged into. - */ -void subsystem (const struct passwd *pw) -{ - /* - * The new root directory must begin with a "/" character. - */ - - if (pw->pw_dir[0] != '/') { - printf (_("Invalid root directory '%s'\n"), pw->pw_dir); - SYSLOG ((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name)); - closelog (); - exit (EXIT_FAILURE); - } - - /* - * The directory must be accessible and the current process - * must be able to change into it. - */ - - if ( (chdir (pw->pw_dir) != 0) - || (chroot (pw->pw_dir) != 0)) { - (void) printf (_("Can't change root directory to '%s'\n"), - pw->pw_dir); - SYSLOG ((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name)); - closelog (); - exit (EXIT_FAILURE); - } -} - diff --git a/libmisc/sulog.c b/libmisc/sulog.c deleted file mode 100644 index 3e95613..0000000 --- a/libmisc/sulog.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1992, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> -#include <time.h> -#include "prototypes.h" -#include "defines.h" -#include "getdef.h" - -/* - * sulog - log a SU command execution result - */ -void sulog (const char *tty, bool success, const char *oldname, const char *name) -{ - const char *sulog_file; - time_t now; - struct tm *tm; - FILE *fp; - mode_t oldmask; - gid_t oldgid = 0; - - if (success) { - SYSLOG ((LOG_INFO, - "Successful su for %s by %s",name,oldname)); - } else { - SYSLOG ((LOG_NOTICE, - "FAILED su for %s by %s",name,oldname)); - } - - sulog_file = getdef_str ("SULOG_FILE"); - if (NULL == sulog_file) { - return; - } - - oldgid = getgid (); - oldmask = umask (077); - /* Switch to group root to avoid creating the sulog file with - * the wrong group ownership. */ - if ((oldgid != 0) && (setgid (0) != 0)) { - SYSLOG ((LOG_INFO, - "su session not logged to %s", sulog_file)); - /* Continue, but do not switch back to oldgid later */ - oldgid = 0; - } - fp = fopen (sulog_file, "a+"); - (void) umask (oldmask); - if ((oldgid != 0) && (setgid (oldgid) != 0)) { - perror ("setgid"); - SYSLOG ((LOG_ERR, - "can't switch back to group `%d' in sulog", - oldgid)); - /* Do not return if the group permission were raised. */ - exit (EXIT_FAILURE); - } - if (fp == (FILE *) 0) { - return; /* can't open or create logfile */ - } - - (void) time (&now); - tm = localtime (&now); - - fprintf (fp, "SU %.02d/%.02d %.02d:%.02d %c %s %s-%s\n", - tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, - success ? '+' : '-', tty, oldname, name); - - (void) fflush (fp); - fsync (fileno (fp)); - fclose (fp); - /* TODO: log if failure */ -} - diff --git a/libmisc/ttytype.c b/libmisc/ttytype.c deleted file mode 100644 index f72d957..0000000 --- a/libmisc/ttytype.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include "prototypes.h" -#include "defines.h" -#include "getdef.h" -/* - * ttytype - set ttytype from port to terminal type mapping database - */ -void ttytype (const char *line) -{ - FILE *fp; - char buf[BUFSIZ]; - const char *typefile; - char *cp; - char type[1024] = ""; - char port[1024]; - - if (getenv ("TERM") != NULL) { - return; - } - typefile = getdef_str ("TTYTYPE_FILE"); - if (NULL == typefile) { - return; - } - if (access (typefile, F_OK) != 0) { - return; - } - - fp = fopen (typefile, "r"); - if (NULL == fp) { - perror (typefile); - return; - } - while (fgets (buf, (int) sizeof buf, fp) == buf) { - if (buf[0] == '#') { - continue; - } - - cp = strchr (buf, '\n'); - if (NULL != cp) { - *cp = '\0'; - } - - if ( (sscanf (buf, "%1023s %1023s", type, port) == 2) - && (strcmp (line, port) == 0)) { - break; - } - } - if ((feof (fp) == 0) && (ferror (fp) == 0) && (type[0] != '\0')) { - addenv ("TERM", type); - } - - (void) fclose (fp); -} - diff --git a/libmisc/tz.c b/libmisc/tz.c deleted file mode 100644 index 16d92ad..0000000 --- a/libmisc/tz.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1991 - 1994, Chip Rosenthal - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2010, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ifndef USE_PAM - -#ident "$Id$" - -#include <stdio.h> -#include <string.h> -#include "defines.h" -#include "prototypes.h" -#include "getdef.h" - -/* - * tz - return local timezone name - * - * tz() determines the name of the local timezone by reading the - * contents of the file named by ``fname''. - */ -/*@observer@*/const char *tz (const char *fname) -{ - FILE *fp = NULL; - static char tzbuf[BUFSIZ]; - const char *def_tz = "TZ=CST6CDT"; - - fp = fopen (fname, "r"); - if ( (NULL == fp) - || (fgets (tzbuf, (int) sizeof (tzbuf), fp) == NULL)) { - def_tz = getdef_str ("ENV_TZ"); - if ((NULL == def_tz) || ('/' == def_tz[0])) { - def_tz = "TZ=CST6CDT"; - } - - strcpy (tzbuf, def_tz); - } else { - tzbuf[strlen (tzbuf) - 1] = '\0'; - } - - if (NULL != fp) { - (void) fclose (fp); - } - - return tzbuf; -} -#else /* !USE_PAM */ -extern int errno; /* warning: ANSI C forbids an empty source file */ -#endif /* !USE_PAM */ - diff --git a/libmisc/ulimit.c b/libmisc/ulimit.c deleted file mode 100644 index e331d46..0000000 --- a/libmisc/ulimit.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1997, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#if HAVE_ULIMIT_H -#include <ulimit.h> -#ifndef UL_SETFSIZE -#ifdef UL_SFILLIM -#define UL_SETFSIZE UL_SFILLIM -#else -#define UL_SETFSIZE 2 -#endif -#endif -#elif HAVE_SYS_RESOURCE_H -#include <sys/time.h> /* for struct timeval on sunos4 */ -/* XXX - is the above ok or should it be <time.h> on ultrix? */ -#include <sys/resource.h> -#endif -#include "prototypes.h" - -int set_filesize_limit (int blocks) -{ - int ret = -1; -#if HAVE_ULIMIT_H - if (ulimit (UL_SETFSIZE, blocks) != -1) { - ret = 0; - } -#elif defined(RLIMIT_FSIZE) - struct rlimit rlimit_fsize; - - rlimit_fsize.rlim_cur = 512L * blocks; - rlimit_fsize.rlim_max = rlimit_fsize.rlim_cur; - ret = setrlimit (RLIMIT_FSIZE, &rlimit_fsize); -#endif - - return ret; -} - diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c deleted file mode 100644 index c03feb2..0000000 --- a/libmisc/user_busy.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1991 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 2000, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2000 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id: $" - -#include <assert.h> -#include <stdio.h> -#include <sys/types.h> -#include <dirent.h> -#include <fcntl.h> -#include <unistd.h> -#include "defines.h" -#include "prototypes.h" -#ifdef ENABLE_SUBIDS -#include "subordinateio.h" -#endif /* ENABLE_SUBIDS */ -#include "shadowlog.h" - -#ifdef __linux__ -static int check_status (const char *name, const char *sname, uid_t uid); -static int user_busy_processes (const char *name, uid_t uid); -#else /* !__linux__ */ -static int user_busy_utmp (const char *name); -#endif /* !__linux__ */ - -/* - * user_busy - check if an user if currently running processes - */ -int user_busy (const char *name, uid_t uid) -{ - /* There are no standard ways to get the list of processes. - * An option could be to run an external tool (ps). - */ -#ifdef __linux__ - /* On Linux, directly parse /proc */ - return user_busy_processes (name, uid); -#else /* !__linux__ */ - /* If we cannot rely on /proc, check is there is a record in utmp - * indicating that the user is still logged in */ - return user_busy_utmp (name); -#endif /* !__linux__ */ -} - -#ifndef __linux__ -static int user_busy_utmp (const char *name) -{ -#ifdef USE_UTMPX - struct utmpx *utent; - - setutxent (); - while ((utent = getutxent ()) != NULL) -#else /* !USE_UTMPX */ - struct utmp *utent; - - setutent (); - while ((utent = getutent ()) != NULL) -#endif /* !USE_UTMPX */ - { - if (utent->ut_type != USER_PROCESS) { - continue; - } - if (strncmp (utent->ut_user, name, sizeof utent->ut_user) != 0) { - continue; - } - if (kill (utent->ut_pid, 0) != 0) { - continue; - } - - fprintf (log_get_logfd(), - _("%s: user %s is currently logged in\n"), - log_get_progname(), name); - return 1; - } - - return 0; -} -#endif /* !__linux__ */ - -#ifdef __linux__ -#ifdef ENABLE_SUBIDS -#define in_parentuid_range(uid) ((uid) >= parentuid && (uid) < parentuid + range) -static int different_namespace (const char *sname) -{ - /* 41: /proc/xxxxxxxxxx/task/xxxxxxxxxx/ns/user + \0 */ - char path[41]; - char buf[512], buf2[512]; - ssize_t llen1, llen2; - - snprintf (path, 41, "/proc/%s/ns/user", sname); - - if ((llen1 = readlink (path, buf, sizeof(buf))) == -1) - return 0; - - if ((llen2 = readlink ("/proc/self/ns/user", buf2, sizeof(buf2))) == -1) - return 0; - - if (llen1 == llen2 && memcmp (buf, buf2, llen1) == 0) - return 0; /* same namespace */ - - return 1; -} -#endif /* ENABLE_SUBIDS */ - - -static int check_status (const char *name, const char *sname, uid_t uid) -{ - /* 40: /proc/xxxxxxxxxx/task/xxxxxxxxxx/status + \0 */ - char status[40]; - char line[1024]; - FILE *sfile; - - snprintf (status, 40, "/proc/%s/status", sname); - - sfile = fopen (status, "r"); - if (NULL == sfile) { - return 0; - } - while (fgets (line, sizeof (line), sfile) == line) { - if (strncmp (line, "Uid:\t", 5) == 0) { - unsigned long ruid, euid, suid; - - assert (uid == (unsigned long) uid); - (void) fclose (sfile); - if (sscanf (line, - "Uid:\t%lu\t%lu\t%lu\n", - &ruid, &euid, &suid) == 3) { - if ( (ruid == (unsigned long) uid) - || (euid == (unsigned long) uid) - || (suid == (unsigned long) uid) ) { - return 1; - } -#ifdef ENABLE_SUBIDS - if ( different_namespace (sname) - && ( have_sub_uids(name, ruid, 1) - || have_sub_uids(name, euid, 1) - || have_sub_uids(name, suid, 1)) - ) { - return 1; - } -#endif /* ENABLE_SUBIDS */ - } else { - /* Ignore errors. This is just a best effort. */ - } - return 0; - } - } - (void) fclose (sfile); - return 0; -} - -static int user_busy_processes (const char *name, uid_t uid) -{ - DIR *proc; - struct dirent *ent; - char *tmp_d_name; - pid_t pid; - DIR *task_dir; - /* 22: /proc/xxxxxxxxxx/task + \0 */ - char task_path[22]; - char root_path[22]; - struct stat sbroot; - struct stat sbroot_process; - -#ifdef ENABLE_SUBIDS - sub_uid_open (O_RDONLY); -#endif /* ENABLE_SUBIDS */ - - proc = opendir ("/proc"); - if (proc == NULL) { - perror ("opendir /proc"); -#ifdef ENABLE_SUBIDS - sub_uid_close(); -#endif - return 0; - } - if (stat ("/", &sbroot) != 0) { - perror ("stat (\"/\")"); - (void) closedir (proc); -#ifdef ENABLE_SUBIDS - sub_uid_close(); -#endif - return 0; - } - - while ((ent = readdir (proc)) != NULL) { - tmp_d_name = ent->d_name; - /* - * Ingo Molnar's patch introducing NPTL for 2.4 hides - * threads in the /proc directory by prepending a period. - * This patch is applied by default in some RedHat - * kernels. - */ - if ( (strcmp (tmp_d_name, ".") == 0) - || (strcmp (tmp_d_name, "..") == 0)) { - continue; - } - if (*tmp_d_name == '.') { - tmp_d_name++; - } - - /* Check if this is a valid PID */ - if (get_pid (tmp_d_name, &pid) == 0) { - continue; - } - - /* Check if the process is in our chroot */ - snprintf (root_path, 22, "/proc/%lu/root", (unsigned long) pid); - root_path[21] = '\0'; - if (stat (root_path, &sbroot_process) != 0) { - continue; - } - if ( (sbroot.st_dev != sbroot_process.st_dev) - || (sbroot.st_ino != sbroot_process.st_ino)) { - continue; - } - - if (check_status (name, tmp_d_name, uid) != 0) { - (void) closedir (proc); -#ifdef ENABLE_SUBIDS - sub_uid_close(); -#endif - fprintf (log_get_logfd(), - _("%s: user %s is currently used by process %d\n"), - log_get_progname(), name, pid); - return 1; - } - - snprintf (task_path, 22, "/proc/%lu/task", (unsigned long) pid); - task_path[21] = '\0'; - task_dir = opendir (task_path); - if (task_dir != NULL) { - while ((ent = readdir (task_dir)) != NULL) { - pid_t tid; - if (get_pid (ent->d_name, &tid) == 0) { - continue; - } - if (tid == pid) { - continue; - } - if (check_status (name, task_path+6, uid) != 0) { - (void) closedir (proc); - (void) closedir (task_dir); -#ifdef ENABLE_SUBIDS - sub_uid_close(); -#endif - fprintf (log_get_logfd(), - _("%s: user %s is currently used by process %d\n"), - log_get_progname(), name, pid); - return 1; - } - } - (void) closedir (task_dir); - } else { - /* Ignore errors. This is just a best effort */ - } - } - - (void) closedir (proc); -#ifdef ENABLE_SUBIDS - sub_uid_close(); -#endif /* ENABLE_SUBIDS */ - return 0; -} -#endif /* __linux__ */ - diff --git a/libmisc/utmp.c b/libmisc/utmp.c deleted file mode 100644 index 45b479f..0000000 --- a/libmisc/utmp.c +++ /dev/null @@ -1,474 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2001 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#include "defines.h" -#include "prototypes.h" - -#ifdef USE_UTMPX -#include <utmpx.h> -#else -#include <utmp.h> -#endif - -#include <assert.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netdb.h> -#include <stdio.h> - -#ident "$Id$" - - -/* - * is_my_tty -- determine if "tty" is the same TTY stdin is using - */ -static bool is_my_tty (const char *tty) -{ - /* full_tty shall be at least sizeof utmp.ut_line + 5 */ - char full_tty[200]; - /* tmptty shall be bigger than full_tty */ - static char tmptty[sizeof (full_tty)+1]; - - if ('/' != *tty) { - (void) snprintf (full_tty, sizeof full_tty, "/dev/%s", tty); - tty = &full_tty[0]; - } - - if ('\0' == tmptty[0]) { - const char *tname = ttyname (STDIN_FILENO); - if (NULL != tname) { - (void) strncpy (tmptty, tname, sizeof tmptty); - tmptty[sizeof (tmptty) - 1] = '\0'; - } - } - - if ('\0' == tmptty[0]) { - (void) puts (_("Unable to determine your tty name.")); - exit (EXIT_FAILURE); - } else if (strncmp (tty, tmptty, sizeof (tmptty)) != 0) { - return false; - } else { - return true; - } -} - -/* - * get_current_utmp - return the most probable utmp entry for the current - * session - * - * The utmp file is scanned for an entry with the same process ID. - * The line entered by the *getty / telnetd, etc. should also match - * the current terminal. - * - * When an entry is returned by get_current_utmp, and if the utmp - * structure has a ut_id field, this field should be used to update - * the entry information. - * - * Return NULL if no entries exist in utmp for the current process. - */ -#ifndef USE_UTMPX -/*@null@*/ /*@only@*/struct utmp *get_current_utmp (void) -{ - struct utmp *ut; - struct utmp *ret = NULL; - - setutent (); - - /* First, try to find a valid utmp entry for this process. */ - while ((ut = getutent ()) != NULL) { - if ( (ut->ut_pid == getpid ()) -#ifdef HAVE_STRUCT_UTMP_UT_ID - && ('\0' != ut->ut_id[0]) -#endif -#ifdef HAVE_STRUCT_UTMP_UT_TYPE - && ( (LOGIN_PROCESS == ut->ut_type) - || (USER_PROCESS == ut->ut_type)) -#endif - /* A process may have failed to close an entry - * Check if this entry refers to the current tty */ - && is_my_tty (ut->ut_line)) { - break; - } - } - - if (NULL != ut) { - ret = (struct utmp *) xmalloc (sizeof (*ret)); - memcpy (ret, ut, sizeof (*ret)); - } - - endutent (); - - return ret; -} -#else -/*@null@*/ /*@only*/struct utmpx *get_current_utmp(void) -{ - struct utmpx *ut; - struct utmpx *ret = NULL; - - setutxent (); - - /* Find the utmpx entry for this PID. */ - while ((ut = getutxent ()) != NULL) { - if ( (ut->ut_pid == getpid ()) - && ('\0' != ut->ut_id[0]) - && ( (LOGIN_PROCESS == ut->ut_type) - || (USER_PROCESS == ut->ut_type)) - && is_my_tty (ut->ut_line)) { - break; - } - } - - if (NULL != ut) { - ret = (struct utmpx *) xmalloc (sizeof (*ret)); - memcpy (ret, ut, sizeof (*ret)); - } - - endutxent (); - - return ret; -} -#endif - - -#ifndef USE_PAM -/* - * Some systems already have updwtmp() and possibly updwtmpx(). Others - * don't, so we re-implement these functions if necessary. - */ -#ifndef HAVE_UPDWTMP -static void updwtmp (const char *filename, const struct utmp *ut) -{ - int fd; - - fd = open (filename, O_APPEND | O_WRONLY, 0); - if (fd >= 0) { - write (fd, (const char *) ut, sizeof (*ut)); - close (fd); - } -} -#endif /* ! HAVE_UPDWTMP */ - -#ifdef USE_UTMPX -#ifndef HAVE_UPDWTMPX -static void updwtmpx (const char *filename, const struct utmpx *utx) -{ - int fd; - - fd = open (filename, O_APPEND | O_WRONLY, 0); - if (fd >= 0) { - write (fd, (const char *) utx, sizeof (*utx)); - close (fd); - } -} -#endif /* ! HAVE_UPDWTMPX */ -#endif /* ! USE_UTMPX */ -#endif /* ! USE_PAM */ - - -#ifndef USE_UTMPX -/* - * prepare_utmp - prepare an utmp entry so that it can be logged in a - * utmp/wtmp file. - * - * It accepts an utmp entry in input (ut) to return an entry with - * the right ut_id. This is typically an entry returned by - * get_current_utmp - * If ut is NULL, ut_id will be forged based on the line argument. - * - * The ut_host field of the input structure may also be kept, and is - * used to define the ut_addr/ut_addr_v6 fields. (if these fields - * exist) - * - * Other fields are discarded and filed with new values (if they - * exist). - * - * The returned structure shall be freed by the caller. - */ -/*@only@*/struct utmp *prepare_utmp (const char *name, - const char *line, - const char *host, - /*@null@*/const struct utmp *ut) -{ - struct timeval tv; - char *hostname = NULL; - struct utmp *utent; - - assert (NULL != name); - assert (NULL != line); - - - - if ( (NULL != host) - && ('\0' != host[0])) { - hostname = (char *) xmalloc (strlen (host) + 1); - strcpy (hostname, host); -#ifdef HAVE_STRUCT_UTMP_UT_HOST - } else if ( (NULL != ut) - && ('\0' != ut->ut_host[0])) { - hostname = (char *) xmalloc (sizeof (ut->ut_host) + 1); - strncpy (hostname, ut->ut_host, sizeof (ut->ut_host)); - hostname[sizeof (ut->ut_host)] = '\0'; -#endif /* HAVE_STRUCT_UTMP_UT_HOST */ - } - - if (strncmp(line, "/dev/", 5) == 0) { - line += 5; - } - - - utent = (struct utmp *) xmalloc (sizeof (*utent)); - memzero (utent, sizeof (*utent)); - - - -#ifdef HAVE_STRUCT_UTMP_UT_TYPE - utent->ut_type = USER_PROCESS; -#endif /* HAVE_STRUCT_UTMP_UT_TYPE */ - utent->ut_pid = getpid (); - strncpy (utent->ut_line, line, sizeof (utent->ut_line) - 1); -#ifdef HAVE_STRUCT_UTMP_UT_ID - if (NULL != ut) { - strncpy (utent->ut_id, ut->ut_id, sizeof (utent->ut_id)); - } else { - /* XXX - assumes /dev/tty?? */ - strncpy (utent->ut_id, line + 3, sizeof (utent->ut_id) - 1); - } -#endif /* HAVE_STRUCT_UTMP_UT_ID */ -#ifdef HAVE_STRUCT_UTMP_UT_NAME - strncpy (utent->ut_name, name, sizeof (utent->ut_name)); -#endif /* HAVE_STRUCT_UTMP_UT_NAME */ -#ifdef HAVE_STRUCT_UTMP_UT_USER - strncpy (utent->ut_user, name, sizeof (utent->ut_user) - 1); -#endif /* HAVE_STRUCT_UTMP_UT_USER */ - if (NULL != hostname) { - struct addrinfo *info = NULL; -#ifdef HAVE_STRUCT_UTMP_UT_HOST - strncpy (utent->ut_host, hostname, sizeof (utent->ut_host) - 1); -#endif /* HAVE_STRUCT_UTMP_UT_HOST */ -#ifdef HAVE_STRUCT_UTMP_UT_SYSLEN - utent->ut_syslen = MIN (strlen (hostname), - sizeof (utent->ut_host)); -#endif /* HAVE_STRUCT_UTMP_UT_SYSLEN */ -#if defined(HAVE_STRUCT_UTMP_UT_ADDR) || defined(HAVE_STRUCT_UTMP_UT_ADDR_V6) - if (getaddrinfo (hostname, NULL, NULL, &info) == 0) { - /* getaddrinfo might not be reliable. - * Just try to log what may be useful. - */ - if (info->ai_family == AF_INET) { - struct sockaddr_in *sa = - (struct sockaddr_in *) info->ai_addr; -#ifdef HAVE_STRUCT_UTMP_UT_ADDR - memcpy (&(utent->ut_addr), - &(sa->sin_addr), - MIN (sizeof (utent->ut_addr), - sizeof (sa->sin_addr))); -#endif /* HAVE_STRUCT_UTMP_UT_ADDR */ -#ifdef HAVE_STRUCT_UTMP_UT_ADDR_V6 - memcpy (utent->ut_addr_v6, - &(sa->sin_addr), - MIN (sizeof (utent->ut_addr_v6), - sizeof (sa->sin_addr))); - } else if (info->ai_family == AF_INET6) { - struct sockaddr_in6 *sa = - (struct sockaddr_in6 *) info->ai_addr; - memcpy (utent->ut_addr_v6, - &(sa->sin6_addr), - MIN (sizeof (utent->ut_addr_v6), - sizeof (sa->sin6_addr))); -#endif /* HAVE_STRUCT_UTMP_UT_ADDR_V6 */ - } - freeaddrinfo (info); - } -#endif /* HAVE_STRUCT_UTMP_UT_ADDR || HAVE_STRUCT_UTMP_UT_ADDR_V6 */ - free (hostname); - } - /* ut_exit is only for DEAD_PROCESS */ - utent->ut_session = getsid (0); - if (gettimeofday (&tv, NULL) == 0) { -#ifdef HAVE_STRUCT_UTMP_UT_TIME - utent->ut_time = tv.tv_sec; -#endif /* HAVE_STRUCT_UTMP_UT_TIME */ -#ifdef HAVE_STRUCT_UTMP_UT_XTIME - utent->ut_xtime = tv.tv_usec; -#endif /* HAVE_STRUCT_UTMP_UT_XTIME */ -#ifdef HAVE_STRUCT_UTMP_UT_TV - utent->ut_tv.tv_sec = tv.tv_sec; - utent->ut_tv.tv_usec = tv.tv_usec; -#endif /* HAVE_STRUCT_UTMP_UT_TV */ - } - - return utent; -} - -/* - * setutmp - Update an entry in utmp and log an entry in wtmp - * - * Return 1 on failure and 0 on success. - */ -int setutmp (struct utmp *ut) -{ - int err = 0; - - assert (NULL != ut); - - setutent (); - if (pututline (ut) == NULL) { - err = 1; - } - endutent (); - -#ifndef USE_PAM - /* This is done by pam_lastlog */ - updwtmp (_WTMP_FILE, ut); -#endif /* ! USE_PAM */ - - return err; -} - -#else -/* - * prepare_utmpx - the UTMPX version for prepare_utmp - */ -/*@only@*/struct utmpx *prepare_utmpx (const char *name, - const char *line, - const char *host, - /*@null@*/const struct utmpx *ut) -{ - struct timeval tv; - char *hostname = NULL; - struct utmpx *utxent; - - assert (NULL != name); - assert (NULL != line); - - - - if ( (NULL != host) - && ('\0' != host[0])) { - hostname = (char *) xmalloc (strlen (host) + 1); - strcpy (hostname, host); -#ifdef HAVE_STRUCT_UTMP_UT_HOST - } else if ( (NULL != ut) - && (NULL != ut->ut_host) - && ('\0' != ut->ut_host[0])) { - hostname = (char *) xmalloc (sizeof (ut->ut_host) + 1); - strncpy (hostname, ut->ut_host, sizeof (ut->ut_host)); - hostname[sizeof (ut->ut_host)] = '\0'; -#endif /* HAVE_STRUCT_UTMP_UT_TYPE */ - } - - if (strncmp(line, "/dev/", 5) == 0) { - line += 5; - } - - utxent = (struct utmpx *) xmalloc (sizeof (*utxent)); - memzero (utxent, sizeof (*utxent)); - - - - utxent->ut_type = USER_PROCESS; - utxent->ut_pid = getpid (); - strncpy (utxent->ut_line, line, sizeof (utxent->ut_line)); - /* existence of ut->ut_id is enforced by configure */ - if (NULL != ut) { - strncpy (utxent->ut_id, ut->ut_id, sizeof (utxent->ut_id)); - } else { - /* XXX - assumes /dev/tty?? */ - strncpy (utxent->ut_id, line + 3, sizeof (utxent->ut_id)); - } -#ifdef HAVE_STRUCT_UTMPX_UT_NAME - strncpy (utxent->ut_name, name, sizeof (utxent->ut_name)); -#endif /* HAVE_STRUCT_UTMPX_UT_NAME */ - strncpy (utxent->ut_user, name, sizeof (utxent->ut_user)); - if (NULL != hostname) { - struct addrinfo *info = NULL; -#ifdef HAVE_STRUCT_UTMPX_UT_HOST - strncpy (utxent->ut_host, hostname, sizeof (utxent->ut_host)); -#endif /* HAVE_STRUCT_UTMPX_UT_HOST */ -#ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN - utxent->ut_syslen = MIN (strlen (hostname), - sizeof (utxent->ut_host)); -#endif /* HAVE_STRUCT_UTMPX_UT_SYSLEN */ -#if defined(HAVE_STRUCT_UTMPX_UT_ADDR) || defined(HAVE_STRUCT_UTMPX_UT_ADDR_V6) - if (getaddrinfo (hostname, NULL, NULL, &info) == 0) { - /* getaddrinfo might not be reliable. - * Just try to log what may be useful. - */ - if (info->ai_family == AF_INET) { - struct sockaddr_in *sa = - (struct sockaddr_in *) info->ai_addr; -#ifdef HAVE_STRUCT_UTMPX_UT_ADDR - memcpy (&utxent->ut_addr, - &(sa->sin_addr), - MIN (sizeof (utxent->ut_addr), - sizeof (sa->sin_addr))); -#endif /* HAVE_STRUCT_UTMPX_UT_ADDR */ -#ifdef HAVE_STRUCT_UTMPX_UT_ADDR_V6 - memcpy (utxent->ut_addr_v6, - &(sa->sin_addr), - MIN (sizeof (utxent->ut_addr_v6), - sizeof (sa->sin_addr))); - } else if (info->ai_family == AF_INET6) { - struct sockaddr_in6 *sa = - (struct sockaddr_in6 *) info->ai_addr; - memcpy (utxent->ut_addr_v6, - &(sa->sin6_addr), - MIN (sizeof (utxent->ut_addr_v6), - sizeof (sa->sin6_addr))); -#endif /* HAVE_STRUCT_UTMPX_UT_ADDR_V6 */ - } - freeaddrinfo (info); - } -#endif /* HAVE_STRUCT_UTMPX_UT_ADDR || HAVE_STRUCT_UTMPX_UT_ADDR_V6 */ - free (hostname); - } - /* ut_exit is only for DEAD_PROCESS */ - utxent->ut_session = getsid (0); - if (gettimeofday (&tv, NULL) == 0) { -#ifdef HAVE_STRUCT_UTMPX_UT_TIME - utxent->ut_time = tv.tv_sec; -#endif /* HAVE_STRUCT_UTMPX_UT_TIME */ -#ifdef HAVE_STRUCT_UTMPX_UT_XTIME - utxent->ut_xtime = tv.tv_usec; -#endif /* HAVE_STRUCT_UTMPX_UT_XTIME */ - utxent->ut_tv.tv_sec = tv.tv_sec; - utxent->ut_tv.tv_usec = tv.tv_usec; - } - - return utxent; -} - -/* - * setutmpx - the UTMPX version for setutmp - */ -int setutmpx (struct utmpx *utx) -{ - int err = 0; - - assert (NULL != utx); - - setutxent (); - if (pututxline (utx) == NULL) { - err = 1; - } - endutxent (); - -#ifndef USE_PAM - /* This is done by pam_lastlog */ - updwtmpx (_WTMP_FILE "x", utx); -#endif /* ! USE_PAM */ - - return err; -} -#endif /* USE_UTMPX */ - diff --git a/libmisc/valid.c b/libmisc/valid.c deleted file mode 100644 index 326635f..0000000 --- a/libmisc/valid.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1989 - 1993, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1999, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2005, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <config.h> - -#ident "$Id$" - -#include <sys/types.h> -#include <stdio.h> -#include "prototypes.h" -#include "defines.h" -#include <pwd.h> -/* - * valid - compare encrypted passwords - * - * Valid() compares the DES encrypted password from the password file - * against the password which the user has entered after it has been - * encrypted using the same salt as the original. Entries which do - * not have a password file entry have a NULL pw_name field and this - * is used to indicate that a dummy salt must be used to encrypt the - * password anyway. - */ -bool valid (const char *password, const struct passwd *ent) -{ - const char *encrypted; - /*@observer@*/const char *salt; - - /* - * Start with blank or empty password entries. Always encrypt - * a password if no such user exists. Only if the ID exists and - * the password is really empty do you return quickly. This - * routine is meant to waste CPU time. - */ - - if ((NULL != ent->pw_name) && ('\0' == ent->pw_passwd[0])) { - if ('\0' == password[0]) { - return true; /* user entered nothing */ - } else { - return false; /* user entered something! */ - } - } - - /* - * If there is no entry then we need a salt to use. - */ - - if ((NULL == ent->pw_name) || ('\0' == ent->pw_passwd[0])) { - salt = "xx"; - } else { - salt = ent->pw_passwd; - } - - /* - * Now, perform the encryption using the salt from before on - * the users input. Since we always encrypt the string, it - * should be very difficult to determine if the user exists by - * looking at execution time. - */ - - encrypted = pw_encrypt (password, salt); - - /* - * One last time we must deal with there being no password file - * entry for the user. We use the pw_name == NULL idiom to - * cause non-existent users to not be validated. - */ - - if ( (NULL != ent->pw_name) - && (NULL != encrypted) - && (strcmp (encrypted, ent->pw_passwd) == 0)) { - return true; - } else { - return false; - } -} - diff --git a/libmisc/xgetXXbyYY.c b/libmisc/xgetXXbyYY.c deleted file mode 100644 index 6a3f969..0000000 --- a/libmisc/xgetXXbyYY.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * According to the Linux-PAM documentation: - * - * 4.1. Care about standard library calls - * - * In general, writers of authorization-granting applications should - * assume that each module is likely to call any or all 'libc' functions. - * For 'libc' functions that return pointers to static/dynamically - * allocated structures (ie. the library allocates the memory and the - * user is not expected to 'free()' it) any module call to this function - * is likely to corrupt a pointer previously obtained by the application. - * The application programmer should either re-call such a 'libc' - * function after a call to the Linux-PAM library, or copy the structure - * contents to some safe area of memory before passing control to the - * Linux-PAM library. - * - * Two important function classes that fall into this category are - * getpwnam(3) and syslog(3). - * - * This file provide wrapper to the getpwnam or getpwnam_r functions. - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> -#include "prototypes.h" -#include "shadowlog.h" - -#define XFUNCTION_NAME XPREFIX (FUNCTION_NAME) -#define XPREFIX(name) XPREFIX1 (name) -#define XPREFIX1(name) x##name -#define REENTRANT_NAME APPEND_R (FUNCTION_NAME) -#define APPEND_R(name) APPEND_R1 (name) -#define APPEND_R1(name) name##_r -#define STRINGIZE(name) STRINGIZE1 (name) -#define STRINGIZE1(name) #name - -/*@null@*/ /*@only@*/LOOKUP_TYPE *XFUNCTION_NAME (ARG_TYPE ARG_NAME) -{ -#if HAVE_FUNCTION_R - LOOKUP_TYPE *result=NULL; - char *buffer=NULL; - /* we have to start with something */ - size_t length = 0x100; - - result = malloc(sizeof(LOOKUP_TYPE)); - if (NULL == result) { - fprintf (log_get_logfd(), _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } - - while (true) { - int status; - LOOKUP_TYPE *resbuf = NULL; - buffer = (char *)realloc (buffer, length); - if (NULL == buffer) { - fprintf (log_get_logfd(), _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } - status = REENTRANT_NAME(ARG_NAME, result, buffer, - length, &resbuf); - if ((0 == status) && (resbuf == result)) { - /* Build a result structure that can be freed by - * the shadow *_free functions. */ - LOOKUP_TYPE *ret_result = DUP_FUNCTION(result); - free(buffer); - free(result); - return ret_result; - } - - if (ERANGE != status) { - free (buffer); - free (result); - return NULL; - } - - if (length <= ((size_t)-1 / 4)) { - length *= 4; - } else if (length == (size_t) -1) { - break; - } else { - length = (size_t) -1; - } - } - - free(buffer); - free(result); - return NULL; - -#else /* !HAVE_FUNCTION_R */ - - /* No reentrant function. - * Duplicate the structure to avoid other call to overwrite it. - * - * We should also restore the initial structure. But that would be - * overkill. - */ - LOOKUP_TYPE *result = FUNCTION_NAME(ARG_NAME); - - if (result) { - result = DUP_FUNCTION(result); - if (NULL == result) { - fprintf (log_get_logfd(), _("%s: out of memory\n"), - "x" STRINGIZE(FUNCTION_NAME)); - exit (13); - } - } - - return result; -#endif -} - diff --git a/libmisc/xgetgrgid.c b/libmisc/xgetgrgid.c deleted file mode 100644 index fe99929..0000000 --- a/libmisc/xgetgrgid.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * According to the Linux-PAM documentation: - * - * 4.1. Care about standard library calls - * - * In general, writers of authorization-granting applications should - * assume that each module is likely to call any or all 'libc' functions. - * For 'libc' functions that return pointers to static/dynamically - * allocated structures (ie. the library allocates the memory and the - * user is not expected to 'free()' it) any module call to this function - * is likely to corrupt a pointer previously obtained by the application. - * The application programmer should either re-call such a 'libc' - * function after a call to the Linux-PAM library, or copy the structure - * contents to some safe area of memory before passing control to the - * Linux-PAM library. - * - * Two important function classes that fall into this category are - * getpwnam(3) and syslog(3). - * - * This file provide wrapper to the getpwnam or getpwnam_r functions. - */ - -#include <config.h> - -#include "groupio.h" - -#define LOOKUP_TYPE struct group -#define FUNCTION_NAME getgrgid -#define ARG_TYPE gid_t -#define ARG_NAME gid -#define DUP_FUNCTION __gr_dup -#define HAVE_FUNCTION_R (defined HAVE_GETGRGID_R) - -#include "xgetXXbyYY.c" - diff --git a/libmisc/xgetgrnam.c b/libmisc/xgetgrnam.c deleted file mode 100644 index 66d6f93..0000000 --- a/libmisc/xgetgrnam.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * According to the Linux-PAM documentation: - * - * 4.1. Care about standard library calls - * - * In general, writers of authorization-granting applications should - * assume that each module is likely to call any or all 'libc' functions. - * For 'libc' functions that return pointers to static/dynamically - * allocated structures (ie. the library allocates the memory and the - * user is not expected to 'free()' it) any module call to this function - * is likely to corrupt a pointer previously obtained by the application. - * The application programmer should either re-call such a 'libc' - * function after a call to the Linux-PAM library, or copy the structure - * contents to some safe area of memory before passing control to the - * Linux-PAM library. - * - * Two important function classes that fall into this category are - * getpwnam(3) and syslog(3). - * - * This file provide wrapper to the getpwnam or getpwnam_r functions. - */ - -#include <config.h> - -#include "groupio.h" - -#define LOOKUP_TYPE struct group -#define FUNCTION_NAME getgrnam -#define ARG_TYPE const char * -#define ARG_NAME name -#define DUP_FUNCTION __gr_dup -#define HAVE_FUNCTION_R (defined HAVE_GETGRNAM_R) - -#include "xgetXXbyYY.c" - diff --git a/libmisc/xgetpwnam.c b/libmisc/xgetpwnam.c deleted file mode 100644 index 74eb972..0000000 --- a/libmisc/xgetpwnam.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * According to the Linux-PAM documentation: - * - * 4.1. Care about standard library calls - * - * In general, writers of authorization-granting applications should - * assume that each module is likely to call any or all 'libc' functions. - * For 'libc' functions that return pointers to static/dynamically - * allocated structures (ie. the library allocates the memory and the - * user is not expected to 'free()' it) any module call to this function - * is likely to corrupt a pointer previously obtained by the application. - * The application programmer should either re-call such a 'libc' - * function after a call to the Linux-PAM library, or copy the structure - * contents to some safe area of memory before passing control to the - * Linux-PAM library. - * - * Two important function classes that fall into this category are - * getpwnam(3) and syslog(3). - * - * This file provide wrapper to the getpwnam or getpwnam_r functions. - */ - -#include <config.h> - -#include "pwio.h" - -#define LOOKUP_TYPE struct passwd -#define FUNCTION_NAME getpwnam -#define ARG_TYPE const char * -#define ARG_NAME name -#define DUP_FUNCTION __pw_dup -#define HAVE_FUNCTION_R (defined HAVE_GETPWNAM_R) - -#include "xgetXXbyYY.c" - diff --git a/libmisc/xgetpwuid.c b/libmisc/xgetpwuid.c deleted file mode 100644 index 23b2d0c..0000000 --- a/libmisc/xgetpwuid.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2007 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * According to the Linux-PAM documentation: - * - * 4.1. Care about standard library calls - * - * In general, writers of authorization-granting applications should - * assume that each module is likely to call any or all 'libc' functions. - * For 'libc' functions that return pointers to static/dynamically - * allocated structures (ie. the library allocates the memory and the - * user is not expected to 'free()' it) any module call to this function - * is likely to corrupt a pointer previously obtained by the application. - * The application programmer should either re-call such a 'libc' - * function after a call to the Linux-PAM library, or copy the structure - * contents to some safe area of memory before passing control to the - * Linux-PAM library. - * - * Two important function classes that fall into this category are - * getpwnam(3) and syslog(3). - * - * This file provide wrapper to the getpwnam or getpwnam_r functions. - */ - -#include <config.h> - -#include "pwio.h" - -#define LOOKUP_TYPE struct passwd -#define FUNCTION_NAME getpwuid -#define ARG_TYPE uid_t -#define ARG_NAME uid -#define DUP_FUNCTION __pw_dup -#define HAVE_FUNCTION_R (defined HAVE_GETPWUID_R) - -#include "xgetXXbyYY.c" - diff --git a/libmisc/xgetspnam.c b/libmisc/xgetspnam.c deleted file mode 100644 index 148185f..0000000 --- a/libmisc/xgetspnam.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2008 - 2009, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * According to the Linux-PAM documentation: - * - * 4.1. Care about standard library calls - * - * In general, writers of authorization-granting applications should - * assume that each module is likely to call any or all 'libc' functions. - * For 'libc' functions that return pointers to static/dynamically - * allocated structures (ie. the library allocates the memory and the - * user is not expected to 'free()' it) any module call to this function - * is likely to corrupt a pointer previously obtained by the application. - * The application programmer should either re-call such a 'libc' - * function after a call to the Linux-PAM library, or copy the structure - * contents to some safe area of memory before passing control to the - * Linux-PAM library. - * - * Two important function classes that fall into this category are - * getpwnam(3) and syslog(3). - * - * This file provide wrapper to the getpwnam or getpwnam_r functions. - */ - -#include <config.h> - -#include "shadowio.h" - -#define LOOKUP_TYPE struct spwd -#define FUNCTION_NAME getspnam -#define ARG_TYPE const char * -#define ARG_NAME name -#define DUP_FUNCTION __spw_dup -#define HAVE_FUNCTION_R (defined HAVE_GETSPNAM_R) - -#include "xgetXXbyYY.c" - diff --git a/libmisc/xmalloc.c b/libmisc/xmalloc.c deleted file mode 100644 index 056d472..0000000 --- a/libmisc/xmalloc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1990 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 1996 - 1998, Marek Michałkiewicz - * SPDX-FileCopyrightText: 2003 - 2006, Tomasz Kłoczko - * SPDX-FileCopyrightText: 2008 , Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* Replacements for malloc and strdup with error checking. Too trivial - to be worth copyrighting :-). I did that because a lot of code used - malloc and strdup without checking for NULL pointer, and I like some - message better than a core dump... --marekm - - Yeh, but. Remember that bailing out might leave the system in some - bizarre state. You really want to put in error checking, then add - some back-out failure recovery code. -- jfh */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include <errno.h> -#include "defines.h" -#include "prototypes.h" -#include "shadowlog.h" - -/*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/void *xmalloc (size_t size) -{ - void *ptr; - - ptr = malloc (size); - if (NULL == ptr) { - (void) fprintf (log_get_logfd(), - _("%s: failed to allocate memory: %s\n"), - log_get_progname(), strerror (errno)); - exit (13); - } - return ptr; -} - -/*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *str) -{ - return strcpy (xmalloc (strlen (str) + 1), str); -} diff --git a/libmisc/yesno.c b/libmisc/yesno.c deleted file mode 100644 index cfbe6ec..0000000 --- a/libmisc/yesno.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * SPDX-FileCopyrightText: 1992 - 1994, Julianne Frances Haugh - * SPDX-FileCopyrightText: 2007 - 2008, Nicolas François - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/* - * Common code for yes/no prompting - * - * Used by pwck.c and grpck.c - */ - -#include <config.h> - -#ident "$Id$" - -#include <stdio.h> -#include "prototypes.h" - -/* - * yes_or_no - get answer to question from the user - * - * It returns false if no. - * - * If the read_only flag is set, it will print No, and will return - * false. - */ -bool yes_or_no (bool read_only) -{ - char buf[80]; - - /* - * In read-only mode all questions are answered "no". - */ - if (read_only) { - (void) puts (_("No")); - return false; - } - - /* - * Typically, there's a prompt on stdout, sometimes unflushed. - */ - (void) fflush (stdout); - - /* - * Get a line and see what the first character is. - */ - /* TODO: use gettext */ - if (fgets (buf, (int) sizeof buf, stdin) == buf) { - return buf[0] == 'y' || buf[0] == 'Y'; - } - - return false; -} - |