[svn-upgrade] Integrating new upstream version, shadow (19990709)
This commit is contained in:
57
lib/Makefile.am
Normal file
57
lib/Makefile.am
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.0 foreign
|
||||
|
||||
noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h \
|
||||
faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h \
|
||||
pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h \
|
||||
tcfsio.h
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
|
||||
|
||||
# These files are unneeded for some reason, listed in
|
||||
# order of appearance:
|
||||
#
|
||||
# sources which are not really needed (are they in libc???)
|
||||
# sources for dbm support (not yet used)
|
||||
# sources for LIBOBJS (which are normally in libc)
|
||||
# misc header sources
|
||||
|
||||
EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c \
|
||||
grpack.c gspack.c pwpack.c sppack.c \
|
||||
gshadow_.h shadow_.h lastlog_.h snprintf.h
|
||||
|
||||
EXTRA_libshadow_a_SOURCESS = grent.c pwent.c \
|
||||
mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c \
|
||||
putgrent.c putpwent.c putspent.c \
|
||||
sgetgrent.c sgetpwent.c sgetspent.c snprintf.c \
|
||||
md5.c md5crypt.c
|
||||
|
||||
# We build libshadow for our tools.
|
||||
|
||||
noinst_LIBRARIES = libshadow.a
|
||||
|
||||
libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c \
|
||||
fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c \
|
||||
pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c \
|
||||
tcfsio.c
|
||||
|
||||
libshadow_a_LIBADD = @LIBOBJS@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/lib
|
||||
|
||||
# shared library support
|
||||
libdir = ${exec_prefix}/lib
|
||||
#lib_PROGRAMS = libshadow.la
|
||||
lib_LTLIBRARIES = libshadow.la
|
||||
libshadow_la_SOURCES = ${libshadow_a_SOURCES}
|
||||
#libshadow_la_LIBADD = @LTLIBOBJS@
|
||||
#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
|
||||
libshadow_la_LDFLAGS = -version-info 0:0:0
|
||||
|
||||
# remove the libshadow.so -> libshadow.so.x.x symlink, because this
|
||||
# library is for internal use by this package only. Shadow support
|
||||
# is in libc and no one should be using -lshadow anymore.
|
||||
install-exec-hook:
|
||||
rm -f $(libdir)/libshadow.so
|
||||
|
430
lib/Makefile.in
Normal file
430
lib/Makefile.in
Normal file
@@ -0,0 +1,430 @@
|
||||
# Makefile.in generated automatically by automake 1.3 from Makefile.am
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998 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.
|
||||
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
|
||||
DISTDIR =
|
||||
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
transform = @program_transform_name@
|
||||
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
CATALOGS = @CATALOGS@
|
||||
CATOBJEXT = @CATOBJEXT@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
DATADIRNAME = @DATADIRNAME@
|
||||
GENCAT = @GENCAT@
|
||||
GMOFILES = @GMOFILES@
|
||||
GMSGFMT = @GMSGFMT@
|
||||
GT_NO = @GT_NO@
|
||||
GT_YES = @GT_YES@
|
||||
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
|
||||
INSTOBJEXT = @INSTOBJEXT@
|
||||
INTLDEPS = @INTLDEPS@
|
||||
INTLLIBS = @INTLLIBS@
|
||||
INTLOBJS = @INTLOBJS@
|
||||
LD = @LD@
|
||||
LIBCRACK = @LIBCRACK@
|
||||
LIBCRYPT = @LIBCRYPT@
|
||||
LIBPAM = @LIBPAM@
|
||||
LIBSKEY = @LIBSKEY@
|
||||
LIBTCFS = @LIBTCFS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKINSTALLDIRS = @MKINSTALLDIRS@
|
||||
MSGFMT = @MSGFMT@
|
||||
NM = @NM@
|
||||
PACKAGE = @PACKAGE@
|
||||
POFILES = @POFILES@
|
||||
POSUB = @POSUB@
|
||||
RANLIB = @RANLIB@
|
||||
U = @U@
|
||||
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
|
||||
USE_NLS = @USE_NLS@
|
||||
VERSION = @VERSION@
|
||||
YACC = @YACC@
|
||||
l = @l@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.0 foreign
|
||||
|
||||
noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h \
|
||||
faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h \
|
||||
pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h \
|
||||
tcfsio.h
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
|
||||
|
||||
# These files are unneeded for some reason, listed in
|
||||
# order of appearance:
|
||||
#
|
||||
# sources which are not really needed (are they in libc???)
|
||||
# sources for dbm support (not yet used)
|
||||
# sources for LIBOBJS (which are normally in libc)
|
||||
# misc header sources
|
||||
|
||||
EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c \
|
||||
grpack.c gspack.c pwpack.c sppack.c \
|
||||
gshadow_.h shadow_.h lastlog_.h snprintf.h
|
||||
|
||||
EXTRA_libshadow_a_SOURCESS = grent.c pwent.c \
|
||||
mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c \
|
||||
putgrent.c putpwent.c putspent.c \
|
||||
sgetgrent.c sgetpwent.c sgetspent.c snprintf.c \
|
||||
md5.c md5crypt.c
|
||||
|
||||
# We build libshadow for our tools.
|
||||
|
||||
noinst_LIBRARIES = libshadow.a
|
||||
|
||||
libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c \
|
||||
fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c \
|
||||
pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c \
|
||||
tcfsio.c
|
||||
|
||||
libshadow_a_LIBADD = @LIBOBJS@
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/lib
|
||||
|
||||
# shared library support
|
||||
libdir = ${exec_prefix}/lib
|
||||
#lib_PROGRAMS = libshadow.la
|
||||
lib_LTLIBRARIES = libshadow.la
|
||||
libshadow_la_SOURCES = ${libshadow_a_SOURCES}
|
||||
#libshadow_la_LIBADD = @LTLIBOBJS@
|
||||
#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
|
||||
libshadow_la_LDFLAGS = -version-info 0:0:0
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
libshadow_a_DEPENDENCIES = @LIBOBJS@
|
||||
libshadow_a_OBJECTS = commonio.o dialchk.o dialup.o encrypt.o fputsx.o \
|
||||
getdef.o getpass.o groupio.o gshadow.o lockpw.o port.o pwauth.o pwio.o \
|
||||
rad64.o sgroupio.o shadow.o shadowio.o utent.o tcfsio.o
|
||||
AR = ar
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
|
||||
libshadow_la_LIBADD =
|
||||
libshadow_la_OBJECTS = commonio.lo dialchk.lo dialup.lo encrypt.lo \
|
||||
fputsx.lo getdef.lo getpass.lo groupio.lo gshadow.lo lockpw.lo port.lo \
|
||||
pwauth.lo pwio.lo rad64.lo sgroupio.lo shadow.lo shadowio.lo utent.lo \
|
||||
tcfsio.lo
|
||||
CFLAGS = @CFLAGS@
|
||||
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
|
||||
HEADERS = $(noinst_HEADERS)
|
||||
|
||||
DIST_COMMON = Makefile.am Makefile.in md5.c md5crypt.c mkdir.c \
|
||||
putgrent.c putpwent.c putspent.c rename.c rmdir.c sgetgrent.c \
|
||||
sgetpwent.c sgetspent.c snprintf.c strcasecmp.c strdup.c strerror.c \
|
||||
strstr.c
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP = --best
|
||||
SOURCES = $(libshadow_a_SOURCES) $(libshadow_la_SOURCES)
|
||||
OBJECTS = $(libshadow_a_OBJECTS) $(libshadow_la_OBJECTS)
|
||||
|
||||
all: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .lo .o .s
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps lib/Makefile
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) \
|
||||
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
||||
mostlyclean-noinstLIBRARIES:
|
||||
|
||||
clean-noinstLIBRARIES:
|
||||
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||
|
||||
distclean-noinstLIBRARIES:
|
||||
|
||||
maintainer-clean-noinstLIBRARIES:
|
||||
|
||||
.c.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.s.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
.S.o:
|
||||
$(COMPILE) -c $<
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.o core *.core
|
||||
|
||||
clean-compile:
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
maintainer-clean-compile:
|
||||
|
||||
.c.lo:
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
|
||||
|
||||
.s.lo:
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
|
||||
|
||||
.S.lo:
|
||||
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
|
||||
maintainer-clean-libtool:
|
||||
|
||||
libshadow.a: $(libshadow_a_OBJECTS) $(libshadow_a_DEPENDENCIES)
|
||||
-rm -f libshadow.a
|
||||
$(AR) cru libshadow.a $(libshadow_a_OBJECTS) $(libshadow_a_LIBADD)
|
||||
$(RANLIB) libshadow.a
|
||||
|
||||
mostlyclean-libLTLIBRARIES:
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
|
||||
distclean-libLTLIBRARIES:
|
||||
|
||||
maintainer-clean-libLTLIBRARIES:
|
||||
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(libdir)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
echo "$(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
|
||||
$(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
|
||||
else :; fi; \
|
||||
done
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
|
||||
done
|
||||
|
||||
libshadow.la: $(libshadow_la_OBJECTS) $(libshadow_la_DEPENDENCIES)
|
||||
$(LINK) -rpath $(libdir) $(libshadow_la_LDFLAGS) $(libshadow_la_OBJECTS) $(libshadow_la_LIBADD) $(LIBS)
|
||||
|
||||
tags: TAGS
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP)
|
||||
here=`pwd` && cd $(srcdir) \
|
||||
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS)'; \
|
||||
unique=`for i in $$list; do echo $$i; done | \
|
||||
awk ' { files[$$0] = 1; } \
|
||||
END { for (i in files) print i; }'`; \
|
||||
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|
||||
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
clean-tags:
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID
|
||||
|
||||
maintainer-clean-tags:
|
||||
|
||||
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
|
||||
|
||||
subdir = lib
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
d=$(srcdir); \
|
||||
test -f $(distdir)/$$file \
|
||||
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file; \
|
||||
done
|
||||
commonio.o: commonio.c ../config.h rcsid.h defines.h gshadow_.h \
|
||||
commonio.h
|
||||
dialchk.o: dialchk.c ../config.h rcsid.h defines.h gshadow_.h \
|
||||
prototypes.h dialup.h dialchk.h
|
||||
dialup.o: dialup.c ../config.h rcsid.h prototypes.h defines.h gshadow_.h \
|
||||
dialup.h
|
||||
encrypt.o: encrypt.c ../config.h rcsid.h prototypes.h defines.h \
|
||||
gshadow_.h
|
||||
fputsx.lo fputsx.o: fputsx.c ../config.h defines.h gshadow_.h rcsid.h
|
||||
getdef.lo getdef.o: getdef.c ../config.h rcsid.h prototypes.h defines.h \
|
||||
gshadow_.h getdef.h
|
||||
getpass.lo getpass.o: getpass.c ../config.h rcsid.h defines.h gshadow_.h
|
||||
groupio.lo groupio.o: groupio.c ../config.h rcsid.h prototypes.h \
|
||||
defines.h gshadow_.h commonio.h groupio.h
|
||||
gshadow.lo gshadow.o: gshadow.c ../config.h rcsid.h prototypes.h \
|
||||
defines.h gshadow_.h
|
||||
lockpw.lo lockpw.o: lockpw.c ../config.h
|
||||
port.lo port.o: port.c ../config.h rcsid.h defines.h gshadow_.h port.h
|
||||
putgrent.o: putgrent.c ../config.h prototypes.h defines.h gshadow_.h
|
||||
pwauth.lo pwauth.o: pwauth.c ../config.h rcsid.h prototypes.h defines.h \
|
||||
gshadow_.h pwauth.h getdef.h
|
||||
pwio.lo pwio.o: pwio.c ../config.h rcsid.h prototypes.h defines.h \
|
||||
gshadow_.h commonio.h pwio.h
|
||||
rad64.lo rad64.o: rad64.c ../config.h rcsid.h
|
||||
sgetgrent.o: sgetgrent.c ../config.h rcsid.h defines.h gshadow_.h
|
||||
sgetpwent.o: sgetpwent.c ../config.h rcsid.h defines.h gshadow_.h
|
||||
sgroupio.lo sgroupio.o: sgroupio.c ../config.h rcsid.h prototypes.h \
|
||||
defines.h gshadow_.h commonio.h sgroupio.h
|
||||
shadowio.lo shadowio.o: shadowio.c ../config.h rcsid.h prototypes.h \
|
||||
defines.h gshadow_.h commonio.h shadowio.h
|
||||
shadow.lo shadow.o: shadow.c ../config.h
|
||||
tcfsio.lo tcfsio.o: tcfsio.c ../config.h
|
||||
utent.lo utent.o: utent.c ../config.h
|
||||
|
||||
info:
|
||||
dvi:
|
||||
check: all
|
||||
$(MAKE)
|
||||
installcheck:
|
||||
install-exec: install-libLTLIBRARIES
|
||||
@$(NORMAL_INSTALL)
|
||||
$(MAKE) install-exec-hook
|
||||
|
||||
install-data:
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install: install-exec install-data all
|
||||
@:
|
||||
|
||||
uninstall: uninstall-libLTLIBRARIES
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DATADIR)$(libdir)
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
|
||||
|
||||
clean-generic:
|
||||
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(DISTCLEANFILES)
|
||||
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
|
||||
mostlyclean-libtool mostlyclean-libLTLIBRARIES \
|
||||
mostlyclean-tags mostlyclean-generic
|
||||
|
||||
clean: clean-noinstLIBRARIES clean-compile clean-libtool \
|
||||
clean-libLTLIBRARIES clean-tags clean-generic \
|
||||
mostlyclean
|
||||
|
||||
distclean: distclean-noinstLIBRARIES distclean-compile \
|
||||
distclean-libtool distclean-libLTLIBRARIES \
|
||||
distclean-tags distclean-generic clean
|
||||
-rm -f config.status
|
||||
-rm -f libtool
|
||||
|
||||
maintainer-clean: maintainer-clean-noinstLIBRARIES \
|
||||
maintainer-clean-compile maintainer-clean-libtool \
|
||||
maintainer-clean-libLTLIBRARIES maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
|
||||
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
|
||||
mostlyclean-compile distclean-compile clean-compile \
|
||||
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
|
||||
clean-libtool maintainer-clean-libtool mostlyclean-libLTLIBRARIES \
|
||||
distclean-libLTLIBRARIES clean-libLTLIBRARIES \
|
||||
maintainer-clean-libLTLIBRARIES uninstall-libLTLIBRARIES \
|
||||
install-libLTLIBRARIES tags mostlyclean-tags distclean-tags clean-tags \
|
||||
maintainer-clean-tags distdir info dvi installcheck install-exec \
|
||||
install-data install uninstall all installdirs mostlyclean-generic \
|
||||
distclean-generic clean-generic maintainer-clean-generic clean \
|
||||
mostlyclean distclean maintainer-clean
|
||||
|
||||
|
||||
# remove the libshadow.so -> libshadow.so.x.x symlink, because this
|
||||
# library is for internal use by this package only. Shadow support
|
||||
# is in libc and no one should be using -lshadow anymore.
|
||||
install-exec-hook:
|
||||
rm -f $(libdir)/libshadow.so
|
||||
|
||||
# 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:
|
739
lib/commonio.c
Normal file
739
lib/commonio.c
Normal file
@@ -0,0 +1,739 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: commonio.c,v 1.14 1998/07/23 22:13:15 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
#include <sys/stat.h>
|
||||
#include <utime.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
#ifdef HAVE_SHADOW_H
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
|
||||
#include "commonio.h"
|
||||
|
||||
/* local function prototypes */
|
||||
static int check_link_count P_((const char *));
|
||||
static int do_lock_file P_((const char *, const char *));
|
||||
static FILE *fopen_set_perms P_((const char *, const char *, const struct stat *));
|
||||
static int create_backup P_((const char *, FILE *));
|
||||
static void free_linked_list P_((struct commonio_db *));
|
||||
static void add_one_entry P_((struct commonio_db *, struct commonio_entry *));
|
||||
static int name_is_nis P_((const char *));
|
||||
static int write_all P_((const struct commonio_db *));
|
||||
static struct commonio_entry *find_entry_by_name P_((struct commonio_db *, const char *));
|
||||
|
||||
#ifdef HAVE_LCKPWDF
|
||||
static int lock_count = 0;
|
||||
#endif
|
||||
|
||||
static int
|
||||
check_link_count(const char *file)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat(file, &sb) != 0)
|
||||
return 0;
|
||||
|
||||
if (sb.st_nlink != 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
do_lock_file(const char *file, const char *lock)
|
||||
{
|
||||
int fd;
|
||||
int pid;
|
||||
int len;
|
||||
int retval;
|
||||
char buf[32];
|
||||
|
||||
if ((fd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0600)) == -1)
|
||||
return 0;
|
||||
|
||||
pid = getpid();
|
||||
snprintf(buf, sizeof buf, "%d", pid);
|
||||
len = strlen(buf) + 1;
|
||||
if (write(fd, buf, len) != len) {
|
||||
close(fd);
|
||||
unlink(file);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (link(file, lock) == 0) {
|
||||
retval = check_link_count(file);
|
||||
unlink(file);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((fd = open(lock, O_RDWR)) == -1) {
|
||||
unlink(file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
len = read(fd, buf, sizeof(buf) - 1);
|
||||
close(fd);
|
||||
if (len <= 0) {
|
||||
unlink(file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
if ((pid = strtol(buf, (char **) 0, 10)) == 0) {
|
||||
unlink(file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (kill(pid, 0) == 0) {
|
||||
unlink(file);
|
||||
errno = EEXIST;
|
||||
return 0;
|
||||
}
|
||||
if (unlink(lock) != 0) {
|
||||
unlink(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if (link(file, lock) == 0 && check_link_count(file))
|
||||
retval = 1;
|
||||
|
||||
unlink(file);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static FILE *
|
||||
fopen_set_perms(const char *name, const char *mode, const struct stat *sb)
|
||||
{
|
||||
FILE *fp;
|
||||
mode_t mask;
|
||||
|
||||
mask = umask(0777);
|
||||
fp = fopen(name, mode);
|
||||
umask(mask);
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_FCHOWN
|
||||
if (fchown(fileno(fp), sb->st_uid, sb->st_gid))
|
||||
goto fail;
|
||||
#else
|
||||
if (chown(name, sb->st_mode))
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHMOD
|
||||
if (fchmod(fileno(fp), sb->st_mode & 0664))
|
||||
goto fail;
|
||||
#else
|
||||
if (chmod(name, sb->st_mode & 0664))
|
||||
goto fail;
|
||||
#endif
|
||||
return fp;
|
||||
|
||||
fail:
|
||||
fclose(fp);
|
||||
unlink(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
create_backup(const char *backup, FILE *fp)
|
||||
{
|
||||
struct stat sb;
|
||||
struct utimbuf ub;
|
||||
FILE *bkfp;
|
||||
int c;
|
||||
mode_t mask;
|
||||
|
||||
if (fstat(fileno(fp), &sb))
|
||||
return -1;
|
||||
|
||||
mask = umask(077);
|
||||
bkfp = fopen(backup, "w");
|
||||
umask(mask);
|
||||
if (!bkfp)
|
||||
return -1;
|
||||
|
||||
/* TODO: faster copy, not one-char-at-a-time. --marekm */
|
||||
rewind(fp);
|
||||
while ((c = getc(fp)) != EOF) {
|
||||
if (putc(c, bkfp) == EOF)
|
||||
break;
|
||||
}
|
||||
if (c != EOF || fflush(bkfp)) {
|
||||
fclose(bkfp);
|
||||
return -1;
|
||||
}
|
||||
if (fclose(bkfp))
|
||||
return -1;
|
||||
|
||||
ub.actime = sb.st_atime;
|
||||
ub.modtime = sb.st_mtime;
|
||||
utime(backup, &ub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
free_linked_list(struct commonio_db *db)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
while (db->head) {
|
||||
p = db->head;
|
||||
db->head = p->next;
|
||||
|
||||
if (p->line)
|
||||
free(p->line);
|
||||
|
||||
if (p->entry)
|
||||
db->ops->free(p->entry);
|
||||
|
||||
free(p);
|
||||
}
|
||||
db->tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_setname(struct commonio_db *db, const char *name)
|
||||
{
|
||||
strcpy(db->filename, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_present(const struct commonio_db *db)
|
||||
{
|
||||
return (access(db->filename, F_OK) == 0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_lock_nowait(struct commonio_db *db)
|
||||
{
|
||||
char file[1024];
|
||||
char lock[1024];
|
||||
|
||||
if (db->locked)
|
||||
return 1;
|
||||
|
||||
snprintf(file, sizeof file, "%s.%ld", db->filename, (long) getpid());
|
||||
snprintf(lock, sizeof lock, "%s.lock", db->filename);
|
||||
if (do_lock_file(file, lock)) {
|
||||
db->locked = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_lock(struct commonio_db *db)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_LCKPWDF
|
||||
/*
|
||||
* only if the system libc has a real lckpwdf() - the one from
|
||||
* lockpw.c calls us and would cause infinite recursion!
|
||||
*/
|
||||
if (db->use_lckpwdf) {
|
||||
/*
|
||||
* Call lckpwdf() on the first lock.
|
||||
* If it succeeds, call *_lock() only once
|
||||
* (no retries, it should always succeed).
|
||||
*/
|
||||
if (lock_count == 0) {
|
||||
if (lckpwdf() == -1)
|
||||
return 0; /* failure */
|
||||
}
|
||||
if (!commonio_lock_nowait(db)) {
|
||||
ulckpwdf();
|
||||
return 0; /* failure */
|
||||
}
|
||||
lock_count++;
|
||||
return 1; /* success */
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* lckpwdf() not used - do it the old way.
|
||||
*/
|
||||
#ifndef LOCK_TRIES
|
||||
#define LOCK_TRIES 15
|
||||
#endif
|
||||
|
||||
#ifndef LOCK_SLEEP
|
||||
#define LOCK_SLEEP 1
|
||||
#endif
|
||||
for (i = 0; i < LOCK_TRIES; i++) {
|
||||
if (i > 0)
|
||||
sleep(LOCK_SLEEP); /* delay between retries */
|
||||
if (commonio_lock_nowait(db))
|
||||
return 1; /* success */
|
||||
/* no unnecessary retries on "permission denied" errors */
|
||||
if (geteuid() != 0)
|
||||
return 0;
|
||||
}
|
||||
return 0; /* failure */
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_unlock(struct commonio_db *db)
|
||||
{
|
||||
char lock[1024];
|
||||
|
||||
if (db->isopen) {
|
||||
db->readonly = 1;
|
||||
if (!commonio_close(db))
|
||||
return 0;
|
||||
}
|
||||
if (db->locked) {
|
||||
/*
|
||||
* Unlock in reverse order: remove the lock file,
|
||||
* then call ulckpwdf() (if used) on last unlock.
|
||||
*/
|
||||
db->locked = 0;
|
||||
snprintf(lock, sizeof lock, "%s.lock", db->filename);
|
||||
unlink(lock);
|
||||
#ifdef HAVE_LCKPWDF
|
||||
if (db->use_lckpwdf && lock_count > 0) {
|
||||
lock_count--;
|
||||
if (lock_count == 0)
|
||||
ulckpwdf();
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_one_entry(struct commonio_db *db, struct commonio_entry *p)
|
||||
{
|
||||
p->next = NULL;
|
||||
p->prev = db->tail;
|
||||
if (!db->head)
|
||||
db->head = p;
|
||||
if (db->tail)
|
||||
db->tail->next = p;
|
||||
db->tail = p;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
name_is_nis(const char *n)
|
||||
{
|
||||
return (n[0] == '+' || n[0] == '-');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* New entries are inserted before the first NIS entry. Order is preserved
|
||||
* when db is written out.
|
||||
*/
|
||||
#ifndef KEEP_NIS_AT_END
|
||||
#define KEEP_NIS_AT_END 1
|
||||
#endif
|
||||
|
||||
#if KEEP_NIS_AT_END
|
||||
/* prototype */
|
||||
static void add_one_entry_nis P_((struct commonio_db *, struct commonio_entry *));
|
||||
|
||||
static void
|
||||
add_one_entry_nis(struct commonio_db *db, struct commonio_entry *new)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
for (p = db->head; p; p = p->next) {
|
||||
if (name_is_nis(p->entry ? db->ops->getname(p->entry) : p->line)) {
|
||||
new->next = p;
|
||||
new->prev = p->prev;
|
||||
if (p->prev)
|
||||
p->prev->next = new;
|
||||
else
|
||||
db->head = new;
|
||||
p->prev = new;
|
||||
return;
|
||||
}
|
||||
}
|
||||
add_one_entry(db, new);
|
||||
}
|
||||
#endif /* KEEP_NIS_AT_END */
|
||||
|
||||
|
||||
int
|
||||
commonio_open(struct commonio_db *db, int mode)
|
||||
{
|
||||
char buf[8192];
|
||||
char *cp;
|
||||
char *line;
|
||||
struct commonio_entry *p;
|
||||
void *entry;
|
||||
int flags = mode;
|
||||
|
||||
mode &= ~O_CREAT;
|
||||
|
||||
if (db->isopen || (mode != O_RDONLY && mode != O_RDWR)) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
db->readonly = (mode == O_RDONLY);
|
||||
if (!db->readonly && !db->locked) {
|
||||
errno = EACCES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
db->head = db->tail = db->cursor = NULL;
|
||||
db->changed = 0;
|
||||
|
||||
db->fp = fopen(db->filename, db->readonly ? "r" : "r+");
|
||||
|
||||
/*
|
||||
* If O_CREAT was specified and the file didn't exist, it will be
|
||||
* created by commonio_close(). We have no entries to read yet. --marekm
|
||||
*/
|
||||
if (!db->fp) {
|
||||
if ((flags & O_CREAT) && errno == ENOENT) {
|
||||
db->isopen = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (db->ops->fgets(buf, sizeof buf, db->fp)) {
|
||||
if ((cp = strrchr(buf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
if (!(line = strdup(buf)))
|
||||
goto cleanup;
|
||||
|
||||
if (name_is_nis(line)) {
|
||||
entry = NULL;
|
||||
} else if ((entry = db->ops->parse(line))) {
|
||||
entry = db->ops->dup(entry);
|
||||
if (!entry)
|
||||
goto cleanup_line;
|
||||
}
|
||||
|
||||
p = (struct commonio_entry *) malloc(sizeof *p);
|
||||
if (!p)
|
||||
goto cleanup_entry;
|
||||
|
||||
p->entry = entry;
|
||||
p->line = line;
|
||||
p->changed = 0;
|
||||
|
||||
add_one_entry(db, p);
|
||||
}
|
||||
|
||||
db->isopen = 1;
|
||||
return 1;
|
||||
|
||||
cleanup_entry:
|
||||
if (entry)
|
||||
db->ops->free(entry);
|
||||
cleanup_line:
|
||||
free(line);
|
||||
cleanup:
|
||||
free_linked_list(db);
|
||||
fclose(db->fp);
|
||||
db->fp = NULL;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_all(const struct commonio_db *db)
|
||||
{
|
||||
const struct commonio_entry *p;
|
||||
void *entry;
|
||||
|
||||
for (p = db->head; p; p = p->next) {
|
||||
if (p->changed) {
|
||||
entry = p->entry;
|
||||
if (db->ops->put(entry, db->fp))
|
||||
return -1;
|
||||
} else if (p->line) {
|
||||
if (db->ops->fputs(p->line, db->fp) == EOF)
|
||||
return -1;
|
||||
if (putc('\n', db->fp) == EOF)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_close(struct commonio_db *db)
|
||||
{
|
||||
char buf[1024];
|
||||
int errors = 0;
|
||||
struct stat sb;
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
db->isopen = 0;
|
||||
|
||||
if (!db->changed || db->readonly) {
|
||||
fclose(db->fp);
|
||||
db->fp = NULL;
|
||||
goto success;
|
||||
}
|
||||
|
||||
memzero(&sb, sizeof sb);
|
||||
if (db->fp) {
|
||||
if (fstat(fileno(db->fp), &sb)) {
|
||||
fclose(db->fp);
|
||||
db->fp = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create backup file.
|
||||
*/
|
||||
snprintf(buf, sizeof buf, "%s-", db->filename);
|
||||
|
||||
if (create_backup(buf, db->fp))
|
||||
errors++;
|
||||
|
||||
if (fclose(db->fp))
|
||||
errors++;
|
||||
|
||||
if (errors) {
|
||||
db->fp = NULL;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Default permissions for new [g]shadow files.
|
||||
* (passwd and group always exist...)
|
||||
*/
|
||||
sb.st_mode = 0400;
|
||||
sb.st_uid = 0;
|
||||
sb.st_gid = 0;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof buf, "%s+", db->filename);
|
||||
|
||||
db->fp = fopen_set_perms(buf, "w", &sb);
|
||||
if (!db->fp)
|
||||
goto fail;
|
||||
|
||||
if (write_all(db))
|
||||
errors++;
|
||||
|
||||
if (fflush(db->fp))
|
||||
errors++;
|
||||
#ifdef HAVE_FSYNC
|
||||
if (fsync(fileno(db->fp)))
|
||||
errors++;
|
||||
#else
|
||||
sync();
|
||||
#endif
|
||||
if (fclose(db->fp))
|
||||
errors++;
|
||||
|
||||
db->fp = NULL;
|
||||
|
||||
if (errors) {
|
||||
unlink(buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rename(buf, db->filename))
|
||||
goto fail;
|
||||
|
||||
success:
|
||||
free_linked_list(db);
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
free_linked_list(db);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct commonio_entry *
|
||||
find_entry_by_name(struct commonio_db *db, const char *name)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
void *ep;
|
||||
|
||||
for (p = db->head; p; p = p->next) {
|
||||
ep = p->entry;
|
||||
if (ep && strcmp(db->ops->getname(ep), name) == 0)
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_update(struct commonio_db *db, const void *entry)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
void *nentry;
|
||||
|
||||
if (!db->isopen || db->readonly) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (!(nentry = db->ops->dup(entry))) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
p = find_entry_by_name(db, db->ops->getname(entry));
|
||||
if (p) {
|
||||
db->ops->free(p->entry);
|
||||
p->entry = nentry;
|
||||
p->changed = 1;
|
||||
db->cursor = p;
|
||||
|
||||
db->changed = 1;
|
||||
return 1;
|
||||
}
|
||||
/* not found, new entry */
|
||||
p = (struct commonio_entry *) malloc(sizeof *p);
|
||||
if (!p) {
|
||||
db->ops->free(nentry);
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->entry = nentry;
|
||||
p->line = NULL;
|
||||
p->changed = 1;
|
||||
|
||||
#if KEEP_NIS_AT_END
|
||||
add_one_entry_nis(db, p);
|
||||
#else
|
||||
add_one_entry(db, p);
|
||||
#endif
|
||||
|
||||
db->changed = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
commonio_del_entry(struct commonio_db *db, const struct commonio_entry *p)
|
||||
{
|
||||
if (p == db->cursor)
|
||||
db->cursor = p->next;
|
||||
|
||||
if (p->prev)
|
||||
p->prev->next = p->next;
|
||||
else
|
||||
db->head = p->next;
|
||||
|
||||
if (p->next)
|
||||
p->next->prev = p->prev;
|
||||
else
|
||||
db->tail = p->prev;
|
||||
|
||||
db->changed = 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_remove(struct commonio_db *db, const char *name)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
if (!db->isopen || db->readonly) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
p = find_entry_by_name(db, name);
|
||||
if (!p) {
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
commonio_del_entry(db, p);
|
||||
|
||||
if (p->line)
|
||||
free(p->line);
|
||||
|
||||
if (p->entry)
|
||||
db->ops->free(p->entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
const void *
|
||||
commonio_locate(struct commonio_db *db, const char *name)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
p = find_entry_by_name(db, name);
|
||||
if (!p) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
db->cursor = p;
|
||||
return p->entry;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
commonio_rewind(struct commonio_db *db)
|
||||
{
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
db->cursor = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
const void *
|
||||
commonio_next(struct commonio_db *db)
|
||||
{
|
||||
void *entry;
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (db->cursor == NULL)
|
||||
db->cursor = db->head;
|
||||
else
|
||||
db->cursor = db->cursor->next;
|
||||
|
||||
while (db->cursor) {
|
||||
entry = db->cursor->entry;
|
||||
if (entry)
|
||||
return entry;
|
||||
|
||||
db->cursor = db->cursor->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
101
lib/commonio.h
Normal file
101
lib/commonio.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/* $Id: commonio.h,v 1.4 1998/01/29 23:22:27 marekm Exp $ */
|
||||
|
||||
/*
|
||||
* Linked list entry.
|
||||
*/
|
||||
struct commonio_entry {
|
||||
char *line;
|
||||
void *entry; /* struct passwd, struct spwd, ... */
|
||||
struct commonio_entry *prev, *next;
|
||||
int changed:1;
|
||||
};
|
||||
|
||||
/*
|
||||
* Operations depending on database type: passwd, group, shadow etc.
|
||||
*/
|
||||
struct commonio_ops {
|
||||
/*
|
||||
* Make a copy of the object (for example, struct passwd)
|
||||
* and all strings pointed by it, in malloced memory.
|
||||
*/
|
||||
void * (*dup) P_((const void *));
|
||||
|
||||
/*
|
||||
* free() the object including any strings pointed by it.
|
||||
*/
|
||||
void (*free) P_((void *));
|
||||
|
||||
/*
|
||||
* Return the name of the object (for example, pw_name
|
||||
* for struct passwd).
|
||||
*/
|
||||
const char * (*getname) P_((const void *));
|
||||
|
||||
/*
|
||||
* Parse a string, return object (in static area -
|
||||
* should be copied using the dup operation above).
|
||||
*/
|
||||
void * (*parse) P_((const char *));
|
||||
|
||||
/*
|
||||
* Write the object to the file (this calls putpwent()
|
||||
* for struct passwd, for example).
|
||||
*/
|
||||
int (*put) P_((const void *, FILE *));
|
||||
|
||||
/*
|
||||
* fgets and fputs (can be replaced by versions that
|
||||
* understand line continuation conventions).
|
||||
*/
|
||||
char * (*fgets) P_((char *, int, FILE *));
|
||||
int (*fputs) P_((const char *, FILE *));
|
||||
};
|
||||
|
||||
/*
|
||||
* Database structure.
|
||||
*/
|
||||
struct commonio_db {
|
||||
/*
|
||||
* Name of the data file.
|
||||
*/
|
||||
char filename[1024];
|
||||
|
||||
/*
|
||||
* Operations from above.
|
||||
*/
|
||||
struct commonio_ops *ops;
|
||||
|
||||
/*
|
||||
* Currently open file stream.
|
||||
*/
|
||||
FILE *fp;
|
||||
|
||||
/*
|
||||
* Head, tail, current position in linked list.
|
||||
*/
|
||||
struct commonio_entry *head, *tail, *cursor;
|
||||
|
||||
/*
|
||||
* Various flags.
|
||||
*/
|
||||
int changed:1;
|
||||
int isopen:1;
|
||||
int locked:1;
|
||||
int readonly:1;
|
||||
int use_lckpwdf:1;
|
||||
};
|
||||
|
||||
extern int commonio_setname P_((struct commonio_db *, const char *));
|
||||
extern int commonio_present P_((const struct commonio_db *));
|
||||
extern int commonio_lock P_((struct commonio_db *));
|
||||
extern int commonio_lock_nowait P_((struct commonio_db *));
|
||||
extern int commonio_open P_((struct commonio_db *, int));
|
||||
extern const void *commonio_locate P_((struct commonio_db *, const char *));
|
||||
extern int commonio_update P_((struct commonio_db *, const void *));
|
||||
extern int commonio_remove P_((struct commonio_db *, const char *));
|
||||
extern int commonio_rewind P_((struct commonio_db *));
|
||||
extern const void *commonio_next P_((struct commonio_db *));
|
||||
extern int commonio_close P_((struct commonio_db *));
|
||||
extern int commonio_unlock P_((struct commonio_db *));
|
||||
extern void commonio_del_entry P_((struct commonio_db *, const struct commonio_entry *));
|
||||
|
319
lib/defines.h
Normal file
319
lib/defines.h
Normal file
@@ -0,0 +1,319 @@
|
||||
/* $Id: defines.h,v 1.14 1999/03/07 19:14:34 marekm Exp $ */
|
||||
/* some useful defines */
|
||||
|
||||
#ifndef _DEFINES_H_
|
||||
#define _DEFINES_H_
|
||||
|
||||
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
|
||||
|
||||
/* Take care of NLS matters. */
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#if !HAVE_SETLOCALE
|
||||
# define setlocale(Category, Locale) /* empty */
|
||||
#endif
|
||||
|
||||
#define gettext_noop(String) (String)
|
||||
/* #define gettext_def(String) "#define String" */
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# undef bindtextdomain
|
||||
# define bindtextdomain(Domain, Directory) /* empty */
|
||||
# undef textdomain
|
||||
# define textdomain(Domain) /* empty */
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
|
||||
#ifndef P_
|
||||
# ifdef PROTOTYPES
|
||||
# define P_(x) x
|
||||
# else
|
||||
# define P_(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else /* not STDC_HEADERS */
|
||||
# ifndef HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr(), *strrchr(), *strtok();
|
||||
# ifndef HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy((s), (d), (n))
|
||||
# endif
|
||||
#endif /* not STDC_HEADERS */
|
||||
|
||||
/* Solaris 2.4 defines __SVR4, but not SVR4 -j. */
|
||||
|
||||
#ifdef __SVR4
|
||||
# ifndef SVR4
|
||||
# define SVR4 __SVR4
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#if HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else /* not TIME_WITH_SYS_TIME */
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif /* not TIME_WITH_SYS_TIME */
|
||||
|
||||
#ifdef HAVE_MEMSET
|
||||
# define memzero(ptr, size) memset((void *)(ptr), 0, (size))
|
||||
#else
|
||||
# define memzero(ptr, size) bzero((char *)(ptr), (size))
|
||||
#endif
|
||||
#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
|
||||
|
||||
#ifdef HAVE_DIRENT_H /* DIR_SYSV */
|
||||
# include <dirent.h>
|
||||
# define DIRECT dirent
|
||||
#else
|
||||
# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# ifdef HAVE_SYS_DIR_H /* DIR_??? */
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# ifdef HAVE_NDIR_H /* DIR_BSD */
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
# define DIRECT direct
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
/*
|
||||
* Possible cases:
|
||||
* - /usr/include/shadow.h exists and includes the shadow group stuff.
|
||||
* - /usr/include/shadow.h exists, but we use our own gshadow.h.
|
||||
* - /usr/include/shadow.h doesn't exist, use our own shadow.h and gshadow.h.
|
||||
*/
|
||||
#if HAVE_SHADOW_H
|
||||
#include <shadow.h>
|
||||
#if defined(SHADOWGRP) && !defined(GSHADOW)
|
||||
#include "gshadow_.h"
|
||||
#endif
|
||||
#else /* not HAVE_SHADOW_H */
|
||||
#include "shadow_.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "gshadow_.h"
|
||||
#endif
|
||||
#endif /* not HAVE_SHADOW_H */
|
||||
#endif /* SHADOWPWD */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef NGROUPS_MAX
|
||||
#ifdef NGROUPS
|
||||
#define NGROUPS_MAX NGROUPS
|
||||
#else
|
||||
#define NGROUPS_MAX 64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_SYSLOG
|
||||
#include <syslog.h>
|
||||
|
||||
#ifndef LOG_WARN
|
||||
#define LOG_WARN LOG_WARNING
|
||||
#endif
|
||||
|
||||
/* cleaner than lots of #ifdefs everywhere - use this as follows:
|
||||
SYSLOG((LOG_CRIT, "user %s cracked root", user)); */
|
||||
#if HAVE_SETLOCALE
|
||||
/* Temporarily set LC_TIME to "C" to avoid strange dates in syslog.
|
||||
This is a workaround for a more general syslog(d) design problem -
|
||||
syslogd should log the current system time for each event, and not
|
||||
trust the formatted time received from the unix domain socket. -MM */
|
||||
#define SYSLOG(x) \
|
||||
do { \
|
||||
char *saved_locale = setlocale(LC_ALL, NULL); \
|
||||
if (saved_locale) \
|
||||
saved_locale = strdup(saved_locale); \
|
||||
if (saved_locale) \
|
||||
setlocale(LC_TIME, "C"); \
|
||||
syslog x ; \
|
||||
if (saved_locale) { \
|
||||
setlocale(LC_ALL, saved_locale); \
|
||||
free(saved_locale); \
|
||||
} \
|
||||
} while (0)
|
||||
#else /* !HAVE_SETLOCALE */
|
||||
#define SYSLOG(x) syslog x
|
||||
#endif /* !HAVE_SETLOCALE */
|
||||
|
||||
#else /* !USE_SYSLOG */
|
||||
|
||||
#define SYSLOG(x) /* empty */
|
||||
#define openlog(a,b,c) /* empty */
|
||||
#define closelog() /* empty */
|
||||
|
||||
#endif /* !USE_SYSLOG */
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
# define X_OK 1
|
||||
# define W_OK 2
|
||||
# define R_OK 4
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
# define SEEK_SET 0
|
||||
# define SEEK_CUR 1
|
||||
# define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifdef STAT_MACROS_BROKEN
|
||||
# define S_ISDIR(x) ((x) & S_IFMT) == S_IFDIR)
|
||||
# define S_ISREG(x) ((x) & S_IFMT) == S_IFREG)
|
||||
# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
|
||||
#if HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
|
||||
# define GTTY(fd, termio) tcgetattr(fd, termio)
|
||||
# define TERMIO struct termios
|
||||
# define USE_TERMIOS
|
||||
#elif HAVE_TERMIO_H
|
||||
# include <sys/ioctl.h>
|
||||
# include <termio.h>
|
||||
# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
|
||||
# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
|
||||
# define TEMRIO struct termio
|
||||
# define USE_TERMIO
|
||||
#elif HAVE_SGTTY_H
|
||||
# include <sgtty.h>
|
||||
# define STTY(fd, termio) stty(fd, termio)
|
||||
# define GTTY(fd, termio) gtty(fd, termio)
|
||||
# define TERMIO struct sgttyb
|
||||
# define USE_SGTTY
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Password aging constants
|
||||
*
|
||||
* DAY - seconds / day
|
||||
* WEEK - seconds / week
|
||||
* SCALE - seconds / aging unit
|
||||
*/
|
||||
|
||||
/* Solaris defines this in shadow.h */
|
||||
#ifndef DAY
|
||||
#define DAY (24L*3600L)
|
||||
#endif
|
||||
|
||||
#define WEEK (7*DAY)
|
||||
|
||||
#ifdef ITI_AGING
|
||||
#define SCALE 1
|
||||
#else
|
||||
#define SCALE DAY
|
||||
#endif
|
||||
|
||||
/* Copy string pointed by B to array A with size checking. It was originally
|
||||
in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
|
||||
very sloppy coding used to assume that BUFSIZ will always be enough... */
|
||||
|
||||
/* danger - side effects */
|
||||
#define STRFCPY(A,B) \
|
||||
(strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
|
||||
|
||||
/* get rid of a few ugly repeated #ifdefs in pwent.c and grent.c */
|
||||
/* XXX - this is ugly too, configure should test it and not check for
|
||||
any hardcoded system names, if possible. --marekm */
|
||||
#if defined(SVR4) || defined(AIX) || defined(__linux__)
|
||||
#define SETXXENT_TYPE void
|
||||
#define SETXXENT_RET(x) return
|
||||
#define SETXXENT_TEST(x) x; if (0) /* compiler should optimize this away */
|
||||
#else
|
||||
#define SETXXENT_TYPE int
|
||||
#define SETXXENT_RET(x) return(x)
|
||||
#define SETXXENT_TEST(x) if (x)
|
||||
#endif
|
||||
|
||||
#ifndef PASSWD_FILE
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
#endif
|
||||
|
||||
#ifndef GROUP_FILE
|
||||
#define GROUP_FILE "/etc/group"
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
#ifndef SHADOW_FILE
|
||||
#define SHADOW_FILE "/etc/shadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#ifndef SGROUP_FILE
|
||||
#define SGROUP_FILE "/etc/gshadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PASSWD_PAG_FILE PASSWD_FILE ".pag"
|
||||
#define GROUP_PAG_FILE GROUP_FILE ".pag"
|
||||
#define SHADOW_PAG_FILE SHADOW_FILE ".pag"
|
||||
#define SGROUP_PAG_FILE SGROUP_FILE ".pag"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
#ifdef sun /* hacks for compiling on SunOS */
|
||||
# ifndef SOLARIS
|
||||
extern int fputs();
|
||||
extern char *strdup();
|
||||
extern char *strerror();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
#include "snprintf.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* string to use for the pw_passwd field in /etc/passwd when using
|
||||
* shadow passwords - most systems use "x" but there are a few
|
||||
* exceptions, so it can be changed here if necessary. --marekm
|
||||
*/
|
||||
#ifndef SHADOW_PASSWD_STRING
|
||||
#define SHADOW_PASSWD_STRING "x"
|
||||
#endif
|
||||
|
||||
#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
|
||||
#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
|
||||
#else
|
||||
#define PAM_STRERROR(pamh, err) pam_strerror(err)
|
||||
#endif
|
||||
|
||||
#endif /* _DEFINES_H_ */
|
77
lib/dialchk.c
Normal file
77
lib/dialchk.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 1989 - 1991, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: dialchk.c,v 1.5 1998/12/28 20:34:34 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "dialup.h"
|
||||
#include "dialchk.h"
|
||||
|
||||
/*
|
||||
* Check for dialup password
|
||||
*
|
||||
* dialcheck tests to see if tty is listed as being a dialup
|
||||
* line. If so, a dialup password may be required if the shell
|
||||
* is listed as one which requires a second password.
|
||||
*/
|
||||
|
||||
int
|
||||
dialcheck(const char *tty, const char *sh)
|
||||
{
|
||||
struct dialup *dialup;
|
||||
char *pass;
|
||||
char *cp;
|
||||
|
||||
setduent ();
|
||||
|
||||
if (! isadialup (tty)) {
|
||||
endduent ();
|
||||
return (1);
|
||||
}
|
||||
if (! (dialup = getdushell (sh))) {
|
||||
endduent ();
|
||||
return (1);
|
||||
}
|
||||
endduent ();
|
||||
|
||||
if (dialup->du_passwd[0] == '\0')
|
||||
return (1);
|
||||
|
||||
if (! (pass = getpass(_("Dialup Password:"))))
|
||||
return (0);
|
||||
|
||||
cp = pw_encrypt (pass, dialup->du_passwd);
|
||||
strzero(pass);
|
||||
return (strcmp (cp, dialup->du_passwd) == 0);
|
||||
}
|
16
lib/dialchk.h
Normal file
16
lib/dialchk.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/* $Id: dialchk.h,v 1.1 1997/12/07 23:26:49 marekm Exp $ */
|
||||
#ifndef _DIALCHK_H_
|
||||
#define _DIALCHK_H_
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/*
|
||||
* Check for dialup password
|
||||
*
|
||||
* dialcheck tests to see if tty is listed as being a dialup
|
||||
* line. If so, a dialup password may be required if the shell
|
||||
* is listed as one which requires a second password.
|
||||
*/
|
||||
extern int dialcheck P_((const char *tty, const char *sh));
|
||||
|
||||
#endif
|
169
lib/dialup.c
Normal file
169
lib/dialup.c
Normal file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 1989 - 1991, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: dialup.c,v 1.3 1997/12/07 23:26:50 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "dialup.h"
|
||||
|
||||
static FILE *dialpwd;
|
||||
|
||||
void
|
||||
setduent(void)
|
||||
{
|
||||
if (dialpwd)
|
||||
rewind (dialpwd);
|
||||
else
|
||||
dialpwd = fopen (DIALPWD, "r");
|
||||
}
|
||||
|
||||
void
|
||||
endduent(void)
|
||||
{
|
||||
if (dialpwd)
|
||||
fclose (dialpwd);
|
||||
|
||||
dialpwd = (FILE *) 0;
|
||||
}
|
||||
|
||||
struct dialup *
|
||||
fgetduent(FILE *fp)
|
||||
{
|
||||
static struct dialup dialup; /* static structure to point to */
|
||||
static char sh[128]; /* some space for a login shell */
|
||||
static char passwd[128]; /* some space for dialup password */
|
||||
char buf[BUFSIZ];
|
||||
char *cp;
|
||||
char *cp2;
|
||||
|
||||
if (! fp)
|
||||
return 0;
|
||||
|
||||
if (! fp || feof (fp))
|
||||
return ((struct dialup *) 0);
|
||||
|
||||
while (fgets (buf, sizeof buf, fp) == buf && buf[0] == '#')
|
||||
;
|
||||
|
||||
if (feof (fp))
|
||||
return ((struct dialup *) 0);
|
||||
|
||||
if ((cp = strchr (buf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
if (! (cp = strchr (buf, ':')))
|
||||
return ((struct dialup *) 0);
|
||||
|
||||
if (cp - buf > sizeof sh) /* something is fishy ... */
|
||||
return ((struct dialup *) 0);
|
||||
|
||||
*cp++ = '\0';
|
||||
(void) strcpy (sh, buf);
|
||||
sh[cp - buf] = '\0';
|
||||
|
||||
if ((cp2 = strchr (cp, ':')))
|
||||
*cp2 = '\0';
|
||||
|
||||
if (strlen (cp) + 1 > sizeof passwd) /* something is REALLY fishy */
|
||||
return ((struct dialup *) 0);
|
||||
|
||||
(void) strcpy (passwd, cp);
|
||||
|
||||
dialup.du_shell = sh;
|
||||
dialup.du_passwd = passwd;
|
||||
|
||||
return (&dialup);
|
||||
}
|
||||
|
||||
struct dialup *
|
||||
getduent(void)
|
||||
{
|
||||
if (! dialpwd)
|
||||
setduent ();
|
||||
|
||||
return fgetduent (dialpwd);
|
||||
}
|
||||
|
||||
struct dialup *
|
||||
getdushell(const char *sh)
|
||||
{
|
||||
struct dialup *dialup;
|
||||
|
||||
while ((dialup = getduent ())) {
|
||||
if (strcmp (sh, dialup->du_shell) == 0)
|
||||
return (dialup);
|
||||
|
||||
if (strcmp (dialup->du_shell, "*") == 0)
|
||||
return (dialup);
|
||||
}
|
||||
return ((struct dialup *) 0);
|
||||
}
|
||||
|
||||
int
|
||||
isadialup(const char *tty)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ];
|
||||
int dialup = 0;
|
||||
|
||||
if (! (fp = fopen (DIALUPS, "r")))
|
||||
return (0);
|
||||
|
||||
while (fgets (buf, sizeof buf, fp) == buf) {
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
|
||||
buf[strlen (buf) - 1] = '\0';
|
||||
|
||||
if (strcmp (buf, tty) == 0) {
|
||||
dialup = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
return (dialup);
|
||||
}
|
||||
|
||||
int
|
||||
putduent(const struct dialup *dial, FILE *fp)
|
||||
{
|
||||
if (! fp || ! dial)
|
||||
return -1;
|
||||
|
||||
if (fprintf (fp, "%s:%s\n", dial->du_shell, dial->du_passwd) == EOF)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
66
lib/dialup.h
Normal file
66
lib/dialup.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 1989 - 1991, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure of the /etc/d_passwd file
|
||||
*
|
||||
* The d_passwd file contains the names of login shells which require
|
||||
* dialup passwords. Each line contains the fully qualified path name
|
||||
* for the shell, followed by an optional password. Each field is
|
||||
* separated by a ':'.
|
||||
*
|
||||
* Structure of the /etc/dialups file
|
||||
*
|
||||
* The dialups file contains the names of ports which may be dialup
|
||||
* lines. Each line consists of the last component of the path
|
||||
* name. The leading "/dev/" string is removed.
|
||||
*
|
||||
* $Id: dialup.h,v 1.2 1997/05/01 23:14:39 marekm Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DIALUP_H
|
||||
#define _DIALUP_H
|
||||
|
||||
struct dialup {
|
||||
char *du_shell;
|
||||
char *du_passwd;
|
||||
};
|
||||
|
||||
extern void setduent P_((void));
|
||||
extern void endduent P_((void));
|
||||
extern struct dialup *fgetduent P_((FILE *));
|
||||
extern struct dialup *getduent P_((void));
|
||||
extern struct dialup *getdushell P_((const char *));
|
||||
extern int putduent P_((const struct dialup *, FILE *));
|
||||
extern int isadialup P_((const char *));
|
||||
|
||||
#define DIALPWD "/etc/d_passwd"
|
||||
#define DIALUPS "/etc/dialups"
|
||||
|
||||
#endif
|
123
lib/encrypt.c
Normal file
123
lib/encrypt.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 1990 - 1993, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: encrypt.c,v 1.6 1999/03/07 19:14:35 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
extern char *crypt();
|
||||
extern char *libshadow_md5_crypt P_((const char *, const char *));
|
||||
|
||||
char *
|
||||
pw_encrypt(const char *clear, const char *salt)
|
||||
{
|
||||
static char cipher[128];
|
||||
char *cp;
|
||||
#ifdef SW_CRYPT
|
||||
static int count;
|
||||
#endif
|
||||
|
||||
#ifdef MD5_CRYPT
|
||||
/*
|
||||
* If the salt string from the password file or from crypt_make_salt()
|
||||
* begins with the magic string, use the new algorithm.
|
||||
*/
|
||||
if (strncmp(salt, "$1$", 3) == 0)
|
||||
return libshadow_md5_crypt(clear, salt);
|
||||
#endif
|
||||
|
||||
#ifdef SW_CRYPT
|
||||
/*
|
||||
* Copy over the salt. It is always the first two
|
||||
* characters of the string.
|
||||
*/
|
||||
|
||||
cipher[0] = salt[0];
|
||||
cipher[1] = salt[1];
|
||||
cipher[2] = '\0';
|
||||
|
||||
/*
|
||||
* Loop up to ten times on the cleartext password.
|
||||
* This is because the input limit for passwords is
|
||||
* 80 characters.
|
||||
*
|
||||
* The initial salt is that provided by the user, or the
|
||||
* one generated above. The subsequent salts are gotten
|
||||
* from the first two characters of the previous encrypted
|
||||
* block of characters.
|
||||
*/
|
||||
|
||||
for (count = 0;count < 10;count++) {
|
||||
cp = crypt(clear, salt);
|
||||
if (!cp) {
|
||||
perror("crypt");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(cp) != 13)
|
||||
return cp;
|
||||
strcat(cipher, cp + 2);
|
||||
salt = cipher + 11 * count + 2;
|
||||
|
||||
if (strlen(clear) > 8)
|
||||
clear += 8;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#else
|
||||
cp = crypt(clear, salt);
|
||||
if (!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...
|
||||
*/
|
||||
perror("crypt");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(cp) != 13)
|
||||
return cp; /* nonstandard crypt() in libc, better bail out */
|
||||
strcpy(cipher, cp);
|
||||
|
||||
#ifdef DOUBLESIZE
|
||||
if (strlen (clear) > 8) {
|
||||
cp = crypt(clear + 8, salt);
|
||||
if (!cp) {
|
||||
perror("crypt");
|
||||
exit(1);
|
||||
}
|
||||
strcat(cipher, cp + 2);
|
||||
}
|
||||
#endif /* DOUBLESIZE */
|
||||
#endif /* SW_CRYPT */
|
||||
return cipher;
|
||||
}
|
55
lib/faillog.h
Normal file
55
lib/faillog.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* faillog.h - login failure logging file format
|
||||
*
|
||||
* $Id: faillog.h,v 1.3 1997/05/01 23:14:39 marekm Exp $
|
||||
*
|
||||
* The login failure file is maintained by login(1) and faillog(8)
|
||||
* Each record in the file represents a separate UID and the file
|
||||
* is indexed in that fashion.
|
||||
*/
|
||||
|
||||
#ifndef _FAILLOG_H
|
||||
#define _FAILLOG_H
|
||||
|
||||
struct faillog {
|
||||
short fail_cnt; /* failures since last success */
|
||||
short fail_max; /* failures before turning account off */
|
||||
char fail_line[12]; /* last failure occured here */
|
||||
time_t fail_time; /* last failure occured then */
|
||||
/*
|
||||
* If nonzero, the account will be re-enabled if there are no
|
||||
* failures for fail_locktime seconds since last failure.
|
||||
*/
|
||||
long fail_locktime;
|
||||
};
|
||||
|
||||
#endif
|
80
lib/fputsx.c
Normal file
80
lib/fputsx.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: fputsx.c,v 1.5 1999/06/07 16:40:44 marekm Exp $")
|
||||
|
||||
char *
|
||||
fgetsx(char *buf, int cnt, FILE *f)
|
||||
{
|
||||
char *cp = buf;
|
||||
char *ep;
|
||||
|
||||
while (cnt > 0) {
|
||||
if (fgets (cp, cnt, f) == 0) {
|
||||
if (cp == buf)
|
||||
return 0;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if ((ep = strrchr (cp, '\\')) && *(ep + 1) == '\n') {
|
||||
if ((cnt -= ep - cp) > 0)
|
||||
*(cp = ep) = '\0';
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
fputsx(const char *s, FILE *stream)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0;*s;i++, s++) {
|
||||
if (putc (*s, stream) == EOF)
|
||||
return EOF;
|
||||
|
||||
#if 0 /* The standard getgr*() can't handle that. --marekm */
|
||||
if (i > (BUFSIZ/2)) {
|
||||
if (putc ('\\', stream) == EOF ||
|
||||
putc ('\n', stream) == EOF)
|
||||
return EOF;
|
||||
|
||||
i = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
400
lib/getdef.c
Normal file
400
lib/getdef.c
Normal file
@@ -0,0 +1,400 @@
|
||||
/*
|
||||
* Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: getdef.c,v 1.12 1999/03/07 19:14:36 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* A configuration item definition.
|
||||
*/
|
||||
|
||||
struct itemdef {
|
||||
const char *name; /* name of the item */
|
||||
char *value; /* value given, or NULL if no value */
|
||||
};
|
||||
|
||||
/*
|
||||
* This list *must* be sorted by the "name" member.
|
||||
*/
|
||||
|
||||
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
|
||||
static struct itemdef def_table[] = {
|
||||
{ "CHFN_AUTH", NULL },
|
||||
{ "CHFN_RESTRICT", NULL },
|
||||
{ "CONSOLE", NULL },
|
||||
{ "CONSOLE_GROUPS", NULL },
|
||||
{ "CRACKLIB_DICTPATH", NULL },
|
||||
{ "CREATE_HOME", NULL },
|
||||
{ "DEFAULT_HOME", NULL },
|
||||
{ "DIALUPS_CHECK_ENAB", NULL },
|
||||
{ "ENVIRON_FILE", NULL },
|
||||
{ "ENV_HZ", NULL },
|
||||
{ "ENV_PATH" , NULL },
|
||||
{ "ENV_SUPATH", NULL },
|
||||
{ "ENV_TZ", NULL },
|
||||
{ "ERASECHAR", NULL },
|
||||
{ "FAILLOG_ENAB", NULL },
|
||||
{ "FAIL_DELAY", NULL },
|
||||
{ "FAKE_SHELL", NULL },
|
||||
{ "FTMP_FILE", NULL },
|
||||
{ "GID_MAX", NULL },
|
||||
{ "GID_MIN", NULL },
|
||||
{ "HUSHLOGIN_FILE", NULL },
|
||||
{ "ISSUE_FILE", NULL },
|
||||
{ "KILLCHAR", NULL },
|
||||
{ "LASTLOG_ENAB", NULL },
|
||||
{ "LOGIN_RETRIES", NULL },
|
||||
{ "LOGIN_STRING", NULL },
|
||||
{ "LOGIN_TIMEOUT", NULL },
|
||||
{ "LOG_OK_LOGINS", NULL },
|
||||
{ "LOG_UNKFAIL_ENAB", NULL },
|
||||
{ "MAIL_CHECK_ENAB", NULL },
|
||||
{ "MAIL_DIR", NULL },
|
||||
{ "MAIL_FILE", NULL },
|
||||
{ "MD5_CRYPT_ENAB", NULL },
|
||||
{ "MOTD_FILE", NULL },
|
||||
{ "NOLOGINS_FILE", NULL },
|
||||
{ "NOLOGIN_STR", NULL },
|
||||
{ "NO_PASSWORD_CONSOLE", NULL },
|
||||
{ "OBSCURE_CHECKS_ENAB", NULL },
|
||||
{ "PASS_ALWAYS_WARN", NULL },
|
||||
{ "PASS_CHANGE_TRIES", NULL },
|
||||
{ "PASS_MAX_DAYS", NULL },
|
||||
{ "PASS_MAX_LEN", NULL },
|
||||
{ "PASS_MIN_DAYS", NULL },
|
||||
{ "PASS_MIN_LEN", NULL },
|
||||
{ "PASS_WARN_AGE", NULL },
|
||||
{ "PORTTIME_CHECKS_ENAB", NULL },
|
||||
{ "QMAIL_DIR", NULL },
|
||||
{ "QUOTAS_ENAB", NULL },
|
||||
{ "SULOG_FILE", NULL },
|
||||
{ "SU_NAME", NULL },
|
||||
{ "SU_WHEEL_ONLY", NULL },
|
||||
#ifdef USE_SYSLOG
|
||||
{ "SYSLOG_SG_ENAB", NULL },
|
||||
{ "SYSLOG_SU_ENAB", NULL },
|
||||
#endif
|
||||
{ "TTYGROUP", NULL },
|
||||
{ "TTYPERM", NULL },
|
||||
{ "TTYTYPE_FILE", NULL },
|
||||
{ "UID_MAX", NULL },
|
||||
{ "UID_MIN", NULL },
|
||||
{ "ULIMIT", NULL },
|
||||
{ "UMASK", NULL },
|
||||
{ "USERDEL_CMD", NULL },
|
||||
};
|
||||
|
||||
#ifndef LOGINDEFS
|
||||
#define LOGINDEFS "/etc/login.defs"
|
||||
#endif
|
||||
|
||||
static char def_fname[] = LOGINDEFS; /* login config defs file */
|
||||
static int def_loaded = 0; /* are defs already loaded? */
|
||||
|
||||
extern long strtol();
|
||||
|
||||
/* local function prototypes */
|
||||
static struct itemdef *def_find P_((const char *));
|
||||
static void def_load P_((void));
|
||||
|
||||
|
||||
/*
|
||||
* getdef_str - get string value from table of definitions.
|
||||
*
|
||||
* Return point to static data for specified item, or NULL if item is not
|
||||
* defined. First time invoked, will load definitions from the file.
|
||||
*/
|
||||
|
||||
char *
|
||||
getdef_str(const char *item)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
return ((d = def_find(item)) == NULL ? (char *)NULL : d->value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getdef_bool - get boolean value from table of definitions.
|
||||
*
|
||||
* Return TRUE if specified item is defined as "yes", else FALSE.
|
||||
*/
|
||||
|
||||
int
|
||||
getdef_bool(const char *item)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
if ((d = def_find(item)) == NULL || d->value == NULL)
|
||||
return 0;
|
||||
|
||||
return (strcasecmp(d->value, "yes") == 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getdef_num - get numerical value from table of definitions
|
||||
*
|
||||
* Returns numeric value of specified item, else the "dflt" value if
|
||||
* the item is not defined. Octal (leading "0") and hex (leading "0x")
|
||||
* values are handled.
|
||||
*/
|
||||
|
||||
int
|
||||
getdef_num(const char *item, int dflt)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
if ((d = def_find(item)) == NULL || d->value == NULL)
|
||||
return dflt;
|
||||
|
||||
return (int) strtol(d->value, (char **)NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getdef_long - get long integer value from table of definitions
|
||||
*
|
||||
* Returns numeric value of specified item, else the "dflt" value if
|
||||
* the item is not defined. Octal (leading "0") and hex (leading "0x")
|
||||
* values are handled.
|
||||
*/
|
||||
|
||||
long
|
||||
getdef_long(const char *item, long dflt)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
if ((d = def_find(item)) == NULL || d->value == NULL)
|
||||
return dflt;
|
||||
|
||||
return strtol(d->value, (char **)NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* putdef_str - override the value read from /etc/login.defs
|
||||
* (also used when loading the initial defaults)
|
||||
*/
|
||||
|
||||
int
|
||||
putdef_str(const char *name, const char *value)
|
||||
{
|
||||
struct itemdef *d;
|
||||
char *cp;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
/*
|
||||
* Locate the slot to save the value. If this parameter
|
||||
* is unknown then "def_find" will print an err message.
|
||||
*/
|
||||
if ((d = def_find(name)) == NULL)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Save off the value.
|
||||
*/
|
||||
if ((cp = strdup(value)) == NULL) {
|
||||
fprintf(stderr,
|
||||
_("Could not allocate space for config info.\n"));
|
||||
SYSLOG((LOG_ERR,
|
||||
"could not allocate space for config info"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (d->value)
|
||||
free(d->value);
|
||||
|
||||
d->value = cp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* def_find - locate named item in table
|
||||
*
|
||||
* Search through a sorted table of configurable items to locate the
|
||||
* specified configuration option.
|
||||
*/
|
||||
|
||||
static struct itemdef *
|
||||
def_find(const char *name)
|
||||
{
|
||||
int min, max, curr, n;
|
||||
|
||||
/*
|
||||
* Invariant - desired item in range [min:max].
|
||||
*/
|
||||
|
||||
min = 0;
|
||||
max = NUMDEFS-1;
|
||||
|
||||
/*
|
||||
* Binary search into the table. Relies on the items being
|
||||
* sorted by name.
|
||||
*/
|
||||
|
||||
while (min <= max) {
|
||||
curr = (min+max)/2;
|
||||
|
||||
if (! (n = strcmp(def_table[curr].name, name)))
|
||||
return &def_table[curr];
|
||||
|
||||
if (n < 0)
|
||||
min = curr+1;
|
||||
else
|
||||
max = curr-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Item was never found.
|
||||
*/
|
||||
|
||||
fprintf(stderr, _("configuration error - unknown item '%s' (notify administrator)\n"), name);
|
||||
SYSLOG((LOG_CRIT, "unknown configuration item `%s'", name));
|
||||
return (struct itemdef *) NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* def_load - load configuration table
|
||||
*
|
||||
* Loads the user-configured options from the default configuration file
|
||||
*/
|
||||
|
||||
static void
|
||||
def_load(void)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
char buf[1024], *name, *value, *s;
|
||||
|
||||
/*
|
||||
* Open the configuration definitions file.
|
||||
*/
|
||||
if ((fp = fopen(def_fname, "r")) == NULL) {
|
||||
SYSLOG((LOG_CRIT, "cannot open login definitions %s [%m]",
|
||||
def_fname));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the initialized flag.
|
||||
* (do it early to prevent recursion in putdef_str())
|
||||
*/
|
||||
++def_loaded;
|
||||
|
||||
/*
|
||||
* Go through all of the lines in the file.
|
||||
*/
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
|
||||
/*
|
||||
* Trim trailing whitespace.
|
||||
*/
|
||||
for (i = strlen(buf)-1 ; i >= 0 ; --i) {
|
||||
if (!isspace(buf[i]))
|
||||
break;
|
||||
}
|
||||
buf[++i] = '\0';
|
||||
|
||||
/*
|
||||
* Break the line into two fields.
|
||||
*/
|
||||
name = buf + strspn(buf, " \t"); /* first nonwhite */
|
||||
if (*name == '\0' || *name == '#')
|
||||
continue; /* comment or empty */
|
||||
|
||||
s = name + strcspn(name, " \t"); /* end of field */
|
||||
if (*s == '\0')
|
||||
continue; /* only 1 field?? */
|
||||
|
||||
*s++ = '\0';
|
||||
value = s + strspn(s, " \"\t"); /* next nonwhite */
|
||||
*(value + strcspn(value, "\"")) = '\0';
|
||||
|
||||
/*
|
||||
* Store the value in def_table.
|
||||
*/
|
||||
putdef_str(name, value);
|
||||
}
|
||||
(void) fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CKDEFS
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
struct itemdef *d;
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
def_load ();
|
||||
|
||||
for (i = 0 ; i < NUMDEFS ; ++i) {
|
||||
if ((d = def_find(def_table[i].name)) == NULL)
|
||||
printf(_("error - lookup '%s' failed\n"), def_table[i].name);
|
||||
else
|
||||
printf("%4d %-24s %s\n", i+1, d->name, d->value);
|
||||
}
|
||||
for (i = 1;i < argc;i++) {
|
||||
if ((cp = getdef_str (argv[1])) != NULL)
|
||||
printf ("%s `%s'\n", argv[1], cp);
|
||||
else
|
||||
printf (_("%s not found\n"), argv[1]);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
11
lib/getdef.h
Normal file
11
lib/getdef.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _GETDEF_H
|
||||
#define _GETDEF_H
|
||||
|
||||
/* getdef.c */
|
||||
extern int getdef_bool P_((const char *));
|
||||
extern long getdef_long P_((const char *, long));
|
||||
extern int getdef_num P_((const char *, int));
|
||||
extern char *getdef_str P_((const char *));
|
||||
extern int putdef_str P_((const char *, const char *));
|
||||
|
||||
#endif /* _GETDEF_H */
|
268
lib/getpass.c
Normal file
268
lib/getpass.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright 1990 - 1995, Julianne Frances Haugh
|
||||
* Copyright 1998, Pavel Machek <pavel@ucw.cz>
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: getpass.c,v 1.9 1999/06/07 16:40:44 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* new code, #undef if there are any problems... */
|
||||
#define USE_SETJMP 1
|
||||
|
||||
#ifdef USE_SETJMP
|
||||
#include <setjmp.h>
|
||||
|
||||
static sigjmp_buf intr; /* where to jump on SIGINT */
|
||||
#endif
|
||||
|
||||
static int sig_caught;
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
#endif
|
||||
|
||||
/*ARGSUSED*/
|
||||
static RETSIGTYPE
|
||||
sig_catch(int sig)
|
||||
{
|
||||
sig_caught = 1;
|
||||
#ifdef USE_SETJMP
|
||||
siglongjmp(intr, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MAXLEN 127
|
||||
|
||||
#ifndef NEW_READPASS /* ./configure --enable-readpass */
|
||||
#define OLD_READPASS 1
|
||||
#endif
|
||||
|
||||
#ifndef OLD_READPASS
|
||||
static char *
|
||||
readpass(FILE *fp)
|
||||
{
|
||||
static char input[MAXLEN + 1], asterix[MAXLEN + 1];
|
||||
static char once;
|
||||
char *cp, *ap, c;
|
||||
int i;
|
||||
|
||||
if (!once) {
|
||||
srandom(time(0)*getpid());
|
||||
once = 1;
|
||||
}
|
||||
cp = input;
|
||||
ap = asterix;
|
||||
while (read(fileno(fp), &c, 1)) {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
goto endwhile;
|
||||
case '\b':
|
||||
case 127:
|
||||
if (cp > input) {
|
||||
cp--; ap--;
|
||||
for (i = 0; i < (*ap); i++) {
|
||||
putc('\b', stdout);
|
||||
putc(' ', stdout);
|
||||
putc('\b', stdout);
|
||||
}
|
||||
} else
|
||||
putc('\a', stdout); /* BEL */
|
||||
break;
|
||||
default:
|
||||
*cp++ = c;
|
||||
*ap++ = (random() % 4)+1;
|
||||
for (i = 0; i < (*(ap-1)); i++)
|
||||
putc('*', stdout);
|
||||
break;
|
||||
}
|
||||
fflush(stdout);
|
||||
if (cp == input + MAXLEN)
|
||||
break;
|
||||
}
|
||||
endwhile:
|
||||
*cp = 0;
|
||||
putc('\n', stdout);
|
||||
return input;
|
||||
}
|
||||
#else
|
||||
static char *
|
||||
readpass(FILE *fp)
|
||||
{
|
||||
static char input[MAXLEN + 1];
|
||||
char *cp;
|
||||
|
||||
if (fgets(input, sizeof input, fp) == input) {
|
||||
if ((cp = strrchr(input, '\n')))
|
||||
*cp = '\0';
|
||||
else
|
||||
input[sizeof input - 1] = '\0';
|
||||
#ifdef USE_SGTTY
|
||||
putc('\n', stdout);
|
||||
#endif
|
||||
return input;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *
|
||||
libshadow_getpass(const char *prompt)
|
||||
{
|
||||
static char nostring[1] = "";
|
||||
static char *return_value;
|
||||
volatile int tty_opened;
|
||||
static FILE *fp;
|
||||
volatile int is_tty;
|
||||
#ifdef HAVE_SIGACTION
|
||||
struct sigaction old_sigact;
|
||||
#else
|
||||
RETSIGTYPE (*old_signal)();
|
||||
#endif
|
||||
TERMIO new_modes;
|
||||
TERMIO old_modes;
|
||||
|
||||
/*
|
||||
* set a flag so the SIGINT signal can be re-sent if it
|
||||
* is caught
|
||||
*/
|
||||
|
||||
sig_caught = 0;
|
||||
return_value = NULL;
|
||||
tty_opened = 0;
|
||||
|
||||
/*
|
||||
* if /dev/tty can't be opened, getpass() needs to read
|
||||
* from stdin instead.
|
||||
*/
|
||||
|
||||
if ((fp = fopen ("/dev/tty", "r")) == 0) {
|
||||
fp = stdin;
|
||||
setbuf (fp, (char *) 0);
|
||||
} else {
|
||||
tty_opened = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* the current tty modes must be saved so they can be
|
||||
* restored later on. echo will be turned off, except
|
||||
* for the newline character (BSD has to punt on this)
|
||||
*/
|
||||
|
||||
is_tty = 1;
|
||||
if (GTTY(fileno(fp), &old_modes)) {
|
||||
is_tty = 0;
|
||||
#if 0 /* to make getpass work with redirected stdin */
|
||||
return_value = NULL;
|
||||
goto out2;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_SETJMP
|
||||
/*
|
||||
* If we get a SIGINT, sig_catch() will jump here -
|
||||
* no need to press Enter after Ctrl-C.
|
||||
*/
|
||||
if (sigsetjmp(intr, 1))
|
||||
goto out;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
sigact.sa_handler = sig_catch;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
sigaction(SIGINT, &sigact, &old_sigact);
|
||||
#else
|
||||
old_signal = signal (SIGINT, sig_catch);
|
||||
#endif
|
||||
|
||||
new_modes = old_modes;
|
||||
|
||||
#ifdef USE_SGTTY
|
||||
new_modes.sg_flags &= ~ECHO ;
|
||||
#else
|
||||
#ifdef OLD_READPASS
|
||||
new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK);
|
||||
#else
|
||||
new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK|ICANON);
|
||||
#endif
|
||||
new_modes.c_lflag |= ECHONL;
|
||||
#endif
|
||||
|
||||
if (is_tty) {
|
||||
if (STTY(fileno(fp), &new_modes))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* the prompt is output, and the response read without
|
||||
* echoing. the trailing newline must be removed. if
|
||||
* the fgets() returns an error, a NULL pointer is
|
||||
* returned.
|
||||
*/
|
||||
|
||||
if ((fputs(prompt, stdout) != EOF) && (fflush(stdout) != EOF))
|
||||
return_value = readpass(fp);
|
||||
out:
|
||||
/*
|
||||
* the old SIGINT handler is restored after the tty
|
||||
* modes. then /dev/tty is closed if it was opened in
|
||||
* the beginning. finally, if a signal was caught it
|
||||
* is sent to this process for normal processing.
|
||||
*/
|
||||
|
||||
if (is_tty) {
|
||||
if (STTY(fileno(fp), &old_modes))
|
||||
return_value = NULL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
(void) sigaction (SIGINT, &old_sigact, NULL);
|
||||
#else
|
||||
(void) signal (SIGINT, old_signal);
|
||||
#endif
|
||||
out2:
|
||||
if (tty_opened)
|
||||
(void) fclose (fp);
|
||||
|
||||
if (sig_caught) {
|
||||
kill(getpid(), SIGINT);
|
||||
return_value = NULL;
|
||||
}
|
||||
if (!return_value) {
|
||||
nostring[0] = '\0';
|
||||
return_value = nostring;
|
||||
}
|
||||
return return_value;
|
||||
}
|
211
lib/grdbm.c
Normal file
211
lib/grdbm.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifdef NDBM
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: grdbm.c,v 1.3 1997/12/07 23:26:52 marekm Exp $")
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
#include <ndbm.h>
|
||||
extern DBM *gr_dbm;
|
||||
|
||||
#define GRP_FRAG 256
|
||||
|
||||
/*
|
||||
* gr_dbm_update
|
||||
*
|
||||
* Updates the DBM password files, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
gr_dbm_update(const struct group *gr)
|
||||
{
|
||||
datum key;
|
||||
datum content;
|
||||
char data[BUFSIZ*8];
|
||||
char grpkey[60];
|
||||
char *cp;
|
||||
int len;
|
||||
int i;
|
||||
int cnt;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! gr_dbm)
|
||||
setgrent ();
|
||||
|
||||
once++;
|
||||
}
|
||||
if (! gr_dbm)
|
||||
return 0;
|
||||
|
||||
len = gr_pack (gr, data);
|
||||
|
||||
if (len <= GRP_FRAG) {
|
||||
content.dsize = len;
|
||||
content.dptr = data;
|
||||
|
||||
key.dsize = strlen (gr->gr_name);
|
||||
key.dptr = gr->gr_name;
|
||||
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
key.dsize = sizeof gr->gr_gid;
|
||||
key.dptr = (char *) &gr->gr_gid;
|
||||
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
} else {
|
||||
content.dsize = sizeof cnt;
|
||||
content.dptr = (char *) &cnt;
|
||||
cnt = (len + (GRP_FRAG-1)) / GRP_FRAG;
|
||||
|
||||
key.dsize = strlen (gr->gr_name);
|
||||
key.dptr = gr->gr_name;
|
||||
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
key.dsize = sizeof gr->gr_gid;
|
||||
key.dptr = (char *) &gr->gr_gid;
|
||||
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
for (cp = data, i = 0;i < cnt;i++) {
|
||||
content.dsize = len > GRP_FRAG ? GRP_FRAG:len;
|
||||
len -= content.dsize;
|
||||
content.dptr = cp;
|
||||
cp += content.dsize;
|
||||
|
||||
key.dsize = sizeof i + strlen (gr->gr_name);
|
||||
key.dptr = grpkey;
|
||||
memcpy (grpkey, (char *) &i, sizeof i);
|
||||
strcpy (grpkey + sizeof i, gr->gr_name);
|
||||
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
key.dsize = sizeof i + sizeof gr->gr_gid;
|
||||
key.dptr = grpkey;
|
||||
memcpy (grpkey, (char *) &i, sizeof i);
|
||||
memcpy (grpkey + sizeof i, (char *) &gr->gr_gid,
|
||||
sizeof gr->gr_gid);
|
||||
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* gr_dbm_remove
|
||||
*
|
||||
* Deletes the DBM group file entries, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
gr_dbm_remove(const struct group *gr)
|
||||
{
|
||||
datum key;
|
||||
datum content;
|
||||
char grpkey[60];
|
||||
int i;
|
||||
int cnt;
|
||||
int errors = 0;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! gr_dbm)
|
||||
setgrent ();
|
||||
|
||||
once++;
|
||||
}
|
||||
if (! gr_dbm)
|
||||
return 0;
|
||||
|
||||
key.dsize = strlen (gr->gr_name);
|
||||
key.dptr = (char *) gr->gr_name;
|
||||
content = dbm_fetch (gr_dbm, key);
|
||||
if (content.dptr == 0)
|
||||
++errors;
|
||||
else {
|
||||
if (content.dsize == sizeof (int)) {
|
||||
memcpy ((char *) &cnt, content.dptr, sizeof cnt);
|
||||
|
||||
for (i = 0;i < cnt;i++) {
|
||||
key.dsize = sizeof i + strlen (gr->gr_name);
|
||||
key.dptr = grpkey;
|
||||
memcpy (grpkey, (char *) &i, sizeof i);
|
||||
strcpy (grpkey + sizeof i, gr->gr_name);
|
||||
if (dbm_delete (gr_dbm, key))
|
||||
++errors;
|
||||
}
|
||||
} else {
|
||||
if (dbm_delete (gr_dbm, key))
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
key.dsize = sizeof gr->gr_gid;
|
||||
key.dptr = (char *) &gr->gr_gid;
|
||||
content = dbm_fetch (gr_dbm, key);
|
||||
if (content.dptr == 0)
|
||||
++errors;
|
||||
else {
|
||||
if (content.dsize == sizeof (int)) {
|
||||
memcpy ((char *) &cnt, content.dptr, sizeof cnt);
|
||||
|
||||
for (i = 0;i < cnt;i++) {
|
||||
key.dsize = sizeof i + sizeof gr->gr_gid;
|
||||
key.dptr = grpkey;
|
||||
memcpy (grpkey, (char *) &i, sizeof i);
|
||||
memcpy (grpkey + sizeof i, (char *) &gr->gr_gid,
|
||||
sizeof gr->gr_gid);
|
||||
|
||||
if (dbm_delete (gr_dbm, key))
|
||||
++errors;
|
||||
}
|
||||
} else {
|
||||
if (dbm_delete (gr_dbm, key))
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
return errors ? 0:1;
|
||||
}
|
||||
|
||||
int
|
||||
gr_dbm_present(void)
|
||||
{
|
||||
return (access(GROUP_PAG_FILE, F_OK) == 0);
|
||||
}
|
||||
#endif
|
185
lib/groupio.c
Normal file
185
lib/groupio.c
Normal file
@@ -0,0 +1,185 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: groupio.c,v 1.7 1998/01/29 23:22:28 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include "commonio.h"
|
||||
#include "groupio.h"
|
||||
|
||||
extern int putgrent P_((const struct group *, FILE *));
|
||||
extern struct group *sgetgrent P_((const char *));
|
||||
|
||||
struct group *
|
||||
__gr_dup(const struct group *grent)
|
||||
{
|
||||
struct group *gr;
|
||||
int i;
|
||||
|
||||
if (!(gr = (struct group *) malloc(sizeof *gr)))
|
||||
return NULL;
|
||||
*gr = *grent;
|
||||
if (!(gr->gr_name = strdup(grent->gr_name)))
|
||||
return NULL;
|
||||
if (!(gr->gr_passwd = strdup(grent->gr_passwd)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; grent->gr_mem[i]; i++)
|
||||
;
|
||||
gr->gr_mem = (char **) malloc((i + 1) * sizeof(char *));
|
||||
if (!gr->gr_mem)
|
||||
return NULL;
|
||||
for (i = 0; grent->gr_mem[i]; i++) {
|
||||
gr->gr_mem[i] = strdup(grent->gr_mem[i]);
|
||||
if (!gr->gr_mem[i])
|
||||
return NULL;
|
||||
}
|
||||
gr->gr_mem[i] = NULL;
|
||||
return gr;
|
||||
}
|
||||
|
||||
static void *
|
||||
group_dup(const void *ent)
|
||||
{
|
||||
const struct group *gr = ent;
|
||||
return __gr_dup(gr);
|
||||
}
|
||||
|
||||
static void
|
||||
group_free(void *ent)
|
||||
{
|
||||
struct group *gr = ent;
|
||||
|
||||
free(gr->gr_name);
|
||||
free(gr->gr_passwd);
|
||||
while(*(gr->gr_mem)) {
|
||||
free(*(gr->gr_mem));
|
||||
gr->gr_mem++;
|
||||
}
|
||||
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;
|
||||
return (putgrent(gr, file) == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct commonio_ops group_ops = {
|
||||
group_dup,
|
||||
group_free,
|
||||
group_getname,
|
||||
group_parse,
|
||||
group_put,
|
||||
fgetsx,
|
||||
fputsx
|
||||
};
|
||||
|
||||
static struct commonio_db group_db = {
|
||||
GROUP_FILE, /* filename */
|
||||
&group_ops, /* ops */
|
||||
NULL, /* fp */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
0, /* changed */
|
||||
0, /* isopen */
|
||||
0, /* locked */
|
||||
0, /* readonly */
|
||||
0 /* use_lckpwdf */
|
||||
};
|
||||
|
||||
int
|
||||
gr_name(const char *filename)
|
||||
{
|
||||
return commonio_setname(&group_db, filename);
|
||||
}
|
||||
|
||||
int
|
||||
gr_lock(void)
|
||||
{
|
||||
return commonio_lock(&group_db);
|
||||
}
|
||||
|
||||
int
|
||||
gr_open(int mode)
|
||||
{
|
||||
return commonio_open(&group_db, mode);
|
||||
}
|
||||
|
||||
const struct group *
|
||||
gr_locate(const char *name)
|
||||
{
|
||||
return commonio_locate(&group_db, name);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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 = 1;
|
||||
}
|
||||
|
||||
struct commonio_entry *
|
||||
__gr_get_head(void)
|
||||
{
|
||||
return group_db.head;
|
||||
}
|
||||
|
||||
void
|
||||
__gr_del_entry(const struct commonio_entry *ent)
|
||||
{
|
||||
commonio_del_entry(&group_db, ent);
|
||||
}
|
12
lib/groupio.h
Normal file
12
lib/groupio.h
Normal file
@@ -0,0 +1,12 @@
|
||||
extern struct group *__gr_dup P_((const struct group *));
|
||||
extern void __gr_set_changed P_((void));
|
||||
extern int gr_close P_((void));
|
||||
extern const struct group *gr_locate P_((const char *));
|
||||
extern int gr_lock P_((void));
|
||||
extern int gr_name P_((const char *));
|
||||
extern const struct group *gr_next P_((void));
|
||||
extern int gr_open P_((int));
|
||||
extern int gr_remove P_((const char *));
|
||||
extern int gr_rewind P_((void));
|
||||
extern int gr_unlock P_((void));
|
||||
extern int gr_update P_((const struct group *));
|
95
lib/grpack.c
Normal file
95
lib/grpack.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 1990, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: grpack.c,v 1.3 1997/12/07 23:26:52 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
int
|
||||
gr_pack(const struct group *group, char *buf)
|
||||
{
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
cp = buf;
|
||||
strcpy (cp, group->gr_name);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
strcpy (cp, group->gr_passwd);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
memcpy (cp, (const char *) &group->gr_gid, sizeof group->gr_gid);
|
||||
cp += sizeof group->gr_gid;
|
||||
|
||||
for (i = 0;group->gr_mem[i];i++) {
|
||||
strcpy (cp, group->gr_mem[i]);
|
||||
cp += strlen (cp) + 1;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
|
||||
return cp - buf;
|
||||
}
|
||||
|
||||
int
|
||||
gr_unpack(char *buf, int len, struct group *group)
|
||||
{
|
||||
char *org = buf;
|
||||
int i;
|
||||
|
||||
group->gr_name = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
group->gr_passwd = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
memcpy ((char *) &group->gr_gid, (char *) buf, sizeof group->gr_gid);
|
||||
buf += sizeof group->gr_gid;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
for (i = 0;*buf && i < 1024;i++) {
|
||||
group->gr_mem[i] = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
}
|
||||
group->gr_mem[i] = (char *) 0;
|
||||
return 0;
|
||||
}
|
167
lib/gsdbm.c
Normal file
167
lib/gsdbm.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#if defined(NDBM) && defined(SHADOWGRP) /*{*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: gsdbm.c,v 1.3 1997/12/07 23:26:53 marekm Exp $")
|
||||
|
||||
#include <ndbm.h>
|
||||
extern DBM *sg_dbm;
|
||||
|
||||
#define GRP_FRAG 256
|
||||
|
||||
/*
|
||||
* sg_dbm_update
|
||||
*
|
||||
* Updates the DBM password files, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
sg_dbm_update(const struct sgrp *sgr)
|
||||
{
|
||||
datum key;
|
||||
datum content;
|
||||
char data[BUFSIZ*8];
|
||||
char sgrpkey[60];
|
||||
char *cp;
|
||||
int len;
|
||||
int i;
|
||||
int cnt;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! sg_dbm)
|
||||
setsgent ();
|
||||
|
||||
once++;
|
||||
}
|
||||
if (! sg_dbm)
|
||||
return 0;
|
||||
|
||||
len = sgr_pack (sgr, data);
|
||||
|
||||
if (len <= GRP_FRAG) {
|
||||
content.dsize = len;
|
||||
content.dptr = data;
|
||||
|
||||
key.dsize = strlen (sgr->sg_name);
|
||||
key.dptr = sgr->sg_name;
|
||||
if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
} else {
|
||||
content.dsize = sizeof cnt;
|
||||
content.dptr = (char *) &cnt;
|
||||
cnt = (len + (GRP_FRAG-1)) / GRP_FRAG;
|
||||
|
||||
key.dsize = strlen (sgr->sg_name);
|
||||
key.dptr = sgr->sg_name;
|
||||
if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
for (cp = data, i = 0;i < cnt;i++) {
|
||||
content.dsize = len > GRP_FRAG ? GRP_FRAG:len;
|
||||
len -= content.dsize;
|
||||
content.dptr = cp;
|
||||
cp += content.dsize;
|
||||
|
||||
key.dsize = sizeof i + strlen (sgr->sg_name);
|
||||
key.dptr = sgrpkey;
|
||||
memcpy (sgrpkey, (char *) &i, sizeof i);
|
||||
strcpy (sgrpkey + sizeof i, sgr->sg_name);
|
||||
if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sg_dbm_remove
|
||||
*
|
||||
* Deletes the DBM shadow group file entries, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
sg_dbm_remove(const char *name)
|
||||
{
|
||||
datum key;
|
||||
datum content;
|
||||
char grpkey[60];
|
||||
int i;
|
||||
int cnt;
|
||||
int errors = 0;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! sg_dbm)
|
||||
setsgent ();
|
||||
|
||||
once++;
|
||||
}
|
||||
if (! sg_dbm)
|
||||
return 0;
|
||||
|
||||
key.dsize = strlen (name);
|
||||
key.dptr = name;
|
||||
content = dbm_fetch (sg_dbm, key);
|
||||
if (content.dptr == 0)
|
||||
++errors;
|
||||
else {
|
||||
if (content.dsize == sizeof (int)) {
|
||||
memcpy ((char *) &cnt, content.dptr, sizeof cnt);
|
||||
|
||||
for (i = 0;i < cnt;i++) {
|
||||
key.dsize = sizeof i + strlen (name);
|
||||
key.dptr = grpkey;
|
||||
memcpy (grpkey, (char *) &i, sizeof i);
|
||||
strcpy (grpkey + sizeof i, name);
|
||||
if (dbm_delete (sg_dbm, key))
|
||||
++errors;
|
||||
}
|
||||
} else {
|
||||
if (dbm_delete (sg_dbm, key))
|
||||
++errors;
|
||||
}
|
||||
}
|
||||
return errors ? 0:1;
|
||||
}
|
||||
|
||||
int
|
||||
sg_dbm_present(void)
|
||||
{
|
||||
return (access(SGROUP_PAG_FILE, F_OK) == 0);
|
||||
}
|
||||
#endif /*} SHADOWGRP && NDBM */
|
528
lib/gshadow.c
Normal file
528
lib/gshadow.c
Normal file
@@ -0,0 +1,528 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
/* Newer versions of Linux libc already have shadow support. */
|
||||
#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: gshadow.c,v 1.6 1998/04/02 21:51:43 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#ifdef NDBM
|
||||
#include <ndbm.h>
|
||||
#include <fcntl.h>
|
||||
DBM *sg_dbm;
|
||||
int sg_dbm_mode = -1;
|
||||
static int dbmopened;
|
||||
static int dbmerror;
|
||||
#endif
|
||||
|
||||
#define MAXMEM 1024
|
||||
|
||||
static FILE *shadow;
|
||||
static char sgrbuf[BUFSIZ*4];
|
||||
static char *members[MAXMEM+1];
|
||||
static char *admins[MAXMEM+1];
|
||||
static struct sgrp sgroup;
|
||||
|
||||
extern char *fgetsx();
|
||||
extern int fputsx();
|
||||
|
||||
#define FIELDS 4
|
||||
|
||||
#ifdef USE_NIS
|
||||
static int nis_used;
|
||||
static int nis_ignore;
|
||||
static enum { native, start, middle, native2 } nis_state;
|
||||
static int nis_bound;
|
||||
static char *nis_domain;
|
||||
static char *nis_key;
|
||||
static int nis_keylen;
|
||||
static char *nis_val;
|
||||
static int nis_vallen;
|
||||
#define IS_NISCHAR(c) ((c)=='+')
|
||||
#endif
|
||||
|
||||
#ifdef USE_NIS
|
||||
|
||||
/*
|
||||
* __setsgNIS - turn on or off NIS searches
|
||||
*/
|
||||
|
||||
void
|
||||
__setsgNIS(int flag)
|
||||
{
|
||||
nis_ignore = ! flag;
|
||||
|
||||
if (nis_ignore)
|
||||
nis_used = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* bind_nis - bind to NIS server
|
||||
*/
|
||||
|
||||
static int
|
||||
bind_nis(void)
|
||||
{
|
||||
if (yp_get_default_domain (&nis_domain))
|
||||
return -1;
|
||||
|
||||
nis_bound = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char **
|
||||
list(char *s, char **l)
|
||||
{
|
||||
int nmembers = 0;
|
||||
|
||||
while (s && *s) {
|
||||
l[nmembers++] = s;
|
||||
if ((s = strchr (s, ',')))
|
||||
*s++ = '\0';
|
||||
}
|
||||
l[nmembers] = (char *) 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
setsgent(void)
|
||||
{
|
||||
#ifdef NDBM
|
||||
int mode;
|
||||
#endif /* NDBM */
|
||||
|
||||
#ifdef USE_NIS
|
||||
nis_state = native;
|
||||
#endif
|
||||
if (shadow)
|
||||
rewind (shadow);
|
||||
else
|
||||
shadow = fopen(SGROUP_FILE, "r");
|
||||
|
||||
/*
|
||||
* Attempt to open the DBM files if they have never been opened
|
||||
* and an error has never been returned.
|
||||
*/
|
||||
|
||||
#ifdef NDBM
|
||||
if (! dbmerror && ! dbmopened) {
|
||||
char dbmfiles[BUFSIZ];
|
||||
|
||||
strcpy (dbmfiles, SGROUP_PAG_FILE);
|
||||
|
||||
if (sg_dbm_mode == -1)
|
||||
mode = O_RDWR;
|
||||
else
|
||||
mode = (sg_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY;
|
||||
|
||||
if (access(dbmfiles, F_OK) ||
|
||||
(! (sg_dbm = dbm_open(SGROUP_FILE, mode, 0))))
|
||||
dbmerror = 1;
|
||||
else
|
||||
dbmopened = 1;
|
||||
}
|
||||
#endif /* NDBM */
|
||||
}
|
||||
|
||||
void
|
||||
endsgent(void)
|
||||
{
|
||||
if (shadow)
|
||||
(void) fclose (shadow);
|
||||
|
||||
shadow = (FILE *) 0;
|
||||
#ifdef NDBM
|
||||
if (dbmopened && sg_dbm) {
|
||||
dbm_close (sg_dbm);
|
||||
dbmopened = 0;
|
||||
sg_dbm = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
struct sgrp *
|
||||
sgetsgent(const char *string)
|
||||
{
|
||||
char *fields[FIELDS];
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
strncpy (sgrbuf, string, (int) sizeof sgrbuf - 1);
|
||||
sgrbuf[sizeof sgrbuf - 1] = '\0';
|
||||
|
||||
if ((cp = strrchr (sgrbuf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
* There should be exactly 4 colon separated fields. Find
|
||||
* all 4 of them and save the starting addresses in fields[].
|
||||
*/
|
||||
|
||||
for (cp = sgrbuf, i = 0;i < FIELDS && cp;i++) {
|
||||
fields[i] = cp;
|
||||
if ((cp = strchr (cp, ':')))
|
||||
*cp++ = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* If there was an extra field somehow, or perhaps not enough,
|
||||
* the line is invalid.
|
||||
*/
|
||||
|
||||
if (cp || i != FIELDS)
|
||||
#ifdef USE_NIS
|
||||
if (! IS_NISCHAR (fields[0][0]))
|
||||
return 0;
|
||||
else
|
||||
nis_used = 1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
sgroup.sg_name = fields[0];
|
||||
sgroup.sg_passwd = fields[1];
|
||||
sgroup.sg_adm = list (fields[2], admins);
|
||||
sgroup.sg_mem = list (fields[3], members);
|
||||
|
||||
return &sgroup;
|
||||
}
|
||||
|
||||
/*
|
||||
* fgetsgent - convert next line in stream to (struct sgrp)
|
||||
*
|
||||
* fgetsgent() reads the next line from the provided stream and
|
||||
* converts it to a (struct sgrp). NULL is returned on EOF.
|
||||
*/
|
||||
|
||||
struct sgrp *
|
||||
fgetsgent(FILE *fp)
|
||||
{
|
||||
char buf[sizeof sgrbuf];
|
||||
char *cp;
|
||||
|
||||
if (! fp)
|
||||
return (0);
|
||||
|
||||
#ifdef USE_NIS
|
||||
while (fgetsx (buf, sizeof buf, fp) != (char *) 0)
|
||||
#else
|
||||
if (fgetsx (buf, sizeof buf, fp) != (char *) 0)
|
||||
#endif
|
||||
{
|
||||
if ((cp = strchr (buf, '\n')))
|
||||
*cp = '\0';
|
||||
#ifdef USE_NIS
|
||||
if (nis_ignore && IS_NISCHAR (buf[0]))
|
||||
continue;
|
||||
#endif
|
||||
return (sgetsgent (buf));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* getsgent - get a single shadow group entry
|
||||
*/
|
||||
|
||||
struct sgrp *
|
||||
getsgent(void)
|
||||
{
|
||||
#ifdef USE_NIS
|
||||
int nis_1_group = 0;
|
||||
struct sgrp *val;
|
||||
char buf[BUFSIZ];
|
||||
#endif
|
||||
if (! shadow)
|
||||
setsgent ();
|
||||
|
||||
#ifdef USE_NIS
|
||||
again:
|
||||
/*
|
||||
* See if we are reading from the local file.
|
||||
*/
|
||||
|
||||
if (nis_state == native || nis_state == native2) {
|
||||
|
||||
/*
|
||||
* Get the next entry from the shadow group file. Return
|
||||
* NULL right away if there is none.
|
||||
*/
|
||||
|
||||
if (! (val = fgetsgent (shadow)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If this entry began with a NIS escape character, we have
|
||||
* to see if this is just a single group, or if the entire
|
||||
* map is being asked for.
|
||||
*/
|
||||
|
||||
if (IS_NISCHAR (val->sg_name[0])) {
|
||||
if (val->sg_name[1])
|
||||
nis_1_group = 1;
|
||||
else
|
||||
nis_state = start;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this isn't a NIS group and this isn't an escape to go
|
||||
* use a NIS map, it must be a regular local group.
|
||||
*/
|
||||
|
||||
if (nis_1_group == 0 && nis_state != start)
|
||||
return val;
|
||||
|
||||
/*
|
||||
* If this is an escape to use an NIS map, switch over to
|
||||
* that bunch of code.
|
||||
*/
|
||||
|
||||
if (nis_state == start)
|
||||
goto again;
|
||||
|
||||
/*
|
||||
* NEEDSWORK. Here we substitute pieces-parts of this entry.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
if (nis_bound == 0) {
|
||||
if (bind_nis ()) {
|
||||
nis_state = native2;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
if (nis_state == start) {
|
||||
if (yp_first (nis_domain, "gshadow.byname", &nis_key,
|
||||
&nis_keylen, &nis_val, &nis_vallen)) {
|
||||
nis_state = native2;
|
||||
goto again;
|
||||
}
|
||||
nis_state = middle;
|
||||
} else if (nis_state == middle) {
|
||||
if (yp_next (nis_domain, "gshadow.byname", nis_key,
|
||||
nis_keylen, &nis_key, &nis_keylen,
|
||||
&nis_val, &nis_vallen)) {
|
||||
nis_state = native2;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return sgetsgent (nis_val);
|
||||
}
|
||||
#else
|
||||
return (fgetsgent (shadow));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* getsgnam - get a shadow group entry by name
|
||||
*/
|
||||
|
||||
struct sgrp *
|
||||
getsgnam(const char *name)
|
||||
{
|
||||
struct sgrp *sgrp;
|
||||
#ifdef NDBM
|
||||
datum key;
|
||||
datum content;
|
||||
#endif
|
||||
#ifdef USE_NIS
|
||||
char buf[BUFSIZ];
|
||||
static char save_name[16];
|
||||
int nis_disabled = 0;
|
||||
#endif
|
||||
|
||||
setsgent ();
|
||||
|
||||
#ifdef NDBM
|
||||
|
||||
/*
|
||||
* If the DBM file are now open, create a key for this group and
|
||||
* try to fetch the entry from the database. A matching record
|
||||
* will be unpacked into a static structure and returned to
|
||||
* the user.
|
||||
*/
|
||||
|
||||
if (dbmopened) {
|
||||
key.dsize = strlen (name);
|
||||
key.dptr = (void *) name;
|
||||
|
||||
content = dbm_fetch (sg_dbm, key);
|
||||
if (content.dptr != 0) {
|
||||
memcpy (sgrbuf, content.dptr, content.dsize);
|
||||
sgroup.sg_mem = members;
|
||||
sgroup.sg_adm = admins;
|
||||
sgr_unpack (sgrbuf, content.dsize, &sgroup);
|
||||
return &sgroup;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NIS
|
||||
if (nis_used) {
|
||||
again:
|
||||
|
||||
/*
|
||||
* Search the gshadow.byname map for this group.
|
||||
*/
|
||||
|
||||
if (! nis_bound)
|
||||
bind_nis ();
|
||||
|
||||
if (nis_bound) {
|
||||
char *cp;
|
||||
|
||||
if (yp_match (nis_domain, "gshadow.byname", name,
|
||||
strlen (name), &nis_val, &nis_vallen) == 0) {
|
||||
if (cp = strchr (nis_val, '\n'))
|
||||
*cp = '\0';
|
||||
|
||||
nis_state = middle;
|
||||
if (sgrp = sgetsgent (nis_val)) {
|
||||
strcpy (save_name, sgrp->sg_name);
|
||||
nis_key = save_name;
|
||||
nis_keylen = strlen (save_name);
|
||||
}
|
||||
return sgrp;
|
||||
}
|
||||
}
|
||||
nis_state = native2;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NIS
|
||||
if (nis_used) {
|
||||
nis_ignore++;
|
||||
nis_disabled++;
|
||||
}
|
||||
#endif
|
||||
while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
|
||||
if (strcmp (name, sgrp->sg_name) == 0)
|
||||
break;
|
||||
}
|
||||
#ifdef USE_NIS
|
||||
nis_ignore--;
|
||||
#endif
|
||||
if (sgrp)
|
||||
return sgrp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* putsgent - output shadow group entry in text form
|
||||
*
|
||||
* putsgent() converts the contents of a (struct sgrp) to text and
|
||||
* writes the result to the given stream. This is the logical
|
||||
* opposite of fgetsgent.
|
||||
*/
|
||||
|
||||
int
|
||||
putsgent(const struct sgrp *sgrp, FILE *fp)
|
||||
{
|
||||
char *buf, *cp;
|
||||
int i;
|
||||
size_t size;
|
||||
|
||||
if (! fp || ! sgrp)
|
||||
return -1;
|
||||
|
||||
/* calculate the required buffer size */
|
||||
size = strlen(sgrp->sg_name) + strlen(sgrp->sg_passwd) + 10;
|
||||
for (i = 0; sgrp->sg_adm && sgrp->sg_adm[i]; i++)
|
||||
size += strlen(sgrp->sg_adm[i]) + 1;
|
||||
for (i = 0; sgrp->sg_mem && sgrp->sg_mem[i]; i++)
|
||||
size += strlen(sgrp->sg_mem[i]) + 1;
|
||||
|
||||
buf = malloc(size);
|
||||
if (!buf)
|
||||
return -1;
|
||||
cp = buf;
|
||||
|
||||
/*
|
||||
* Copy the group name and passwd.
|
||||
*/
|
||||
|
||||
strcpy (cp, sgrp->sg_name);
|
||||
cp += strlen (cp);
|
||||
*cp++ = ':';
|
||||
|
||||
strcpy (cp, sgrp->sg_passwd);
|
||||
cp += strlen (cp);
|
||||
*cp++ = ':';
|
||||
|
||||
/*
|
||||
* Copy the administrators, separating each from the other
|
||||
* with a ",".
|
||||
*/
|
||||
|
||||
for (i = 0;sgrp->sg_adm[i];i++) {
|
||||
if (i > 0)
|
||||
*cp++ = ',';
|
||||
|
||||
strcpy (cp, sgrp->sg_adm[i]);
|
||||
cp += strlen (cp);
|
||||
}
|
||||
*cp++ = ':';
|
||||
|
||||
/*
|
||||
* Now do likewise with the group members.
|
||||
*/
|
||||
|
||||
for (i = 0;sgrp->sg_mem[i];i++) {
|
||||
if (i > 0)
|
||||
*cp++ = ',';
|
||||
|
||||
strcpy (cp, sgrp->sg_mem[i]);
|
||||
cp += strlen (cp);
|
||||
}
|
||||
*cp++ = '\n';
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
* Output using the function which understands the line
|
||||
* continuation conventions.
|
||||
*/
|
||||
|
||||
if (fputsx(buf, fp) == EOF) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif /*} SHADOWGRP */
|
71
lib/gshadow_.h
Normal file
71
lib/gshadow_.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 1988 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*
|
||||
* $Id: gshadow_.h,v 1.2 1997/05/01 23:14:41 marekm Exp $
|
||||
*/
|
||||
|
||||
#ifndef _H_GSHADOW
|
||||
#define _H_GSHADOW
|
||||
|
||||
/*
|
||||
* Shadow group security file structure
|
||||
*/
|
||||
|
||||
struct sgrp {
|
||||
char *sg_name; /* group name */
|
||||
char *sg_passwd; /* group password */
|
||||
char **sg_adm; /* group administator list */
|
||||
char **sg_mem; /* group membership list */
|
||||
};
|
||||
|
||||
/*
|
||||
* Shadow group security file functions.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
|
||||
#if __STDC__
|
||||
struct sgrp *getsgent (void);
|
||||
struct sgrp *getsgnam (const char *);
|
||||
struct sgrp *sgetsgent (const char *);
|
||||
struct sgrp *fgetsgent (FILE *);
|
||||
void setsgent (void);
|
||||
void endsgent (void);
|
||||
int putsgent (const struct sgrp *, FILE *);
|
||||
#else
|
||||
struct sgrp *getsgent ();
|
||||
struct sgrp *getsgnam ();
|
||||
struct sgrp *sgetsgent ();
|
||||
struct sgrp *fgetsgent ();
|
||||
void setsgent ();
|
||||
void endsgent ();
|
||||
int putsgent ();
|
||||
#endif
|
||||
|
||||
#define GSHADOW "/etc/gshadow"
|
||||
#endif /* ifndef _H_GSHADOW */
|
150
lib/gspack.c
Normal file
150
lib/gspack.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifdef SHADOWGRP /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: gspack.c,v 1.3 1997/12/07 23:26:53 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
|
||||
/*
|
||||
* sgr_pack - convert a shadow group structure to a packed
|
||||
* shadow group record
|
||||
*
|
||||
* sgr_pack takes the shadow group structure and packs
|
||||
* the components in a record. this record will be
|
||||
* unpacked later by sgr_unpack.
|
||||
*/
|
||||
|
||||
int
|
||||
sgr_pack(const struct sgrp *sgrp, char *buf)
|
||||
{
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The name and password are both easy - append each string
|
||||
* to the buffer. These are always the first two strings
|
||||
* in a record.
|
||||
*/
|
||||
|
||||
cp = buf;
|
||||
strcpy (cp, sgrp->sg_name);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
strcpy (cp, sgrp->sg_passwd);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
/*
|
||||
* The arrays of administrators and members are slightly
|
||||
* harder. Each element is appended as a string, with a
|
||||
* final '\0' appended to serve as a blank string. The
|
||||
* number of elements is not known in advance, so the
|
||||
* entire collection of administrators must be scanned to
|
||||
* find the start of the members.
|
||||
*/
|
||||
|
||||
for (i = 0;sgrp->sg_adm[i];i++) {
|
||||
strcpy (cp, sgrp->sg_adm[i]);
|
||||
cp += strlen (cp) + 1;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
|
||||
for (i = 0;sgrp->sg_mem[i];i++) {
|
||||
strcpy (cp, sgrp->sg_mem[i]);
|
||||
cp += strlen (cp) + 1;
|
||||
}
|
||||
*cp++ = '\0';
|
||||
|
||||
return cp - buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* sgr_unpack - convert a packed shadow group record to an
|
||||
* unpacked record
|
||||
*
|
||||
* sgr_unpack converts a record which was packed by sgr_pack
|
||||
* into the normal shadow group structure format.
|
||||
*/
|
||||
|
||||
int
|
||||
sgr_unpack(char *buf, int len, struct sgrp *sgrp)
|
||||
{
|
||||
char *org = buf;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* The name and password are both easy - they are the first
|
||||
* two strings in the record.
|
||||
*/
|
||||
|
||||
sgrp->sg_name = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
sgrp->sg_passwd = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* The administrators and members are slightly more difficult.
|
||||
* The arrays are lists of strings. Each list is terminated
|
||||
* by a string of length zero. This string is detected by
|
||||
* looking for an initial character of '\0'.
|
||||
*/
|
||||
|
||||
for (i = 0;*buf && i < 1024;i++) {
|
||||
sgrp->sg_adm[i] = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
}
|
||||
sgrp->sg_adm[i] = (char *) 0;
|
||||
if (! *buf)
|
||||
buf++;
|
||||
|
||||
for (i = 0;*buf && i < 1024;i++) {
|
||||
sgrp->sg_mem[i] = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
}
|
||||
sgrp->sg_mem[i] = (char *) 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /*}*/
|
50
lib/lastlog_.h
Normal file
50
lib/lastlog_.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* lastlog.h - structure of lastlog file
|
||||
*
|
||||
* $Id: lastlog_.h,v 1.2 1997/05/01 23:14:42 marekm Exp $
|
||||
*
|
||||
* This file defines a lastlog file structure which should be sufficient
|
||||
* to hold the information required by login. It should only be used if
|
||||
* there is no real lastlog.h file.
|
||||
*/
|
||||
|
||||
#ifndef __LASTLOG_H
|
||||
#define __LASTLOG_H
|
||||
|
||||
struct lastlog {
|
||||
time_t ll_time;
|
||||
char ll_line[12];
|
||||
char ll_host[16];
|
||||
};
|
||||
|
||||
#define HAVE_LL_HOST
|
||||
#endif /* _LASTLOG_H */
|
114
lib/lockpw.c
Normal file
114
lib/lockpw.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 1992, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifndef HAVE_LCKPWDF
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: lockpw.c,v 1.4 1998/01/29 23:22:28 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include "pwio.h"
|
||||
#ifdef SHADOWPWD
|
||||
#include "shadowio.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* lckpwdf - lock the password files
|
||||
*/
|
||||
|
||||
int
|
||||
lckpwdf(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We have 15 seconds to lock the whole mess
|
||||
*/
|
||||
|
||||
for (i = 0;i < 15;i++)
|
||||
if (pw_lock ())
|
||||
break;
|
||||
else
|
||||
sleep (1);
|
||||
|
||||
/*
|
||||
* Did we run out of time?
|
||||
*/
|
||||
|
||||
if (i == 15)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Nope, use any remaining time to lock the shadow password
|
||||
* file.
|
||||
*/
|
||||
|
||||
for (;i < 15;i++)
|
||||
if (spw_lock ())
|
||||
break;
|
||||
else
|
||||
sleep (1);
|
||||
|
||||
/*
|
||||
* Out of time yet?
|
||||
*/
|
||||
|
||||
if (i == 15) {
|
||||
pw_unlock ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Nope - and both files are now locked.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ulckpwdf - unlock the password files
|
||||
*/
|
||||
|
||||
int
|
||||
ulckpwdf(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Unlock both files.
|
||||
*/
|
||||
|
||||
return (pw_unlock () && spw_unlock ()) ? 0:-1;
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif
|
261
lib/md5.c
Normal file
261
lib/md5.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* This code implements the MD5 message-digest algorithm.
|
||||
* The algorithm is due to Ron Rivest. This code was
|
||||
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||
* This code is in the public domain; do with it what you wish.
|
||||
*
|
||||
* Equivalent code is available from RSA Data Security, Inc.
|
||||
* This code has been tested against that, and is equivalent,
|
||||
* except that you don't need to include two pages of legalese
|
||||
* with every copy.
|
||||
*
|
||||
* To compute the message digest of a chunk of bytes, declare an
|
||||
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||
* needed on buffers full of bytes, and then call MD5Final, which
|
||||
* will fill a supplied 16-byte array with the digest.
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
#ifdef MD5_CRYPT
|
||||
#include <string.h> /* for memcpy() */
|
||||
#include "md5.h"
|
||||
|
||||
#ifndef HIGHFIRST
|
||||
#define byteReverse(buf, len) /* Nothing */
|
||||
#else
|
||||
void byteReverse(unsigned char *buf, unsigned longs);
|
||||
|
||||
#ifndef ASM_MD5
|
||||
/*
|
||||
* Note: this code is harmless on little-endian machines.
|
||||
*/
|
||||
void
|
||||
byteReverse(unsigned char *buf, unsigned longs)
|
||||
{
|
||||
uint32 t;
|
||||
do {
|
||||
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||
((unsigned) buf[1] << 8 | buf[0]);
|
||||
*(uint32 *) buf = t;
|
||||
buf += 4;
|
||||
} while (--longs);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
void
|
||||
MD5Init(struct MD5Context *ctx)
|
||||
{
|
||||
ctx->buf[0] = 0x67452301;
|
||||
ctx->buf[1] = 0xefcdab89;
|
||||
ctx->buf[2] = 0x98badcfe;
|
||||
ctx->buf[3] = 0x10325476;
|
||||
|
||||
ctx->bits[0] = 0;
|
||||
ctx->bits[1] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update context to reflect the concatenation of another buffer full
|
||||
* of bytes.
|
||||
*/
|
||||
void
|
||||
MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
|
||||
{
|
||||
uint32 t;
|
||||
|
||||
/* Update bitcount */
|
||||
|
||||
t = ctx->bits[0];
|
||||
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
|
||||
ctx->bits[1]++; /* Carry from low to high */
|
||||
ctx->bits[1] += len >> 29;
|
||||
|
||||
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
|
||||
|
||||
/* Handle any leading odd-sized chunks */
|
||||
|
||||
if (t) {
|
||||
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||
|
||||
t = 64 - t;
|
||||
if (len < t) {
|
||||
memcpy(p, buf, len);
|
||||
return;
|
||||
}
|
||||
memcpy(p, buf, t);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
buf += t;
|
||||
len -= t;
|
||||
}
|
||||
/* Process data in 64-byte chunks */
|
||||
|
||||
while (len >= 64) {
|
||||
memcpy(ctx->in, buf, 64);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
buf += 64;
|
||||
len -= 64;
|
||||
}
|
||||
|
||||
/* Handle any remaining bytes of data. */
|
||||
|
||||
memcpy(ctx->in, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Final wrapup - pad to 64-byte boundary with the bit pattern
|
||||
* 1 0* (64-bit count of bits processed, MSB-first)
|
||||
*/
|
||||
void
|
||||
MD5Final(unsigned char digest[16], struct MD5Context *ctx)
|
||||
{
|
||||
unsigned count;
|
||||
unsigned char *p;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||
|
||||
/* Set the first char of padding to 0x80. This is safe since there is
|
||||
always at least one byte free */
|
||||
p = ctx->in + count;
|
||||
*p++ = 0x80;
|
||||
|
||||
/* Bytes of padding needed to make 64 bytes */
|
||||
count = 64 - 1 - count;
|
||||
|
||||
/* Pad out to 56 mod 64 */
|
||||
if (count < 8) {
|
||||
/* Two lots of padding: Pad the first block to 64 bytes */
|
||||
memset(p, 0, count);
|
||||
byteReverse(ctx->in, 16);
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
|
||||
/* Now fill the next block with 56 bytes */
|
||||
memset(ctx->in, 0, 56);
|
||||
} else {
|
||||
/* Pad block to 56 bytes */
|
||||
memset(p, 0, count - 8);
|
||||
}
|
||||
byteReverse(ctx->in, 14);
|
||||
|
||||
/* Append length in bits and transform */
|
||||
((uint32 *) ctx->in)[14] = ctx->bits[0];
|
||||
((uint32 *) ctx->in)[15] = ctx->bits[1];
|
||||
|
||||
MD5Transform(ctx->buf, (uint32 *) ctx->in);
|
||||
byteReverse((unsigned char *) ctx->buf, 4);
|
||||
memcpy(digest, ctx->buf, 16);
|
||||
memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
|
||||
}
|
||||
|
||||
#ifndef ASM_MD5
|
||||
|
||||
/* The four core functions - F1 is optimized somewhat */
|
||||
|
||||
/* #define F1(x, y, z) (x & y | ~x & z) */
|
||||
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define F2(x, y, z) F1(z, x, y)
|
||||
#define F3(x, y, z) (x ^ y ^ z)
|
||||
#define F4(x, y, z) (y ^ (x | ~z))
|
||||
|
||||
/* This is the central step in the MD5 algorithm. */
|
||||
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
|
||||
|
||||
/*
|
||||
* The core of the MD5 algorithm, this alters an existing MD5 hash to
|
||||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void
|
||||
MD5Transform(uint32 buf[4], uint32 const in[16])
|
||||
{
|
||||
register uint32 a, b, c, d;
|
||||
|
||||
a = buf[0];
|
||||
b = buf[1];
|
||||
c = buf[2];
|
||||
d = buf[3];
|
||||
|
||||
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||
|
||||
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||
|
||||
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||
|
||||
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||
|
||||
buf[0] += a;
|
||||
buf[1] += b;
|
||||
buf[2] += c;
|
||||
buf[3] += d;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* MD5_CRYPT */
|
27
lib/md5.h
Normal file
27
lib/md5.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
|
||||
#ifdef __alpha
|
||||
typedef unsigned int uint32;
|
||||
#else
|
||||
typedef unsigned long uint32;
|
||||
#endif
|
||||
|
||||
struct MD5Context {
|
||||
uint32 buf[4];
|
||||
uint32 bits[2];
|
||||
unsigned char in[64];
|
||||
};
|
||||
|
||||
void MD5Init(struct MD5Context *context);
|
||||
void MD5Update(struct MD5Context *context, unsigned char const *buf,
|
||||
unsigned len);
|
||||
void MD5Final(unsigned char digest[16], struct MD5Context *context);
|
||||
void MD5Transform(uint32 buf[4], uint32 const in[16]);
|
||||
|
||||
/*
|
||||
* This is needed to make RSAREF happy on some MS-DOS compilers.
|
||||
*/
|
||||
typedef struct MD5Context MD5_CTX;
|
||||
|
||||
#endif /* !MD5_H */
|
151
lib/md5crypt.c
Normal file
151
lib/md5crypt.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
|
||||
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ported from FreeBSD to Linux, only minimal changes. --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef MD5_CRYPT
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: md5crypt.c,v 1.3 1998/01/29 23:22:29 marekm Exp $")
|
||||
|
||||
#include <unistd.h>
|
||||
/* #include <stdio.h> */
|
||||
#include <string.h>
|
||||
#include "md5.h"
|
||||
|
||||
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
static void
|
||||
to64(char *s, unsigned long v, int n)
|
||||
{
|
||||
while (--n >= 0) {
|
||||
*s++ = itoa64[v&0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* UNIX password
|
||||
*
|
||||
* Use MD5 for what it is best at...
|
||||
*/
|
||||
|
||||
char *
|
||||
libshadow_md5_crypt(const char *pw, const char *salt)
|
||||
{
|
||||
static char *magic = "$1$"; /*
|
||||
* This string is magic for
|
||||
* this algorithm. Having
|
||||
* it this way, we can get
|
||||
* get better later on
|
||||
*/
|
||||
static char passwd[120], *p;
|
||||
static const char *sp,*ep;
|
||||
unsigned char final[16];
|
||||
int sl,pl,i,j;
|
||||
MD5_CTX ctx,ctx1;
|
||||
unsigned long l;
|
||||
|
||||
/* Refine the Salt first */
|
||||
sp = salt;
|
||||
|
||||
/* If it starts with the magic string, then skip that */
|
||||
if(!strncmp(sp,magic,strlen(magic)))
|
||||
sp += strlen(magic);
|
||||
|
||||
/* It stops at the first '$', max 8 chars */
|
||||
for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
|
||||
continue;
|
||||
|
||||
/* get the length of the true salt */
|
||||
sl = ep - sp;
|
||||
|
||||
MD5Init(&ctx);
|
||||
|
||||
/* The password first, since that is what is most unknown */
|
||||
MD5Update(&ctx,pw,strlen(pw));
|
||||
|
||||
/* Then our magic string */
|
||||
MD5Update(&ctx,magic,strlen(magic));
|
||||
|
||||
/* Then the raw salt */
|
||||
MD5Update(&ctx,sp,sl);
|
||||
|
||||
/* Then just as many characters of the MD5(pw,salt,pw) */
|
||||
MD5Init(&ctx1);
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
MD5Update(&ctx1,sp,sl);
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
MD5Final(final,&ctx1);
|
||||
for(pl = strlen(pw); pl > 0; pl -= 16)
|
||||
MD5Update(&ctx,final,pl>16 ? 16 : pl);
|
||||
|
||||
/* Don't leave anything around in vm they could use. */
|
||||
memset(final,0,sizeof final);
|
||||
|
||||
/* Then something really weird... */
|
||||
for (j=0,i = strlen(pw); i ; i >>= 1)
|
||||
if(i&1)
|
||||
MD5Update(&ctx, final+j, 1);
|
||||
else
|
||||
MD5Update(&ctx, pw+j, 1);
|
||||
|
||||
/* Now make the output string */
|
||||
strcpy(passwd,magic);
|
||||
strncat(passwd,sp,sl);
|
||||
strcat(passwd,"$");
|
||||
|
||||
MD5Final(final,&ctx);
|
||||
|
||||
/*
|
||||
* and now, just to make sure things don't run too fast
|
||||
* On a 60 Mhz Pentium this takes 34 msec, so you would
|
||||
* need 30 seconds to build a 1000 entry dictionary...
|
||||
*/
|
||||
for(i=0;i<1000;i++) {
|
||||
MD5Init(&ctx1);
|
||||
if(i & 1)
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
else
|
||||
MD5Update(&ctx1,final,16);
|
||||
|
||||
if(i % 3)
|
||||
MD5Update(&ctx1,sp,sl);
|
||||
|
||||
if(i % 7)
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
|
||||
if(i & 1)
|
||||
MD5Update(&ctx1,final,16);
|
||||
else
|
||||
MD5Update(&ctx1,pw,strlen(pw));
|
||||
MD5Final(final,&ctx1);
|
||||
}
|
||||
|
||||
p = passwd + strlen(passwd);
|
||||
|
||||
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
|
||||
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
|
||||
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
|
||||
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
|
||||
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
|
||||
l = final[11] ; to64(p,l,2); p += 2;
|
||||
*p = '\0';
|
||||
|
||||
/* Don't leave anything around in vm they could use. */
|
||||
memset(final,0,sizeof final);
|
||||
|
||||
return passwd;
|
||||
}
|
||||
#endif
|
60
lib/mkdir.c
Normal file
60
lib/mkdir.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1991, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: mkdir.c,v 1.4 1998/01/29 23:22:30 marekm Exp $")
|
||||
|
||||
/*
|
||||
* mkdir - create a directory
|
||||
*
|
||||
* mkdir is provided for systems which do not include the mkdir()
|
||||
* system call.
|
||||
*/
|
||||
|
||||
int
|
||||
mkdir(const char *dir, int mode)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (fork()) {
|
||||
while (wait(&status) != -1)
|
||||
;
|
||||
|
||||
return status >> 8;
|
||||
}
|
||||
close(2);
|
||||
open("/dev/null", O_WRONLY);
|
||||
umask(0777 & ~ mode);
|
||||
execl("/bin/mkdir", "mkdir", dir, 0);
|
||||
_exit(127);
|
||||
/*NOTREACHED*/
|
||||
}
|
21
lib/pam_defs.h
Normal file
21
lib/pam_defs.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_misc.h>
|
||||
|
||||
/* compatibility with different versions of Linux-PAM */
|
||||
#ifndef PAM_ESTABLISH_CRED
|
||||
#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH
|
||||
#endif
|
||||
#ifndef PAM_DELETE_CRED
|
||||
#define PAM_DELETE_CRED PAM_CRED_DELETE
|
||||
#endif
|
||||
#ifndef PAM_NEW_AUTHTOK_REQD
|
||||
#define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD
|
||||
#endif
|
||||
#ifndef PAM_DATA_SILENT
|
||||
#define PAM_DATA_SILENT 0
|
||||
#endif
|
||||
#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
|
||||
#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
|
||||
#else
|
||||
#define PAM_STRERROR(pamh, err) pam_strerror(err)
|
||||
#endif
|
439
lib/port.c
Normal file
439
lib/port.c
Normal file
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: port.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include "defines.h"
|
||||
#include "port.h"
|
||||
|
||||
extern int errno;
|
||||
|
||||
static FILE *ports;
|
||||
|
||||
/*
|
||||
* portcmp - compare the name of a port to a /etc/porttime entry
|
||||
*
|
||||
* portcmp works like strcmp, except that if the last character
|
||||
* in a failing match is a '*', the match is considered to have
|
||||
* passed. The "*" match is suppressed whenever the port is "SU",
|
||||
* which is the token the "su" command uses to validate access.
|
||||
* A match returns 0, failure returns non-zero.
|
||||
*/
|
||||
|
||||
static int
|
||||
portcmp(const char *pattern, const char *port)
|
||||
{
|
||||
const char *orig = port;
|
||||
|
||||
while (*pattern && *pattern == *port)
|
||||
pattern++, port++;
|
||||
|
||||
if (*pattern == 0 && *port == 0)
|
||||
return 0;
|
||||
if (orig[0] == 'S' && orig[1] == 'U' && orig[2] == '\0')
|
||||
return 1;
|
||||
|
||||
return *pattern == '*' ? 0:1;
|
||||
}
|
||||
|
||||
/*
|
||||
* setportent - open /etc/porttime file or rewind
|
||||
*
|
||||
* the /etc/porttime file is rewound if already open, or
|
||||
* opened for reading.
|
||||
*/
|
||||
|
||||
static void
|
||||
setportent(void)
|
||||
{
|
||||
if (ports)
|
||||
rewind (ports);
|
||||
else
|
||||
ports = fopen (PORTS, "r");
|
||||
}
|
||||
|
||||
/*
|
||||
* endportent - close the /etc/porttime file
|
||||
*
|
||||
* the /etc/porttime file is closed and the ports variable set
|
||||
* to NULL to indicate that the /etc/porttime file is no longer
|
||||
* open.
|
||||
*/
|
||||
|
||||
static void
|
||||
endportent(void)
|
||||
{
|
||||
if (ports)
|
||||
fclose (ports);
|
||||
|
||||
ports = (FILE *) 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* getportent - read a single entry from /etc/porttime
|
||||
*
|
||||
* the next line in /etc/porttime is converted to a (struct port)
|
||||
* and a pointer to a static (struct port) is returned to the
|
||||
* invoker. NULL is returned on either EOF or error. errno is
|
||||
* set to EINVAL on error to distinguish the two conditions.
|
||||
*/
|
||||
|
||||
static struct port *
|
||||
getportent(void)
|
||||
{
|
||||
static struct port port; /* static struct to point to */
|
||||
static char buf[BUFSIZ]; /* some space for stuff */
|
||||
static char *ttys[PORT_TTY+1]; /* some pointers to tty names */
|
||||
static char *users[PORT_IDS+1]; /* some pointers to user ids */
|
||||
static struct pt_time ptimes[PORT_TIMES+1]; /* time ranges */
|
||||
char *cp; /* pointer into line */
|
||||
int dtime; /* scratch time of day */
|
||||
int i, j;
|
||||
int saveerr = errno; /* errno value on entry */
|
||||
|
||||
/*
|
||||
* If the ports file is not open, open the file. Do not rewind
|
||||
* since we want to search from the beginning each time.
|
||||
*/
|
||||
|
||||
if (! ports)
|
||||
setportent ();
|
||||
|
||||
if (! ports) {
|
||||
errno = saveerr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common point for beginning a new line -
|
||||
*
|
||||
* - read a line, and NUL terminate
|
||||
* - skip lines which begin with '#'
|
||||
* - parse off the tty names
|
||||
* - parse off a list of user names
|
||||
* - parse off a list of days and times
|
||||
*/
|
||||
|
||||
again:
|
||||
|
||||
/*
|
||||
* Get the next line and remove the last character, which
|
||||
* is a '\n'. Lines which begin with '#' are all ignored.
|
||||
*/
|
||||
|
||||
if (fgets (buf, sizeof buf, ports) == 0) {
|
||||
errno = saveerr;
|
||||
return 0;
|
||||
}
|
||||
if (buf[0] == '#')
|
||||
goto again;
|
||||
|
||||
/*
|
||||
* Get the name of the TTY device. It is the first colon
|
||||
* separated field, and is the name of the TTY with no
|
||||
* leading "/dev". The entry '*' is used to specify all
|
||||
* TTY devices.
|
||||
*/
|
||||
|
||||
buf[strlen (buf) - 1] = 0;
|
||||
|
||||
port.pt_names = ttys;
|
||||
for (cp = buf, j = 0;j < PORT_TTY;j++) {
|
||||
port.pt_names[j] = cp;
|
||||
while (*cp && *cp != ':' && *cp != ',')
|
||||
cp++;
|
||||
|
||||
if (! *cp)
|
||||
goto again; /* line format error */
|
||||
|
||||
if (*cp == ':') /* end of tty name list */
|
||||
break;
|
||||
|
||||
if (*cp == ',') /* end of current tty name */
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*cp++ = 0;
|
||||
port.pt_names[j + 1] = (char *) 0;
|
||||
|
||||
/*
|
||||
* Get the list of user names. It is the second colon
|
||||
* separated field, and is a comma separated list of user
|
||||
* names. The entry '*' is used to specify all usernames.
|
||||
* The last entry in the list is a (char *) 0 pointer.
|
||||
*/
|
||||
|
||||
if (*cp != ':') {
|
||||
port.pt_users = users;
|
||||
port.pt_users[0] = cp;
|
||||
|
||||
for (j = 1;*cp != ':';cp++) {
|
||||
if (*cp == ',' && j < PORT_IDS) {
|
||||
*cp++ = 0;
|
||||
port.pt_users[j++] = cp;
|
||||
}
|
||||
}
|
||||
port.pt_users[j] = 0;
|
||||
} else
|
||||
port.pt_users = 0;
|
||||
|
||||
if (*cp != ':')
|
||||
goto again;
|
||||
|
||||
*cp++ = 0;
|
||||
|
||||
/*
|
||||
* Get the list of valid times. The times field is the third
|
||||
* colon separated field and is a list of days of the week and
|
||||
* times during which this port may be used by this user. The
|
||||
* valid days are 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', and 'Sa'.
|
||||
*
|
||||
* In addition, the value 'Al' represents all 7 days, and 'Wk'
|
||||
* represents the 5 weekdays.
|
||||
*
|
||||
* Times are given as HHMM-HHMM. The ending time may be before
|
||||
* the starting time. Days are presumed to wrap at 0000.
|
||||
*/
|
||||
|
||||
if (*cp == '\0') {
|
||||
port.pt_times = 0;
|
||||
return &port;
|
||||
}
|
||||
|
||||
port.pt_times = ptimes;
|
||||
|
||||
/*
|
||||
* Get the next comma separated entry
|
||||
*/
|
||||
|
||||
for (j = 0;*cp && j < PORT_TIMES;j++) {
|
||||
|
||||
/*
|
||||
* Start off with no days of the week
|
||||
*/
|
||||
|
||||
port.pt_times[j].t_days = 0;
|
||||
|
||||
/*
|
||||
* Check each two letter sequence to see if it is
|
||||
* one of the abbreviations for the days of the
|
||||
* week or the other two values.
|
||||
*/
|
||||
|
||||
for (i = 0;cp[i] && cp[i + 1] && isalpha (cp[i]);i += 2) {
|
||||
switch ((cp[i] << 8) | (cp[i + 1])) {
|
||||
case ('S' << 8) | 'u':
|
||||
port.pt_times[j].t_days |= 01;
|
||||
break;
|
||||
case ('M' << 8) | 'o':
|
||||
port.pt_times[j].t_days |= 02;
|
||||
break;
|
||||
case ('T' << 8) | 'u':
|
||||
port.pt_times[j].t_days |= 04;
|
||||
break;
|
||||
case ('W' << 8) | 'e':
|
||||
port.pt_times[j].t_days |= 010;
|
||||
break;
|
||||
case ('T' << 8) | 'h':
|
||||
port.pt_times[j].t_days |= 020;
|
||||
break;
|
||||
case ('F' << 8) | 'r':
|
||||
port.pt_times[j].t_days |= 040;
|
||||
break;
|
||||
case ('S' << 8) | 'a':
|
||||
port.pt_times[j].t_days |= 0100;
|
||||
break;
|
||||
case ('W' << 8) | 'k':
|
||||
port.pt_times[j].t_days |= 076;
|
||||
break;
|
||||
case ('A' << 8) | 'l':
|
||||
port.pt_times[j].t_days |= 0177;
|
||||
break;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The default is 'Al' if no days were seen.
|
||||
*/
|
||||
|
||||
if (i == 0)
|
||||
port.pt_times[j].t_days = 0177;
|
||||
|
||||
/*
|
||||
* The start and end times are separated from each
|
||||
* other by a '-'. The times are four digit numbers
|
||||
* representing the times of day.
|
||||
*/
|
||||
|
||||
for (dtime = 0;cp[i] && isdigit (cp[i]);i++)
|
||||
dtime = dtime * 10 + cp[i] - '0';
|
||||
|
||||
if (cp[i] != '-' || dtime > 2400 || dtime % 100 > 59)
|
||||
goto again;
|
||||
port.pt_times[j].t_start = dtime;
|
||||
cp = cp + i + 1;
|
||||
|
||||
for (dtime = i = 0;cp[i] && isdigit (cp[i]);i++)
|
||||
dtime = dtime * 10 + cp[i] - '0';
|
||||
|
||||
if ((cp[i] != ',' && cp[i]) ||
|
||||
dtime > 2400 || dtime % 100 > 59)
|
||||
goto again;
|
||||
|
||||
port.pt_times[j].t_end = dtime;
|
||||
cp = cp + i + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* The end of the list is indicated by a pair of -1's for the
|
||||
* start and end times.
|
||||
*/
|
||||
|
||||
port.pt_times[j].t_start = port.pt_times[j].t_end = -1;
|
||||
|
||||
return &port;
|
||||
}
|
||||
|
||||
/*
|
||||
* getttyuser - get ports information for user and tty
|
||||
*
|
||||
* getttyuser() searches the ports file for an entry with a TTY
|
||||
* and user field both of which match the supplied TTY and
|
||||
* user name. The file is searched from the beginning, so the
|
||||
* entries are treated as an ordered list.
|
||||
*/
|
||||
|
||||
static struct port *
|
||||
getttyuser(const char *tty, const char *user)
|
||||
{
|
||||
int i, j;
|
||||
struct port *port;
|
||||
|
||||
setportent ();
|
||||
|
||||
while ((port = getportent ())) {
|
||||
if (port->pt_names == 0 || port->pt_users == 0)
|
||||
continue;
|
||||
|
||||
for (i = 0;port->pt_names[i];i++)
|
||||
if (portcmp (port->pt_names[i], tty) == 0)
|
||||
break;
|
||||
|
||||
if (port->pt_names[i] == 0)
|
||||
continue;
|
||||
|
||||
for (j = 0;port->pt_users[j];j++)
|
||||
if (strcmp (user, port->pt_users[j]) == 0 ||
|
||||
strcmp (port->pt_users[j], "*") == 0)
|
||||
break;
|
||||
|
||||
if (port->pt_users[j] != 0)
|
||||
break;
|
||||
}
|
||||
endportent ();
|
||||
return port;
|
||||
}
|
||||
|
||||
/*
|
||||
* isttytime - tell if a given user may login at a particular time
|
||||
*
|
||||
* isttytime searches the ports file for an entry which matches
|
||||
* the user name and TTY given.
|
||||
*/
|
||||
|
||||
int
|
||||
isttytime(const char *id, const char *port, time_t when)
|
||||
{
|
||||
int i;
|
||||
int dtime;
|
||||
struct port *pp;
|
||||
struct tm *tm;
|
||||
|
||||
/*
|
||||
* Try to find a matching entry for this user. Default to
|
||||
* letting the user in - there are pleny of ways to have an
|
||||
* entry to match all users.
|
||||
*/
|
||||
|
||||
if (! (pp = getttyuser (port, id)))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* The entry is there, but has no time entries - don't
|
||||
* ever let them login.
|
||||
*/
|
||||
|
||||
if (pp->pt_times == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The current time is converted to HHMM format for
|
||||
* comparision against the time values in the TTY entry.
|
||||
*/
|
||||
|
||||
tm = localtime (&when);
|
||||
dtime = tm->tm_hour * 100 + tm->tm_min;
|
||||
|
||||
/*
|
||||
* Each time entry is compared against the current
|
||||
* time. For entries with the start after the end time,
|
||||
* the comparision is made so that the time is between
|
||||
* midnight and either the start or end time.
|
||||
*/
|
||||
|
||||
for (i = 0;pp->pt_times[i].t_start != -1;i++) {
|
||||
if (! (pp->pt_times[i].t_days & PORT_DAY(tm->tm_wday)))
|
||||
continue;
|
||||
|
||||
if (pp->pt_times[i].t_start <= pp->pt_times[i].t_end) {
|
||||
if (dtime >= pp->pt_times[i].t_start &&
|
||||
dtime <= pp->pt_times[i].t_end)
|
||||
return 1;
|
||||
} else {
|
||||
if (dtime >= pp->pt_times[i].t_start ||
|
||||
dtime <= pp->pt_times[i].t_end)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* No matching time entry was found, user shouldn't
|
||||
* be let in right now.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
81
lib/port.h
Normal file
81
lib/port.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 1989 - 1991, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* port.h - structure of /etc/porttime
|
||||
*
|
||||
* $Id: port.h,v 1.2 1997/05/01 23:14:43 marekm Exp $
|
||||
*
|
||||
* Each entry in /etc/porttime consists of a TTY device
|
||||
* name or "*" to indicate all TTY devices, followed by
|
||||
* a list of 1 or more user IDs or "*" to indicate all
|
||||
* user names, followed by a list of zero or more valid
|
||||
* login times. Login time entries consist of zero or
|
||||
* more day names (Su, Mo, Tu, We, Th, Fr, Sa, Wk, Al)
|
||||
* followed by a pair of time values in HHMM format
|
||||
* separated by a "-".
|
||||
*/
|
||||
|
||||
/*
|
||||
* PORTS - Name of system port access time file.
|
||||
* PORT_IDS - Allowable number of IDs per entry.
|
||||
* PORT_TTY - Allowable number of TTYs per entry.
|
||||
* PORT_TIMES - Allowable number of time entries per entry.
|
||||
* PORT_DAY - Day of the week to a bit value (0 = Sunday).
|
||||
*/
|
||||
|
||||
#define PORTS "/etc/porttime"
|
||||
#define PORT_IDS 64
|
||||
#define PORT_TTY 64
|
||||
#define PORT_TIMES 24
|
||||
#define PORT_DAY(day) (1<<(day))
|
||||
|
||||
/*
|
||||
* pt_names - pointer to array of device names in /dev/
|
||||
* pt_users - pointer to array of applicable user IDs.
|
||||
* pt_times - pointer to list of allowable time periods.
|
||||
*/
|
||||
|
||||
struct port {
|
||||
char **pt_names;
|
||||
char **pt_users;
|
||||
struct pt_time *pt_times;
|
||||
};
|
||||
|
||||
/*
|
||||
* t_days - bit array for each day of the week (0 = Sunday)
|
||||
* t_start - starting time for this entry
|
||||
* t_end - ending time for this entry
|
||||
*/
|
||||
|
||||
struct pt_time {
|
||||
short t_days;
|
||||
short t_start;
|
||||
short t_end;
|
||||
};
|
213
lib/prototypes.h
Normal file
213
lib/prototypes.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/*
|
||||
* prototypes.h
|
||||
*
|
||||
* Missing function prototypes
|
||||
*
|
||||
* Juha Virtanen, <jiivee@hut.fi>; November 1995
|
||||
*/
|
||||
/*
|
||||
* $Id: prototypes.h,v 1.13 1999/07/09 18:02:43 marekm Exp $
|
||||
*
|
||||
* Added a macro to work around ancient (non-ANSI) compilers, just in case
|
||||
* someone ever tries to compile this with SunOS cc... --marekm
|
||||
*/
|
||||
|
||||
#ifndef _PROTOTYPES_H
|
||||
#define _PROTOTYPES_H
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <utmp.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/* addgrps.c */
|
||||
extern int add_groups P_((const char *));
|
||||
extern void add_cons_grps P_((void));
|
||||
|
||||
/* age.c */
|
||||
#ifdef SHADOWPWD
|
||||
extern void agecheck P_((const struct passwd *pw, const struct spwd *sp));
|
||||
extern int expire P_((const struct passwd *pw, const struct spwd *sp));
|
||||
extern int isexpired P_((const struct passwd *pw, const struct spwd *sp));
|
||||
#else
|
||||
extern void agecheck P_((const struct passwd *pw));
|
||||
extern int expire P_((const struct passwd *pw));
|
||||
extern int isexpired P_((const struct passwd *pw));
|
||||
#endif
|
||||
|
||||
/* basename() renamed to Basename() to avoid libc name space confusion */
|
||||
/* basename.c */
|
||||
extern char *Basename P_((char *str));
|
||||
|
||||
/* chkshell.c */
|
||||
extern int check_shell P_((const char *));
|
||||
|
||||
/* chowndir.c */
|
||||
extern int chown_tree P_((const char *, uid_t, uid_t, gid_t, gid_t));
|
||||
|
||||
/* chowntty.c */
|
||||
extern void chown_tty P_((const char *, const struct passwd *));
|
||||
|
||||
/* console.c */
|
||||
extern int console P_((const char *tty));
|
||||
extern int is_listed P_((const char *cfgin, const char *tty, int def));
|
||||
|
||||
/* copydir.c */
|
||||
extern int copy_tree P_((const char *, const char *, uid_t, gid_t));
|
||||
extern int remove_tree P_((const char *));
|
||||
|
||||
/* encrypt.c */
|
||||
extern char *pw_encrypt P_((const char *, const char *));
|
||||
|
||||
/* entry.c */
|
||||
extern void entry P_((const char *name, struct passwd *pwent));
|
||||
|
||||
/* env.c */
|
||||
extern void addenv P_((const char *, const char *));
|
||||
extern void initenv P_((void));
|
||||
extern void set_env P_((int, char * const *));
|
||||
extern void sanitize_env P_((void));
|
||||
|
||||
/* fields.c */
|
||||
extern void change_field P_((char *buf, size_t maxsize, const char *prompt));
|
||||
extern int valid_field P_((const char *field, const char *illegal));
|
||||
|
||||
/* fputsx.c */
|
||||
extern char *fgetsx P_((char *, int, FILE *));
|
||||
extern int fputsx P_((const char *, FILE *));
|
||||
|
||||
/* grdbm.c */
|
||||
extern int gr_dbm_remove P_((const struct group *gr));
|
||||
extern int gr_dbm_update P_((const struct group *gr));
|
||||
extern int gr_dbm_present P_((void));
|
||||
|
||||
/* grent.c */
|
||||
extern int putgrent P_((const struct group *, FILE *));
|
||||
|
||||
/* grpack.c */
|
||||
extern int gr_pack P_((const struct group *group, char *buf));
|
||||
extern int gr_unpack P_((char *buf, int len, struct group *group));
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
/* gsdbm.c */
|
||||
extern int sg_dbm_remove P_((const char *name));
|
||||
extern int sg_dbm_update P_((const struct sgrp *sgr));
|
||||
extern int sg_dbm_present P_((void));
|
||||
|
||||
/* gspack.c */
|
||||
extern int sgr_pack P_((const struct sgrp *sgrp, char *buf));
|
||||
extern int sgr_unpack P_((char *buf, int len, struct sgrp *sgrp));
|
||||
#endif
|
||||
|
||||
/* hushed.c */
|
||||
extern int hushed P_((const struct passwd *pw));
|
||||
|
||||
/* limits.c */
|
||||
extern void setup_limits P_((const struct passwd *));
|
||||
|
||||
/* list.c */
|
||||
extern char **add_list P_((char **list, const char *member));
|
||||
extern char **del_list P_((char **list, const char *member));
|
||||
extern char **dup_list P_((char * const *list));
|
||||
extern int is_on_list P_((char * const *list, const char *member));
|
||||
extern char **comma_to_list P_((const char *comma));
|
||||
|
||||
/* login.c */
|
||||
extern void login_prompt P_((const char *, char *, int));
|
||||
|
||||
/* login_desrpc.c */
|
||||
extern int login_desrpc P_((const char *));
|
||||
|
||||
/* mail.c */
|
||||
extern void mailcheck P_((void));
|
||||
|
||||
/* motd.c */
|
||||
extern void motd P_((void));
|
||||
|
||||
/* myname.c */
|
||||
extern struct passwd *get_my_pwent P_((void));
|
||||
|
||||
/* obscure.c */
|
||||
extern int obscure P_((const char *, const char *, const struct passwd *));
|
||||
|
||||
/* pam_pass.c */
|
||||
extern int do_pam_passwd P_((const char *, int, int));
|
||||
|
||||
/* port.c */
|
||||
extern int isttytime P_((const char *, const char *, time_t));
|
||||
|
||||
/* pwd2spwd.c */
|
||||
#ifdef SHADOWPWD
|
||||
extern struct spwd *pwd_to_spwd P_((const struct passwd *pw));
|
||||
#endif
|
||||
|
||||
/* pwdcheck.c */
|
||||
extern void passwd_check P_((const char *, const char *, const char *));
|
||||
|
||||
/* pwd_init.c */
|
||||
extern void pwd_init P_((void));
|
||||
|
||||
/* pwdbm.c */
|
||||
extern int pw_dbm_remove P_((const struct passwd *pw));
|
||||
extern int pw_dbm_update P_((const struct passwd *pw));
|
||||
extern int pw_dbm_present P_((void));
|
||||
|
||||
/* pwpack.c */
|
||||
extern int pw_pack P_((const struct passwd *passwd, char *buf));
|
||||
extern int pw_unpack P_((char *buf, int len, struct passwd *passwd));
|
||||
|
||||
/* rad64.c */
|
||||
extern int c64i P_((char c));
|
||||
extern int i64c P_((int i));
|
||||
|
||||
/* rlogin.c */
|
||||
extern int do_rlogin P_((const char *, char *, int, char *, int));
|
||||
|
||||
/* setugid.c */
|
||||
extern int setup_groups P_((const struct passwd *));
|
||||
extern int change_uid P_((const struct passwd *));
|
||||
extern int setup_uid_gid P_((const struct passwd *, int));
|
||||
|
||||
/* setup.c */
|
||||
extern void setup P_((struct passwd *info));
|
||||
|
||||
/* setupenv.c */
|
||||
extern void setup_env P_((struct passwd *));
|
||||
|
||||
/* shell.c */
|
||||
extern void shell P_((const char *file, const char *arg));
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
/* spdbm.c */
|
||||
extern int sp_dbm_remove P_((const char *user));
|
||||
extern int sp_dbm_update P_((const struct spwd *sp));
|
||||
extern int sp_dbm_present P_((void));
|
||||
|
||||
/* sppack.c */
|
||||
extern int spw_pack P_((const struct spwd *spwd, char *buf));
|
||||
extern int spw_unpack P_((char *buf, int len, struct spwd *spwd));
|
||||
#endif
|
||||
|
||||
/* strtoday.c */
|
||||
extern long strtoday P_((const char *str));
|
||||
|
||||
/* ttytype.c */
|
||||
extern void ttytype P_((const char *line));
|
||||
|
||||
/* ulimit.c */
|
||||
extern void set_filesize_limit P_((int));
|
||||
|
||||
/* utmp.c */
|
||||
extern void checkutmp P_((int));
|
||||
extern void setutmp P_((const char *, const char *, const char *));
|
||||
|
||||
/* valid.c */
|
||||
extern int valid P_((const char *, const struct passwd *));
|
||||
|
||||
/* xmalloc.c */
|
||||
extern char *xmalloc P_((size_t size));
|
||||
extern char *xstrdup P_((const char *str));
|
||||
|
||||
#endif /* _PROTOTYPES_H */
|
75
lib/putgrent.c
Normal file
75
lib/putgrent.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
int
|
||||
putgrent(const struct group *g, FILE *f)
|
||||
{
|
||||
char *buf, *cp;
|
||||
int i;
|
||||
size_t size;
|
||||
|
||||
if (!g || !f)
|
||||
return -1;
|
||||
|
||||
/* calculate the required buffer size (40 is added for the
|
||||
numeric GID, colons, newline, and terminating NUL). */
|
||||
size = strlen(g->gr_name) + strlen(g->gr_passwd) + 40;
|
||||
for (i = 0; g->gr_mem && g->gr_mem[i]; i++)
|
||||
size += strlen(g->gr_mem[i]) + 1;
|
||||
|
||||
buf = malloc(size);
|
||||
if (!buf)
|
||||
return -1;
|
||||
|
||||
sprintf(buf, "%s:%s:%ld:", g->gr_name, g->gr_passwd, (long) g->gr_gid);
|
||||
cp = buf + strlen(buf);
|
||||
for (i = 0; g->gr_mem && g->gr_mem[i]; i++) {
|
||||
if (i > 0)
|
||||
*cp++ = ',';
|
||||
strcpy(cp, g->gr_mem[i]);
|
||||
cp += strlen(cp);
|
||||
}
|
||||
*cp++ = '\n';
|
||||
*cp = '\0';
|
||||
|
||||
if (fputsx(buf, f) == EOF || ferror(f)) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
72
lib/putpwent.c
Normal file
72
lib/putpwent.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: putpwent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
|
||||
/*
|
||||
* putpwent - Output a (struct passwd) in character format
|
||||
*
|
||||
* putpwent() writes out a (struct passwd) in the format it appears
|
||||
* in in flat ASCII files.
|
||||
*
|
||||
* (Author: Dr. Micheal Newberry)
|
||||
*/
|
||||
|
||||
int
|
||||
putpwent(const struct passwd *p, FILE *f)
|
||||
{
|
||||
int status;
|
||||
|
||||
#if defined(SUN) || defined(BSD) || defined(SUN4)
|
||||
status = fprintf (f, "%s:%s:%d:%d:%s,%s:%s:%s\n",
|
||||
p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid,
|
||||
p->pw_gecos, p->pw_comment, p->pw_dir, p->pw_shell) == EOF;
|
||||
#else
|
||||
status = fprintf (f, "%s:%s", p->pw_name, p->pw_passwd) == EOF;
|
||||
#ifdef ATT_AGE
|
||||
if (p->pw_age && p->pw_age[0])
|
||||
status |= fprintf (f, ",%s", p->pw_age) == EOF;
|
||||
#endif
|
||||
status |= fprintf (f, ":%d:%d:%s", p->pw_uid, p->pw_gid,
|
||||
p->pw_gecos) == EOF;
|
||||
#ifdef ATT_COMMENT
|
||||
if (p->pw_comment && p->pw_comment[0])
|
||||
status |= fprintf (f, ",%s", p->pw_comment) == EOF;
|
||||
#endif
|
||||
status |= fprintf (f, ":%s:%s\n", p->pw_dir, p->pw_shell) == EOF;
|
||||
#endif
|
||||
return status;
|
||||
}
|
103
lib/putspent.c
Normal file
103
lib/putspent.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifdef SHADOWPWD /*{*/
|
||||
#ifndef HAVE_PUTSPENT
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: putspent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
putspent(const struct spwd *sp, FILE *fp)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
if (! fp || ! sp)
|
||||
return -1;
|
||||
|
||||
if (fprintf (fp, "%s:%s:", sp->sp_namp, sp->sp_pwdp) < 0)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_lstchg != -1) {
|
||||
if (fprintf (fp, "%ld:", sp->sp_lstchg) < 0)
|
||||
errors++;
|
||||
} else if (putc (':', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_min != -1) {
|
||||
if (fprintf (fp, "%ld:", sp->sp_min) < 0)
|
||||
errors++;
|
||||
} else if (putc (':', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_max != -1) {
|
||||
if (fprintf (fp, "%ld:", sp->sp_max) < 0)
|
||||
errors++;
|
||||
} else if (putc (':', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_warn != -1) {
|
||||
if (fprintf (fp, "%ld:", sp->sp_warn) < 0)
|
||||
errors++;
|
||||
} else if (putc (':', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_inact != -1) {
|
||||
if (fprintf (fp, "%ld:", sp->sp_inact) < 0)
|
||||
errors++;
|
||||
} else if (putc (':', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_expire != -1) {
|
||||
if (fprintf (fp, "%ld:", sp->sp_expire) < 0)
|
||||
errors++;
|
||||
} else if (putc (':', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (sp->sp_flag != -1) {
|
||||
if (fprintf (fp, "%ld", sp->sp_flag) < 0)
|
||||
errors++;
|
||||
}
|
||||
if (putc ('\n', fp) == EOF)
|
||||
errors++;
|
||||
|
||||
if (errors)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif /*}*/
|
548
lib/pwauth.c
Normal file
548
lib/pwauth.c
Normal file
@@ -0,0 +1,548 @@
|
||||
/*
|
||||
* Copyright 1992 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pwauth.c,v 1.9 1998/12/28 20:34:38 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "pwauth.h"
|
||||
#include "getdef.h"
|
||||
|
||||
#ifdef SKEY
|
||||
#include <skey.h>
|
||||
#endif
|
||||
|
||||
#ifdef OPIE
|
||||
#include <opie.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__ /* standard password prompt by default */
|
||||
static const char *PROMPT = gettext_noop("Password: ");
|
||||
#else
|
||||
static const char *PROMPT = gettext_noop("%s's Password:");
|
||||
#endif
|
||||
|
||||
extern char *getpass();
|
||||
|
||||
#ifdef AUTH_METHODS
|
||||
/*
|
||||
* Look-up table for bound-in methods. Put the name that the
|
||||
* method is known by in the password field as "name" and a
|
||||
* pointer to the function
|
||||
*/
|
||||
|
||||
struct method {
|
||||
char *name;
|
||||
int (*func) P_((const char *, int, const char *));
|
||||
};
|
||||
|
||||
#ifdef PAD_AUTH
|
||||
int pad_auth();
|
||||
#endif
|
||||
static struct method methods[] = {
|
||||
#ifdef PAD_AUTH
|
||||
{ "pad", pad_auth },
|
||||
#endif
|
||||
{ "", 0 }
|
||||
};
|
||||
#endif /* AUTH_METHODS */
|
||||
|
||||
int wipe_clear_pass = 1;
|
||||
char *clear_pass = NULL;
|
||||
|
||||
/*
|
||||
* _old_auth - perform getpass/crypt authentication
|
||||
*
|
||||
* _old_auth gets the user's cleartext password and encrypts it
|
||||
* using the salt in the encrypted password. The results are
|
||||
* compared.
|
||||
*/
|
||||
|
||||
static int
|
||||
_old_auth(const char *cipher, const char *user, int reason, const char *input)
|
||||
{
|
||||
char prompt[1024];
|
||||
char *clear = NULL;
|
||||
const char *cp;
|
||||
int retval;
|
||||
#ifdef SKEY
|
||||
int use_skey = 0;
|
||||
char challenge_info[40];
|
||||
struct skey skey;
|
||||
#endif
|
||||
|
||||
#ifdef OPIE
|
||||
int use_opie = 0;
|
||||
char o_challenge_info[OPIE_CHALLENGE_MAX + 1];
|
||||
struct opie opie;
|
||||
/*
|
||||
* This implementation is based almost entirely on the SKEY code
|
||||
* above. Thus the opie struct is called skey, etc. I am unaware
|
||||
* if the system works at the same time, but I cannot imagine why
|
||||
* anyone would want to do this....
|
||||
* -- A.R.
|
||||
* Mod: 5/14/98 A.R.
|
||||
* Made the OPIE code separate from the S/Key code. Now
|
||||
* (conceivably) both can be compiled in and function apart from
|
||||
* one another (assuming a sysadmin really wants to maintain OPIE
|
||||
* and an S/Key databases....).
|
||||
*
|
||||
* Also cleaned up the code a bit. Will be adding second-prompt
|
||||
* support (the traditional Echo-on S/Key/OPIE-only prompts to let
|
||||
* the users see the one-time passwords they are typing/pasting
|
||||
* in....
|
||||
* -- A.R.
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There are programs for adding and deleting authentication data.
|
||||
*/
|
||||
|
||||
if (reason == PW_ADD || reason == PW_DELETE)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* There are even programs for changing the user name ...
|
||||
*/
|
||||
|
||||
if (reason == PW_CHANGE && input != (char *) 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
*
|
||||
* When we change a password and we are root, we don't prompt.
|
||||
* This is so root can change any password without having to
|
||||
* know it. This is a policy decision that might have to be
|
||||
* revisited.
|
||||
*/
|
||||
|
||||
if (reason == PW_CHANGE && getuid () == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
*
|
||||
* When we are logging in a user with no ciphertext password,
|
||||
* we don't prompt for the password or anything. In reality
|
||||
* the user could just hit <ENTER>, so it doesn't really
|
||||
* matter.
|
||||
*/
|
||||
|
||||
if (cipher == (char *) 0 || *cipher == '\0')
|
||||
return 0;
|
||||
|
||||
#ifdef SKEY
|
||||
/*
|
||||
* If the user has an S/KEY entry show them the pertinent info
|
||||
* and then we can try validating the created cyphertext and the SKEY.
|
||||
* If there is no SKEY information we default to not using SKEY.
|
||||
*/
|
||||
|
||||
if (skeychallenge (&skey, user, challenge_info) == 0)
|
||||
use_skey = 1;
|
||||
#endif
|
||||
|
||||
#ifdef OPIE
|
||||
/*
|
||||
* Ditto above, for OPIE passwords.
|
||||
* -- AR
|
||||
*/
|
||||
|
||||
o_challenge_info[0] = '\0';
|
||||
if (opiechallenge(&opie, user, o_challenge_info) == 0)
|
||||
use_opie = 1;
|
||||
|
||||
if (use_opie == 0)
|
||||
opieverify(&opie, (char *)NULL);
|
||||
/*
|
||||
* This call to opieverify is necessary within OPIE's interface:
|
||||
* Every call to opiechallenge(), which checks to see if the user
|
||||
* has an OPIE password, and if so get the challenge, must be
|
||||
* accompanied by exactly one call to opieverify, which clears
|
||||
* any outstanding locks, and otherwise cleans up.
|
||||
* -- AR
|
||||
*/
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prompt for the password as required. FTPD and REXECD both
|
||||
* get the cleartext password for us.
|
||||
*/
|
||||
|
||||
if (reason != PW_FTP && reason != PW_REXEC && !input) {
|
||||
if (! (cp = getdef_str ("LOGIN_STRING")))
|
||||
cp = PROMPT;
|
||||
#ifdef SKEY
|
||||
if (use_skey)
|
||||
printf ("[%s]\n", challenge_info);
|
||||
#endif
|
||||
|
||||
#ifdef OPIE
|
||||
if (use_opie)
|
||||
printf("[ %s ]\n", o_challenge_info);
|
||||
#endif
|
||||
|
||||
snprintf(prompt, sizeof prompt, cp, user);
|
||||
clear = getpass(_(prompt));
|
||||
if (!clear) {
|
||||
static char c[1];
|
||||
c[0] = '\0';
|
||||
clear = c;
|
||||
}
|
||||
input = clear;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the cleartext password into a ciphertext string.
|
||||
* If the two match, the return value will be zero, which is
|
||||
* SUCCESS. Otherwise we see if SKEY is being used and check
|
||||
* the results there as well.
|
||||
*/
|
||||
|
||||
retval = strcmp(pw_encrypt(input, cipher), cipher);
|
||||
|
||||
#ifdef OPIE
|
||||
/*
|
||||
* This is required because using OPIE, opieverify() MUST be called
|
||||
* opiechallenge() above even if OPIE isn't being used in this case,
|
||||
* so locks get released, etc.
|
||||
* -- AR
|
||||
*/
|
||||
|
||||
if ((retval == 0) && use_opie)
|
||||
opieverify(&opie, (char *)NULL);
|
||||
#endif
|
||||
|
||||
#ifdef SKEY
|
||||
if (retval && use_skey) {
|
||||
int passcheck = -1;
|
||||
|
||||
#if 0 /* some skey libs don't have skey_passcheck. --marekm */
|
||||
passcheck = skey_passcheck(user, input);
|
||||
#else
|
||||
if (skeyverify(&skey, input) == 0)
|
||||
passcheck = skey.n;
|
||||
#endif /* if 0 */
|
||||
if (passcheck > 0)
|
||||
retval = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OPIE
|
||||
if (retval && use_opie) {
|
||||
if (opieverify(&opie, input) == 0)
|
||||
retval = 0;
|
||||
}
|
||||
#endif /* OPIE */
|
||||
|
||||
/*
|
||||
* Things like RADIUS authentication may need the password -
|
||||
* if the external variable wipe_clear_pass is zero, we will
|
||||
* not wipe it (the caller should wipe clear_pass when it is
|
||||
* no longer needed). --marekm
|
||||
*/
|
||||
|
||||
clear_pass = clear;
|
||||
if (wipe_clear_pass && clear && *clear)
|
||||
strzero(clear);
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef AUTH_METHODS
|
||||
/*
|
||||
* _pw_auth - perform alternate password authentication
|
||||
*
|
||||
* pw_auth executes the alternate password authentication method
|
||||
* described in the user's password entry. _pw_auth does the real
|
||||
* work, pw_auth splits the authentication string into individual
|
||||
* command names.
|
||||
*/
|
||||
|
||||
static int
|
||||
_pw_auth(const char *command, const char *user, int reason, const char *input)
|
||||
{
|
||||
RETSIGTYPE (*sigint)();
|
||||
RETSIGTYPE (*sigquit)();
|
||||
#ifdef SIGTSTP
|
||||
RETSIGTYPE (*sigtstp)();
|
||||
#endif
|
||||
int pid;
|
||||
int status;
|
||||
int i;
|
||||
char * const argv[5];
|
||||
int argc = 0;
|
||||
int pipes[2];
|
||||
char *empty_env = NULL;
|
||||
int use_pipe;
|
||||
|
||||
/*
|
||||
* Start with a quick sanity check. ALL command names must
|
||||
* be fully-qualified path names.
|
||||
*/
|
||||
|
||||
if (command[0] != '/')
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Set the keyboard signals to be ignored. When the user kills
|
||||
* the child we don't want the parent dying as well.
|
||||
*/
|
||||
|
||||
sigint = signal (SIGINT, SIG_IGN);
|
||||
sigquit = signal (SIGQUIT, SIG_IGN);
|
||||
#ifdef SIGTSTP
|
||||
sigtstp = signal (SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FTP and REXEC reasons don't give the program direct access
|
||||
* to the user. This means that the program can only get input
|
||||
* from this function. So we set up a pipe for that purpose.
|
||||
*/
|
||||
|
||||
use_pipe = (reason == PW_FTP || reason == PW_REXEC);
|
||||
if (use_pipe)
|
||||
if (pipe (pipes))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* The program will be forked off with the parent process waiting
|
||||
* on the child to tell it how successful it was.
|
||||
*/
|
||||
|
||||
switch (pid = fork ()) {
|
||||
|
||||
/*
|
||||
* The fork() failed completely. Clean up as needed and
|
||||
* return to the caller.
|
||||
*/
|
||||
case -1:
|
||||
if (use_pipe) {
|
||||
close (pipes[0]);
|
||||
close (pipes[1]);
|
||||
}
|
||||
return -1;
|
||||
case 0:
|
||||
|
||||
/*
|
||||
* Let the child catch the SIGINT and SIGQUIT
|
||||
* signals. The parent, however, will continue
|
||||
* to ignore them.
|
||||
*/
|
||||
signal (SIGINT, SIG_DFL);
|
||||
signal (SIGQUIT, SIG_DFL);
|
||||
|
||||
/*
|
||||
* Set up the command line. The first argument is
|
||||
* the name of the command being executed. The
|
||||
* second is the command line option for the reason,
|
||||
* and the third is the user name.
|
||||
*/
|
||||
argv[argc++] = command;
|
||||
switch (reason) {
|
||||
case PW_SU: argv[argc++] = "-s"; break;
|
||||
case PW_LOGIN: argv[argc++] = "-l"; break;
|
||||
case PW_ADD: argv[argc++] = "-a"; break;
|
||||
case PW_CHANGE: argv[argc++] = "-c"; break;
|
||||
case PW_DELETE: argv[argc++] = "-d"; break;
|
||||
case PW_TELNET: argv[argc++] = "-t"; break;
|
||||
case PW_RLOGIN: argv[argc++] = "-r"; break;
|
||||
case PW_FTP: argv[argc++] = "-f"; break;
|
||||
case PW_REXEC: argv[argc++] = "-x"; break;
|
||||
}
|
||||
if (reason == PW_CHANGE && input)
|
||||
argv[argc++] = input;
|
||||
|
||||
argv[argc++] = user;
|
||||
argv[argc] = (char *) 0;
|
||||
|
||||
/*
|
||||
* The FTP and REXEC reasons use a pipe to communicate
|
||||
* with the parent. The other standard I/O descriptors
|
||||
* are closed and re-opened as /dev/null.
|
||||
*/
|
||||
if (use_pipe) {
|
||||
close (0);
|
||||
close (1);
|
||||
close (2);
|
||||
|
||||
if (dup (pipes[0]) != 0)
|
||||
exit (1);
|
||||
|
||||
close (pipes[0]);
|
||||
close (pipes[1]);
|
||||
|
||||
if (open ("/dev/null", O_WRONLY) != 1)
|
||||
exit (1);
|
||||
|
||||
if (open ("/dev/null", O_WRONLY) != 2)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now we execute the command directly.
|
||||
* Do it with empty environment for safety. --marekm
|
||||
*/
|
||||
execve(command, argv, &empty_env);
|
||||
_exit((errno == ENOENT) ? 127 : 126);
|
||||
/*NOTREACHED*/
|
||||
default:
|
||||
/*
|
||||
* FTP and REXEC cause a single line of text to be
|
||||
* sent to the child over a pipe that was set up
|
||||
* earlier.
|
||||
*/
|
||||
if (use_pipe) {
|
||||
close (pipes[0]);
|
||||
|
||||
if (input)
|
||||
write (pipes[1], input, strlen (input));
|
||||
|
||||
write (pipes[1], "\n", 1);
|
||||
close (pipes[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait on the child to die. When it does you will
|
||||
* get the exit status and use that to determine if
|
||||
* the authentication program was successful.
|
||||
*/
|
||||
while ((i = wait (&status)) != pid && i != -1)
|
||||
;
|
||||
|
||||
/*
|
||||
* Re-set the signals to their earlier values.
|
||||
*/
|
||||
signal (SIGINT, sigint);
|
||||
signal (SIGQUIT, sigquit);
|
||||
#ifdef SIGTSTP
|
||||
signal (SIGTSTP, sigtstp);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make sure we found the right process!
|
||||
*/
|
||||
if (i == -1)
|
||||
return -1;
|
||||
|
||||
if (status == 0)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* _builtin_auth - lookup routine in table and execute
|
||||
*/
|
||||
|
||||
static int
|
||||
_builtin_auth(const char *command, const char *user, int reason, const char *input)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Scan the table, looking for a match. If we fall off
|
||||
* the end, it must mean that this method isn't supported,
|
||||
* so we fail the authentication.
|
||||
*/
|
||||
|
||||
for (i = 0;methods[i].name[0];i++) {
|
||||
if (! strcmp (command, methods[i].name))
|
||||
break;
|
||||
}
|
||||
if (methods[i].name[0] == '\0')
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Call the pointed to function with the other three
|
||||
* arguments.
|
||||
*/
|
||||
|
||||
return (methods[i].func) (user, reason, input);
|
||||
}
|
||||
#endif /* AUTH_METHODS */
|
||||
|
||||
/*
|
||||
* This function does the real work. It splits the list of program names
|
||||
* up into individual programs and executes them one at a time.
|
||||
*/
|
||||
|
||||
int
|
||||
pw_auth(const char *command, const char *user, int reason, const char *input)
|
||||
{
|
||||
#ifdef AUTH_METHODS
|
||||
char buf[256];
|
||||
char *cmd, *end;
|
||||
int rc;
|
||||
|
||||
/*
|
||||
* Quick little sanity check ...
|
||||
*/
|
||||
|
||||
if (strlen (command) >= sizeof buf)
|
||||
return -1;
|
||||
|
||||
strcpy (buf, command); /* safe (because of the above check) --marekm */
|
||||
|
||||
/*
|
||||
* Find each command and make sure it is NUL-terminated. Then
|
||||
* invoke _pw_auth to actually run the program. The first
|
||||
* failing program ends the whole mess.
|
||||
*/
|
||||
|
||||
for (cmd = buf;cmd;cmd = end) {
|
||||
if ((end = strchr (cmd, ';')))
|
||||
*end++ = '\0';
|
||||
|
||||
if (cmd[0] != '@')
|
||||
rc = _old_auth (cmd, user, reason, input);
|
||||
else if (cmd[1] == '/')
|
||||
rc = _pw_auth (cmd + 1, user, reason, input);
|
||||
else
|
||||
rc = _builtin_auth (cmd + 1, user, reason, input);
|
||||
if (rc)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return _old_auth(command, user, reason, input);
|
||||
#endif
|
||||
}
|
60
lib/pwauth.h
Normal file
60
lib/pwauth.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 1992 - 1993, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*
|
||||
* $Id: pwauth.h,v 1.2 1997/05/01 23:14:44 marekm Exp $
|
||||
*/
|
||||
|
||||
#if __STDC__
|
||||
int pw_auth(const char *program,const char *user,int flag,const char *input);
|
||||
#else
|
||||
int pw_auth ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Local access
|
||||
*/
|
||||
|
||||
#define PW_SU 1
|
||||
#define PW_LOGIN 2
|
||||
|
||||
/*
|
||||
* Administrative functions
|
||||
*/
|
||||
|
||||
#define PW_ADD 101
|
||||
#define PW_CHANGE 102
|
||||
#define PW_DELETE 103
|
||||
|
||||
/*
|
||||
* Network access
|
||||
*/
|
||||
|
||||
#define PW_TELNET 201
|
||||
#define PW_RLOGIN 202
|
||||
#define PW_FTP 203
|
||||
#define PW_REXEC 204
|
143
lib/pwdbm.c
Normal file
143
lib/pwdbm.c
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifdef NDBM /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pwdbm.c,v 1.4 1997/12/14 20:07:19 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <ndbm.h>
|
||||
extern DBM *pw_dbm;
|
||||
|
||||
/*
|
||||
* pw_dbm_update
|
||||
*
|
||||
* Updates the DBM password files, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
pw_dbm_update(const struct passwd *pw)
|
||||
{
|
||||
datum key;
|
||||
datum content;
|
||||
char data[BUFSIZ];
|
||||
int len;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! pw_dbm)
|
||||
setpwent ();
|
||||
once++;
|
||||
}
|
||||
if (! pw_dbm)
|
||||
return 0;
|
||||
|
||||
len = pw_pack (pw, data);
|
||||
content.dsize = len;
|
||||
content.dptr = data;
|
||||
|
||||
key.dsize = strlen (pw->pw_name);
|
||||
key.dptr = pw->pw_name;
|
||||
|
||||
if (dbm_store(pw_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* XXX - on systems with 16-bit UIDs (such as Linux/x86)
|
||||
* name "aa" and UID 24929 will give the same key. This
|
||||
* happens only rarely, but code which only "works most
|
||||
* of the time" is not good enough...
|
||||
*
|
||||
* This needs to be fixed in several places (pwdbm.c,
|
||||
* grdbm.c, pwent.c, grent.c). Fixing it will cause
|
||||
* incompatibility with existing dbm files.
|
||||
*
|
||||
* Summary: don't use this stuff for now. --marekm
|
||||
*/
|
||||
|
||||
key.dsize = sizeof pw->pw_uid;
|
||||
key.dptr = (char *) &pw->pw_uid;
|
||||
|
||||
if (dbm_store(pw_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* pw_dbm_remove
|
||||
*
|
||||
* Removes the DBM password entry, if it exists.
|
||||
*/
|
||||
|
||||
int
|
||||
pw_dbm_remove(const struct passwd *pw)
|
||||
{
|
||||
datum key;
|
||||
static int once;
|
||||
char data[BUFSIZ];
|
||||
|
||||
if (! once) {
|
||||
if (! pw_dbm)
|
||||
setpwent ();
|
||||
once++;
|
||||
}
|
||||
if (! pw_dbm)
|
||||
return 0;
|
||||
|
||||
key.dsize = strlen (pw->pw_name);
|
||||
key.dptr = pw->pw_name;
|
||||
|
||||
if (dbm_delete (pw_dbm, key))
|
||||
return 0;
|
||||
|
||||
key.dsize = sizeof pw->pw_uid;
|
||||
key.dptr = (char *) &pw->pw_uid;
|
||||
|
||||
if (dbm_delete (pw_dbm, key))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
pw_dbm_present(void)
|
||||
{
|
||||
return (access(PASSWD_PAG_FILE, F_OK) == 0);
|
||||
}
|
||||
#endif /* NDBM */
|
187
lib/pwio.c
Normal file
187
lib/pwio.c
Normal file
@@ -0,0 +1,187 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pwio.c,v 1.9 1998/01/29 23:22:31 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "commonio.h"
|
||||
#include "pwio.h"
|
||||
|
||||
extern struct passwd *sgetpwent P_((const char *));
|
||||
extern int putpwent P_((const struct passwd *, FILE *));
|
||||
|
||||
struct passwd *
|
||||
__pw_dup(const struct passwd *pwent)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
if (!(pw = (struct passwd *) malloc(sizeof *pw)))
|
||||
return NULL;
|
||||
*pw = *pwent;
|
||||
if (!(pw->pw_name = strdup(pwent->pw_name)))
|
||||
return NULL;
|
||||
if (!(pw->pw_passwd = strdup(pwent->pw_passwd)))
|
||||
return NULL;
|
||||
#ifdef ATT_AGE
|
||||
if (!(pw->pw_age = strdup(pwent->pw_age)))
|
||||
return NULL;
|
||||
#endif
|
||||
#ifdef ATT_COMMENT
|
||||
if (!(pw->pw_comment = strdup(pwent->pw_comment)))
|
||||
return NULL;
|
||||
#endif
|
||||
if (!(pw->pw_gecos = strdup(pwent->pw_gecos)))
|
||||
return NULL;
|
||||
if (!(pw->pw_dir = strdup(pwent->pw_dir)))
|
||||
return NULL;
|
||||
if (!(pw->pw_shell = strdup(pwent->pw_shell)))
|
||||
return NULL;
|
||||
return pw;
|
||||
}
|
||||
|
||||
static void *
|
||||
passwd_dup(const void *ent)
|
||||
{
|
||||
const struct passwd *pw = ent;
|
||||
return __pw_dup(pw);
|
||||
}
|
||||
|
||||
static void
|
||||
passwd_free(void *ent)
|
||||
{
|
||||
struct passwd *pw = ent;
|
||||
|
||||
free(pw->pw_name);
|
||||
free(pw->pw_passwd);
|
||||
#ifdef ATT_AGE
|
||||
free(pw->pw_age);
|
||||
#endif
|
||||
#ifdef ATT_COMMENT
|
||||
free(pw->pw_comment);
|
||||
#endif
|
||||
free(pw->pw_gecos);
|
||||
free(pw->pw_dir);
|
||||
free(pw->pw_shell);
|
||||
free(pw);
|
||||
}
|
||||
|
||||
static const char *
|
||||
passwd_getname(const void *ent)
|
||||
{
|
||||
const struct passwd *pw = ent;
|
||||
return pw->pw_name;
|
||||
}
|
||||
|
||||
static void *
|
||||
passwd_parse(const char *line)
|
||||
{
|
||||
return (void *) sgetpwent(line);
|
||||
}
|
||||
|
||||
static int
|
||||
passwd_put(const void *ent, FILE *file)
|
||||
{
|
||||
const struct passwd *pw = ent;
|
||||
return (putpwent(pw, file) == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct commonio_ops passwd_ops = {
|
||||
passwd_dup,
|
||||
passwd_free,
|
||||
passwd_getname,
|
||||
passwd_parse,
|
||||
passwd_put,
|
||||
fgets,
|
||||
fputs
|
||||
};
|
||||
|
||||
static struct commonio_db passwd_db = {
|
||||
PASSWD_FILE, /* filename */
|
||||
&passwd_ops, /* ops */
|
||||
NULL, /* fp */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
0, /* changed */
|
||||
0, /* isopen */
|
||||
0, /* locked */
|
||||
0, /* readonly */
|
||||
1 /* use_lckpwdf */
|
||||
};
|
||||
|
||||
int
|
||||
pw_name(const char *filename)
|
||||
{
|
||||
return commonio_setname(&passwd_db, filename);
|
||||
}
|
||||
|
||||
int
|
||||
pw_lock(void)
|
||||
{
|
||||
return commonio_lock(&passwd_db);
|
||||
}
|
||||
|
||||
int
|
||||
pw_open(int mode)
|
||||
{
|
||||
return commonio_open(&passwd_db, mode);
|
||||
}
|
||||
|
||||
const struct passwd *
|
||||
pw_locate(const char *name)
|
||||
{
|
||||
return commonio_locate(&passwd_db, name);
|
||||
}
|
||||
|
||||
int
|
||||
pw_update(const struct passwd *pw)
|
||||
{
|
||||
return commonio_update(&passwd_db, (const void *) pw);
|
||||
}
|
||||
|
||||
int
|
||||
pw_remove(const char *name)
|
||||
{
|
||||
return commonio_remove(&passwd_db, name);
|
||||
}
|
||||
|
||||
int
|
||||
pw_rewind(void)
|
||||
{
|
||||
return commonio_rewind(&passwd_db);
|
||||
}
|
||||
|
||||
const struct passwd *
|
||||
pw_next(void)
|
||||
{
|
||||
return commonio_next(&passwd_db);
|
||||
}
|
||||
|
||||
int
|
||||
pw_close(void)
|
||||
{
|
||||
return commonio_close(&passwd_db);
|
||||
}
|
||||
|
||||
int
|
||||
pw_unlock(void)
|
||||
{
|
||||
return commonio_unlock(&passwd_db);
|
||||
}
|
||||
|
||||
struct commonio_entry *
|
||||
__pw_get_head(void)
|
||||
{
|
||||
return passwd_db.head;
|
||||
}
|
||||
|
||||
void
|
||||
__pw_del_entry(const struct commonio_entry *ent)
|
||||
{
|
||||
commonio_del_entry(&passwd_db, ent);
|
||||
}
|
12
lib/pwio.h
Normal file
12
lib/pwio.h
Normal file
@@ -0,0 +1,12 @@
|
||||
extern struct passwd *__pw_dup P_((const struct passwd *));
|
||||
extern void __pw_set_changed P_((void));
|
||||
extern int pw_close P_((void));
|
||||
extern const struct passwd *pw_locate P_((const char *));
|
||||
extern int pw_lock P_((void));
|
||||
extern int pw_name P_((const char *));
|
||||
extern const struct passwd *pw_next P_((void));
|
||||
extern int pw_open P_((int));
|
||||
extern int pw_remove P_((const char *));
|
||||
extern int pw_rewind P_((void));
|
||||
extern int pw_unlock P_((void));
|
||||
extern int pw_update P_((const struct passwd *));
|
163
lib/pwpack.c
Normal file
163
lib/pwpack.c
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pwpack.c,v 1.4 1998/04/16 19:57:42 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
|
||||
|
||||
/*
|
||||
* pw_pack - convert a (struct pwd) to a packed record
|
||||
* WARNING: buf must be large enough, no check for overrun!
|
||||
*/
|
||||
|
||||
int
|
||||
pw_pack(const struct passwd *passwd, char *buf)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp = buf;
|
||||
strcpy (cp, passwd->pw_name);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
strcpy (cp, passwd->pw_passwd);
|
||||
#ifdef ATT_AGE
|
||||
if (passwd->pw_age[0]) {
|
||||
*cp++ = ',';
|
||||
strcat (cp, passwd->pw_age);
|
||||
}
|
||||
#endif
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
memcpy (cp, (const char *) &passwd->pw_uid, sizeof passwd->pw_uid);
|
||||
cp += sizeof passwd->pw_uid;
|
||||
|
||||
memcpy (cp, (const char *) &passwd->pw_gid, sizeof passwd->pw_gid);
|
||||
cp += sizeof passwd->pw_gid;
|
||||
#ifdef BSD_QUOTA
|
||||
memcpy (cp, (const char *) &passwd->pw_quota, sizeof passwd->pw_quota);
|
||||
cp += sizeof passwd->pw_quota;
|
||||
#endif
|
||||
#ifdef ATT_COMMENT
|
||||
if (passwd->pw_comment) {
|
||||
strcpy (cp, passwd->pw_comment);
|
||||
cp += strlen (cp) + 1;
|
||||
} else
|
||||
*cp++ = '\0';
|
||||
#endif
|
||||
strcpy (cp, passwd->pw_gecos);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
strcpy (cp, passwd->pw_dir);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
strcpy (cp, passwd->pw_shell);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
return cp - buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* pw_unpack - convert a packed (struct pwd) record to a (struct pwd)
|
||||
*/
|
||||
|
||||
int
|
||||
pw_unpack(char *buf, int len, struct passwd *passwd)
|
||||
{
|
||||
char *org = buf;
|
||||
#ifdef ATT_AGE
|
||||
char *cp;
|
||||
#endif
|
||||
|
||||
memzero(passwd, sizeof *passwd);
|
||||
|
||||
passwd->pw_name = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
passwd->pw_passwd = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
#ifdef ATT_AGE
|
||||
if (cp = strchr (passwd->pw_passwd, ',')) {
|
||||
*cp++ = '\0';
|
||||
passwd->pw_age = cp;
|
||||
} else
|
||||
passwd->pw_age = "";
|
||||
#endif
|
||||
|
||||
memcpy ((void *) &passwd->pw_uid, (void *) buf, sizeof passwd->pw_uid);
|
||||
buf += sizeof passwd->pw_uid;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
memcpy ((void *) &passwd->pw_gid, (void *) buf, sizeof passwd->pw_gid);
|
||||
buf += sizeof passwd->pw_gid;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
#ifdef BSD_QUOTA
|
||||
memcpy ((void *) &passwd->pw_quota, (void *) buf,
|
||||
sizeof passwd->pw_quota);
|
||||
buf += sizeof passwd->pw_quota;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
#endif
|
||||
#ifdef ATT_COMMENT
|
||||
passwd->pw_comment = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
#endif
|
||||
passwd->pw_gecos = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
passwd->pw_dir = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
passwd->pw_shell = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
126
lib/rad64.c
Normal file
126
lib/rad64.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 1989 - 1992, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: rad64.c,v 1.4 1997/12/07 23:26:56 marekm Exp $")
|
||||
|
||||
/*
|
||||
* c64i - convert a radix 64 character to an integer
|
||||
*/
|
||||
|
||||
int
|
||||
c64i(char c)
|
||||
{
|
||||
if (c == '.')
|
||||
return (0);
|
||||
|
||||
if (c == '/')
|
||||
return (1);
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - '0' + 2);
|
||||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (c - 'A' + 12);
|
||||
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return (c - 'a' + 38);
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* i64c - convert an integer to a radix 64 character
|
||||
*/
|
||||
|
||||
int
|
||||
i64c(int i)
|
||||
{
|
||||
if (i <= 0)
|
||||
return ('.');
|
||||
|
||||
if (i == 1)
|
||||
return ('/');
|
||||
|
||||
if (i >= 2 && i < 12)
|
||||
return ('0' - 2 + i);
|
||||
|
||||
if (i >= 12 && i < 38)
|
||||
return ('A' - 12 + i);
|
||||
|
||||
if (i >= 38 && i < 63)
|
||||
return ('a' - 38 + i);
|
||||
|
||||
return ('z');
|
||||
}
|
||||
|
||||
#ifndef HAVE_A64L
|
||||
|
||||
/*
|
||||
* l64a - convert a long to a string of radix 64 characters
|
||||
*/
|
||||
|
||||
char *
|
||||
l64a(long l)
|
||||
{
|
||||
static char buf[8];
|
||||
int i = 0;
|
||||
|
||||
if (l < 0L)
|
||||
return ((char *) 0);
|
||||
|
||||
do {
|
||||
buf[i++] = i64c ((int) (l % 64));
|
||||
buf[i] = '\0';
|
||||
} while (l /= 64L, l > 0 && i < 6);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* a64l - convert a radix 64 string to a long integer
|
||||
*/
|
||||
|
||||
long
|
||||
a64l(const char *s)
|
||||
{
|
||||
int i;
|
||||
long value;
|
||||
long shift = 0;
|
||||
|
||||
for (i = 0, value = 0L;i < 6 && *s;s++) {
|
||||
value += (c64i (*s) << shift);
|
||||
shift += 6;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
#endif /* !HAVE_A64L */
|
22
lib/rcsid.h
Normal file
22
lib/rcsid.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* $Id: rcsid.h,v 1.2 1999/06/07 16:40:44 marekm Exp $
|
||||
*/
|
||||
#define PKG_VER " $Package: " PACKAGE " $ $Version: " VERSION " $ "
|
||||
#if defined(NO_RCSID) || defined(lint)
|
||||
#define RCSID(x) /* empty */
|
||||
#else
|
||||
#if __STDC__
|
||||
/*
|
||||
* This function is never called from anywhere, but it calls itself
|
||||
* recursively only to fool gcc to not generate warnings :-).
|
||||
*/
|
||||
static const char *rcsid(const char *);
|
||||
#define RCSID(x) \
|
||||
static const char *rcsid(const char *s) { \
|
||||
return rcsid(x); }
|
||||
#else /* ! __STDC__ */
|
||||
#define RCSID(x) \
|
||||
static char *rcsid(s) char *s; { \
|
||||
return rcsid(x); }
|
||||
#endif /* ! __STDC__ */
|
||||
#endif
|
91
lib/rename.c
Normal file
91
lib/rename.c
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 1993 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: rename.c,v 1.3 1997/12/07 23:26:57 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* rename - rename a file to another name
|
||||
*
|
||||
* rename is provided for systems which do not include the rename()
|
||||
* system call.
|
||||
*/
|
||||
|
||||
int
|
||||
rename(const char *begin, const char *end)
|
||||
{
|
||||
struct stat s1, s2;
|
||||
extern int errno;
|
||||
int orig_err = errno;
|
||||
|
||||
if (stat (begin, &s1))
|
||||
return -1;
|
||||
|
||||
if (stat (end, &s2)) {
|
||||
errno = orig_err;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* See if this is a cross-device link. We do this to
|
||||
* insure that the link below has a chance of working.
|
||||
*/
|
||||
|
||||
if (s1.st_dev != s2.st_dev) {
|
||||
errno = EXDEV;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we can unlink the existing destination
|
||||
* file. If the unlink works the directory is writable,
|
||||
* so there is no need here to figure that out.
|
||||
*/
|
||||
|
||||
if (unlink (end))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now just link the original name to the final name. If there
|
||||
* was no file previously, this link will fail if the target
|
||||
* directory isn't writable. The unlink will fail if the source
|
||||
* directory isn't writable, but life stinks ...
|
||||
*/
|
||||
|
||||
if (link (begin, end) || unlink (begin))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
59
lib/rmdir.c
Normal file
59
lib/rmdir.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 1991, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: rmdir.c,v 1.4 1998/01/29 23:22:31 marekm Exp $")
|
||||
|
||||
/*
|
||||
* rmdir - remove a directory
|
||||
*
|
||||
* rmdir is provided for systems which do not include the rmdir()
|
||||
* system call.
|
||||
*/
|
||||
|
||||
int
|
||||
rmdir(const char *dir)
|
||||
{
|
||||
int status;
|
||||
|
||||
if (fork()) {
|
||||
while (wait(&status) != -1)
|
||||
;
|
||||
|
||||
return status >> 8;
|
||||
}
|
||||
close(2);
|
||||
open("/dev/null", O_WRONLY);
|
||||
execl("/bin/rmdir", "rmdir", dir, 0);
|
||||
_exit(127);
|
||||
/*NOTREACHED*/
|
||||
}
|
140
lib/sgetgrent.c
Normal file
140
lib/sgetgrent.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: sgetgrent.c,v 1.4 1998/04/02 21:51:45 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include "defines.h"
|
||||
|
||||
#define NFIELDS 4
|
||||
|
||||
/*
|
||||
* list - turn a comma-separated string into an array of (char *)'s
|
||||
*
|
||||
* list() converts the comma-separated list of member names into
|
||||
* an array of character pointers.
|
||||
*
|
||||
* WARNING: I profiled this once with and without strchr() calls
|
||||
* and found that using a register variable and an explicit loop
|
||||
* works best. For large /etc/group files, this is a major win.
|
||||
*
|
||||
* FINALLY added dynamic allocation. Still need to fix sgetsgent().
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
static char **
|
||||
list(char *s)
|
||||
{
|
||||
static char **members = 0;
|
||||
static int size = 0; /* max members + 1 */
|
||||
int i;
|
||||
char **rbuf;
|
||||
|
||||
i = 0;
|
||||
for (;;) {
|
||||
/* check if there is room for another pointer (to a group
|
||||
member name, or terminating NULL). */
|
||||
if (i >= size) {
|
||||
size = i + 100; /* at least: i + 1 */
|
||||
if (members) {
|
||||
rbuf = realloc(members, size * sizeof(char *));
|
||||
} else {
|
||||
/* for old (before ANSI C) implementations of
|
||||
realloc() that don't handle NULL properly */
|
||||
rbuf = malloc(size * sizeof(char *));
|
||||
}
|
||||
if (!rbuf) {
|
||||
if (members)
|
||||
free(members);
|
||||
members = 0;
|
||||
size = 0;
|
||||
return (char **) 0;
|
||||
}
|
||||
members = rbuf;
|
||||
}
|
||||
if (!s || s[0] == '\0')
|
||||
break;
|
||||
members[i++] = s;
|
||||
while (*s && *s != ',')
|
||||
s++;
|
||||
if (*s)
|
||||
*s++ = '\0';
|
||||
}
|
||||
members[i] = (char *) 0;
|
||||
return members;
|
||||
}
|
||||
|
||||
|
||||
struct group *
|
||||
sgetgrent(const char *buf)
|
||||
{
|
||||
static char *grpbuf = 0;
|
||||
static size_t size = 0;
|
||||
static char *grpfields[NFIELDS];
|
||||
static struct group grent;
|
||||
int i;
|
||||
char *cp;
|
||||
|
||||
if (strlen(buf) + 1 > size) {
|
||||
/* no need to use realloc() here - just free it and
|
||||
allocate a larger block */
|
||||
if (grpbuf)
|
||||
free(grpbuf);
|
||||
size = strlen(buf) + 1000; /* at least: strlen(buf) + 1 */
|
||||
grpbuf = malloc(size);
|
||||
if (!grpbuf) {
|
||||
size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
strcpy(grpbuf, buf);
|
||||
|
||||
if ((cp = strrchr(grpbuf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
for (cp = grpbuf, i = 0; i < NFIELDS && cp; i++) {
|
||||
grpfields[i] = cp;
|
||||
if ((cp = strchr(cp, ':')))
|
||||
*cp++ = 0;
|
||||
}
|
||||
if (i < (NFIELDS-1) || *grpfields[2] == '\0')
|
||||
return 0;
|
||||
grent.gr_name = grpfields[0];
|
||||
grent.gr_passwd = grpfields[1];
|
||||
grent.gr_gid = atoi(grpfields[2]);
|
||||
grent.gr_mem = list(grpfields[3]);
|
||||
if (!grent.gr_mem)
|
||||
return (struct group *) 0; /* out of memory */
|
||||
|
||||
return &grent;
|
||||
}
|
136
lib/sgetpwent.c
Normal file
136
lib/sgetpwent.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: sgetpwent.c,v 1.5 1998/04/02 21:51:46 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#define NFIELDS 7
|
||||
|
||||
/*
|
||||
* sgetpwent - convert a string to a (struct passwd)
|
||||
*
|
||||
* sgetpwent() parses a string into the parts required for a password
|
||||
* structure. Strict checking is made for the UID and GID fields and
|
||||
* presence of the correct number of colons. Any failing tests result
|
||||
* in a NULL pointer being returned.
|
||||
*
|
||||
* NOTE: This function uses hard-coded string scanning functions for
|
||||
* performance reasons. I am going to come up with some conditional
|
||||
* compilation glarp to improve on this in the future.
|
||||
*/
|
||||
|
||||
struct passwd *
|
||||
sgetpwent(const char *buf)
|
||||
{
|
||||
static struct passwd pwent;
|
||||
static char pwdbuf[1024];
|
||||
register int i;
|
||||
register char *cp;
|
||||
char *ep;
|
||||
char *fields[NFIELDS];
|
||||
|
||||
/*
|
||||
* Copy the string to a static buffer so the pointers into
|
||||
* the password structure remain valid.
|
||||
*/
|
||||
|
||||
if (strlen(buf) >= sizeof pwdbuf)
|
||||
return 0; /* fail if too long */
|
||||
strcpy(pwdbuf, buf);
|
||||
|
||||
/*
|
||||
* Save a pointer to the start of each colon separated
|
||||
* field. The fields are converted into NUL terminated strings.
|
||||
*/
|
||||
|
||||
for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
|
||||
fields[i] = cp;
|
||||
while (*cp && *cp != ':')
|
||||
++cp;
|
||||
|
||||
if (*cp)
|
||||
*cp++ = '\0';
|
||||
else
|
||||
cp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* There must be exactly NFIELDS colon separated fields or
|
||||
* the entry is invalid. Also, the UID and GID must be non-blank.
|
||||
*/
|
||||
|
||||
if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Each of the fields is converted the appropriate data type
|
||||
* and the result assigned to the password structure. If the
|
||||
* UID or GID does not convert to an integer value, a NULL
|
||||
* pointer is returned.
|
||||
*/
|
||||
|
||||
pwent.pw_name = fields[0];
|
||||
pwent.pw_passwd = fields[1];
|
||||
if (fields[2][0] == '\0' ||
|
||||
((pwent.pw_uid = strtol (fields[2], &ep, 10)) == 0 && *ep)) {
|
||||
return 0;
|
||||
}
|
||||
if (fields[3][0] == '\0' ||
|
||||
((pwent.pw_gid = strtol (fields[3], &ep, 10)) == 0 && *ep)) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef ATT_AGE
|
||||
cp = pwent.pw_passwd;
|
||||
while (*cp && *cp != ',')
|
||||
++cp;
|
||||
|
||||
if (*cp) {
|
||||
*cp++ = '\0';
|
||||
pwent.pw_age = cp;
|
||||
} else {
|
||||
cp = 0;
|
||||
pwent.pw_age = "";
|
||||
}
|
||||
#endif
|
||||
pwent.pw_gecos = fields[4];
|
||||
#ifdef ATT_COMMENT
|
||||
pwent.pw_comment = "";
|
||||
#endif
|
||||
pwent.pw_dir = fields[5];
|
||||
pwent.pw_shell = fields[6];
|
||||
|
||||
return &pwent;
|
||||
}
|
198
lib/sgetspent.c
Normal file
198
lib/sgetspent.c
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifdef SHADOWPWD /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: sgetspent.c,v 1.5 1998/04/02 21:51:47 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#define FIELDS 9
|
||||
#define OFIELDS 5
|
||||
|
||||
/*
|
||||
* sgetspent - convert string in shadow file format to (struct spwd *)
|
||||
*/
|
||||
|
||||
struct spwd *
|
||||
sgetspent(const char *string)
|
||||
{
|
||||
static char spwbuf[1024];
|
||||
static struct spwd spwd;
|
||||
char *fields[FIELDS];
|
||||
char *cp;
|
||||
char *cpp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Copy string to local buffer. It has to be tokenized and we
|
||||
* have to do that to our private copy.
|
||||
*/
|
||||
|
||||
if (strlen(string) >= sizeof spwbuf)
|
||||
return 0; /* fail if too long */
|
||||
strcpy(spwbuf, string);
|
||||
|
||||
if ((cp = strrchr (spwbuf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
* Tokenize the string into colon separated fields. Allow up to
|
||||
* FIELDS different fields.
|
||||
*/
|
||||
|
||||
for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) {
|
||||
fields[i] = cp;
|
||||
while (*cp && *cp != ':')
|
||||
cp++;
|
||||
|
||||
if (*cp)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* It is acceptable for the last SVR4 field to be blank. This
|
||||
* results in the loop being terminated early. In which case,
|
||||
* we just make the last field be blank and be done with it.
|
||||
*/
|
||||
|
||||
if (i == (FIELDS-1))
|
||||
fields[i++] = cp;
|
||||
|
||||
if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Start populating the structure. The fields are all in
|
||||
* static storage, as is the structure we pass back.
|
||||
*/
|
||||
|
||||
spwd.sp_namp = fields[0];
|
||||
spwd.sp_pwdp = fields[1];
|
||||
|
||||
/*
|
||||
* Get the last changed date. For all of the integer fields,
|
||||
* we check for proper format. It is an error to have an
|
||||
* incorrectly formatted number.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[2][0] == '\0')
|
||||
spwd.sp_lstchg = -1;
|
||||
|
||||
/*
|
||||
* Get the minimum period between password changes.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[3][0] == '\0')
|
||||
spwd.sp_min = -1;
|
||||
|
||||
/*
|
||||
* Get the maximum number of days a password is valid.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[4][0] == '\0')
|
||||
spwd.sp_max = -1;
|
||||
|
||||
/*
|
||||
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
|
||||
* formatted file), initialize the other field members to -1.
|
||||
*/
|
||||
|
||||
#if 0 /* SVR4 */
|
||||
if (i == OFIELDS)
|
||||
return 0;
|
||||
#else
|
||||
if (i == OFIELDS) {
|
||||
spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
|
||||
spwd.sp_flag = -1;
|
||||
|
||||
return &spwd;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The rest of the fields are mandatory for SVR4, but optional
|
||||
* for anything else. However, if one is present the others
|
||||
* must be as well.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the number of days of password expiry warning.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[5][0] == '\0')
|
||||
spwd.sp_warn = -1;
|
||||
|
||||
/*
|
||||
* Get the number of days of inactivity before an account is
|
||||
* disabled.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[6][0] == '\0')
|
||||
spwd.sp_inact = -1;
|
||||
|
||||
/*
|
||||
* Get the number of days after the epoch before the account is
|
||||
* set to expire.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[7][0] == '\0')
|
||||
spwd.sp_expire = -1;
|
||||
|
||||
/*
|
||||
* This field is reserved for future use. But it isn't supposed
|
||||
* to have anything other than a valid integer in it.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
|
||||
return 0;
|
||||
} else if (fields[8][0] == '\0')
|
||||
spwd.sp_flag = -1;
|
||||
|
||||
return (&spwd);
|
||||
}
|
||||
#endif /*}*/
|
213
lib/sgroupio.c
Normal file
213
lib/sgroupio.c
Normal file
@@ -0,0 +1,213 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: sgroupio.c,v 1.9 1998/01/29 23:22:31 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include "commonio.h"
|
||||
#include "sgroupio.h"
|
||||
|
||||
extern int putsgent P_((const struct sgrp *, FILE *));
|
||||
extern struct sgrp *sgetsgent P_((const char *));
|
||||
|
||||
struct sgrp *
|
||||
__sgr_dup(const struct sgrp *sgent)
|
||||
{
|
||||
struct sgrp *sg;
|
||||
int i;
|
||||
|
||||
if (!(sg = (struct sgrp *) malloc(sizeof *sg)))
|
||||
return NULL;
|
||||
*sg = *sgent;
|
||||
if (!(sg->sg_name = strdup(sgent->sg_name)))
|
||||
return NULL;
|
||||
if (!(sg->sg_passwd = strdup(sgent->sg_passwd)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; sgent->sg_adm[i]; i++)
|
||||
;
|
||||
sg->sg_adm = (char **) malloc((i + 1) * sizeof(char *));
|
||||
if (!sg->sg_adm)
|
||||
return NULL;
|
||||
for (i = 0; sgent->sg_adm[i]; i++) {
|
||||
sg->sg_adm[i] = strdup(sgent->sg_adm[i]);
|
||||
if (!sg->sg_adm[i])
|
||||
return NULL;
|
||||
}
|
||||
sg->sg_adm[i] = NULL;
|
||||
|
||||
for (i = 0; sgent->sg_mem[i]; i++)
|
||||
;
|
||||
sg->sg_mem = (char **) malloc((i + 1) * sizeof(char *));
|
||||
if (!sg->sg_mem)
|
||||
return NULL;
|
||||
for (i = 0; sgent->sg_mem[i]; i++) {
|
||||
sg->sg_mem[i] = strdup(sgent->sg_mem[i]);
|
||||
if (!sg->sg_mem[i])
|
||||
return NULL;
|
||||
}
|
||||
sg->sg_mem[i] = NULL;
|
||||
|
||||
return sg;
|
||||
}
|
||||
|
||||
static void *
|
||||
gshadow_dup(const void *ent)
|
||||
{
|
||||
const struct sgrp *sg = ent;
|
||||
return __sgr_dup(sg);
|
||||
}
|
||||
|
||||
static void
|
||||
gshadow_free(void *ent)
|
||||
{
|
||||
struct sgrp *sg = ent;
|
||||
|
||||
free(sg->sg_name);
|
||||
free(sg->sg_passwd);
|
||||
while(*(sg->sg_adm)) {
|
||||
free(*(sg->sg_adm));
|
||||
sg->sg_adm++;
|
||||
}
|
||||
while(*(sg->sg_mem)) {
|
||||
free(*(sg->sg_mem));
|
||||
sg->sg_mem++;
|
||||
}
|
||||
free(sg);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gshadow_getname(const void *ent)
|
||||
{
|
||||
const struct sgrp *gr = ent;
|
||||
return gr->sg_name;
|
||||
}
|
||||
|
||||
static void *
|
||||
gshadow_parse(const char *line)
|
||||
{
|
||||
return (void *) sgetsgent(line);
|
||||
}
|
||||
|
||||
static int
|
||||
gshadow_put(const void *ent, FILE *file)
|
||||
{
|
||||
const struct sgrp *sg = ent;
|
||||
return (putsgent(sg, file) == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct commonio_ops gshadow_ops = {
|
||||
gshadow_dup,
|
||||
gshadow_free,
|
||||
gshadow_getname,
|
||||
gshadow_parse,
|
||||
gshadow_put,
|
||||
fgetsx,
|
||||
fputsx
|
||||
};
|
||||
|
||||
static struct commonio_db gshadow_db = {
|
||||
SGROUP_FILE, /* filename */
|
||||
&gshadow_ops, /* ops */
|
||||
NULL, /* fp */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
0, /* changed */
|
||||
0, /* isopen */
|
||||
0, /* locked */
|
||||
0, /* readonly */
|
||||
0 /* use_lckpwdf */
|
||||
};
|
||||
|
||||
int
|
||||
sgr_name(const char *filename)
|
||||
{
|
||||
return commonio_setname(&gshadow_db, filename);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_file_present(void)
|
||||
{
|
||||
return commonio_present(&gshadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_lock(void)
|
||||
{
|
||||
return commonio_lock(&gshadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_open(int mode)
|
||||
{
|
||||
return commonio_open(&gshadow_db, mode);
|
||||
}
|
||||
|
||||
const struct sgrp *
|
||||
sgr_locate(const char *name)
|
||||
{
|
||||
return commonio_locate(&gshadow_db, name);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_update(const struct sgrp *sg)
|
||||
{
|
||||
return commonio_update(&gshadow_db, (const void *) sg);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_remove(const char *name)
|
||||
{
|
||||
return commonio_remove(&gshadow_db, name);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_rewind(void)
|
||||
{
|
||||
return commonio_rewind(&gshadow_db);
|
||||
}
|
||||
|
||||
const struct sgrp *
|
||||
sgr_next(void)
|
||||
{
|
||||
return commonio_next(&gshadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_close(void)
|
||||
{
|
||||
return commonio_close(&gshadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
sgr_unlock(void)
|
||||
{
|
||||
return commonio_unlock(&gshadow_db);
|
||||
}
|
||||
|
||||
void
|
||||
__sgr_set_changed(void)
|
||||
{
|
||||
gshadow_db.changed = 1;
|
||||
}
|
||||
|
||||
struct commonio_entry *
|
||||
__sgr_get_head(void)
|
||||
{
|
||||
return gshadow_db.head;
|
||||
}
|
||||
|
||||
void
|
||||
__sgr_del_entry(const struct commonio_entry *ent)
|
||||
{
|
||||
commonio_del_entry(&gshadow_db, ent);
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif
|
13
lib/sgroupio.h
Normal file
13
lib/sgroupio.h
Normal file
@@ -0,0 +1,13 @@
|
||||
extern struct sgrp *__sgr_dup P_((const struct sgrp *));
|
||||
extern void __sgr_set_changed P_((void));
|
||||
extern int sgr_close P_((void));
|
||||
extern int sgr_file_present P_((void));
|
||||
extern const struct sgrp *sgr_locate P_((const char *));
|
||||
extern int sgr_lock P_((void));
|
||||
extern int sgr_name P_((const char *));
|
||||
extern const struct sgrp *sgr_next P_((void));
|
||||
extern int sgr_open P_((int));
|
||||
extern int sgr_remove P_((const char *));
|
||||
extern int sgr_rewind P_((void));
|
||||
extern int sgr_unlock P_((void));
|
||||
extern int sgr_update P_((const struct sgrp *));
|
592
lib/shadow.c
Normal file
592
lib/shadow.c
Normal file
@@ -0,0 +1,592 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
/* Newer versions of Linux libc already have shadow support. */
|
||||
#if defined(SHADOWPWD) && !defined(HAVE_GETSPNAM) /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: shadow.c,v 1.6 1998/01/29 23:22:32 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef NDBM
|
||||
#include <ndbm.h>
|
||||
#include <fcntl.h>
|
||||
DBM *sp_dbm;
|
||||
int sp_dbm_mode = -1;
|
||||
static int dbmopened;
|
||||
static int dbmerror;
|
||||
#endif
|
||||
|
||||
#ifdef USE_NIS
|
||||
static int nis_used;
|
||||
static int nis_ignore;
|
||||
static enum { native, start, middle, native2 } nis_state;
|
||||
static int nis_bound;
|
||||
static char *nis_domain;
|
||||
static char *nis_key;
|
||||
static int nis_keylen;
|
||||
static char *nis_val;
|
||||
static int nis_vallen;
|
||||
#define IS_NISCHAR(c) ((c)=='+')
|
||||
#endif
|
||||
|
||||
static FILE *shadow;
|
||||
static char spwbuf[BUFSIZ];
|
||||
static struct spwd spwd;
|
||||
|
||||
#define FIELDS 9
|
||||
#define OFIELDS 5
|
||||
|
||||
#ifdef USE_NIS
|
||||
|
||||
/*
|
||||
* __setspNIS - turn on or off NIS searches
|
||||
*/
|
||||
|
||||
void
|
||||
__setspNIS(int flag)
|
||||
{
|
||||
nis_ignore = ! flag;
|
||||
|
||||
if (nis_ignore)
|
||||
nis_used = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* bind_nis - bind to NIS server
|
||||
*/
|
||||
|
||||
static int
|
||||
bind_nis(void)
|
||||
{
|
||||
if (yp_get_default_domain (&nis_domain))
|
||||
return -1;
|
||||
|
||||
nis_bound = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* setspent - initialize access to shadow text and DBM files
|
||||
*/
|
||||
|
||||
void
|
||||
setspent(void)
|
||||
{
|
||||
if (shadow)
|
||||
rewind(shadow);
|
||||
else
|
||||
shadow = fopen(SHADOW_FILE, "r");
|
||||
|
||||
#ifdef USE_NIS
|
||||
nis_state = native;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Attempt to open the DBM files if they have never been opened
|
||||
* and an error has never been returned.
|
||||
*/
|
||||
|
||||
#ifdef NDBM
|
||||
if (! dbmerror && ! dbmopened) {
|
||||
int mode;
|
||||
char dbmfiles[BUFSIZ];
|
||||
|
||||
strcpy (dbmfiles, SHADOW_PAG_FILE);
|
||||
|
||||
if (sp_dbm_mode == -1)
|
||||
mode = O_RDWR;
|
||||
else
|
||||
mode = (sp_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY;
|
||||
|
||||
if (! (sp_dbm = dbm_open (SHADOW_FILE, mode, 0)))
|
||||
dbmerror = 1;
|
||||
else
|
||||
dbmopened = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* endspent - terminate access to shadow text and DBM files
|
||||
*/
|
||||
|
||||
void
|
||||
endspent(void)
|
||||
{
|
||||
if (shadow)
|
||||
(void) fclose (shadow);
|
||||
|
||||
shadow = (FILE *) 0;
|
||||
#ifdef NDBM
|
||||
if (dbmopened && sp_dbm) {
|
||||
dbm_close (sp_dbm);
|
||||
sp_dbm = 0;
|
||||
}
|
||||
dbmopened = 0;
|
||||
dbmerror = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* my_sgetspent - convert string in shadow file format to (struct spwd *)
|
||||
*/
|
||||
|
||||
static struct spwd *
|
||||
my_sgetspent(const char *string)
|
||||
{
|
||||
char *fields[FIELDS];
|
||||
char *cp;
|
||||
char *cpp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Copy string to local buffer. It has to be tokenized and we
|
||||
* have to do that to our private copy.
|
||||
*/
|
||||
|
||||
if (strlen(string) >= sizeof spwbuf)
|
||||
return 0;
|
||||
strcpy(spwbuf, string);
|
||||
|
||||
if ((cp = strrchr (spwbuf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
* Tokenize the string into colon separated fields. Allow up to
|
||||
* FIELDS different fields.
|
||||
*/
|
||||
|
||||
for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) {
|
||||
fields[i] = cp;
|
||||
while (*cp && *cp != ':')
|
||||
cp++;
|
||||
|
||||
if (*cp)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* It is acceptable for the last SVR4 field to be blank. This
|
||||
* results in the loop being terminated early. In which case,
|
||||
* we just make the last field be blank and be done with it.
|
||||
*/
|
||||
|
||||
if (i == (FIELDS-1))
|
||||
fields[i++] = cp;
|
||||
|
||||
if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Start populating the structure. The fields are all in
|
||||
* static storage, as is the structure we pass back. If we
|
||||
* ever see a name with '+' as the first character, we try
|
||||
* to turn on NIS processing.
|
||||
*/
|
||||
|
||||
spwd.sp_namp = fields[0];
|
||||
#ifdef USE_NIS
|
||||
if (IS_NISCHAR (fields[0][0]))
|
||||
nis_used = 1;
|
||||
#endif
|
||||
spwd.sp_pwdp = fields[1];
|
||||
|
||||
/*
|
||||
* Get the last changed date. For all of the integer fields,
|
||||
* we check for proper format. It is an error to have an
|
||||
* incorrectly formatted number, unless we are using NIS.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_lstchg = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[2][0] == '\0')
|
||||
spwd.sp_lstchg = -1;
|
||||
|
||||
/*
|
||||
* Get the minimum period between password changes.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_min = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[3][0] == '\0')
|
||||
spwd.sp_min = -1;
|
||||
|
||||
/*
|
||||
* Get the maximum number of days a password is valid.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_max = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[4][0] == '\0')
|
||||
spwd.sp_max = -1;
|
||||
|
||||
/*
|
||||
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
|
||||
* formatted file), initialize the other field members to -1.
|
||||
*/
|
||||
|
||||
#if 0 /* SVR4 */
|
||||
if (i == OFIELDS)
|
||||
return 0;
|
||||
#else
|
||||
if (i == OFIELDS) {
|
||||
spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
|
||||
spwd.sp_flag = -1;
|
||||
|
||||
return &spwd;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The rest of the fields are mandatory for SVR4, but optional
|
||||
* for anything else. However, if one is present the others
|
||||
* must be as well.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the number of days of password expiry warning.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_warn = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[5][0] == '\0')
|
||||
spwd.sp_warn = -1;
|
||||
|
||||
/*
|
||||
* Get the number of days of inactivity before an account is
|
||||
* disabled.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_inact = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[6][0] == '\0')
|
||||
spwd.sp_inact = -1;
|
||||
|
||||
/*
|
||||
* Get the number of days after the epoch before the account is
|
||||
* set to expire.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_expire = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[7][0] == '\0')
|
||||
spwd.sp_expire = -1;
|
||||
|
||||
/*
|
||||
* This field is reserved for future use. But it isn't supposed
|
||||
* to have anything other than a valid integer in it.
|
||||
*/
|
||||
|
||||
if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
|
||||
#ifdef USE_NIS
|
||||
if (! nis_used)
|
||||
return 0;
|
||||
else
|
||||
spwd.sp_flag = -1;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
} else if (fields[8][0] == '\0')
|
||||
spwd.sp_flag = -1;
|
||||
|
||||
return (&spwd);
|
||||
}
|
||||
|
||||
/*
|
||||
* fgetspent - get an entry from a /etc/shadow formatted stream
|
||||
*/
|
||||
|
||||
struct spwd *
|
||||
fgetspent(FILE *fp)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
char *cp;
|
||||
|
||||
if (! fp)
|
||||
return (0);
|
||||
|
||||
#ifdef USE_NIS
|
||||
while (fgets (buf, sizeof buf, fp) != (char *) 0)
|
||||
#else
|
||||
if (fgets (buf, sizeof buf, fp) != (char *) 0)
|
||||
#endif
|
||||
{
|
||||
if ((cp = strchr (buf, '\n')))
|
||||
*cp = '\0';
|
||||
#ifdef USE_NIS
|
||||
if (nis_ignore && IS_NISCHAR (buf[0]))
|
||||
continue;
|
||||
#endif
|
||||
return my_sgetspent(buf);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* getspent - get a (struct spwd *) from the current shadow file
|
||||
*/
|
||||
|
||||
struct spwd *
|
||||
getspent(void)
|
||||
{
|
||||
#ifdef USE_NIS
|
||||
int nis_1_user = 0;
|
||||
struct spwd *val;
|
||||
char buf[BUFSIZ];
|
||||
#endif
|
||||
if (! shadow)
|
||||
setspent ();
|
||||
|
||||
#ifdef USE_NIS
|
||||
again:
|
||||
/*
|
||||
* See if we are reading from the local file.
|
||||
*/
|
||||
|
||||
if (nis_state == native || nis_state == native2) {
|
||||
|
||||
/*
|
||||
* Get the next entry from the shadow file. Return NULL
|
||||
* right away if there is none.
|
||||
*/
|
||||
|
||||
if (! (val = fgetspent (shadow)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If this entry began with a NIS escape character, we have
|
||||
* to see if this is just a single user, or if the entire
|
||||
* map is being asked for.
|
||||
*/
|
||||
|
||||
if (IS_NISCHAR (val->sp_namp[0])) {
|
||||
if (val->sp_namp[1])
|
||||
nis_1_user = 1;
|
||||
else
|
||||
nis_state = start;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this isn't a NIS user and this isn't an escape to go
|
||||
* use a NIS map, it must be a regular local user.
|
||||
*/
|
||||
|
||||
if (nis_1_user == 0 && nis_state != start)
|
||||
return val;
|
||||
|
||||
/*
|
||||
* If this is an escape to use an NIS map, switch over to
|
||||
* that bunch of code.
|
||||
*/
|
||||
|
||||
if (nis_state == start)
|
||||
goto again;
|
||||
|
||||
/*
|
||||
* NEEDSWORK. Here we substitute pieces-parts of this entry.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
if (nis_bound == 0) {
|
||||
if (bind_nis ()) {
|
||||
nis_state = native2;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
if (nis_state == start) {
|
||||
if (yp_first (nis_domain, "shadow.bynam", &nis_key,
|
||||
&nis_keylen, &nis_val, &nis_vallen)) {
|
||||
nis_state = native2;
|
||||
goto again;
|
||||
}
|
||||
nis_state = middle;
|
||||
} else if (nis_state == middle) {
|
||||
if (yp_next (nis_domain, "shadow.bynam", nis_key,
|
||||
nis_keylen, &nis_key, &nis_keylen,
|
||||
&nis_val, &nis_vallen)) {
|
||||
nis_state = native2;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
return my_sgetspent(nis_val);
|
||||
}
|
||||
#else
|
||||
return (fgetspent (shadow));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* getspnam - get a shadow entry by name
|
||||
*/
|
||||
|
||||
struct spwd *
|
||||
getspnam(const char *name)
|
||||
{
|
||||
struct spwd *sp;
|
||||
#ifdef NDBM
|
||||
datum key;
|
||||
datum content;
|
||||
#endif
|
||||
#ifdef USE_NIS
|
||||
char buf[BUFSIZ];
|
||||
static char save_name[16];
|
||||
int nis_disabled = 0;
|
||||
#endif
|
||||
|
||||
setspent ();
|
||||
|
||||
#ifdef NDBM
|
||||
|
||||
/*
|
||||
* If the DBM file are now open, create a key for this UID and
|
||||
* try to fetch the entry from the database. A matching record
|
||||
* will be unpacked into a static structure and returned to
|
||||
* the user.
|
||||
*/
|
||||
|
||||
if (dbmopened) {
|
||||
key.dsize = strlen (name);
|
||||
key.dptr = (char *) name;
|
||||
|
||||
content = dbm_fetch (sp_dbm, key);
|
||||
if (content.dptr != 0) {
|
||||
memcpy (spwbuf, content.dptr, content.dsize);
|
||||
spw_unpack (spwbuf, content.dsize, &spwd);
|
||||
endspent();
|
||||
return &spwd;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NIS
|
||||
/*
|
||||
* Search the shadow.byname map for this user.
|
||||
*/
|
||||
|
||||
if (! nis_ignore && ! nis_bound)
|
||||
bind_nis ();
|
||||
|
||||
if (! nis_ignore && nis_bound) {
|
||||
char *cp;
|
||||
|
||||
if (yp_match (nis_domain, "shadow.byname", name,
|
||||
strlen (name), &nis_val, &nis_vallen) == 0) {
|
||||
|
||||
if (cp = strchr (nis_val, '\n'))
|
||||
*cp = '\0';
|
||||
|
||||
nis_state = middle;
|
||||
if ((sp = my_sgetspent(nis_val))) {
|
||||
strcpy (save_name, sp->sp_namp);
|
||||
nis_key = save_name;
|
||||
nis_keylen = strlen (save_name);
|
||||
}
|
||||
endspent();
|
||||
return sp;
|
||||
} else
|
||||
nis_state = native2;
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_NIS
|
||||
/*
|
||||
* NEEDSWORK -- this is a mess, and it is the same mess in the
|
||||
* other three files. I can't just blindly turn off NIS because
|
||||
* this might be the first pass through the local files. In
|
||||
* that case, I never discover that NIS is present.
|
||||
*/
|
||||
|
||||
if (nis_used) {
|
||||
nis_ignore++;
|
||||
nis_disabled++;
|
||||
}
|
||||
#endif
|
||||
while ((sp = getspent ()) != (struct spwd *) 0) {
|
||||
if (strcmp (name, sp->sp_namp) == 0)
|
||||
break;
|
||||
}
|
||||
#ifdef USE_NIS
|
||||
if (nis_disabled)
|
||||
nis_ignore--;
|
||||
#endif
|
||||
endspent();
|
||||
return (sp);
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif /*}*/
|
89
lib/shadow_.h
Normal file
89
lib/shadow_.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 1988 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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.
|
||||
*/
|
||||
|
||||
#ifndef _H_SHADOW
|
||||
#define _H_SHADOW
|
||||
|
||||
/*
|
||||
* This information is not derived from AT&T licensed sources. Posted
|
||||
* to the USENET 11/88, and updated 11/90 with information from SVR4.
|
||||
*
|
||||
* $Id: shadow_.h,v 1.2 1997/05/01 23:14:48 marekm Exp $
|
||||
*/
|
||||
|
||||
#ifdef ITI_AGING
|
||||
typedef time_t sptime;
|
||||
#else
|
||||
typedef long sptime;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Shadow password security file structure.
|
||||
*/
|
||||
|
||||
struct spwd {
|
||||
char *sp_namp; /* login name */
|
||||
char *sp_pwdp; /* encrypted password */
|
||||
sptime sp_lstchg; /* date of last change */
|
||||
sptime sp_min; /* minimum number of days between changes */
|
||||
sptime sp_max; /* maximum number of days between changes */
|
||||
sptime sp_warn; /* number of days of warning before password
|
||||
expires */
|
||||
sptime sp_inact; /* number of days after password expires
|
||||
until the account becomes unusable. */
|
||||
sptime sp_expire; /* days since 1/1/70 until account expires */
|
||||
unsigned long sp_flag; /* reserved for future use */
|
||||
};
|
||||
|
||||
/*
|
||||
* Shadow password security file functions.
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* for FILE */
|
||||
|
||||
#if defined(__STDC__)
|
||||
struct spwd *getspent (void);
|
||||
struct spwd *getspnam (const char *);
|
||||
struct spwd *sgetspent (const char *);
|
||||
struct spwd *fgetspent (FILE *);
|
||||
void setspent (void);
|
||||
void endspent (void);
|
||||
int putspent (const struct spwd *, FILE *);
|
||||
#else
|
||||
struct spwd *getspent ();
|
||||
struct spwd *getspnam ();
|
||||
struct spwd *sgetspent ();
|
||||
struct spwd *fgetspent ();
|
||||
void setspent ();
|
||||
void endspent ();
|
||||
int putspent ();
|
||||
#endif
|
||||
|
||||
#define SHADOW "/etc/shadow"
|
||||
#endif
|
172
lib/shadowio.c
Normal file
172
lib/shadowio.c
Normal file
@@ -0,0 +1,172 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: shadowio.c,v 1.11 1998/01/29 23:22:32 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#ifdef HAVE_SHADOW_H
|
||||
# include <shadow.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
|
||||
#include "commonio.h"
|
||||
#include "shadowio.h"
|
||||
|
||||
struct spwd *
|
||||
__spw_dup(const struct spwd *spent)
|
||||
{
|
||||
struct spwd *sp;
|
||||
|
||||
if (!(sp = (struct spwd *) malloc(sizeof *sp)))
|
||||
return NULL;
|
||||
*sp = *spent;
|
||||
if (!(sp->sp_namp = strdup(spent->sp_namp)))
|
||||
return NULL;
|
||||
if (!(sp->sp_pwdp = strdup(spent->sp_pwdp)))
|
||||
return NULL;
|
||||
return sp;
|
||||
}
|
||||
|
||||
static void *
|
||||
shadow_dup(const void *ent)
|
||||
{
|
||||
const struct spwd *sp = ent;
|
||||
return __spw_dup(sp);
|
||||
}
|
||||
|
||||
static void
|
||||
shadow_free(void *ent)
|
||||
{
|
||||
struct spwd *sp = ent;
|
||||
|
||||
free(sp->sp_namp);
|
||||
free(sp->sp_pwdp);
|
||||
free(sp);
|
||||
}
|
||||
|
||||
static const char *
|
||||
shadow_getname(const void *ent)
|
||||
{
|
||||
const struct spwd *sp = ent;
|
||||
return sp->sp_namp;
|
||||
}
|
||||
|
||||
static void *
|
||||
shadow_parse(const char *line)
|
||||
{
|
||||
return (void *) sgetspent(line);
|
||||
}
|
||||
|
||||
static int
|
||||
shadow_put(const void *ent, FILE *file)
|
||||
{
|
||||
const struct spwd *sp = ent;
|
||||
return (putspent(sp, file) == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
static struct commonio_ops shadow_ops = {
|
||||
shadow_dup,
|
||||
shadow_free,
|
||||
shadow_getname,
|
||||
shadow_parse,
|
||||
shadow_put,
|
||||
fgets,
|
||||
fputs
|
||||
};
|
||||
|
||||
static struct commonio_db shadow_db = {
|
||||
SHADOW_FILE, /* filename */
|
||||
&shadow_ops, /* ops */
|
||||
NULL, /* fp */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
0, /* changed */
|
||||
0, /* isopen */
|
||||
0, /* locked */
|
||||
0, /* readonly */
|
||||
1 /* use_lckpwdf */
|
||||
};
|
||||
|
||||
int
|
||||
spw_name(const char *filename)
|
||||
{
|
||||
return commonio_setname(&shadow_db, filename);
|
||||
}
|
||||
|
||||
int
|
||||
spw_file_present(void)
|
||||
{
|
||||
return commonio_present(&shadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
spw_lock(void)
|
||||
{
|
||||
return commonio_lock(&shadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
spw_open(int mode)
|
||||
{
|
||||
return commonio_open(&shadow_db, mode);
|
||||
}
|
||||
|
||||
const struct spwd *
|
||||
spw_locate(const char *name)
|
||||
{
|
||||
return commonio_locate(&shadow_db, name);
|
||||
}
|
||||
|
||||
int
|
||||
spw_update(const struct spwd *sp)
|
||||
{
|
||||
return commonio_update(&shadow_db, (const void *) sp);
|
||||
}
|
||||
|
||||
int
|
||||
spw_remove(const char *name)
|
||||
{
|
||||
return commonio_remove(&shadow_db, name);
|
||||
}
|
||||
|
||||
int
|
||||
spw_rewind(void)
|
||||
{
|
||||
return commonio_rewind(&shadow_db);
|
||||
}
|
||||
|
||||
const struct spwd *
|
||||
spw_next(void)
|
||||
{
|
||||
return commonio_next(&shadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
spw_close(void)
|
||||
{
|
||||
return commonio_close(&shadow_db);
|
||||
}
|
||||
|
||||
int
|
||||
spw_unlock(void)
|
||||
{
|
||||
return commonio_unlock(&shadow_db);
|
||||
}
|
||||
|
||||
struct commonio_entry *
|
||||
__spw_get_head(void)
|
||||
{
|
||||
return shadow_db.head;
|
||||
}
|
||||
|
||||
void
|
||||
__spw_del_entry(const struct commonio_entry *ent)
|
||||
{
|
||||
commonio_del_entry(&shadow_db, ent);
|
||||
}
|
||||
#endif
|
13
lib/shadowio.h
Normal file
13
lib/shadowio.h
Normal file
@@ -0,0 +1,13 @@
|
||||
extern struct spwd *__spw_dup P_((const struct spwd *));
|
||||
extern void __spw_set_changed P_((void));
|
||||
extern int spw_close P_((void));
|
||||
extern int spw_file_present P_((void));
|
||||
extern const struct spwd *spw_locate P_((const char *));
|
||||
extern int spw_lock P_((void));
|
||||
extern int spw_name P_((const char *));
|
||||
extern const struct spwd *spw_next P_((void));
|
||||
extern int spw_open P_((int));
|
||||
extern int spw_remove P_((const char *));
|
||||
extern int spw_rewind P_((void));
|
||||
extern int spw_unlock P_((void));
|
||||
extern int spw_update P_((const struct spwd *));
|
320
lib/snprintf.c
Normal file
320
lib/snprintf.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/**************************************************************
|
||||
* Original:
|
||||
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
|
||||
* A bombproof version of doprnt (dopr) included.
|
||||
* Sigh. This sort of thing is always nasty do deal with. Note that
|
||||
* the version here does not include floating point...
|
||||
*
|
||||
* snprintf() is used instead of sprintf() as it does limit checks
|
||||
* for string length. This covers a nasty loophole.
|
||||
*
|
||||
* The other functions are there to prevent NULL pointers from
|
||||
* causing nast effects.
|
||||
**************************************************************/
|
||||
|
||||
/* $XFree86: xc/lib/misc/snprintf.c,v 3.0 1996/08/26 06:19:23 dawes Exp $ */
|
||||
|
||||
#include <ctype.h>
|
||||
#include "snprintf.h"
|
||||
|
||||
static void dopr();
|
||||
static char *end;
|
||||
|
||||
/* varargs declarations: */
|
||||
|
||||
#if defined(HAVE_STDARG_H)
|
||||
# include <stdarg.h>
|
||||
# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
|
||||
# define VA_LOCAL_DECL va_list ap;
|
||||
# define VA_START(f) va_start(ap, f)
|
||||
# define VA_SHIFT(v,t) ; /* no-op for ANSI */
|
||||
# define VA_END va_end(ap)
|
||||
#else
|
||||
# if defined(HAVE_VARARGS_H)
|
||||
# include <varargs.h>
|
||||
# undef HAVE_STDARGS
|
||||
# define VA_LOCAL_DECL va_list ap;
|
||||
# define VA_START(f) va_start(ap) /* f is ignored! */
|
||||
# define VA_SHIFT(v,t) v = va_arg(ap,t)
|
||||
# define VA_END va_end(ap)
|
||||
# else
|
||||
/*XX ** NO VARARGS ** XX*/
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARGS
|
||||
int snprintf (char *str, size_t count, const char *fmt, ...);
|
||||
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
|
||||
#else
|
||||
int snprintf ();
|
||||
int vsnprintf ();
|
||||
#endif
|
||||
|
||||
int
|
||||
vsnprintf(str, count, fmt, args)
|
||||
char *str;
|
||||
size_t count;
|
||||
const char *fmt;
|
||||
va_list args;
|
||||
{
|
||||
str[0] = 0;
|
||||
end = str+count-1;
|
||||
dopr( str, fmt, args );
|
||||
if( count>0 ){
|
||||
end[0] = 0;
|
||||
}
|
||||
return(strlen(str));
|
||||
}
|
||||
|
||||
/* VARARGS3 */
|
||||
#ifdef HAVE_STDARGS
|
||||
int
|
||||
snprintf (char *str,size_t count,const char *fmt,...)
|
||||
#else
|
||||
int
|
||||
snprintf (va_alist) va_dcl
|
||||
#endif
|
||||
{
|
||||
#ifndef HAVE_STDARGS
|
||||
char *str;
|
||||
size_t count;
|
||||
char *fmt;
|
||||
#endif
|
||||
VA_LOCAL_DECL
|
||||
|
||||
VA_START (fmt);
|
||||
VA_SHIFT (str, char *);
|
||||
VA_SHIFT (count, size_t );
|
||||
VA_SHIFT (fmt, char *);
|
||||
(void) vsnprintf ( str, count, fmt, ap);
|
||||
VA_END;
|
||||
return( strlen( str ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* dopr(): poor man's version of doprintf
|
||||
*/
|
||||
|
||||
static void fmtstr(
|
||||
#if NeedFunctionPrototypes
|
||||
char *value, int ljust, int len, int zpad
|
||||
#endif
|
||||
);
|
||||
|
||||
static void fmtnum(
|
||||
#if NeedFunctionPrototypes
|
||||
long value, int base, int dosign, int ljust, int len, int zpad
|
||||
#endif
|
||||
);
|
||||
|
||||
static void dostr(
|
||||
#if NeedFunctionPrototypes
|
||||
char *
|
||||
#endif
|
||||
);
|
||||
|
||||
static char *output;
|
||||
|
||||
static void dopr_outch(
|
||||
#if NeedFunctionPrototypes
|
||||
int c
|
||||
#endif
|
||||
);
|
||||
|
||||
static void
|
||||
dopr( buffer, format, args )
|
||||
char *buffer;
|
||||
char *format;
|
||||
va_list args;
|
||||
{
|
||||
int ch;
|
||||
long value;
|
||||
int longflag = 0;
|
||||
char *strvalue;
|
||||
int ljust;
|
||||
int len;
|
||||
int zpad;
|
||||
|
||||
output = buffer;
|
||||
while( (ch = *format++) ){
|
||||
switch( ch ){
|
||||
case '%':
|
||||
ljust = len = zpad = 0;
|
||||
nextch:
|
||||
ch = *format++;
|
||||
switch( ch ){
|
||||
case 0:
|
||||
dostr( "**end of format**" );
|
||||
return;
|
||||
case '-': ljust = 1; goto nextch;
|
||||
case '0': /* set zero padding if len not set */
|
||||
if(len==0) zpad = '0';
|
||||
case '1': case '2': case '3':
|
||||
case '4': case '5': case '6':
|
||||
case '7': case '8': case '9':
|
||||
len = len*10 + ch - '0';
|
||||
goto nextch;
|
||||
case 'l': longflag = 1; goto nextch;
|
||||
case 'u': case 'U':
|
||||
/*fmtnum(value,base,dosign,ljust,len,zpad) */
|
||||
if( longflag ){
|
||||
value = va_arg( args, long );
|
||||
} else {
|
||||
value = va_arg( args, int );
|
||||
}
|
||||
fmtnum( value, 10,0, ljust, len, zpad ); break;
|
||||
case 'o': case 'O':
|
||||
/*fmtnum(value,base,dosign,ljust,len,zpad) */
|
||||
if( longflag ){
|
||||
value = va_arg( args, long );
|
||||
} else {
|
||||
value = va_arg( args, int );
|
||||
}
|
||||
fmtnum( value, 8,0, ljust, len, zpad ); break;
|
||||
case 'd': case 'D':
|
||||
if( longflag ){
|
||||
value = va_arg( args, long );
|
||||
} else {
|
||||
value = va_arg( args, int );
|
||||
}
|
||||
fmtnum( value, 10,1, ljust, len, zpad ); break;
|
||||
case 'x':
|
||||
if( longflag ){
|
||||
value = va_arg( args, long );
|
||||
} else {
|
||||
value = va_arg( args, int );
|
||||
}
|
||||
fmtnum( value, 16,0, ljust, len, zpad ); break;
|
||||
case 'X':
|
||||
if( longflag ){
|
||||
value = va_arg( args, long );
|
||||
} else {
|
||||
value = va_arg( args, int );
|
||||
}
|
||||
fmtnum( value,-16,0, ljust, len, zpad ); break;
|
||||
case 's':
|
||||
strvalue = va_arg( args, char *);
|
||||
fmtstr( strvalue,ljust,len,zpad ); break;
|
||||
case 'c':
|
||||
ch = va_arg( args, int );
|
||||
dopr_outch( ch ); break;
|
||||
case '%': dopr_outch( ch ); continue;
|
||||
default:
|
||||
dostr( "???????" );
|
||||
}
|
||||
longflag = 0;
|
||||
break;
|
||||
default:
|
||||
dopr_outch( ch );
|
||||
break;
|
||||
}
|
||||
}
|
||||
*output = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
fmtstr( value, ljust, len, zpad )
|
||||
char *value;
|
||||
int ljust, len, zpad;
|
||||
{
|
||||
int padlen, strlen; /* amount to pad */
|
||||
|
||||
if( value == 0 ){
|
||||
value = "<NULL>";
|
||||
}
|
||||
for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
|
||||
padlen = len - strlen;
|
||||
if( padlen < 0 ) padlen = 0;
|
||||
if( ljust ) padlen = -padlen;
|
||||
while( padlen > 0 ) {
|
||||
dopr_outch( ' ' );
|
||||
--padlen;
|
||||
}
|
||||
dostr( value );
|
||||
while( padlen < 0 ) {
|
||||
dopr_outch( ' ' );
|
||||
++padlen;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fmtnum( value, base, dosign, ljust, len, zpad )
|
||||
long value;
|
||||
int base, dosign, ljust, len, zpad;
|
||||
{
|
||||
int signvalue = 0;
|
||||
unsigned long uvalue;
|
||||
char convert[20];
|
||||
int place = 0;
|
||||
int padlen = 0; /* amount to pad */
|
||||
int caps = 0;
|
||||
|
||||
/* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
|
||||
value, base, dosign, ljust, len, zpad )); */
|
||||
uvalue = value;
|
||||
if( dosign ){
|
||||
if( value < 0 ) {
|
||||
signvalue = '-';
|
||||
uvalue = -value;
|
||||
}
|
||||
}
|
||||
if( base < 0 ){
|
||||
caps = 1;
|
||||
base = -base;
|
||||
}
|
||||
do{
|
||||
convert[place++] =
|
||||
(caps? "0123456789ABCDEF":"0123456789abcdef")
|
||||
[uvalue % (unsigned)base ];
|
||||
uvalue = (uvalue / (unsigned)base );
|
||||
}while(uvalue);
|
||||
convert[place] = 0;
|
||||
padlen = len - place;
|
||||
if( padlen < 0 ) padlen = 0;
|
||||
if( ljust ) padlen = -padlen;
|
||||
/* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
|
||||
convert,place,signvalue,padlen)); */
|
||||
if( zpad && padlen > 0 ){
|
||||
if( signvalue ){
|
||||
dopr_outch( signvalue );
|
||||
--padlen;
|
||||
signvalue = 0;
|
||||
}
|
||||
while( padlen > 0 ){
|
||||
dopr_outch( zpad );
|
||||
--padlen;
|
||||
}
|
||||
}
|
||||
while( padlen > 0 ) {
|
||||
dopr_outch( ' ' );
|
||||
--padlen;
|
||||
}
|
||||
if( signvalue ) dopr_outch( signvalue );
|
||||
while( place > 0 ) dopr_outch( convert[--place] );
|
||||
while( padlen < 0 ){
|
||||
dopr_outch( ' ' );
|
||||
++padlen;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dostr( str )
|
||||
char *str;
|
||||
{
|
||||
while(*str) dopr_outch(*str++);
|
||||
}
|
||||
|
||||
static void
|
||||
dopr_outch( c )
|
||||
int c;
|
||||
{
|
||||
if( iscntrl(c) && c != '\n' && c != '\t' ){
|
||||
c = '@' + (c & 0x1F);
|
||||
if( end == 0 || output < end ){
|
||||
*output++ = '^';
|
||||
}
|
||||
}
|
||||
if( end == 0 || output < end ){
|
||||
*output++ = c;
|
||||
}
|
||||
}
|
51
lib/snprintf.h
Normal file
51
lib/snprintf.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/* $XFree86: xc/lib/misc/snprintf.h,v 3.1 1996/08/26 14:42:33 dawes Exp $ */
|
||||
|
||||
#ifndef SNPRINTF_H
|
||||
#define SNPRINTF_H
|
||||
|
||||
#ifdef HAS_SNPRINTF
|
||||
#ifdef LIBXT
|
||||
#define _XtSnprintf snprintf
|
||||
#define _XtVsnprintf vsnprintf
|
||||
#endif
|
||||
#ifdef LIBX11
|
||||
#define _XSnprintf snprintf
|
||||
#define _XVsnprintf vsnprintf
|
||||
#endif
|
||||
#else /* !HAS_SNPRINTF */
|
||||
|
||||
#ifdef LIBXT
|
||||
#define snprintf _XtSnprintf
|
||||
#define vsnprintf _XtVsnprintf
|
||||
#endif
|
||||
#ifdef LIBX11
|
||||
#define snprintf _XSnprintf
|
||||
#define vsnprintf _XVsnprintf
|
||||
#endif
|
||||
|
||||
#if 1 /* the system might have no X11 headers. -MM */
|
||||
#include <X11/Xos.h>
|
||||
#include <X11/Xlib.h>
|
||||
#else /* but we still need this... */
|
||||
#include <sys/types.h>
|
||||
/* adjust the following defines if necessary (pre-ANSI) */
|
||||
#define NeedFunctionPrototypes 1
|
||||
#define NeedVarargsPrototypes 1
|
||||
#endif
|
||||
|
||||
#if NeedVarargsPrototypes
|
||||
#define HAVE_STDARG_H
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDARG_H
|
||||
#include <stdarg.h>
|
||||
extern int snprintf (char *str, size_t count, const char *fmt, ...);
|
||||
extern int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
|
||||
#else
|
||||
extern int snprintf ();
|
||||
extern int vsnprintf ();
|
||||
#endif
|
||||
|
||||
#endif /* HAS_SNPRINTF */
|
||||
|
||||
#endif /* SNPRINTF_H */
|
116
lib/spdbm.c
Normal file
116
lib/spdbm.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#if defined(SHADOWPWD) && defined(NDBM) /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: spdbm.c,v 1.3 1997/12/07 23:26:58 marekm Exp $")
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <ndbm.h>
|
||||
extern DBM *sp_dbm;
|
||||
|
||||
/*
|
||||
* sp_dbm_update
|
||||
*
|
||||
* Updates the DBM password files, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
sp_dbm_update(struct spwd *sp)
|
||||
{
|
||||
datum key;
|
||||
datum content;
|
||||
char data[BUFSIZ];
|
||||
int len;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! sp_dbm)
|
||||
setspent ();
|
||||
|
||||
once++;
|
||||
}
|
||||
if (! sp_dbm)
|
||||
return 0;
|
||||
|
||||
len = spw_pack (sp, data);
|
||||
|
||||
content.dsize = len;
|
||||
content.dptr = data;
|
||||
|
||||
key.dsize = strlen (sp->sp_namp);
|
||||
key.dptr = sp->sp_namp;
|
||||
if (dbm_store (sp_dbm, key, content, DBM_REPLACE))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* sp_dbm_remove
|
||||
*
|
||||
* Updates the DBM password files, if they exist.
|
||||
*/
|
||||
|
||||
int
|
||||
sp_dbm_remove(char *user)
|
||||
{
|
||||
datum key;
|
||||
static int once;
|
||||
|
||||
if (! once) {
|
||||
if (! sp_dbm)
|
||||
setspent ();
|
||||
|
||||
once++;
|
||||
}
|
||||
if (! sp_dbm)
|
||||
return 0;
|
||||
|
||||
key.dsize = strlen (user);
|
||||
key.dptr = user;
|
||||
if (dbm_delete (sp_dbm, key))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
sp_dbm_present(void)
|
||||
{
|
||||
return (access(SHADOW_PAG_FILE, F_OK) == 0);
|
||||
}
|
||||
#endif /*} SHADOWPWD && NDBM */
|
113
lib/sppack.c
Normal file
113
lib/sppack.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 1990 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
#ifdef SHADOWPWD /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: sppack.c,v 1.3 1997/12/07 23:26:58 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "defines.h"
|
||||
|
||||
int
|
||||
spw_pack(const struct spwd *spwd, char *buf)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
cp = buf;
|
||||
strcpy (cp, spwd->sp_namp);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
strcpy (cp, spwd->sp_pwdp);
|
||||
cp += strlen (cp) + 1;
|
||||
|
||||
memcpy (cp, &spwd->sp_min, sizeof spwd->sp_min);
|
||||
cp += sizeof spwd->sp_min;
|
||||
|
||||
memcpy (cp, &spwd->sp_max, sizeof spwd->sp_max);
|
||||
cp += sizeof spwd->sp_max;
|
||||
|
||||
memcpy (cp, &spwd->sp_lstchg, sizeof spwd->sp_lstchg);
|
||||
cp += sizeof spwd->sp_lstchg;
|
||||
|
||||
memcpy (cp, &spwd->sp_warn, sizeof spwd->sp_warn);
|
||||
cp += sizeof spwd->sp_warn;
|
||||
|
||||
memcpy (cp, &spwd->sp_inact, sizeof spwd->sp_inact);
|
||||
cp += sizeof spwd->sp_inact;
|
||||
|
||||
memcpy (cp, &spwd->sp_expire, sizeof spwd->sp_expire);
|
||||
cp += sizeof spwd->sp_expire;
|
||||
|
||||
memcpy (cp, &spwd->sp_flag, sizeof spwd->sp_flag);
|
||||
cp += sizeof spwd->sp_flag;
|
||||
|
||||
return cp - buf;
|
||||
}
|
||||
|
||||
int
|
||||
spw_unpack(char *buf, int len, struct spwd *spwd)
|
||||
{
|
||||
char *org = buf;
|
||||
|
||||
spwd->sp_namp = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
|
||||
spwd->sp_pwdp = buf;
|
||||
buf += strlen (buf) + 1;
|
||||
|
||||
memcpy (&spwd->sp_min, buf, sizeof spwd->sp_min);
|
||||
buf += sizeof spwd->sp_min;
|
||||
|
||||
memcpy (&spwd->sp_max, buf, sizeof spwd->sp_max);
|
||||
buf += sizeof spwd->sp_max;
|
||||
|
||||
memcpy (&spwd->sp_lstchg, buf, sizeof spwd->sp_lstchg);
|
||||
buf += sizeof spwd->sp_lstchg;
|
||||
|
||||
memcpy (&spwd->sp_warn, buf, sizeof spwd->sp_warn);
|
||||
buf += sizeof spwd->sp_warn;
|
||||
|
||||
memcpy (&spwd->sp_inact, buf, sizeof spwd->sp_inact);
|
||||
buf += sizeof spwd->sp_inact;
|
||||
|
||||
memcpy (&spwd->sp_expire, buf, sizeof spwd->sp_expire);
|
||||
buf += sizeof spwd->sp_expire;
|
||||
|
||||
memcpy (&spwd->sp_flag, buf, sizeof spwd->sp_flag);
|
||||
buf += sizeof spwd->sp_flag;
|
||||
|
||||
if (buf - org > len)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /*}*/
|
25
lib/strcasecmp.c
Normal file
25
lib/strcasecmp.c
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: strcasecmp.c,v 1.1 1999/07/09 18:02:43 marekm Exp $")
|
||||
|
||||
/*
|
||||
* strcasecmp - compare strings, ignoring case
|
||||
*/
|
||||
|
||||
char *
|
||||
strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
int ret;
|
||||
|
||||
for (;;) {
|
||||
ret = tolower(*s1) - tolower(*s2);
|
||||
if (ret || *s1 == '\0' || *s2 == '\0')
|
||||
break;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return ret;
|
||||
}
|
16
lib/strdup.c
Normal file
16
lib/strdup.c
Normal file
@@ -0,0 +1,16 @@
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: strdup.c,v 1.2 1997/12/07 23:26:59 marekm Exp $")
|
||||
|
||||
extern char *malloc();
|
||||
|
||||
char *
|
||||
strdup(const char *str)
|
||||
{
|
||||
char *s = malloc(strlen(str) + 1);
|
||||
|
||||
if (s)
|
||||
strcpy(s, str);
|
||||
return s;
|
||||
}
|
23
lib/strerror.c
Normal file
23
lib/strerror.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <config.h>
|
||||
#include <errno.h>
|
||||
#include "defines.h"
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: strerror.c,v 1.3 1998/12/28 20:34:39 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
||||
char *
|
||||
strerror(int err)
|
||||
{
|
||||
static char unknown[80];
|
||||
|
||||
if (err >= 0 && err < sys_nerr)
|
||||
return sys_errlist[err];
|
||||
|
||||
snprintf(unknown, sizeof unknown, _("Unknown error %d"), err);
|
||||
errno = EINVAL;
|
||||
return unknown;
|
||||
}
|
55
lib/strstr.c
Normal file
55
lib/strstr.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
#include "defines.h"
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: strstr.c,v 1.4 1998/01/29 23:22:32 marekm Exp $")
|
||||
|
||||
/*
|
||||
* strstr - find substring in string
|
||||
*/
|
||||
|
||||
char *
|
||||
strstr(const char *string, const char *pattern)
|
||||
{
|
||||
char *cp;
|
||||
int len;
|
||||
|
||||
len = strlen (pattern);
|
||||
|
||||
for (cp = string;cp = strchr (cp, *pattern);) {
|
||||
if (strncmp (cp, pattern, len) == 0)
|
||||
return cp;
|
||||
|
||||
cp++;
|
||||
}
|
||||
return 0;
|
||||
}
|
90
lib/tcfsio.c
Normal file
90
lib/tcfsio.c
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_TCFS
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#ifdef TCFS_GDBM_SUPPORT
|
||||
#undef GDBM_SUPPORT
|
||||
#define GDBM_SUPPORT
|
||||
#endif
|
||||
|
||||
#include <tcfslib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "commonio.h"
|
||||
#include "tcfsio.h"
|
||||
|
||||
static struct commonio_db tcfs_db = {
|
||||
TCFSPWDFILE, /* filename */
|
||||
NULL, /* ops */
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
};
|
||||
|
||||
int
|
||||
tcfs_file_present(void)
|
||||
{
|
||||
return commonio_present(&tcfs_db);
|
||||
}
|
||||
|
||||
int
|
||||
tcfs_lock(void)
|
||||
{
|
||||
return commonio_lock(&tcfs_db);
|
||||
}
|
||||
|
||||
int
|
||||
tcfs_open(int mode)
|
||||
{
|
||||
return 1;
|
||||
/* return tcfs_open(); */
|
||||
}
|
||||
|
||||
tcfspwdb *
|
||||
tcfs_locate(char *name)
|
||||
{
|
||||
return tcfs_getpwnam(name, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
tcfs_update(char *user, struct tcfspwd *tcfspword)
|
||||
{
|
||||
char *o, *p;
|
||||
|
||||
o=(char*)calloc(128,sizeof(char));
|
||||
p=(char*)calloc(128,sizeof(char));
|
||||
strcpy (o, tcfspword->tcfsorig);
|
||||
strcpy (p, tcfspword->tcfspass);
|
||||
return tcfs_chgkey(user,o,p);
|
||||
}
|
||||
|
||||
int
|
||||
tcfs_remove(char *name)
|
||||
{
|
||||
return tcfs_putpwnam(name, NULL, U_DEL);
|
||||
}
|
||||
|
||||
int
|
||||
tcfs_close(void)
|
||||
{
|
||||
return 1;
|
||||
/* return tcfs_close(&shadow_db); */
|
||||
}
|
||||
|
||||
int
|
||||
tcfs_unlock(void)
|
||||
{
|
||||
return commonio_unlock(&tcfs_db);
|
||||
}
|
||||
|
||||
#endif
|
14
lib/tcfsio.h
Normal file
14
lib/tcfsio.h
Normal file
@@ -0,0 +1,14 @@
|
||||
struct tcfspwd {
|
||||
char tcfspass[200]; /* new password */
|
||||
char tcfsorig[200]; /* old password */
|
||||
};
|
||||
|
||||
extern int tcfs_close P_((void));
|
||||
extern int tcfs_file_present P_((void));
|
||||
extern tcfspwdb *tcfs_locate P_((char *));
|
||||
extern int tcfs_lock P_((void));
|
||||
extern int tcfs_name P_((char *));
|
||||
extern int tcfs_open P_((int));
|
||||
extern int tcfs_remove P_((char *));
|
||||
extern int tcfs_unlock P_((void));
|
||||
extern int tcfs_update P_((char *, struct tcfspwd *));
|
114
lib/utent.c
Normal file
114
lib/utent.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 1993 - 1994, Julianne Frances Haugh
|
||||
* 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH 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 JULIE HAUGH 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>
|
||||
|
||||
#ifndef HAVE_GETUTENT
|
||||
|
||||
#include "defines.h"
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <utmp.h>
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id: utent.c,v 1.4 1998/01/29 23:22:32 marekm Exp $";
|
||||
#endif
|
||||
|
||||
static int utmp_fd = -1;
|
||||
static struct utmp utmp_buf;
|
||||
|
||||
/*
|
||||
* setutent - open or rewind the utmp file
|
||||
*/
|
||||
|
||||
void
|
||||
setutent(void)
|
||||
{
|
||||
if (utmp_fd == -1)
|
||||
if ((utmp_fd = open (_UTMP_FILE, O_RDWR)) == -1)
|
||||
utmp_fd = open (_UTMP_FILE, O_RDONLY);
|
||||
|
||||
if (utmp_fd != -1)
|
||||
lseek (utmp_fd, (off_t) 0L, SEEK_SET);
|
||||
}
|
||||
|
||||
/*
|
||||
* endutent - close the utmp file
|
||||
*/
|
||||
|
||||
void
|
||||
endutent(void)
|
||||
{
|
||||
if (utmp_fd != -1)
|
||||
close (utmp_fd);
|
||||
|
||||
utmp_fd = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* getutent - get the next record from the utmp file
|
||||
*/
|
||||
|
||||
struct utmp *
|
||||
getutent(void)
|
||||
{
|
||||
if (utmp_fd == -1)
|
||||
setutent ();
|
||||
|
||||
if (utmp_fd == -1)
|
||||
return 0;
|
||||
|
||||
if (read (utmp_fd, &utmp_buf, sizeof utmp_buf) != sizeof utmp_buf)
|
||||
return 0;
|
||||
|
||||
return &utmp_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* getutline - get the utmp entry matching ut_line
|
||||
*/
|
||||
|
||||
struct utmp *
|
||||
getutline(const struct utmp *utent)
|
||||
{
|
||||
struct utmp save;
|
||||
struct utmp *new;
|
||||
|
||||
save = *utent;
|
||||
while (new = getutent ())
|
||||
if (strncmp (new->ut_line, save.ut_line, sizeof new->ut_line))
|
||||
continue;
|
||||
else
|
||||
return new;
|
||||
|
||||
return (struct utmp *) 0;
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif
|
Reference in New Issue
Block a user