diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Makefile.am | 2 | ||||
-rw-r--r-- | lib/Makefile.in | 596 | ||||
-rw-r--r-- | lib/commonio.c | 34 | ||||
-rw-r--r-- | lib/commonio.h | 5 | ||||
-rw-r--r-- | lib/defines.h | 2 | ||||
-rw-r--r-- | lib/encrypt.c | 15 | ||||
-rw-r--r-- | lib/exitcodes.h | 2 | ||||
-rw-r--r-- | lib/faillog.h | 2 | ||||
-rw-r--r-- | lib/fields.c | 2 | ||||
-rw-r--r-- | lib/fputsx.c | 2 | ||||
-rw-r--r-- | lib/getdef.c | 8 | ||||
-rw-r--r-- | lib/getlong.c | 2 | ||||
-rw-r--r-- | lib/groupio.c | 8 | ||||
-rw-r--r-- | lib/groupio.c~ | 458 | ||||
-rw-r--r-- | lib/groupio.h | 2 | ||||
-rw-r--r-- | lib/groupmem.c | 12 | ||||
-rw-r--r-- | lib/gshadow.c | 2 | ||||
-rw-r--r-- | lib/gshadow_.h | 2 | ||||
-rw-r--r-- | lib/lockpw.c | 2 | ||||
-rw-r--r-- | lib/port.c | 2 | ||||
-rw-r--r-- | lib/port.h | 2 | ||||
-rw-r--r-- | lib/prototypes.h | 17 | ||||
-rw-r--r-- | lib/pwauth.c | 10 | ||||
-rw-r--r-- | lib/pwauth.h | 2 | ||||
-rw-r--r-- | lib/pwio.c | 2 | ||||
-rw-r--r-- | lib/pwio.h | 2 | ||||
-rw-r--r-- | lib/pwmem.c | 16 | ||||
-rw-r--r-- | lib/sgetgrent.c | 2 | ||||
-rw-r--r-- | lib/sgetpwent.c | 2 | ||||
-rw-r--r-- | lib/sgroupio.c | 15 | ||||
-rw-r--r-- | lib/sgroupio.h | 2 | ||||
-rw-r--r-- | lib/shadow.c | 2 | ||||
-rw-r--r-- | lib/shadowio.c | 2 | ||||
-rw-r--r-- | lib/shadowio.h | 2 | ||||
-rw-r--r-- | lib/shadowmem.c | 10 | ||||
-rw-r--r-- | lib/subordinateio.c | 614 | ||||
-rw-r--r-- | lib/subordinateio.h | 41 | ||||
-rw-r--r-- | lib/utent.c | 2 |
38 files changed, 1261 insertions, 644 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am index c448dd30..6db86cd6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -39,6 +39,8 @@ libshadow_la_SOURCES = \ pwio.c \ pwio.h \ pwmem.c \ + subordinateio.h \ + subordinateio.c \ selinux.c \ semanage.c \ sgetgrent.c \ diff --git a/lib/Makefile.in b/lib/Makefile.in deleted file mode 100644 index c6d74f48..00000000 --- a/lib/Makefile.in +++ /dev/null @@ -1,596 +0,0 @@ -# Makefile.in generated by automake 1.11.5 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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__make_dryrun = \ - { \ - am__dry=no; \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ - | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ - *) \ - for am__flg in $$MAKEFLAGS; do \ - case $$am__flg in \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done;; \ - esac; \ - test $$am__dry = yes; \ - } -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_TCB_TRUE@am__append_1 = tcbfuncs.c tcbfuncs.h -subdir = lib -DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.in -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(install_sh) -d -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libshadow_la_LIBADD = -am__libshadow_la_SOURCES_DIST = commonio.c commonio.h defines.h \ - encrypt.c exitcodes.h faillog.h fields.c fputsx.c getdef.c \ - getdef.h get_gid.c getlong.c get_pid.c get_uid.c getulong.c \ - groupio.c groupmem.c groupio.h gshadow.c lockpw.c nscd.c \ - nscd.h pam_defs.h port.c port.h prototypes.h pwauth.c pwauth.h \ - pwio.c pwio.h pwmem.c selinux.c semanage.c sgetgrent.c \ - sgetpwent.c sgetspent.c sgroupio.c sgroupio.h shadow.c \ - shadowio.c shadowio.h shadowmem.c spawn.c utent.c tcbfuncs.c \ - tcbfuncs.h -@WITH_TCB_TRUE@am__objects_1 = tcbfuncs.lo -am_libshadow_la_OBJECTS = commonio.lo encrypt.lo fields.lo fputsx.lo \ - getdef.lo get_gid.lo getlong.lo get_pid.lo get_uid.lo \ - getulong.lo groupio.lo groupmem.lo gshadow.lo lockpw.lo \ - nscd.lo port.lo pwauth.lo pwio.lo pwmem.lo selinux.lo \ - semanage.lo sgetgrent.lo sgetpwent.lo sgetspent.lo sgroupio.lo \ - shadow.lo shadowio.lo shadowmem.lo spawn.lo utent.lo \ - $(am__objects_1) -libshadow_la_OBJECTS = $(am_libshadow_la_OBJECTS) -libshadow_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libshadow_la_LDFLAGS) $(LDFLAGS) -o $@ -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ - $(LDFLAGS) -o $@ -SOURCES = $(libshadow_la_SOURCES) -DIST_SOURCES = $(am__libshadow_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 -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AR = @AR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = -DEPDIR = @DEPDIR@ -DLLTOOL = @DLLTOOL@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -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@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBMD = @LIBMD@ -LIBOBJS = @LIBOBJS@ -LIBPAM = @LIBPAM@ -LIBS = @LIBS@ -LIBSELINUX = @LIBSELINUX@ -LIBSEMANAGE = @LIBSEMANAGE@ -LIBSKEY = @LIBSKEY@ -LIBTCB = @LIBTCB@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -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@ -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@ -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@ -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@ -AUTOMAKE_OPTIONS = 1.0 foreign -noinst_LTLIBRARIES = libshadow.la -libshadow_la_LDFLAGS = -version-info 0:0:0 -libshadow_la_SOURCES = commonio.c commonio.h defines.h encrypt.c \ - exitcodes.h faillog.h fields.c fputsx.c getdef.c getdef.h \ - get_gid.c getlong.c get_pid.c get_uid.c getulong.c groupio.c \ - groupmem.c groupio.h gshadow.c lockpw.c nscd.c nscd.h \ - pam_defs.h port.c port.h prototypes.h pwauth.c pwauth.h pwio.c \ - pwio.h pwmem.c selinux.c semanage.c sgetgrent.c sgetpwent.c \ - sgetspent.c sgroupio.c sgroupio.h shadow.c shadowio.c \ - shadowio.h shadowmem.c spawn.c utent.c $(am__append_1) - -# These files are unneeded for some reason, listed in -# order of appearance: -# -# sources for dbm support (not yet used) -EXTRA_DIST = \ - .indent.pro \ - gshadow_.h - -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(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 lib/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign lib/Makefile -.PRECIOUS: 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__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - 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)'; for p in $$list; do \ - dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" != "$$p" || dir=.; \ - echo "rm -f \"$${dir}/so_locations\""; \ - rm -f "$${dir}/so_locations"; \ - done -libshadow.la: $(libshadow_la_OBJECTS) $(libshadow_la_DEPENDENCIES) $(EXTRA_libshadow_la_DEPENDENCIES) - $(libshadow_la_LINK) $(libshadow_la_OBJECTS) $(libshadow_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commonio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/encrypt.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fields.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fputsx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_gid.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_pid.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_uid.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getdef.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getlong.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getulong.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/groupio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/groupmem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gshadow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockpw.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nscd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/port.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwauth.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwmem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/selinux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/semanage.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgetgrent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgetpwent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgetspent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sgroupio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shadow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shadowio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/shadowmem.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spawn.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tcbfuncs.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/utent.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c $< - -.c.obj: -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - mkid -fID $$unique -tags: TAGS - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - set x; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - 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 -CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ - $(TAGS_FILES) $(LISP) - list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | \ - $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in files) print i; }; }'`; \ - 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" - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(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." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -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 -rf ./$(DEPDIR) - -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 all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES ctags 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 uninstall uninstall-am - - -# 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/lib/commonio.c b/lib/commonio.c index 6b6ce7b9..cc536bf1 100644 --- a/lib/commonio.c +++ b/lib/commonio.c @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: commonio.c 3727 2012-05-18 19:44:53Z nekral-guest $" +#ident "$Id$" #include "defines.h" #include <assert.h> @@ -1113,6 +1113,38 @@ int commonio_update (struct commonio_db *db, const void *eptr) return 1; } +#ifdef ENABLE_SUBIDS +int commonio_append (struct commonio_db *db, const void *eptr) +{ + struct commonio_entry *p; + void *nentry; + + if (!db->isopen || db->readonly) { + errno = EINVAL; + return 0; + } + nentry = db->ops->dup (eptr); + if (NULL == nentry) { + errno = ENOMEM; + return 0; + } + /* new entry */ + p = (struct commonio_entry *) malloc (sizeof *p); + if (NULL == p) { + db->ops->free (nentry); + errno = ENOMEM; + return 0; + } + + p->eptr = nentry; + p->line = NULL; + p->changed = true; + add_one_entry (db, p); + + db->changed = true; + return 1; +} +#endif /* ENABLE_SUBIDS */ void commonio_del_entry (struct commonio_db *db, const struct commonio_entry *p) { diff --git a/lib/commonio.h b/lib/commonio.h index a1117a8b..0a316f9c 100644 --- a/lib/commonio.h +++ b/lib/commonio.h @@ -30,7 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: commonio.h 3640 2011-11-19 21:51:52Z nekral-guest $ */ +/* $Id$ */ #ifndef _COMMONIO_H #define _COMMONIO_H @@ -146,6 +146,9 @@ extern int commonio_lock_nowait (struct commonio_db *, bool log); extern int commonio_open (struct commonio_db *, int); extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *); extern int commonio_update (struct commonio_db *, const void *); +#ifdef ENABLE_SUBIDS +extern int commonio_append (struct commonio_db *, const void *); +#endif /* ENABLE_SUBIDS */ extern int commonio_remove (struct commonio_db *, const char *); extern int commonio_rewind (struct commonio_db *); extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *); diff --git a/lib/defines.h b/lib/defines.h index c5d84a81..62bd73e5 100644 --- a/lib/defines.h +++ b/lib/defines.h @@ -1,4 +1,4 @@ -/* $Id: defines.h 3492 2011-09-18 20:44:09Z nekral-guest $ */ +/* $Id$ */ /* some useful defines */ #ifndef _DEFINES_H_ diff --git a/lib/encrypt.c b/lib/encrypt.c index a0cbf2c6..53c99c94 100644 --- a/lib/encrypt.c +++ b/lib/encrypt.c @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: encrypt.c 3231 2010-08-22 13:04:54Z nekral-guest $" +#ident "$Id$" #include <unistd.h> #include <stdio.h> @@ -40,23 +40,22 @@ #include "prototypes.h" #include "defines.h" -/*@exposed@*/char *pw_encrypt (const char *clear, const char *salt) +/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt) { static char cipher[128]; char *cp; cp = crypt (clear, salt); - if (!cp) { + if (NULL == cp) { /* * Single Unix Spec: crypt() may return a null pointer, - * and set errno to indicate an error. The caller doesn't - * expect us to return NULL, so... + * and set errno to indicate an error. In this case return + * the NULL so the caller can handle appropriately. */ - perror ("crypt"); - exit (EXIT_FAILURE); + return NULL; } - /* The GNU crypt does not return NULL if the algorithm is not + /* Some crypt() do not return NULL if the algorithm is not * supported, and return a DES encrypted password. */ if ((NULL != salt) && (salt[0] == '$') && (strlen (cp) <= 13)) { diff --git a/lib/exitcodes.h b/lib/exitcodes.h index 10a7ed30..96b2340b 100644 --- a/lib/exitcodes.h +++ b/lib/exitcodes.h @@ -27,7 +27,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: exitcodes.h 2849 2009-04-30 21:08:49Z nekral-guest $ */ +/* $Id$ */ /* * Exit codes used by shadow programs diff --git a/lib/faillog.h b/lib/faillog.h index f232eb8c..a0a95b34 100644 --- a/lib/faillog.h +++ b/lib/faillog.h @@ -32,7 +32,7 @@ /* * faillog.h - login failure logging file format * - * $Id: faillog.h 1980 2008-04-27 00:40:09Z nekral-guest $ + * $Id$ * * The login failure file is maintained by login(1) and faillog(8) * Each record in the file represents a separate UID and the file diff --git a/lib/fields.c b/lib/fields.c index 06079d6a..649fae17 100644 --- a/lib/fields.c +++ b/lib/fields.c @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: fields.c 3380 2011-07-08 19:56:18Z nekral-guest $" +#ident "$Id$" #include <ctype.h> #include <string.h> diff --git a/lib/fputsx.c b/lib/fputsx.c index c162bc11..c42b40bd 100644 --- a/lib/fputsx.c +++ b/lib/fputsx.c @@ -36,7 +36,7 @@ #include "defines.h" #include "prototypes.h" -#ident "$Id: fputsx.c 3021 2009-06-12 20:20:45Z nekral-guest $" +#ident "$Id$" /*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *buf, int cnt, FILE * f) diff --git a/lib/getdef.c b/lib/getdef.c index ac08163c..b5f780ca 100644 --- a/lib/getdef.c +++ b/lib/getdef.c @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: getdef.c 3095 2010-03-04 18:11:13Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" @@ -81,6 +81,12 @@ static struct itemdef def_table[] = { {"SHA_CRYPT_MAX_ROUNDS", NULL}, {"SHA_CRYPT_MIN_ROUNDS", NULL}, #endif + {"SUB_GID_COUNT", NULL}, + {"SUB_GID_MAX", NULL}, + {"SUB_GID_MIN", NULL}, + {"SUB_UID_COUNT", NULL}, + {"SUB_UID_MAX", NULL}, + {"SUB_UID_MIN", NULL}, {"SULOG_FILE", NULL}, {"SU_NAME", NULL}, {"SYS_GID_MAX", NULL}, diff --git a/lib/getlong.c b/lib/getlong.c index 7f9912c6..47c3a605 100644 --- a/lib/getlong.c +++ b/lib/getlong.c @@ -29,7 +29,7 @@ #include <config.h> -#ident "$Id: getlong.c 2795 2009-04-24 23:27:12Z nekral-guest $" +#ident "$Id$" #include <stdlib.h> #include <errno.h> diff --git a/lib/groupio.c b/lib/groupio.c index 46444967..2a37bfd9 100644 --- a/lib/groupio.c +++ b/lib/groupio.c @@ -33,7 +33,7 @@ #include <config.h> -#ident "$Id: groupio.c 3296 2011-02-16 20:32:16Z nekral-guest $" +#ident "$Id$" #include <assert.h> #include <stdio.h> @@ -330,7 +330,7 @@ static /*@null@*/struct commonio_entry *merge_group_entries ( /* Concatenate the 2 lines */ new_line_len = strlen (gr1->line) + strlen (gr2->line) +1; - new_line = (char *)malloc ((new_line_len + 1) * sizeof(char*)); + new_line = (char *)malloc (new_line_len + 1); if (NULL == new_line) { errno = ENOMEM; return NULL; @@ -353,7 +353,7 @@ static /*@null@*/struct commonio_entry *merge_group_entries ( members++; } } - new_members = (char **)malloc ( (members+1) * sizeof(char*) ); + new_members = (char **)calloc ( (members+1), sizeof(char*) ); if (NULL == new_members) { free (new_line); errno = ENOMEM; @@ -362,6 +362,8 @@ static /*@null@*/struct commonio_entry *merge_group_entries ( for (i=0; NULL != gptr1->gr_mem[i]; i++) { new_members[i] = gptr1->gr_mem[i]; } + /* NULL termination enforced by above calloc */ + members = i; for (i=0; NULL != gptr2->gr_mem[i]; i++) { char **pmember = new_members; diff --git a/lib/groupio.c~ b/lib/groupio.c~ new file mode 100644 index 00000000..244307fc --- /dev/null +++ b/lib/groupio.c~ @@ -0,0 +1,458 @@ +/* + * Copyright (c) 1990 - 1994, Julianne Frances Haugh + * Copyright (c) 1996 - 2000, Marek Michałkiewicz + * Copyright (c) 2001 , Michał Moskal + * Copyright (c) 2005 , Tomasz Kłoczko + * Copyright (c) 2007 - 2010, Nicolas François + * All rights reserved. + * + * 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 <config.h> + +#ident "$Id$" + +#include <assert.h> +#include <stdio.h> + +#include "prototypes.h" +#include "defines.h" +#include "commonio.h" +#include "getdef.h" +#include "groupio.h" + +static /*@null@*/struct commonio_entry *merge_group_entries ( + /*@null@*/ /*@returned@*/struct commonio_entry *gr1, + /*@null@*/struct commonio_entry *gr2); +static int split_groups (unsigned int max_members); +static int group_open_hook (void); + +static /*@null@*/ /*@only@*/void *group_dup (const void *ent) +{ + const struct group *gr = ent; + + return __gr_dup (gr); +} + +static void group_free (/*@out@*/ /*@only@*/void *ent) +{ + struct group *gr = ent; + + gr_free (gr); +} + +static const char *group_getname (const void *ent) +{ + const struct group *gr = ent; + + return gr->gr_name; +} + +static void *group_parse (const char *line) +{ + return (void *) sgetgrent (line); +} + +static int group_put (const void *ent, FILE * file) +{ + const struct group *gr = ent; + + if ( (NULL == gr) + || (valid_field (gr->gr_name, ":\n") == -1) + || (valid_field (gr->gr_passwd, ":\n") == -1) + || (gr->gr_gid == (gid_t)-1)) { + return -1; + } + + /* FIXME: fail also if gr->gr_mem == NULL ?*/ + if (NULL != gr->gr_mem) { + size_t i; + for (i = 0; NULL != gr->gr_mem[i]; i++) { + if (valid_field (gr->gr_mem[i], ",:\n") == -1) { + return -1; + } + } + } + + return (putgrent (gr, file) == -1) ? -1 : 0; +} + +static int group_close_hook (void) +{ + unsigned int max_members = getdef_unum("MAX_MEMBERS_PER_GROUP", 0); + + if (0 == max_members) { + return 1; + } + + return split_groups (max_members); +} + +static struct commonio_ops group_ops = { + group_dup, + group_free, + group_getname, + group_parse, + group_put, + fgetsx, + fputsx, + group_open_hook, + group_close_hook +}; + +static /*@owned@*/struct commonio_db group_db = { + GROUP_FILE, /* filename */ + &group_ops, /* ops */ + NULL, /* fp */ +#ifdef WITH_SELINUX + NULL, /* scontext */ +#endif + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + false, /* changed */ + false, /* isopen */ + false, /* locked */ + false /* readonly */ +}; + +int gr_setdbname (const char *filename) +{ + return commonio_setname (&group_db, filename); +} + +/*@observer@*/const char *gr_dbname (void) +{ + return group_db.filename; +} + +int gr_lock (void) +{ + return commonio_lock (&group_db); +} + +int gr_open (int mode) +{ + return commonio_open (&group_db, mode); +} + +/*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name) +{ + return commonio_locate (&group_db, name); +} + +/*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid) +{ + const struct group *grp; + + gr_rewind (); + while ( ((grp = gr_next ()) != NULL) + && (grp->gr_gid != gid)) { + } + + return grp; +} + +int gr_update (const struct group *gr) +{ + return commonio_update (&group_db, (const void *) gr); +} + +int gr_remove (const char *name) +{ + return commonio_remove (&group_db, name); +} + +int gr_rewind (void) +{ + return commonio_rewind (&group_db); +} + +/*@observer@*/ /*@null@*/const struct group *gr_next (void) +{ + return commonio_next (&group_db); +} + +int gr_close (void) +{ + return commonio_close (&group_db); +} + +int gr_unlock (void) +{ + return commonio_unlock (&group_db); +} + +void __gr_set_changed (void) +{ + group_db.changed = true; +} + +/*@dependent@*/ /*@null@*/struct commonio_entry *__gr_get_head (void) +{ + return group_db.head; +} + +/*@observer@*/const struct commonio_db *__gr_get_db (void) +{ + return &group_db; +} + +void __gr_del_entry (const struct commonio_entry *ent) +{ + commonio_del_entry (&group_db, ent); +} + +static int gr_cmp (const void *p1, const void *p2) +{ + gid_t u1, u2; + + if ((*(struct commonio_entry **) p1)->eptr == NULL) { + return 1; + } + if ((*(struct commonio_entry **) p2)->eptr == NULL) { + return -1; + } + + u1 = ((struct group *) (*(struct commonio_entry **) p1)->eptr)->gr_gid; + u2 = ((struct group *) (*(struct commonio_entry **) p2)->eptr)->gr_gid; + + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +/* Sort entries by GID */ +int gr_sort () +{ + return commonio_sort (&group_db, gr_cmp); +} + +static int group_open_hook (void) +{ + unsigned int max_members = getdef_unum("MAX_MEMBERS_PER_GROUP", 0); + struct commonio_entry *gr1, *gr2; + + if (0 == max_members) { + return 1; + } + + for (gr1 = group_db.head; NULL != gr1; gr1 = gr1->next) { + for (gr2 = gr1->next; NULL != gr2; gr2 = gr2->next) { + struct group *g1 = (struct group *)gr1->eptr; + struct group *g2 = (struct group *)gr2->eptr; + if (NULL != g1 && + NULL != g2 && + 0 == strcmp (g1->gr_name, g2->gr_name) && + 0 == strcmp (g1->gr_passwd, g2->gr_passwd) && + g1->gr_gid == g2->gr_gid) { + /* Both group entries refer to the same + * group. It is a split group. Merge the + * members. */ + gr1 = merge_group_entries (gr1, gr2); + if (NULL == gr1) + return 0; + /* Unlink gr2 */ + if (NULL != gr2->next) { + gr2->next->prev = gr2->prev; + } + /* gr2 does not start with head */ + assert (NULL != gr2->prev); + gr2->prev->next = gr2->next; + } + } + assert (NULL != gr1); + } + + return 1; +} + +/* + * Merge the list of members of the two group entries. + * + * The commonio_entry arguments shall be group entries. + * + * You should not merge the members of two groups if they don't have the + * same name, password and gid. + * + * It merge the members of the second entry in the first one, and return + * the modified first entry on success, or NULL on failure (with errno + * set). + */ +static /*@null@*/struct commonio_entry *merge_group_entries ( + /*@null@*/ /*@returned@*/struct commonio_entry *gr1, + /*@null@*/struct commonio_entry *gr2) +{ + struct group *gptr1; + struct group *gptr2; + char **new_members; + size_t members = 0; + char *new_line; + size_t new_line_len, i; + if (NULL == gr2 || NULL == gr1) { + errno = EINVAL; + return NULL; + } + + gptr1 = (struct group *)gr1->eptr; + gptr2 = (struct group *)gr2->eptr; + if (NULL == gptr2 || NULL == gptr1) { + errno = EINVAL; + return NULL; + } + + /* Concatenate the 2 lines */ + new_line_len = strlen (gr1->line) + strlen (gr2->line) +2; + new_line = (char *)malloc ((new_line_len + 1) * sizeof(char*)); + if (NULL == new_line) { + errno = ENOMEM; + return NULL; + } + snprintf(new_line, new_line_len, "%s\n%s", gr1->line, gr2->line); + new_line[new_line_len] = '\0'; + + /* Concatenate the 2 list of members */ + for (i=0; NULL != gptr1->gr_mem[i]; i++); + members += i; + for (i=0; NULL != gptr2->gr_mem[i]; i++) { + char **pmember = gptr1->gr_mem; + while (NULL != *pmember) { + if (0 == strcmp(*pmember, gptr2->gr_mem[i])) { + break; + } + pmember++; + } + if (NULL == *pmember) { + members++; + } + } + new_members = (char **)malloc ( (members+1) * sizeof(char*) ); + if (NULL == new_members) { + free (new_line); + errno = ENOMEM; + return NULL; + } + for (i=0; NULL != gptr1->gr_mem[i]; i++) { + new_members[i] = gptr1->gr_mem[i]; + } + members = i; + for (i=0; NULL != gptr2->gr_mem[i]; i++) { + char **pmember = new_members; + while (NULL != *pmember) { + if (0 == strcmp(*pmember, gptr2->gr_mem[i])) { + break; + } + pmember++; + } + if (NULL == *pmember) { + new_members[members] = gptr2->gr_mem[i]; + members++; + new_members[members] = NULL; + } + } + + gr1->line = new_line; + gptr1->gr_mem = new_members; + + return gr1; +} + +/* + * Scan the group database and split the groups which have more members + * than specified, if this is the result from a current change. + * + * Return 0 on failure (errno set) and 1 on success. + */ +static int split_groups (unsigned int max_members) +{ + struct commonio_entry *gr; + + for (gr = group_db.head; NULL != gr; gr = gr->next) { + struct group *gptr = (struct group *)gr->eptr; + struct commonio_entry *new; + struct group *new_gptr; + unsigned int members = 0; + unsigned int i; + + /* Check if this group must be split */ + if (!gr->changed) { + continue; + } + if (NULL == gptr) { + continue; + } + for (members = 0; NULL != gptr->gr_mem[members]; members++); + if (members <= max_members) { + continue; + } + + new = (struct commonio_entry *) malloc (sizeof *new); + if (NULL == new) { + errno = ENOMEM; + return 0; + } + new->eptr = group_dup(gr->eptr); + if (NULL == new->eptr) { + free (new); + errno = ENOMEM; + return 0; + } + new_gptr = (struct group *)new->eptr; + new->line = NULL; + new->changed = true; + + /* Enforce the maximum number of members on gptr */ + for (i = max_members; NULL != gptr->gr_mem[i]; i++) { + free (gptr->gr_mem[i]); + gptr->gr_mem[i] = NULL; + } + /* Shift all the members */ + /* The number of members in new_gptr will be check later */ + for (i = 0; NULL != new_gptr->gr_mem[i + max_members]; i++) { + if (NULL != new_gptr->gr_mem[i]) { + free (new_gptr->gr_mem[i]); + } + new_gptr->gr_mem[i] = new_gptr->gr_mem[i + max_members]; + new_gptr->gr_mem[i + max_members] = NULL; + } + for (; NULL != new_gptr->gr_mem[i]; i++) { + free (new_gptr->gr_mem[i]); + new_gptr->gr_mem[i] = NULL; + } + + /* insert the new entry in the list */ + new->prev = gr; + new->next = gr->next; + gr->next = new; + } + + return 1; +} + diff --git a/lib/groupio.h b/lib/groupio.h index 64405233..e1f1b029 100644 --- a/lib/groupio.h +++ b/lib/groupio.h @@ -31,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: groupio.h 2783 2009-04-23 21:19:02Z nekral-guest $ */ +/* $Id$ */ #ifndef _GROUPIO_H #define _GROUPIO_H diff --git a/lib/groupmem.c b/lib/groupmem.c index 078d1d6c..e69c3107 100644 --- a/lib/groupmem.c +++ b/lib/groupmem.c @@ -3,7 +3,7 @@ * Copyright (c) 1996 - 2000, Marek Michałkiewicz * Copyright (c) 2001 , Michał Moskal * Copyright (c) 2005 , Tomasz Kłoczko - * Copyright (c) 2007 - 2010, Nicolas François + * Copyright (c) 2007 - 2013, Nicolas François * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ #include <config.h> -#ident "$Id: groupmem.c 3231 2010-08-22 13:04:54Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" @@ -48,13 +48,19 @@ if (NULL == gr) { return NULL; } + /* The libc might define other fields. They won't be copied. */ + memset (gr, 0, sizeof *gr); gr->gr_gid = grent->gr_gid; + /*@-mustfreeonly@*/ gr->gr_name = strdup (grent->gr_name); + /*@=mustfreeonly@*/ if (NULL == gr->gr_name) { free(gr); return NULL; } + /*@-mustfreeonly@*/ gr->gr_passwd = strdup (grent->gr_passwd); + /*@=mustfreeonly@*/ if (NULL == gr->gr_passwd) { free(gr->gr_name); free(gr); @@ -63,7 +69,9 @@ for (i = 0; grent->gr_mem[i]; i++); + /*@-mustfreeonly@*/ gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *)); + /*@=mustfreeonly@*/ if (NULL == gr->gr_mem) { free(gr->gr_passwd); free(gr->gr_name); diff --git a/lib/gshadow.c b/lib/gshadow.c index 1750eb07..e5a0f61e 100644 --- a/lib/gshadow.c +++ b/lib/gshadow.c @@ -35,7 +35,7 @@ /* Newer versions of Linux libc already have shadow support. */ #if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{ */ -#ident "$Id: gshadow.c 3096 2010-03-10 22:30:03Z nekral-guest $" +#ident "$Id$" #include <stdio.h> #include "prototypes.h" diff --git a/lib/gshadow_.h b/lib/gshadow_.h index 24378efa..7959c5a1 100644 --- a/lib/gshadow_.h +++ b/lib/gshadow_.h @@ -30,7 +30,7 @@ */ /* - * $Id: gshadow_.h 3464 2011-08-14 13:16:54Z nekral-guest $ + * $Id$ */ #ifndef _H_GSHADOW diff --git a/lib/lockpw.c b/lib/lockpw.c index e28e7963..0bcf1955 100644 --- a/lib/lockpw.c +++ b/lib/lockpw.c @@ -33,7 +33,7 @@ #ifndef HAVE_LCKPWDF -#ident "$Id: lockpw.c 1980 2008-04-27 00:40:09Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: port.c 2130 2008-06-13 18:11:09Z nekral-guest $" +#ident "$Id$" #include <stdio.h> #include <ctype.h> @@ -32,7 +32,7 @@ /* * port.h - structure of /etc/porttime * - * $Id: port.h 1980 2008-04-27 00:40:09Z nekral-guest $ + * $Id$ * * Each entry in /etc/porttime consists of a TTY device * name or "*" to indicate all TTY devices, followed by diff --git a/lib/prototypes.h b/lib/prototypes.h index 00d9e0b5..7aaf1a63 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -35,13 +35,15 @@ * * prototypes of libmisc functions, and private lib functions. * - * $Id: prototypes.h 3656 2012-01-08 16:04:27Z nekral-guest $ + * $Id$ * */ #ifndef _PROTOTYPES_H #define _PROTOTYPES_H +#include <config.h> + #include <sys/stat.h> #ifdef USE_UTMPX #include <utmpx.h> @@ -124,7 +126,7 @@ extern int copy_tree (const char *src_root, const char *dst_root, gid_t old_gid, gid_t new_gid); /* encrypt.c */ -extern /*@exposed@*/char *pw_encrypt (const char *, const char *); +extern /*@exposed@*//*@null@*/char *pw_encrypt (const char *, const char *); /* entry.c */ extern void pw_entry (const char *, struct passwd *); @@ -149,6 +151,17 @@ extern int find_new_uid (bool sys_user, uid_t *uid, /*@null@*/uid_t const *preferred_uid); +#ifdef ENABLE_SUBIDS +/* find_new_sub_gids.c */ +extern int find_new_sub_gids (const char *owner, + gid_t *range_start, unsigned long *range_count); + +/* find_new_sub_uids.c */ +extern int find_new_sub_uids (const char *owner, + uid_t *range_start, unsigned long *range_count); +#endif /* ENABLE_SUBIDS */ + + /* get_gid.c */ extern int get_gid (const char *gidstr, gid_t *gid); diff --git a/lib/pwauth.c b/lib/pwauth.c index bfa5c91f..9e24fbf2 100644 --- a/lib/pwauth.c +++ b/lib/pwauth.c @@ -33,7 +33,7 @@ #include <config.h> #ifndef USE_PAM -#ident "$Id: pwauth.c 2782 2009-04-23 20:46:01Z nekral-guest $" +#ident "$Id$" #include <errno.h> #include <fcntl.h> @@ -73,6 +73,7 @@ int pw_auth (const char *cipher, char prompt[1024]; char *clear = NULL; const char *cp; + const char *encrypted; int retval; #ifdef SKEY @@ -177,7 +178,12 @@ int pw_auth (const char *cipher, * the results there as well. */ - retval = strcmp (pw_encrypt (input, cipher), cipher); + encrypted = pw_encrypt (input, cipher); + if (NULL != encrypted) { + retval = strcmp (encrypted, cipher); + } else { + retval = -1; + } #ifdef SKEY /* diff --git a/lib/pwauth.h b/lib/pwauth.h index 1b383433..d6c71dda 100644 --- a/lib/pwauth.h +++ b/lib/pwauth.h @@ -31,7 +31,7 @@ */ /* - * $Id: pwauth.h 2777 2009-04-23 17:43:27Z nekral-guest $ + * $Id$ */ #ifndef USE_PAM @@ -33,7 +33,7 @@ #include <config.h> -#ident "$Id: pwio.c 3296 2011-02-16 20:32:16Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" @@ -31,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: pwio.h 2783 2009-04-23 21:19:02Z nekral-guest $ */ +/* $Id$ */ #ifndef _PWIO_H #define _PWIO_H diff --git a/lib/pwmem.c b/lib/pwmem.c index e23a6dc5..7013e8a3 100644 --- a/lib/pwmem.c +++ b/lib/pwmem.c @@ -3,7 +3,7 @@ * Copyright (c) 1996 - 2000, Marek Michałkiewicz * Copyright (c) 2001 , Michał Moskal * Copyright (c) 2003 - 2005, Tomasz Kłoczko - * Copyright (c) 2007 - 2009, Nicolas François + * Copyright (c) 2007 - 2013, Nicolas François * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ #include <config.h> -#ident "$Id: pwmem.c 3062 2009-09-07 19:08:10Z nekral-guest $" +#ident "$Id$" #include <stdio.h> #include "defines.h" @@ -48,27 +48,37 @@ if (NULL == pw) { return NULL; } + /* The libc might define other fields. They won't be copied. */ + memset (pw, 0, sizeof *pw); pw->pw_uid = pwent->pw_uid; pw->pw_gid = pwent->pw_gid; + /*@-mustfreeonly@*/ pw->pw_name = strdup (pwent->pw_name); + /*@=mustfreeonly@*/ if (NULL == pw->pw_name) { free(pw); return NULL; } + /*@-mustfreeonly@*/ pw->pw_passwd = strdup (pwent->pw_passwd); + /*@=mustfreeonly@*/ if (NULL == pw->pw_passwd) { free(pw->pw_name); free(pw); return NULL; } + /*@-mustfreeonly@*/ pw->pw_gecos = strdup (pwent->pw_gecos); + /*@=mustfreeonly@*/ if (NULL == pw->pw_gecos) { free(pw->pw_passwd); free(pw->pw_name); free(pw); return NULL; } + /*@-mustfreeonly@*/ pw->pw_dir = strdup (pwent->pw_dir); + /*@=mustfreeonly@*/ if (NULL == pw->pw_dir) { free(pw->pw_gecos); free(pw->pw_passwd); @@ -76,7 +86,9 @@ free(pw); return NULL; } + /*@-mustfreeonly@*/ pw->pw_shell = strdup (pwent->pw_shell); + /*@=mustfreeonly@*/ if (NULL == pw->pw_shell) { free(pw->pw_dir); free(pw->pw_gecos); diff --git a/lib/sgetgrent.c b/lib/sgetgrent.c index ff87bb11..206f1c59 100644 --- a/lib/sgetgrent.c +++ b/lib/sgetgrent.c @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: sgetgrent.c 2579 2009-03-21 20:29:58Z nekral-guest $" +#ident "$Id$" #include <stdio.h> #include <sys/types.h> diff --git a/lib/sgetpwent.c b/lib/sgetpwent.c index 80a7adcd..293aabe2 100644 --- a/lib/sgetpwent.c +++ b/lib/sgetpwent.c @@ -32,7 +32,7 @@ #include <config.h> -#ident "$Id: sgetpwent.c 2581 2009-03-21 20:45:35Z nekral-guest $" +#ident "$Id$" #include <sys/types.h> #include "defines.h" diff --git a/lib/sgroupio.c b/lib/sgroupio.c index e0c26545..faed0adf 100644 --- a/lib/sgroupio.c +++ b/lib/sgroupio.c @@ -3,7 +3,7 @@ * Copyright (c) 1996 - 2000, Marek Michałkiewicz * Copyright (c) 2001 , Michał Moskal * Copyright (c) 2005 , Tomasz Kłoczko - * Copyright (c) 2007 - 2008, Nicolas François + * Copyright (c) 2007 - 2013, Nicolas François * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,7 +35,7 @@ #ifdef SHADOWGRP -#ident "$Id: sgroupio.c 3296 2011-02-16 20:32:16Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" @@ -51,12 +51,19 @@ if (NULL == sg) { return NULL; } + /* Do the same as the other _dup function, even if we know the + * structure. */ + memset (sg, 0, sizeof *sg); + /*@-mustfreeonly@*/ sg->sg_name = strdup (sgent->sg_name); + /*@=mustfreeonly@*/ if (NULL == sg->sg_name) { free (sg); return NULL; } + /*@-mustfreeonly@*/ sg->sg_passwd = strdup (sgent->sg_passwd); + /*@=mustfreeonly@*/ if (NULL == sg->sg_passwd) { free (sg->sg_name); free (sg); @@ -64,7 +71,9 @@ } for (i = 0; NULL != sgent->sg_adm[i]; i++); + /*@-mustfreeonly@*/ sg->sg_adm = (char **) malloc ((i + 1) * sizeof (char *)); + /*@=mustfreeonly@*/ if (NULL == sg->sg_adm) { free (sg->sg_passwd); free (sg->sg_name); @@ -87,7 +96,9 @@ sg->sg_adm[i] = NULL; for (i = 0; NULL != sgent->sg_mem[i]; i++); + /*@-mustfreeonly@*/ sg->sg_mem = (char **) malloc ((i + 1) * sizeof (char *)); + /*@=mustfreeonly@*/ if (NULL == sg->sg_mem) { for (i = 0; NULL != sg->sg_adm[i]; i++) { free (sg->sg_adm[i]); diff --git a/lib/sgroupio.h b/lib/sgroupio.h index 2c87e776..163243a4 100644 --- a/lib/sgroupio.h +++ b/lib/sgroupio.h @@ -31,7 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: sgroupio.h 3061 2009-09-07 18:59:03Z nekral-guest $ */ +/* $Id$ */ #ifndef _SGROUPIO_H #define _SGROUPIO_H diff --git a/lib/shadow.c b/lib/shadow.c index c43a0b67..05cb0e4a 100644 --- a/lib/shadow.c +++ b/lib/shadow.c @@ -35,7 +35,7 @@ /* Newer versions of Linux libc already have shadow support. */ #ifndef HAVE_GETSPNAM -#ident "$Id: shadow.c 3181 2010-03-23 08:56:52Z nekral-guest $" +#ident "$Id$" #include <sys/types.h> #include "prototypes.h" diff --git a/lib/shadowio.c b/lib/shadowio.c index 4584a7c0..2930e65d 100644 --- a/lib/shadowio.c +++ b/lib/shadowio.c @@ -33,7 +33,7 @@ #include <config.h> -#ident "$Id: shadowio.c 3296 2011-02-16 20:32:16Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" diff --git a/lib/shadowio.h b/lib/shadowio.h index e4f08f10..229dfdb4 100644 --- a/lib/shadowio.h +++ b/lib/shadowio.h @@ -30,7 +30,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: shadowio.h 2783 2009-04-23 21:19:02Z nekral-guest $ */ +/* $Id$ */ #ifndef _SHADOWIO_H #define _SHADOWIO_H diff --git a/lib/shadowmem.c b/lib/shadowmem.c index 86d4b0a5..8989598f 100644 --- a/lib/shadowmem.c +++ b/lib/shadowmem.c @@ -3,7 +3,7 @@ * Copyright (c) 1996 - 2000, Marek Michałkiewicz * Copyright (c) 2001 , Michał Moskal * Copyright (c) 2005 , Tomasz Kłoczko - * Copyright (c) 2007 - 2009, Nicolas François + * Copyright (c) 2007 - 2013, Nicolas François * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,7 +33,7 @@ #include <config.h> -#ident "$Id: shadowmem.c 3062 2009-09-07 19:08:10Z nekral-guest $" +#ident "$Id$" #include "prototypes.h" #include "defines.h" @@ -49,6 +49,8 @@ if (NULL == sp) { return NULL; } + /* The libc might define other fields. They won't be copied. */ + memset (sp, 0, sizeof *sp); sp->sp_lstchg = spent->sp_lstchg; sp->sp_min = spent->sp_min; sp->sp_max = spent->sp_max; @@ -56,12 +58,16 @@ sp->sp_inact = spent->sp_inact; sp->sp_expire = spent->sp_expire; sp->sp_flag = spent->sp_flag; + /*@-mustfreeonly@*/ sp->sp_namp = strdup (spent->sp_namp); + /*@=mustfreeonly@*/ if (NULL == sp->sp_namp) { free(sp); return NULL; } + /*@-mustfreeonly@*/ sp->sp_pwdp = strdup (spent->sp_pwdp); + /*@=mustfreeonly@*/ if (NULL == sp->sp_pwdp) { free(sp->sp_namp); free(sp); diff --git a/lib/subordinateio.c b/lib/subordinateio.c new file mode 100644 index 00000000..0ba117b0 --- /dev/null +++ b/lib/subordinateio.c @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2012 - Eric Biederman + */ + +#include <config.h> + +#ifdef ENABLE_SUBIDS + +#include "prototypes.h" +#include "defines.h" +#include <stdio.h> +#include "commonio.h" +#include "subordinateio.h" + +struct subordinate_range { + const char *owner; + unsigned long start; + unsigned long count; +}; + +#define NFIELDS 3 + +/* + * subordinate_dup: create a duplicate range + * + * @ent: a pointer to a subordinate_range struct + * + * Returns a pointer to a newly allocated duplicate subordinate_range struct + * or NULL on failure + */ +static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent) +{ + const struct subordinate_range *rangeent = ent; + struct subordinate_range *range; + + range = (struct subordinate_range *) malloc (sizeof *range); + if (NULL == range) { + return NULL; + } + range->owner = strdup (rangeent->owner); + if (NULL == range->owner) { + free(range); + return NULL; + } + range->start = rangeent->start; + range->count = rangeent->count; + + return range; +} + +/* + * subordinate_free: free a subordinate_range struct + * + * @ent: pointer to a subordinate_range struct to free. + */ +static void subordinate_free (/*@out@*/ /*@only@*/void *ent) +{ + struct subordinate_range *rangeent = ent; + + free ((void *)(rangeent->owner)); + free (rangeent); +} + +/* + * subordinate_parse: + * + * @line: a line to parse + * + * Returns a pointer to a subordinate_range struct representing the values + * in @line, or NULL on failure. Note that the returned value should not + * be freed by the caller. + */ +static void *subordinate_parse (const char *line) +{ + static struct subordinate_range range; + static char rangebuf[1024]; + int i; + char *cp; + char *fields[NFIELDS]; + + /* + * Copy the string to a temporary buffer so the substrings can + * be modified to be NULL terminated. + */ + if (strlen (line) >= sizeof rangebuf) + return NULL; /* fail if too long */ + strcpy (rangebuf, line); + + /* + * Save a pointer to the start of each colon separated + * field. The fields are converted into NUL terminated strings. + */ + + for (cp = rangebuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) { + fields[i] = cp; + while (('\0' != *cp) && (':' != *cp)) { + cp++; + } + + if ('\0' != *cp) { + *cp = '\0'; + cp++; + } else { + cp = NULL; + } + } + + /* + * There must be exactly NFIELDS colon separated fields or + * the entry is invalid. Also, fields must be non-blank. + */ + if (i != NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0') + return NULL; + range.owner = fields[0]; + if (getulong (fields[1], &range.start) == 0) + return NULL; + if (getulong (fields[2], &range.count) == 0) + return NULL; + + return ⦥ +} + +/* + * subordinate_put: print a subordinate_range value to a file + * + * @ent: a pointer to a subordinate_range struct to print out. + * @file: file to which to print. + * + * Returns 0 on success, -1 on error. + */ +static int subordinate_put (const void *ent, FILE * file) +{ + const struct subordinate_range *range = ent; + + return fprintf(file, "%s:%lu:%lu\n", + range->owner, + range->start, + range->count) < 0 ? -1 : 0; +} + +static struct commonio_ops subordinate_ops = { + subordinate_dup, /* dup */ + subordinate_free, /* free */ + NULL, /* getname */ + subordinate_parse, /* parse */ + subordinate_put, /* put */ + fgets, /* fgets */ + fputs, /* fputs */ + NULL, /* open_hook */ + NULL, /* close_hook */ +}; + +static /*@observer@*/ /*@null*/const struct subordinate_range *subordinate_next(struct commonio_db *db) +{ + return (const struct subordinate_range *)commonio_next (db); +} + +/* + * range_exists: Check whether @owner owns any ranges + * + * @db: database to query + * @owner: owner being queried + * + * Returns true if @owner owns any subuid ranges, false otherwise. + */ +static const bool range_exists(struct commonio_db *db, const char *owner) +{ + const struct subordinate_range *range; + commonio_rewind(db); + while ((range = commonio_next(db)) != NULL) { + if (0 == strcmp(range->owner, owner)) + return true; + } + return false; +} + +/* + * find_range: find a range which @owner is authorized to use which includes + * subuid @val. + * + * @db: database to query + * @owner: owning uid being queuried + * @val: subuid being searched for. + * + * Returns a range of subuids belonging to @owner and including the subuid + * @val, or NULL if no such range exists. + */ +static const struct subordinate_range *find_range(struct commonio_db *db, + const char *owner, unsigned long val) +{ + const struct subordinate_range *range; + commonio_rewind(db); + while ((range = commonio_next(db)) != NULL) { + unsigned long first = range->start; + unsigned long last = first + range->count - 1; + + if (0 != strcmp(range->owner, owner)) + continue; + + if ((val >= first) && (val <= last)) + return range; + } + return NULL; +} + +/* + * have_range: check whether @owner is authorized to use the range + * (@start .. @start+@count-1). + * @db: database to check + * @owner: owning uid being queried + * @start: start of range + * @count: number of uids in range + * + * Returns true if @owner is authorized to use the range, false otherwise. + */ +static bool have_range(struct commonio_db *db, + const char *owner, unsigned long start, unsigned long count) +{ + const struct subordinate_range *range; + unsigned long end; + + if (count == 0) + return false; + + end = start + count - 1; + range = find_range (db, owner, start); + while (range) { + unsigned long last; + + last = range->start + range->count - 1; + if (last >= (start + count - 1)) + return true; + + count = end - last; + start = last + 1; + range = find_range(db, owner, start); + } + return false; +} + +/* + * subordinate_range_cmp: compare uid ranges + * + * @p1: pointer to a commonio_entry struct to compare + * @p2: pointer to second commonio_entry struct to compare + * + * Returns 0 if the entries are the same. Otherwise return -1 + * if the range in p1 is lower than that in p2, or (if the ranges are + * equal) if the owning uid in p1 is lower than p2's. Return 1 if p1's + * range or owning uid is great than p2's. + */ +static int subordinate_range_cmp (const void *p1, const void *p2) +{ + struct subordinate_range *range1, *range2; + + if ((*(struct commonio_entry **) p1)->eptr == NULL) + return 1; + if ((*(struct commonio_entry **) p2)->eptr == NULL) + return -1; + + range1 = ((struct subordinate_range *) (*(struct commonio_entry **) p1)->eptr); + range2 = ((struct subordinate_range *) (*(struct commonio_entry **) p2)->eptr); + + if (range1->start < range2->start) + return -1; + else if (range1->start > range2->start) + return 1; + else if (range1->count < range2->count) + return -1; + else if (range1->count > range2->count) + return 1; + else + return strcmp(range1->owner, range2->owner); +} + +/* + * find_free_range: find an unused consecutive sequence of ids to allocate + * to a user. + * @db: database to search + * @min: the first uid in the range to find + * @max: the highest uid to find + * @count: the number of uids needed + * + * Return the lowest new uid, or ULONG_MAX on failure. + */ +static unsigned long find_free_range(struct commonio_db *db, + unsigned long min, unsigned long max, + unsigned long count) +{ + const struct subordinate_range *range; + unsigned long low, high; + + /* When given invalid parameters fail */ + if ((count == 0) || (max < min)) + goto fail; + + /* Sort by range then by owner */ + commonio_sort (db, subordinate_range_cmp); + commonio_rewind(db); + + low = min; + while ((range = commonio_next(db)) != NULL) { + unsigned long first = range->start; + unsigned long last = first + range->count - 1; + + /* Find the top end of the hole before this range */ + high = first; + + /* Don't allocate IDs after max (included) */ + if (high > max + 1) { + high = max + 1; + } + + /* Is the hole before this range large enough? */ + if ((high > low) && ((high - low) >= count)) + return low; + + /* Compute the low end of the next hole */ + if (low < (last + 1)) + low = last + 1; + if (low > max) + goto fail; + } + + /* Is the remaining unclaimed area large enough? */ + if (((max - low) + 1) >= count) + return low; +fail: + return ULONG_MAX; +} + +/* + * add_range: add a subuid range to an owning uid's list of authorized + * subuids. + * @db: database to which to add + * @owner: uid which owns the subuid + * @start: the first uid in the owned range + * @count: the number of uids in the range + * + * Return 1 if the range is already present or on succcess. On error + * return 0 and set errno appropriately. + */ +static int add_range(struct commonio_db *db, + const char *owner, unsigned long start, unsigned long count) +{ + struct subordinate_range range; + range.owner = owner; + range.start = start; + range.count = count; + + /* See if the range is already present */ + if (have_range(db, owner, start, count)) + return 1; + + /* Otherwise append the range */ + return commonio_append(db, &range); +} + +/* + * remove_range: remove a range of subuids from an owning uid's list + * of authorized subuids. + * @db: database to work on + * @owner: owning uid whose range is being removed + * @start: start of the range to be removed + * @count: number of uids in the range. + * + * Returns 0 on failure, 1 on success. Failure means that we needed to + * create a new range to represent the new limits, and failed doing so. + */ +static int remove_range (struct commonio_db *db, + const char *owner, + unsigned long start, unsigned long count) +{ + struct commonio_entry *ent; + unsigned long end; + + if (count == 0) { + return 1; + } + + end = start + count - 1; + for (ent = db->head; NULL != ent; ent = ent->next) { + struct subordinate_range *range = ent->eptr; + unsigned long first; + unsigned long last; + + /* Skip unparsed entries */ + if (NULL == range) { + continue; + } + + first = range->start; + last = first + range->count - 1; + + /* Skip entries with a different owner */ + if (0 != strcmp (range->owner, owner)) { + continue; + } + + /* Skip entries outside of the range to remove */ + if ((end < first) || (start > last)) { + continue; + } + + if (start <= first) { + if (end >= last) { + /* to be removed: [start, end] + * range: [first, last] */ + /* entry completely contained in the + * range to remove */ + commonio_del_entry (db, ent); + } else { + /* to be removed: [start, end] + * range: [first, last] */ + /* Remove only the start of the entry */ + range->start = end + 1; + range->count = (last - range->start) + 1; + + ent->changed = true; + db->changed = true; + } + } else { + if (end >= last) { + /* to be removed: [start, end] + * range: [first, last] */ + /* Remove only the end of the entry */ + range->count = start - range->start; + + ent->changed = true; + db->changed = true; + } else { + /* to be removed: [start, end] + * range: [first, last] */ + /* Remove the middle of the range + * This requires to create a new range */ + struct subordinate_range tail; + tail.owner = range->owner; + tail.start = end + 1; + tail.count = (last - tail.start) + 1; + + if (commonio_append (db, &tail) == 0) { + return 0; + } + + range->count = start - range->start; + + ent->changed = true; + db->changed = true; + } + } + } + + return 1; +} + +static struct commonio_db subordinate_uid_db = { + "/etc/subuid", /* filename */ + &subordinate_ops, /* ops */ + NULL, /* fp */ +#ifdef WITH_SELINUX + NULL, /* scontext */ +#endif + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + false, /* changed */ + false, /* isopen */ + false, /* locked */ + false /* readonly */ +}; + +int sub_uid_setdbname (const char *filename) +{ + return commonio_setname (&subordinate_uid_db, filename); +} + +/*@observer@*/const char *sub_uid_dbname (void) +{ + return subordinate_uid_db.filename; +} + +bool sub_uid_file_present (void) +{ + return commonio_present (&subordinate_uid_db); +} + +int sub_uid_lock (void) +{ + return commonio_lock (&subordinate_uid_db); +} + +int sub_uid_open (int mode) +{ + return commonio_open (&subordinate_uid_db, mode); +} + +bool sub_uid_assigned(const char *owner) +{ + return range_exists (&subordinate_uid_db, owner); +} + +bool have_sub_uids(const char *owner, uid_t start, unsigned long count) +{ + return have_range (&subordinate_uid_db, owner, start, count); +} + +int sub_uid_add (const char *owner, uid_t start, unsigned long count) +{ + return add_range (&subordinate_uid_db, owner, start, count); +} + +int sub_uid_remove (const char *owner, uid_t start, unsigned long count) +{ + return remove_range (&subordinate_uid_db, owner, start, count); +} + +int sub_uid_close (void) +{ + return commonio_close (&subordinate_uid_db); +} + +int sub_uid_unlock (void) +{ + return commonio_unlock (&subordinate_uid_db); +} + +uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count) +{ + unsigned long start; + start = find_free_range (&subordinate_uid_db, min, max, count); + return start == ULONG_MAX ? (uid_t) -1 : start; +} + +static struct commonio_db subordinate_gid_db = { + "/etc/subgid", /* filename */ + &subordinate_ops, /* ops */ + NULL, /* fp */ +#ifdef WITH_SELINUX + NULL, /* scontext */ +#endif + NULL, /* head */ + NULL, /* tail */ + NULL, /* cursor */ + false, /* changed */ + false, /* isopen */ + false, /* locked */ + false /* readonly */ +}; + +int sub_gid_setdbname (const char *filename) +{ + return commonio_setname (&subordinate_gid_db, filename); +} + +/*@observer@*/const char *sub_gid_dbname (void) +{ + return subordinate_gid_db.filename; +} + +bool sub_gid_file_present (void) +{ + return commonio_present (&subordinate_gid_db); +} + +int sub_gid_lock (void) +{ + return commonio_lock (&subordinate_gid_db); +} + +int sub_gid_open (int mode) +{ + return commonio_open (&subordinate_gid_db, mode); +} + +bool have_sub_gids(const char *owner, gid_t start, unsigned long count) +{ + return have_range(&subordinate_gid_db, owner, start, count); +} + +bool sub_gid_assigned(const char *owner) +{ + return range_exists (&subordinate_gid_db, owner); +} + +int sub_gid_add (const char *owner, gid_t start, unsigned long count) +{ + return add_range (&subordinate_gid_db, owner, start, count); +} + +int sub_gid_remove (const char *owner, gid_t start, unsigned long count) +{ + return remove_range (&subordinate_gid_db, owner, start, count); +} + +int sub_gid_close (void) +{ + return commonio_close (&subordinate_gid_db); +} + +int sub_gid_unlock (void) +{ + return commonio_unlock (&subordinate_gid_db); +} + +gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count) +{ + unsigned long start; + start = find_free_range (&subordinate_gid_db, min, max, count); + return start == ULONG_MAX ? (gid_t) -1 : start; +} +#else /* !ENABLE_SUBIDS */ +extern int errno; /* warning: ANSI C forbids an empty source file */ +#endif /* !ENABLE_SUBIDS */ + diff --git a/lib/subordinateio.h b/lib/subordinateio.h new file mode 100644 index 00000000..a21d72b8 --- /dev/null +++ b/lib/subordinateio.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2012- Eric W. Biederman + */ + +#ifndef _SUBORDINATEIO_H +#define _SUBORDINATEIO_H + +#include <config.h> + +#ifdef ENABLE_SUBIDS + +#include <sys/types.h> + +extern int sub_uid_close(void); +extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count); +extern bool sub_uid_file_present (void); +extern bool sub_uid_assigned(const char *owner); +extern int sub_uid_lock (void); +extern int sub_uid_setdbname (const char *filename); +extern /*@observer@*/const char *sub_uid_dbname (void); +extern int sub_uid_open (int mode); +extern int sub_uid_unlock (void); +extern int sub_uid_add (const char *owner, uid_t start, unsigned long count); +extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count); +extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count); + +extern int sub_gid_close(void); +extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count); +extern bool sub_gid_file_present (void); +extern bool sub_gid_assigned(const char *owner); +extern int sub_gid_lock (void); +extern int sub_gid_setdbname (const char *filename); +extern /*@observer@*/const char *sub_gid_dbname (void); +extern int sub_gid_open (int mode); +extern int sub_gid_unlock (void); +extern int sub_gid_add (const char *owner, gid_t start, unsigned long count); +extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count); +extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count); +#endif /* ENABLE_SUBIDS */ + +#endif diff --git a/lib/utent.c b/lib/utent.c index 5678cf84..45af2607 100644 --- a/lib/utent.c +++ b/lib/utent.c @@ -39,7 +39,7 @@ #include <utmp.h> #ifndef lint -static char rcsid[] = "$Id: utent.c 3181 2010-03-23 08:56:52Z nekral-guest $"; +static char rcsid[] = "$Id$"; #endif static int utmp_fd = -1; |