[svn-upgrade] Integrating new upstream version, shadow (19990709)
This commit is contained in:
20
libmisc/Makefile.am
Normal file
20
libmisc/Makefile.am
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.0 foreign
|
||||
|
||||
noinst_HEADERS = chkname.h failure.h getdate.h
|
||||
|
||||
noinst_LIBRARIES = libmisc.a
|
||||
|
||||
libdir = $(prefix)/lib
|
||||
localedir = $(datadir)/locale
|
||||
INCLUDES = -I$(top_srcdir)/libmisc -I$(top_srcdir)/lib
|
||||
DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
|
||||
|
||||
libmisc_a_SOURCES = addgrps.c age.c basename.c chkname.c chkshell.c \
|
||||
chowndir.c chowntty.c console.c copydir.c entry.c env.c failure.c \
|
||||
fields.c getdate.y hushed.c isexpired.c limits.c list.c log.c \
|
||||
login_access.c login_desrpc.c login_krb.c loginprompt.c mail.c motd.c \
|
||||
myname.c obscure.c pam_pass.c pwd2spwd.c pwdcheck.c pwd_init.c rlogin.c \
|
||||
salt.c setugid.c setup.c setupenv.c shell.c strtoday.c suauth.c sub.c \
|
||||
sulog.c ttytype.c tz.c ulimit.c utmp.c valid.c xmalloc.c
|
||||
|
||||
418
libmisc/Makefile.in
Normal file
418
libmisc/Makefile.in
Normal file
@@ -0,0 +1,418 @@
|
||||
# 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 = chkname.h failure.h getdate.h
|
||||
|
||||
noinst_LIBRARIES = libmisc.a
|
||||
|
||||
libdir = $(prefix)/lib
|
||||
localedir = $(datadir)/locale
|
||||
INCLUDES = -I$(top_srcdir)/libmisc -I$(top_srcdir)/lib
|
||||
DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
|
||||
|
||||
libmisc_a_SOURCES = addgrps.c age.c basename.c chkname.c chkshell.c \
|
||||
chowndir.c chowntty.c console.c copydir.c entry.c env.c failure.c \
|
||||
fields.c getdate.y hushed.c isexpired.c limits.c list.c log.c \
|
||||
login_access.c login_desrpc.c login_krb.c loginprompt.c mail.c motd.c \
|
||||
myname.c obscure.c pam_pass.c pwd2spwd.c pwdcheck.c pwd_init.c rlogin.c \
|
||||
salt.c setugid.c setup.c setupenv.c shell.c strtoday.c suauth.c sub.c \
|
||||
sulog.c ttytype.c tz.c ulimit.c utmp.c valid.c xmalloc.c
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
libmisc_a_LIBADD =
|
||||
libmisc_a_OBJECTS = addgrps.o age.o basename.o chkname.o chkshell.o \
|
||||
chowndir.o chowntty.o console.o copydir.o entry.o env.o failure.o \
|
||||
fields.o getdate.o hushed.o isexpired.o limits.o list.o log.o \
|
||||
login_access.o login_desrpc.o login_krb.o loginprompt.o mail.o motd.o \
|
||||
myname.o obscure.o pam_pass.o pwd2spwd.o pwdcheck.o pwd_init.o rlogin.o \
|
||||
salt.o setugid.o setup.o setupenv.o shell.o strtoday.o suauth.o sub.o \
|
||||
sulog.o ttytype.o tz.o ulimit.o utmp.o valid.o xmalloc.o
|
||||
AR = ar
|
||||
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 getdate.c
|
||||
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
TAR = tar
|
||||
GZIP = --best
|
||||
SOURCES = $(libmisc_a_SOURCES)
|
||||
OBJECTS = $(libmisc_a_OBJECTS)
|
||||
|
||||
all: Makefile $(LIBRARIES) $(HEADERS)
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .S .c .lo .o .s .y
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps libmisc/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:
|
||||
|
||||
libmisc.a: $(libmisc_a_OBJECTS) $(libmisc_a_DEPENDENCIES)
|
||||
-rm -f libmisc.a
|
||||
$(AR) cru libmisc.a $(libmisc_a_OBJECTS) $(libmisc_a_LIBADD)
|
||||
$(RANLIB) libmisc.a
|
||||
.y.c:
|
||||
$(YACC) $(YFLAGS) $< && mv y.tab.c $*.c
|
||||
if test -f y.tab.h; then \
|
||||
if cmp -s y.tab.h $*.h; then rm -f y.tab.h; else mv y.tab.h $*.h; fi; \
|
||||
else :; fi
|
||||
getdate.h: getdate.c
|
||||
|
||||
|
||||
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 = libmisc
|
||||
|
||||
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
|
||||
addgrps.o: addgrps.c ../config.h ../lib/prototypes.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/rcsid.h
|
||||
age.o: age.c ../config.h ../lib/prototypes.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/rcsid.h
|
||||
basename.o: basename.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/prototypes.h
|
||||
chkname.o: chkname.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h chkname.h
|
||||
chkshell.o: chkshell.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
chowndir.o: chowndir.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
chowntty.o: chowntty.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
console.o: console.c ../config.h ../lib/defines.h ../lib/gshadow_.h \
|
||||
../lib/getdef.h ../lib/rcsid.h
|
||||
copydir.o: copydir.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
entry.o: entry.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
env.o: env.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
failure.o: failure.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/faillog.h ../lib/getdef.h failure.h
|
||||
fields.o: fields.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
getdate.o: getdate.c ../config.h getdate.h ../lib/defines.h \
|
||||
../lib/gshadow_.h
|
||||
hushed.o: hushed.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/prototypes.h ../lib/getdef.h
|
||||
isexpired.o: isexpired.c ../config.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/rcsid.h
|
||||
limits.o: limits.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
list.o: list.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
login_access.o: login_access.c ../config.h ../lib/rcsid.h \
|
||||
../lib/prototypes.h ../lib/defines.h ../lib/gshadow_.h
|
||||
login_desrpc.o: login_desrpc.c ../config.h
|
||||
login_krb.o: login_krb.c ../config.h
|
||||
loginprompt.o: loginprompt.c ../config.h ../lib/rcsid.h \
|
||||
../lib/prototypes.h ../lib/defines.h ../lib/gshadow_.h \
|
||||
../lib/getdef.h
|
||||
log.o: log.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h
|
||||
mail.o: mail.c ../config.h ../lib/prototypes.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/getdef.h ../lib/rcsid.h
|
||||
motd.o: motd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
myname.o: myname.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/prototypes.h
|
||||
obscure.o: obscure.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
pam_pass.o: pam_pass.c ../config.h
|
||||
pwd2spwd.o: pwd2spwd.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
pwdcheck.o: pwdcheck.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/pwauth.h
|
||||
pwd_init.o: pwd_init.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h
|
||||
rlogin.o: rlogin.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
salt.o: salt.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
setugid.o: setugid.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
setupenv.o: setupenv.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
setup.o: setup.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
shell.o: shell.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
strtoday.o: strtoday.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h getdate.h
|
||||
suauth.o: suauth.c ../config.h ../lib/prototypes.h ../lib/defines.h \
|
||||
../lib/gshadow_.h
|
||||
sub.o: sub.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
sulog.o: sulog.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h ../lib/getdef.h
|
||||
ttytype.o: ttytype.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h ../lib/getdef.h
|
||||
tz.o: tz.c ../config.h ../lib/rcsid.h ../lib/defines.h ../lib/gshadow_.h \
|
||||
../lib/getdef.h
|
||||
ulimit.o: ulimit.c ../config.h ../lib/rcsid.h
|
||||
utmp.o: utmp.c ../config.h ../lib/defines.h ../lib/gshadow_.h \
|
||||
../lib/rcsid.h
|
||||
valid.o: valid.c ../config.h ../lib/rcsid.h ../lib/prototypes.h \
|
||||
../lib/defines.h ../lib/gshadow_.h
|
||||
xmalloc.o: xmalloc.c ../config.h ../lib/rcsid.h ../lib/defines.h \
|
||||
../lib/gshadow_.h
|
||||
|
||||
info:
|
||||
dvi:
|
||||
check: all
|
||||
$(MAKE)
|
||||
installcheck:
|
||||
install-exec:
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install-data:
|
||||
@$(NORMAL_INSTALL)
|
||||
|
||||
install: install-exec install-data all
|
||||
@:
|
||||
|
||||
uninstall:
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
|
||||
installdirs:
|
||||
|
||||
|
||||
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-tags \
|
||||
mostlyclean-generic
|
||||
|
||||
clean: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \
|
||||
clean-generic mostlyclean
|
||||
|
||||
distclean: distclean-noinstLIBRARIES distclean-compile \
|
||||
distclean-libtool 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-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 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
|
||||
|
||||
|
||||
# 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:
|
||||
89
libmisc/addgrps.c
Normal file
89
libmisc/addgrps.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_SETGROUPS
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: addgrps.c,v 1.4 1998/12/28 20:34:41 marekm Exp $")
|
||||
|
||||
#define SEP ",:"
|
||||
|
||||
/*
|
||||
* Add groups with names from LIST (separated by commas or colons)
|
||||
* to the supplementary group set. Silently ignore groups which are
|
||||
* already there. Warning: uses strtok().
|
||||
*/
|
||||
|
||||
int
|
||||
add_groups(const char *list)
|
||||
{
|
||||
GETGROUPS_T *grouplist, *tmp;
|
||||
int i, ngroups, added;
|
||||
struct group *grp;
|
||||
char *token;
|
||||
char buf[1024];
|
||||
|
||||
if (strlen(list) >= sizeof(buf)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
strcpy(buf, list);
|
||||
|
||||
i = 16;
|
||||
for (;;) {
|
||||
grouplist = malloc(i * sizeof(GETGROUPS_T));
|
||||
if (!grouplist)
|
||||
return -1;
|
||||
ngroups = getgroups(i, grouplist);
|
||||
if (i > ngroups)
|
||||
break;
|
||||
/* not enough room, so try allocating a larger buffer */
|
||||
free(grouplist);
|
||||
i *= 2;
|
||||
}
|
||||
if (ngroups < 0) {
|
||||
free(grouplist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
added = 0;
|
||||
for (token = strtok(buf, SEP); token; token = strtok(NULL, SEP)) {
|
||||
|
||||
grp = getgrnam(token);
|
||||
if (!grp) {
|
||||
fprintf(stderr, _("Warning: unknown group %s\n"), token);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < ngroups && grouplist[i] != grp->gr_gid; i++)
|
||||
;
|
||||
|
||||
if (i < ngroups)
|
||||
continue;
|
||||
|
||||
if (ngroups >= NGROUPS_MAX) {
|
||||
fprintf(stderr, _("Warning: too many groups\n"));
|
||||
break;
|
||||
}
|
||||
tmp = realloc(grouplist, (ngroups + 1) * sizeof(GETGROUPS_T));
|
||||
if (!tmp) {
|
||||
free(grouplist);
|
||||
return -1;
|
||||
}
|
||||
tmp[ngroups++] = grp->gr_gid;
|
||||
grouplist = tmp;
|
||||
added++;
|
||||
}
|
||||
|
||||
if (added)
|
||||
return setgroups(ngroups, grouplist);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
235
libmisc/age.c
Normal file
235
libmisc/age.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#ifdef HAVE_USERSEC_H
|
||||
#include <userpw.h>
|
||||
#include <usersec.h>
|
||||
#include <userconf.h>
|
||||
#endif
|
||||
|
||||
#ifndef AGING
|
||||
#if defined(SHADOWPWD) || defined(HAVE_USERSEC_H)
|
||||
#define AGING 1
|
||||
#endif
|
||||
#else
|
||||
#if !defined(SHADOWPWD) && !defined(HAVE_USERSEC_H) && !defined(ATT_AGE)
|
||||
#undef AGING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SHADOWPWD) || defined(AGING) /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: age.c,v 1.6 1998/12/28 20:34:42 marekm Exp $")
|
||||
|
||||
#ifndef PASSWD_PROGRAM
|
||||
#define PASSWD_PROGRAM "/bin/passwd"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* expire - force password change if password expired
|
||||
*
|
||||
* expire() calls /bin/passwd to change the user's password
|
||||
* if it has expired.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
int
|
||||
expire(const struct passwd *pw, const struct spwd *sp)
|
||||
{
|
||||
#else
|
||||
int
|
||||
expire(const struct passwd *pw)
|
||||
{
|
||||
#endif
|
||||
int status;
|
||||
int child;
|
||||
int pid;
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
if (! sp)
|
||||
sp = pwd_to_spwd (pw);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if the user's password has expired, and if so
|
||||
* force them to change their password.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
switch (status = isexpired (pw, sp))
|
||||
#else
|
||||
switch (status = isexpired (pw))
|
||||
#endif
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
printf(_("Your password has expired."));
|
||||
break;
|
||||
case 2:
|
||||
printf(_("Your password is inactive."));
|
||||
break;
|
||||
case 3:
|
||||
printf(_("Your login has expired."));
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setting the maximum valid period to less than the minimum
|
||||
* valid period means that the minimum period will never
|
||||
* occur while the password is valid, so the user can never
|
||||
* change that password.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
if (status > 1 || sp->sp_max < sp->sp_min)
|
||||
#else
|
||||
if (status > 1 || c64i (pw->pw_age[0]) < c64i (pw->pw_age[1]))
|
||||
#endif
|
||||
{
|
||||
puts(_(" Contact the system administrator.\n"));
|
||||
exit(1);
|
||||
}
|
||||
puts(_(" Choose a new password.\n"));
|
||||
fflush (stdout);
|
||||
|
||||
/*
|
||||
* Close all the files so that unauthorized access won't
|
||||
* occur. This needs to be done anyway because those files
|
||||
* might become stale after "passwd" is executed.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
endspent ();
|
||||
#endif
|
||||
endpwent ();
|
||||
#ifdef SHADOWGRP
|
||||
endsgent ();
|
||||
#endif
|
||||
endgrent ();
|
||||
|
||||
/*
|
||||
* Execute the /bin/passwd command. The exit status will be
|
||||
* examined to see what the result is. If there are any
|
||||
* errors the routine will exit. This forces the user to
|
||||
* change their password before being able to use the account.
|
||||
*/
|
||||
|
||||
if ((pid = fork ()) == 0) {
|
||||
int err;
|
||||
|
||||
/*
|
||||
* Set the UID to be that of the user. This causes
|
||||
* passwd to work just like it would had they executed
|
||||
* it from the command line while logged in.
|
||||
*/
|
||||
if (setup_uid_gid(pw, 0))
|
||||
_exit(126);
|
||||
|
||||
execl(PASSWD_PROGRAM, PASSWD_PROGRAM, pw->pw_name, (char *)0);
|
||||
err = errno;
|
||||
perror("Can't execute " PASSWD_PROGRAM);
|
||||
_exit((err == ENOENT) ? 127 : 126);
|
||||
} else if (pid == -1) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
while ((child = wait (&status)) != pid && child != -1)
|
||||
;
|
||||
|
||||
if (child == pid && status == 0)
|
||||
return 1;
|
||||
|
||||
exit (1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/*
|
||||
* agecheck - see if warning is needed for password expiration
|
||||
*
|
||||
* agecheck sees how many days until the user's password is going
|
||||
* to expire and warns the user of the pending password expiration.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
void
|
||||
agecheck(const struct passwd *pw, const struct spwd *sp)
|
||||
{
|
||||
#else
|
||||
void
|
||||
agecheck(const struct passwd *pw)
|
||||
{
|
||||
#endif
|
||||
long now = time ((long *) 0) / SCALE;
|
||||
long remain;
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
if (! sp)
|
||||
sp = pwd_to_spwd (pw);
|
||||
|
||||
/*
|
||||
* The last, max, and warn fields must be supported or the
|
||||
* warning period cannot be calculated.
|
||||
*/
|
||||
|
||||
if (sp->sp_lstchg == -1 || sp->sp_max == -1 || sp->sp_warn == -1)
|
||||
return;
|
||||
#else
|
||||
if (pw->pw_age[0] == '\0')
|
||||
return;
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
if ((remain = (sp->sp_lstchg + sp->sp_max) - now) <= sp->sp_warn)
|
||||
#else
|
||||
if ((remain = (a64l (pw->pw_age + 2) + c64i (pw->pw_age[0])) * 7
|
||||
- now) <= getdef_num ("PASS_WARN_AGE", 7))
|
||||
#endif
|
||||
{
|
||||
remain /= DAY/SCALE;
|
||||
if (remain > 1)
|
||||
printf(_("Your password will expire in %ld days.\n"), remain);
|
||||
else if (remain == 1)
|
||||
printf(_("Your password will expire tomorrow.\n"));
|
||||
else if (remain == 0)
|
||||
printf(_("Your password will expire today.\n"));
|
||||
}
|
||||
}
|
||||
#endif /*}*/
|
||||
22
libmisc/basename.c
Normal file
22
libmisc/basename.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* basename.c - not worth copyrighting :-). Some versions of Linux libc
|
||||
* already have basename(), other versions don't. To avoid confusion,
|
||||
* we will not use the function from libc and use a different name here.
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: basename.c,v 1.2 1997/12/07 23:27:00 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
|
||||
char *
|
||||
Basename(char *str)
|
||||
{
|
||||
char *cp = strrchr(str, '/');
|
||||
|
||||
return cp ? cp+1 : str;
|
||||
}
|
||||
73
libmisc/chkname.c
Normal file
73
libmisc/chkname.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* check_user_name(), check_group_name() - check the new user/group
|
||||
* name for validity; return value: 1 - OK, 0 - bad name
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: chkname.c,v 1.4 1998/04/16 19:57:43 marekm Exp $")
|
||||
|
||||
#include <ctype.h>
|
||||
#include "defines.h"
|
||||
#include "chkname.h"
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#else
|
||||
#include <utmp.h>
|
||||
#endif
|
||||
|
||||
static int
|
||||
good_name(const char *name)
|
||||
{
|
||||
/*
|
||||
* User/group names must start with a letter, and may not
|
||||
* contain colons, commas, newlines (used in passwd/group
|
||||
* files...) or any non-printable characters.
|
||||
*/
|
||||
if (!*name || !isalpha(*name))
|
||||
return 0;
|
||||
|
||||
while (*name) {
|
||||
if (*name == ':' || *name == ',' ||
|
||||
*name == '\n' || !isprint(*name))
|
||||
return 0;
|
||||
|
||||
name++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
check_user_name(const char *name)
|
||||
{
|
||||
#if HAVE_UTMPX_H
|
||||
struct utmpx ut;
|
||||
#else
|
||||
struct utmp ut;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* User names are limited by whatever utmp can
|
||||
* handle (usually max 8 characters).
|
||||
*/
|
||||
if (strlen(name) > sizeof(ut.ut_user))
|
||||
return 0;
|
||||
|
||||
return good_name(name);
|
||||
}
|
||||
|
||||
int
|
||||
check_group_name(const char *name)
|
||||
{
|
||||
/*
|
||||
* Arbitrary limit for group names - max 16
|
||||
* characters (same as on HP-UX 10).
|
||||
*/
|
||||
if (strlen(name) > 16)
|
||||
return 0;
|
||||
|
||||
return good_name(name);
|
||||
}
|
||||
15
libmisc/chkname.h
Normal file
15
libmisc/chkname.h
Normal file
@@ -0,0 +1,15 @@
|
||||
/* $Id: chkname.h,v 1.1 1997/12/07 23:27:00 marekm Exp $ */
|
||||
#ifndef _CHKNAME_H_
|
||||
#define _CHKNAME_H_
|
||||
|
||||
/*
|
||||
* check_user_name(), check_group_name() - check the new user/group
|
||||
* name for validity; return value: 1 - OK, 0 - bad name
|
||||
*/
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
extern int check_user_name P_((const char *));
|
||||
extern int check_group_name P_((const char *name));
|
||||
|
||||
#endif
|
||||
98
libmisc/chkshell.c
Normal file
98
libmisc/chkshell.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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: chkshell.c,v 1.1 1997/12/07 23:27:00 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#ifndef SHELLS_FILE
|
||||
#define SHELLS_FILE "/etc/shells"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* check_shell - see if the user's login shell is listed in /etc/shells
|
||||
*
|
||||
* The /etc/shells file is read for valid names of login shells. If the
|
||||
* /etc/shells file does not exist the user cannot set any shell unless
|
||||
* they are root.
|
||||
*
|
||||
* If getusershell() is available (Linux, *BSD, possibly others), use it
|
||||
* instead of re-implementing it.
|
||||
*/
|
||||
|
||||
int
|
||||
check_shell(const char *sh)
|
||||
{
|
||||
char *cp;
|
||||
int found = 0;
|
||||
#ifndef HAVE_GETUSERSHELL
|
||||
char buf[BUFSIZ];
|
||||
FILE *fp;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETUSERSHELL
|
||||
setusershell();
|
||||
while ((cp = getusershell())) {
|
||||
if (*cp == '#')
|
||||
continue;
|
||||
|
||||
if (strcmp(cp, sh) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
endusershell();
|
||||
#else
|
||||
if ((fp = fopen (SHELLS_FILE, "r")) == (FILE *) 0)
|
||||
return 0;
|
||||
|
||||
while (fgets (buf, sizeof(buf), fp)) {
|
||||
if ((cp = strrchr(buf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
|
||||
if (strcmp (buf, sh) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
#endif
|
||||
return found;
|
||||
}
|
||||
|
||||
126
libmisc/chowndir.c
Normal file
126
libmisc/chowndir.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: chowndir.c,v 1.5 1998/04/16 19:57:43 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* chown_tree - change ownership of files in a directory tree
|
||||
*
|
||||
* chown_dir() walks a directory tree and changes the ownership
|
||||
* of all files owned by the provided user ID.
|
||||
*/
|
||||
|
||||
int
|
||||
chown_tree(const char *root, uid_t old_uid, uid_t new_uid, gid_t old_gid, gid_t new_gid)
|
||||
{
|
||||
char new_name[1024];
|
||||
int rc = 0;
|
||||
struct DIRECT *ent;
|
||||
struct stat sb;
|
||||
DIR *dir;
|
||||
|
||||
/*
|
||||
* Make certain the directory exists. This routine is called
|
||||
* directory by the invoker, or recursively.
|
||||
*/
|
||||
|
||||
if (access(root, F_OK) != 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Open the directory and read each entry. Every entry is tested
|
||||
* to see if it is a directory, and if so this routine is called
|
||||
* recursively. If not, it is checked to see if it is owned by
|
||||
* old user ID.
|
||||
*/
|
||||
|
||||
if (! (dir = opendir (root)))
|
||||
return -1;
|
||||
|
||||
while ((ent = readdir (dir))) {
|
||||
|
||||
/*
|
||||
* Skip the "." and ".." entries
|
||||
*/
|
||||
|
||||
if (strcmp (ent->d_name, ".") == 0 ||
|
||||
strcmp (ent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Make the filename for both the source and the
|
||||
* destination files.
|
||||
*/
|
||||
|
||||
if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name)
|
||||
break;
|
||||
|
||||
snprintf(new_name, sizeof new_name, "%s/%s", root, ent->d_name);
|
||||
|
||||
if (stat (new_name, &sb) == -1)
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
|
||||
/*
|
||||
* Do the entire subdirectory.
|
||||
*/
|
||||
|
||||
if ((rc = chown_tree (new_name, old_uid, new_uid,
|
||||
old_gid, new_gid)))
|
||||
break;
|
||||
}
|
||||
if (sb.st_uid == old_uid)
|
||||
chown (new_name, new_uid,
|
||||
sb.st_gid == old_gid ? new_gid:sb.st_gid);
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
/*
|
||||
* Now do the root of the tree
|
||||
*/
|
||||
|
||||
if (! stat (root, &sb)) {
|
||||
if (sb.st_uid == old_uid)
|
||||
chown (root, new_uid,
|
||||
sb.st_gid == old_gid ? new_gid:sb.st_gid);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
127
libmisc/chowntty.c
Normal file
127
libmisc/chowntty.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.
|
||||
* 4. 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: chowntty.c,v 1.7 1998/12/28 20:34:43 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* is_my_tty -- determine if "tty" is the same as TTY stdin is using
|
||||
*/
|
||||
|
||||
static int
|
||||
is_my_tty(const char *tty)
|
||||
{
|
||||
struct stat by_name, by_fd;
|
||||
|
||||
if (stat (tty, &by_name) || fstat (0, &by_fd))
|
||||
return 0;
|
||||
|
||||
if (by_name.st_rdev != by_fd.st_rdev)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* chown_tty() sets the login tty to be owned by the new user ID
|
||||
* with TTYPERM modes
|
||||
*/
|
||||
|
||||
void
|
||||
chown_tty(const char *tty, const struct passwd *info)
|
||||
{
|
||||
char buf[200], full_tty[200];
|
||||
char *group; /* TTY group name or number */
|
||||
struct group *grent;
|
||||
gid_t gid;
|
||||
|
||||
/*
|
||||
* See if login.defs has some value configured for the port group
|
||||
* ID. Otherwise, use the user's primary group ID.
|
||||
*/
|
||||
|
||||
if (! (group = getdef_str ("TTYGROUP")))
|
||||
gid = info->pw_gid;
|
||||
else if (group[0] >= '0' && group[0] <= '9')
|
||||
gid = atoi (group);
|
||||
else if ((grent = getgrnam (group)))
|
||||
gid = grent->gr_gid;
|
||||
else
|
||||
gid = info->pw_gid;
|
||||
|
||||
/*
|
||||
* Change the permissions on the TTY to be owned by the user with
|
||||
* the group as determined above.
|
||||
*/
|
||||
|
||||
if (*tty != '/') {
|
||||
snprintf(full_tty, sizeof full_tty, "/dev/%s", tty);
|
||||
tty = full_tty;
|
||||
}
|
||||
|
||||
if (! is_my_tty (tty)) {
|
||||
SYSLOG((LOG_WARN, "unable to determine TTY name, got %s\n",
|
||||
tty));
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (chown(tty, info->pw_uid, gid) ||
|
||||
chmod(tty, getdef_num("TTYPERM", 0600))) {
|
||||
snprintf(buf, sizeof buf, _("Unable to change tty %s"), tty);
|
||||
SYSLOG((LOG_WARN, "unable to change tty `%s' for user `%s'\n",
|
||||
tty, info->pw_name));
|
||||
closelog();
|
||||
perror (buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Please don't add code to chown /dev/vcs* to the user logging in -
|
||||
* it's a potential security hole. I wouldn't like the previous user
|
||||
* to hold the file descriptor open and watch my screen. We don't
|
||||
* have the *BSD revoke() system call yet, and vhangup() only works
|
||||
* for tty devices (which vcs* is not). --marekm
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
115
libmisc/console.c
Normal file
115
libmisc/console.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 1991, 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 "defines.h"
|
||||
#include <stdio.h>
|
||||
#include "getdef.h"
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: console.c,v 1.5 1998/12/28 20:34:44 marekm Exp $")
|
||||
|
||||
/*
|
||||
* This is now rather generic function which decides if "tty" is listed
|
||||
* under "cfgin" in config (directly or indirectly). Fallback to default if
|
||||
* something is bad.
|
||||
*/
|
||||
int
|
||||
is_listed(const char *cfgin, const char *tty, int def)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[200], *cons, *s;
|
||||
|
||||
/*
|
||||
* If the CONSOLE configuration definition isn't given,
|
||||
* fallback to default.
|
||||
*/
|
||||
|
||||
if ((cons = getdef_str(cfgin)) == NULL)
|
||||
return def;
|
||||
|
||||
/*
|
||||
* If this isn't a filename, then it is a ":" delimited list of
|
||||
* console devices upon which root logins are allowed.
|
||||
*/
|
||||
|
||||
if (*cons != '/') {
|
||||
cons = strcpy(buf, cons);
|
||||
while ((s = strtok(cons, ":")) != NULL) {
|
||||
if (strcmp(s, tty) == 0)
|
||||
return 1;
|
||||
|
||||
cons = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we can't open the console list, then call everything a
|
||||
* console - otherwise root will never be allowed to login.
|
||||
*/
|
||||
|
||||
if ((fp = fopen(cons, "r")) == NULL)
|
||||
return def;
|
||||
|
||||
/*
|
||||
* See if this tty is listed in the console file.
|
||||
*/
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
if (strcmp(buf, tty) == 0) {
|
||||
(void) fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This tty isn't a console.
|
||||
*/
|
||||
|
||||
(void) fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* console - return 1 if the "tty" is a console device, else 0.
|
||||
*
|
||||
* Note - we need to take extreme care here to avoid locking out root logins
|
||||
* if something goes awry. That's why we do things like call everything a
|
||||
* console if the consoles file can't be opened. Because of this, we must
|
||||
* warn the user to protect against the remove of the consoles file since
|
||||
* that would allow an unauthorized root login.
|
||||
*/
|
||||
|
||||
int
|
||||
console(const char *tty)
|
||||
{
|
||||
return is_listed("CONSOLE", tty, 1);
|
||||
}
|
||||
411
libmisc/copydir.c
Normal file
411
libmisc/copydir.c
Normal file
@@ -0,0 +1,411 @@
|
||||
/*
|
||||
* Copyright 1991 - 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: copydir.c,v 1.6 1998/06/25 22:10:42 marekm Exp $")
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
static const char *src_orig;
|
||||
static const char *dst_orig;
|
||||
|
||||
struct link_name {
|
||||
dev_t ln_dev;
|
||||
ino_t ln_ino;
|
||||
int ln_count;
|
||||
char *ln_name;
|
||||
struct link_name *ln_next;
|
||||
};
|
||||
static struct link_name *links;
|
||||
|
||||
/*
|
||||
* remove_link - delete a link from the link list
|
||||
*/
|
||||
|
||||
static void
|
||||
remove_link(struct link_name *ln)
|
||||
{
|
||||
struct link_name *lp;
|
||||
|
||||
if (links == ln) {
|
||||
links = ln->ln_next;
|
||||
free (ln->ln_name);
|
||||
free (ln);
|
||||
return;
|
||||
}
|
||||
for (lp = links;lp;lp = lp->ln_next)
|
||||
if (lp->ln_next == ln)
|
||||
break;
|
||||
|
||||
if (! lp)
|
||||
return;
|
||||
|
||||
lp->ln_next = lp->ln_next->ln_next;
|
||||
free (ln->ln_name);
|
||||
free (ln);
|
||||
}
|
||||
|
||||
/*
|
||||
* check_link - see if a file is really a link
|
||||
*/
|
||||
|
||||
static struct link_name *
|
||||
check_link(const char *name, const struct stat *sb)
|
||||
{
|
||||
struct link_name *lp;
|
||||
int src_len;
|
||||
int dst_len;
|
||||
int name_len;
|
||||
int len;
|
||||
|
||||
for (lp = links;lp;lp = lp->ln_next)
|
||||
if (lp->ln_dev == sb->st_dev && lp->ln_ino == sb->st_ino)
|
||||
return lp;
|
||||
|
||||
if (sb->st_nlink == 1)
|
||||
return 0;
|
||||
|
||||
lp = (struct link_name *) xmalloc (sizeof *lp);
|
||||
src_len = strlen (src_orig);
|
||||
dst_len = strlen (dst_orig);
|
||||
name_len = strlen (name);
|
||||
lp->ln_dev = sb->st_dev;
|
||||
lp->ln_ino = sb->st_ino;
|
||||
lp->ln_count = sb->st_nlink;
|
||||
len = name_len - src_len + dst_len + 1;
|
||||
lp->ln_name = xmalloc(len);
|
||||
snprintf(lp->ln_name, len, "%s%s", dst_orig, name + src_len);
|
||||
lp->ln_next = links;
|
||||
links = lp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy_tree - copy files in a directory tree
|
||||
*
|
||||
* copy_tree() walks a directory tree and copies ordinary files
|
||||
* as it goes.
|
||||
*/
|
||||
|
||||
int
|
||||
copy_tree(const char *src_root, const char *dst_root, uid_t uid, gid_t gid)
|
||||
{
|
||||
char src_name[1024];
|
||||
char dst_name[1024];
|
||||
char buf[1024];
|
||||
int ifd;
|
||||
int ofd;
|
||||
int err = 0;
|
||||
int cnt;
|
||||
int set_orig = 0;
|
||||
struct DIRECT *ent;
|
||||
struct stat sb;
|
||||
struct link_name *lp;
|
||||
DIR *dir;
|
||||
|
||||
/*
|
||||
* Make certain both directories exist. This routine is called
|
||||
* after the home directory is created, or recursively after the
|
||||
* target is created. It assumes the target directory exists.
|
||||
*/
|
||||
|
||||
if (access(src_root, F_OK) != 0 || access(dst_root, F_OK) != 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Open the source directory and read each entry. Every file
|
||||
* entry in the directory is copied with the UID and GID set
|
||||
* to the provided values. As an added security feature only
|
||||
* regular files (and directories ...) are copied, and no file
|
||||
* is made set-ID.
|
||||
*/
|
||||
|
||||
if (! (dir = opendir (src_root)))
|
||||
return -1;
|
||||
|
||||
if (src_orig == 0) {
|
||||
src_orig = src_root;
|
||||
dst_orig = dst_root;
|
||||
set_orig++;
|
||||
}
|
||||
while ((ent = readdir (dir))) {
|
||||
|
||||
/*
|
||||
* Skip the "." and ".." entries
|
||||
*/
|
||||
|
||||
if (strcmp (ent->d_name, ".") == 0 ||
|
||||
strcmp (ent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Make the filename for both the source and the
|
||||
* destination files.
|
||||
*/
|
||||
|
||||
if (strlen (src_root) + strlen (ent->d_name) + 2 > sizeof src_name) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
snprintf(src_name, sizeof src_name, "%s/%s", src_root, ent->d_name);
|
||||
|
||||
if (strlen (dst_root) + strlen (ent->d_name) + 2 > sizeof dst_name) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
snprintf(dst_name, sizeof dst_name, "%s/%s", dst_root, ent->d_name);
|
||||
|
||||
#ifdef S_IFLNK
|
||||
if (lstat (src_name, &sb) == -1)
|
||||
#else
|
||||
if (stat (src_name, &sb) == -1)
|
||||
#endif
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
|
||||
/*
|
||||
* Create a new target directory, make it owned by
|
||||
* the user and then recursively copy that directory.
|
||||
*/
|
||||
|
||||
mkdir (dst_name, sb.st_mode & 0777);
|
||||
chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid,
|
||||
gid == (gid_t) -1 ? sb.st_gid:gid);
|
||||
|
||||
if (copy_tree (src_name, dst_name, uid, gid)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#ifdef S_IFLNK
|
||||
/*
|
||||
* Copy any symbolic links
|
||||
*/
|
||||
|
||||
if (S_ISLNK(sb.st_mode)) {
|
||||
char oldlink[1024];
|
||||
char dummy[1024];
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Get the name of the file which the link points
|
||||
* to. If that name begins with the original
|
||||
* source directory name, that part of the link
|
||||
* name will be replaced with the original
|
||||
* destinateion directory name.
|
||||
*/
|
||||
|
||||
if ((len = readlink(src_name, oldlink, sizeof(oldlink) - 1)) < 0) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
oldlink[len] = '\0'; /* readlink() does not NUL-terminate */
|
||||
if (!strncmp(oldlink, src_orig, strlen(src_orig))) {
|
||||
snprintf(dummy, sizeof dummy, "%s%s",
|
||||
dst_orig, oldlink + strlen(src_orig));
|
||||
strcpy(oldlink, dummy);
|
||||
}
|
||||
if (symlink(oldlink, dst_name)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if this is a previously copied link
|
||||
*/
|
||||
|
||||
if ((lp = check_link (src_name, &sb))) {
|
||||
if (link (lp->ln_name, dst_name)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
if (unlink (src_name)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
if (--lp->ln_count <= 0)
|
||||
remove_link (lp);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Deal with FIFOs and special files. The user really
|
||||
* shouldn't have any of these, but it seems like it
|
||||
* would be nice to copy everything ...
|
||||
*/
|
||||
|
||||
if (!S_ISREG(sb.st_mode)) {
|
||||
if (mknod (dst_name, sb.st_mode & ~07777, sb.st_rdev) ||
|
||||
chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid,
|
||||
gid == (gid_t) -1 ? sb.st_gid:gid) ||
|
||||
chmod (dst_name, sb.st_mode & 07777)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the new file and copy the contents. The new
|
||||
* file will be owned by the provided UID and GID values.
|
||||
*/
|
||||
|
||||
if ((ifd = open (src_name, O_RDONLY)) < 0) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
if ((ofd = open (dst_name, O_WRONLY|O_CREAT, 0)) < 0 ||
|
||||
chown (dst_name, uid == (uid_t) -1 ? sb.st_uid:uid,
|
||||
gid == (gid_t) -1 ? sb.st_gid:gid) ||
|
||||
chmod (dst_name, sb.st_mode & 07777)) {
|
||||
close (ifd);
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
while ((cnt = read (ifd, buf, sizeof buf)) > 0) {
|
||||
if (write (ofd, buf, cnt) != cnt) {
|
||||
cnt = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
close (ifd);
|
||||
close (ofd);
|
||||
|
||||
if (cnt == -1) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
if (set_orig) {
|
||||
src_orig = 0;
|
||||
dst_orig = 0;
|
||||
}
|
||||
return err ? -1:0;
|
||||
}
|
||||
|
||||
/*
|
||||
* remove_tree - remove files in a directory tree
|
||||
*
|
||||
* remove_tree() walks a directory tree and deletes all the files
|
||||
* and directories.
|
||||
*/
|
||||
|
||||
int
|
||||
remove_tree(const char *root)
|
||||
{
|
||||
char new_name[1024];
|
||||
int err = 0;
|
||||
struct DIRECT *ent;
|
||||
struct stat sb;
|
||||
DIR *dir;
|
||||
|
||||
/*
|
||||
* Make certain the directory exists.
|
||||
*/
|
||||
|
||||
if (access(root, F_OK) != 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* Open the source directory and read each entry. Every file
|
||||
* entry in the directory is copied with the UID and GID set
|
||||
* to the provided values. As an added security feature only
|
||||
* regular files (and directories ...) are copied, and no file
|
||||
* is made set-ID.
|
||||
*/
|
||||
|
||||
dir = opendir (root);
|
||||
|
||||
while ((ent = readdir (dir))) {
|
||||
|
||||
/*
|
||||
* Skip the "." and ".." entries
|
||||
*/
|
||||
|
||||
if (strcmp (ent->d_name, ".") == 0 ||
|
||||
strcmp (ent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Make the filename for the current entry.
|
||||
*/
|
||||
|
||||
if (strlen (root) + strlen (ent->d_name) + 2 > sizeof new_name) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
snprintf(new_name, sizeof new_name, "%s/%s", root, ent->d_name);
|
||||
#ifdef S_IFLNK
|
||||
if (lstat (new_name, &sb) == -1)
|
||||
#else
|
||||
if (stat (new_name, &sb) == -1)
|
||||
#endif
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(sb.st_mode)) {
|
||||
|
||||
/*
|
||||
* Recursively delete this directory.
|
||||
*/
|
||||
|
||||
if (remove_tree (new_name)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
if (rmdir (new_name)) {
|
||||
err++;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
unlink (new_name);
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
return err ? -1:0;
|
||||
}
|
||||
99
libmisc/entry.c
Normal file
99
libmisc/entry.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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: entry.c,v 1.3 1997/12/07 23:27:03 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
|
||||
struct passwd *fgetpwent ();
|
||||
|
||||
void
|
||||
entry(const char *name, struct passwd *pwent)
|
||||
{
|
||||
struct passwd *passwd;
|
||||
#ifdef SHADOWPWD
|
||||
struct spwd *spwd;
|
||||
#ifdef ATT_AGE
|
||||
char *l64a ();
|
||||
char *cp;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (! (passwd = getpwnam (name))) {
|
||||
pwent->pw_name = (char *) 0;
|
||||
return;
|
||||
} else {
|
||||
pwent->pw_name = xstrdup (passwd->pw_name);
|
||||
pwent->pw_uid = passwd->pw_uid;
|
||||
pwent->pw_gid = passwd->pw_gid;
|
||||
#ifdef ATT_COMMENT
|
||||
pwent->pw_comment = xstrdup (passwd->pw_comment);
|
||||
#endif
|
||||
pwent->pw_gecos = xstrdup (passwd->pw_gecos);
|
||||
pwent->pw_dir = xstrdup (passwd->pw_dir);
|
||||
pwent->pw_shell = xstrdup (passwd->pw_shell);
|
||||
#if defined(SHADOWPWD) && !defined(AUTOSHADOW)
|
||||
setspent ();
|
||||
if ((spwd = getspnam (name))) {
|
||||
pwent->pw_passwd = xstrdup (spwd->sp_pwdp);
|
||||
#ifdef ATT_AGE
|
||||
pwent->pw_age = (char *) xmalloc (5);
|
||||
|
||||
if (spwd->sp_max > (63*7))
|
||||
spwd->sp_max = (63*7);
|
||||
if (spwd->sp_min > (63*7))
|
||||
spwd->sp_min = (63*7);
|
||||
|
||||
pwent->pw_age[0] = i64c (spwd->sp_max / 7);
|
||||
pwent->pw_age[1] = i64c (spwd->sp_min / 7);
|
||||
|
||||
cp = l64a (spwd->sp_lstchg / 7);
|
||||
pwent->pw_age[2] = cp[0];
|
||||
pwent->pw_age[3] = cp[1];
|
||||
|
||||
pwent->pw_age[4] = '\0';
|
||||
#endif
|
||||
endspent ();
|
||||
return;
|
||||
}
|
||||
endspent ();
|
||||
#endif
|
||||
pwent->pw_passwd = xstrdup (passwd->pw_passwd);
|
||||
#ifdef ATT_AGE
|
||||
pwent->pw_age = xstrdup (passwd->pw_age);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
250
libmisc/env.c
Normal file
250
libmisc/env.c
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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: env.c,v 1.9 1999/03/07 19:14:38 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
/*
|
||||
* NEWENVP_STEP must be a power of two. This is the number
|
||||
* of (char *) pointers to allocate at a time, to avoid using
|
||||
* realloc() too often.
|
||||
*/
|
||||
#define NEWENVP_STEP 16
|
||||
|
||||
size_t newenvc = 0;
|
||||
char **newenvp = NULL;
|
||||
extern char **environ;
|
||||
|
||||
static const char *forbid[] = {
|
||||
"_RLD_=",
|
||||
"BASH_ENV=", /* GNU creeping featurism strikes again... */
|
||||
"ENV=",
|
||||
"HOME=",
|
||||
"IFS=",
|
||||
"KRB_CONF=",
|
||||
"LD_", /* anything with the LD_ prefix */
|
||||
"LIBPATH=",
|
||||
"MAIL=",
|
||||
"NLSPATH=",
|
||||
"PATH=",
|
||||
"SHELL=",
|
||||
"SHLIB_PATH=",
|
||||
(char *) 0
|
||||
};
|
||||
|
||||
/* these are allowed, but with no slashes inside
|
||||
(to work around security problems in GNU gettext) */
|
||||
static const char *noslash[] = {
|
||||
"LANG=",
|
||||
"LANGUAGE=",
|
||||
"LC_", /* anything with the LC_ prefix */
|
||||
(char *) 0
|
||||
};
|
||||
|
||||
/*
|
||||
* initenv() must be called once before using addenv().
|
||||
*/
|
||||
void
|
||||
initenv(void)
|
||||
{
|
||||
newenvp = (char **)xmalloc(NEWENVP_STEP * sizeof(char *));
|
||||
*newenvp = NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addenv(const char *string, const char *value)
|
||||
{
|
||||
char *cp, *newstring;
|
||||
size_t i;
|
||||
size_t n;
|
||||
|
||||
if (value) {
|
||||
newstring = xmalloc(strlen(string) + strlen(value) + 2);
|
||||
sprintf(newstring, "%s=%s", string, value);
|
||||
} else {
|
||||
newstring = xstrdup(string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a '=' character within the string and if none is found
|
||||
* just ignore the whole string.
|
||||
*/
|
||||
|
||||
cp = strchr(newstring, '=');
|
||||
if (!cp) {
|
||||
free(newstring);
|
||||
return;
|
||||
}
|
||||
|
||||
n = (size_t)(cp - newstring);
|
||||
|
||||
for (i = 0; i < newenvc; i++) {
|
||||
if (strncmp(newstring, newenvp[i], n) == 0 &&
|
||||
(newenvp[i][n] == '=' || newenvp[i][n] == '\0'))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < newenvc) {
|
||||
free(newenvp[i]);
|
||||
newenvp[i] = newstring;
|
||||
return;
|
||||
}
|
||||
|
||||
newenvp[newenvc++] = newstring;
|
||||
|
||||
/*
|
||||
* Check whether newenvc is a multiple of NEWENVP_STEP.
|
||||
* If so we have to resize the vector.
|
||||
* the expression (newenvc & (NEWENVP_STEP - 1)) == 0
|
||||
* is equal to (newenvc % NEWENVP_STEP) == 0
|
||||
* as long as NEWENVP_STEP is a power of 2.
|
||||
*/
|
||||
|
||||
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
|
||||
char **__newenvp;
|
||||
size_t newsize;
|
||||
|
||||
/*
|
||||
* If the resize operation succeds we can
|
||||
* happily go on, else print a message.
|
||||
*/
|
||||
|
||||
newsize = (newenvc + NEWENVP_STEP) * sizeof(char *);
|
||||
__newenvp = (char **)realloc(newenvp, newsize);
|
||||
|
||||
if (__newenvp) {
|
||||
/*
|
||||
* If this is our current environment, update
|
||||
* environ so that it doesn't point to some
|
||||
* free memory area (realloc() could move it).
|
||||
*/
|
||||
if (environ == newenvp)
|
||||
environ = __newenvp;
|
||||
newenvp = __newenvp;
|
||||
} else {
|
||||
fprintf(stderr, _("Environment overflow\n"));
|
||||
free(newenvp[--newenvc]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The last entry of newenvp must be NULL
|
||||
*/
|
||||
|
||||
newenvp[newenvc] = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set_env - copy command line arguments into the environment
|
||||
*/
|
||||
void
|
||||
set_env(int argc, char * const *argv)
|
||||
{
|
||||
int noname = 1;
|
||||
char variable[1024];
|
||||
char *cp;
|
||||
|
||||
for ( ; argc > 0; argc--, argv++) {
|
||||
if (strlen(*argv) >= sizeof variable)
|
||||
continue; /* ignore long entries */
|
||||
|
||||
if (! (cp = strchr (*argv, '='))) {
|
||||
snprintf(variable, sizeof variable, "L%d", noname++);
|
||||
addenv(variable, *argv);
|
||||
} else {
|
||||
const char **p;
|
||||
|
||||
for (p = forbid; *p; p++)
|
||||
if (strncmp(*argv, *p, strlen(*p)) == 0)
|
||||
break;
|
||||
|
||||
if (*p) {
|
||||
strncpy(variable, *argv, cp - *argv);
|
||||
variable[cp - *argv] = '\0';
|
||||
printf(_("You may not change $%s\n"), variable);
|
||||
continue;
|
||||
}
|
||||
|
||||
addenv(*argv, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* sanitize_env - remove some nasty environment variables
|
||||
* If you fall into a total paranoia, you should call this
|
||||
* function for any root-setuid program or anything the user
|
||||
* might change the environment with. 99% useless as almost
|
||||
* all modern Unixes will handle setuid executables properly,
|
||||
* but... I feel better with that silly precaution. -j.
|
||||
*/
|
||||
|
||||
void
|
||||
sanitize_env(void)
|
||||
{
|
||||
char **envp = environ;
|
||||
const char **bad;
|
||||
char **cur;
|
||||
char **move;
|
||||
|
||||
for (cur = envp; *cur; cur++) {
|
||||
for (bad = forbid; *bad; bad++) {
|
||||
if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
|
||||
for (move = cur; *move; move++)
|
||||
*move = *(move + 1);
|
||||
cur--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (cur = envp; *cur; cur++) {
|
||||
for (bad = noslash; *bad; bad++) {
|
||||
if (strncmp(*cur, *bad, strlen(*bad)) != 0)
|
||||
continue;
|
||||
if (!strchr(*cur, '/'))
|
||||
continue; /* OK */
|
||||
for (move = cur; *move; move++)
|
||||
*move = *(move + 1);
|
||||
cur--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
278
libmisc/failure.c
Normal file
278
libmisc/failure.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* 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: failure.c,v 1.6 1998/12/28 20:34:46 marekm Exp $")
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include "getdef.h"
|
||||
#include "failure.h"
|
||||
|
||||
#include <utmp.h>
|
||||
|
||||
#define YEAR (365L*DAY)
|
||||
|
||||
/*
|
||||
* failure - make failure entry
|
||||
*
|
||||
* failure() creates a new (struct faillog) entry or updates an
|
||||
* existing one with the current failed login information.
|
||||
*/
|
||||
|
||||
void
|
||||
failure(uid_t uid, const char *tty, struct faillog *fl)
|
||||
{
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Don't do anything if failure logging isn't set up.
|
||||
*/
|
||||
|
||||
if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* The file is indexed by uid value meaning that shared UID's
|
||||
* share failure log records. That's OK since they really
|
||||
* share just about everything else ...
|
||||
*/
|
||||
|
||||
lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
|
||||
if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl)
|
||||
memzero(fl, sizeof *fl);
|
||||
|
||||
/*
|
||||
* Update the record. We increment the failure count to log the
|
||||
* latest failure. The only concern here is overflow, and we'll
|
||||
* check for that. The line name and time of day are both
|
||||
* updated as well.
|
||||
*/
|
||||
|
||||
if (fl->fail_cnt + 1 > 0)
|
||||
fl->fail_cnt++;
|
||||
|
||||
strncpy(fl->fail_line, tty, sizeof fl->fail_line);
|
||||
time(&fl->fail_time);
|
||||
|
||||
/*
|
||||
* Seek back to the correct position in the file and write the
|
||||
* record out. Ideally we should lock the file in case the same
|
||||
* account is being logged simultaneously. But the risk doesn't
|
||||
* seem that great.
|
||||
*/
|
||||
|
||||
lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
|
||||
write(fd, (char *) fl, sizeof *fl);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static int
|
||||
too_many_failures(const struct faillog *fl)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
if (fl->fail_max == 0 || fl->fail_cnt < fl->fail_max)
|
||||
return 0;
|
||||
|
||||
if (fl->fail_locktime == 0)
|
||||
return 1; /* locked until reset manually */
|
||||
|
||||
time(&now);
|
||||
if (fl->fail_time + fl->fail_locktime > now)
|
||||
return 0; /* enough time since last failure */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* failcheck - check for failures > allowable
|
||||
*
|
||||
* failcheck() is called AFTER the password has been validated. If the
|
||||
* account has been "attacked" with too many login failures, failcheck()
|
||||
* returns FALSE to indicate that the login should be denied even though
|
||||
* the password is valid.
|
||||
*/
|
||||
|
||||
int
|
||||
failcheck(uid_t uid, struct faillog *fl, int failed)
|
||||
{
|
||||
int fd;
|
||||
struct faillog fail;
|
||||
|
||||
/*
|
||||
* Suppress the check if the log file isn't there.
|
||||
*/
|
||||
|
||||
if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Get the record from the file and determine if the user has
|
||||
* exceeded the failure limit. If "max" is zero, any number
|
||||
* of failures are permitted. Only when "max" is non-zero and
|
||||
* "cnt" is greater than or equal to "max" is the account
|
||||
* considered to be locked.
|
||||
*
|
||||
* If read fails, there is no record for this user yet (the
|
||||
* file is initially zero length and extended by writes), so
|
||||
* no need to reset the count.
|
||||
*/
|
||||
|
||||
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
|
||||
if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl) {
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (too_many_failures(fl)) {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The record is updated if this is not a failure. The count will
|
||||
* be reset to zero, but the rest of the information will be left
|
||||
* in the record in case someone wants to see where the failed
|
||||
* login originated.
|
||||
*/
|
||||
|
||||
if (!failed) {
|
||||
fail = *fl;
|
||||
fail.fail_cnt = 0;
|
||||
|
||||
lseek (fd, (off_t) sizeof fail * uid, SEEK_SET);
|
||||
write (fd, (char *) &fail, sizeof fail);
|
||||
}
|
||||
close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* failprint - print line of failure information
|
||||
*
|
||||
* failprint takes a (struct faillog) entry and formats it into a
|
||||
* message which is displayed at login time.
|
||||
*/
|
||||
|
||||
void
|
||||
failprint(const struct faillog *fail)
|
||||
{
|
||||
struct tm *tp;
|
||||
#if HAVE_STRFTIME
|
||||
char lasttimeb[256];
|
||||
char *lasttime = lasttimeb;
|
||||
const char *fmt;
|
||||
#else
|
||||
char *lasttime;
|
||||
#endif
|
||||
time_t NOW;
|
||||
|
||||
if (fail->fail_cnt == 0)
|
||||
return;
|
||||
|
||||
tp = localtime (&(fail->fail_time));
|
||||
time(&NOW);
|
||||
|
||||
#if HAVE_STRFTIME
|
||||
/*
|
||||
* Only print as much date and time info as it needed to
|
||||
* know when the failure was.
|
||||
*/
|
||||
|
||||
if (NOW - fail->fail_time >= YEAR)
|
||||
fmt = "%Y";
|
||||
else if (NOW - fail->fail_time >= DAY)
|
||||
fmt = "%A %T";
|
||||
else
|
||||
fmt = "%T";
|
||||
strftime(lasttimeb, sizeof lasttimeb, fmt, tp);
|
||||
#else
|
||||
|
||||
/*
|
||||
* Do the same thing, but don't use strftime since it
|
||||
* probably doesn't exist on this system
|
||||
*/
|
||||
|
||||
lasttime = asctime (tp);
|
||||
lasttime[24] = '\0';
|
||||
|
||||
if (NOW - fail->fail_time < YEAR)
|
||||
lasttime[19] = '\0';
|
||||
if (NOW - fail->fail_time < DAY)
|
||||
lasttime = lasttime + 11;
|
||||
|
||||
if (*lasttime == ' ')
|
||||
lasttime++;
|
||||
#endif
|
||||
printf (_("%d %s since last login. Last was %s on %s.\n"),
|
||||
fail->fail_cnt, fail->fail_cnt > 1 ? _("failures"):_("failure"),
|
||||
lasttime, fail->fail_line);
|
||||
}
|
||||
|
||||
/*
|
||||
* failtmp - update the cummulative failure log
|
||||
*
|
||||
* failtmp updates the (struct utmp) formatted failure log which
|
||||
* maintains a record of all login failures.
|
||||
*/
|
||||
|
||||
void
|
||||
failtmp(const struct utmp *failent)
|
||||
{
|
||||
char *ftmp;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Get the name of the failure file. If no file has been defined
|
||||
* in login.defs, don't do this.
|
||||
*/
|
||||
|
||||
if (!(ftmp = getdef_str("FTMP_FILE")))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Open the file for append. It must already exist for this
|
||||
* feature to be used.
|
||||
*/
|
||||
|
||||
if ((fd = open(ftmp, O_WRONLY|O_APPEND)) == -1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Output the new failure record and close the log file.
|
||||
*/
|
||||
|
||||
write(fd, (const char *) failent, sizeof *failent);
|
||||
close(fd);
|
||||
}
|
||||
44
libmisc/failure.h
Normal file
44
libmisc/failure.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/* $Id: failure.h,v 1.1 1997/12/07 23:27:04 marekm Exp $ */
|
||||
#ifndef _FAILURE_H_
|
||||
#define _FAILURE_H_
|
||||
|
||||
#include "defines.h"
|
||||
#include "faillog.h"
|
||||
#include <utmp.h>
|
||||
|
||||
/*
|
||||
* failure - make failure entry
|
||||
*
|
||||
* failure() creates a new (struct faillog) entry or updates an
|
||||
* existing one with the current failed login information.
|
||||
*/
|
||||
extern void failure P_((uid_t, const char *, struct faillog *));
|
||||
|
||||
/*
|
||||
* failcheck - check for failures > allowable
|
||||
*
|
||||
* failcheck() is called AFTER the password has been validated. If the
|
||||
* account has been "attacked" with too many login failures, failcheck()
|
||||
* returns FALSE to indicate that the login should be denied even though
|
||||
* the password is valid.
|
||||
*/
|
||||
extern int failcheck P_((uid_t, struct faillog *, int));
|
||||
|
||||
/*
|
||||
* failprint - print line of failure information
|
||||
*
|
||||
* failprint takes a (struct faillog) entry and formats it into a
|
||||
* message which is displayed at login time.
|
||||
*/
|
||||
extern void failprint P_((const struct faillog *));
|
||||
|
||||
/*
|
||||
* failtmp - update the cummulative failure log
|
||||
*
|
||||
* failtmp updates the (struct utmp) formatted failure log which
|
||||
* maintains a record of all login failures.
|
||||
*/
|
||||
extern void failtmp P_((const struct utmp *));
|
||||
|
||||
#endif
|
||||
|
||||
104
libmisc/fields.c
Normal file
104
libmisc/fields.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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: fields.c,v 1.5 1997/12/07 23:27:04 marekm Exp $")
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
/*
|
||||
* valid_field - insure that a field contains all legal characters
|
||||
*
|
||||
* The supplied field is scanned for non-printing and other illegal
|
||||
* characters. If any illegal characters are found, valid_field
|
||||
* returns -1. Zero is returned for success.
|
||||
*/
|
||||
|
||||
int
|
||||
valid_field(const char *field, const char *illegal)
|
||||
{
|
||||
const char *cp;
|
||||
|
||||
for (cp = field; *cp && isprint(*cp & 0x7F) && !strchr(illegal, *cp); cp++)
|
||||
;
|
||||
|
||||
if (*cp)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* change_field - change a single field if a new value is given.
|
||||
*
|
||||
* prompt the user with the name of the field being changed and the
|
||||
* current value.
|
||||
*/
|
||||
|
||||
void
|
||||
change_field(char *buf, size_t maxsize, const char *prompt)
|
||||
{
|
||||
char newf[200];
|
||||
char *cp;
|
||||
|
||||
if (maxsize > sizeof(newf))
|
||||
maxsize = sizeof(newf);
|
||||
|
||||
printf ("\t%s [%s]: ", prompt, buf);
|
||||
if (fgets(newf, maxsize, stdin) != newf)
|
||||
return;
|
||||
|
||||
if (!(cp = strchr(newf, '\n')))
|
||||
return;
|
||||
*cp = '\0';
|
||||
|
||||
if (newf[0]) {
|
||||
/*
|
||||
* Remove leading and trailing whitespace. This also
|
||||
* makes it possible to change the field to empty, by
|
||||
* entering a space. --marekm
|
||||
*/
|
||||
|
||||
while (--cp >= newf && isspace(*cp))
|
||||
;
|
||||
*++cp = '\0';
|
||||
|
||||
cp = newf;
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
|
||||
strncpy(buf, cp, maxsize - 1);
|
||||
buf[maxsize - 1] = '\0';
|
||||
}
|
||||
}
|
||||
2006
libmisc/getdate.c
Normal file
2006
libmisc/getdate.c
Normal file
File diff suppressed because it is too large
Load Diff
8
libmisc/getdate.h
Normal file
8
libmisc/getdate.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifndef _GETDATE_H_
|
||||
#define _GETDATE_H_
|
||||
|
||||
#include <config.h>
|
||||
#include "defines.h"
|
||||
|
||||
time_t get_date P_((const char *p, const time_t *now));
|
||||
#endif
|
||||
1024
libmisc/getdate.y
Normal file
1024
libmisc/getdate.y
Normal file
File diff suppressed because it is too large
Load Diff
90
libmisc/hushed.c
Normal file
90
libmisc/hushed.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 1991, 1993, 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: hushed.c,v 1.3 1997/12/07 23:27:05 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
#include "getdef.h"
|
||||
#include <pwd.h>
|
||||
|
||||
/*
|
||||
* hushed - determine if a user receives login messages
|
||||
*
|
||||
* Look in the hushed-logins file (or user's home directory) to see
|
||||
* if the user is to receive the login-time messages.
|
||||
*/
|
||||
|
||||
int
|
||||
hushed(const struct passwd *pw)
|
||||
{
|
||||
char *hushfile;
|
||||
char buf[BUFSIZ];
|
||||
int found;
|
||||
FILE *fp;
|
||||
|
||||
/*
|
||||
* Get the name of the file to use. If this option is not
|
||||
* defined, default to a noisy login.
|
||||
*/
|
||||
|
||||
if ( (hushfile=getdef_str("HUSHLOGIN_FILE")) == NULL )
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If this is not a fully rooted path then see if the
|
||||
* file exists in the user's home directory.
|
||||
*/
|
||||
|
||||
if (hushfile[0] != '/') {
|
||||
strcat(strcat(strcpy(buf, pw->pw_dir), "/"), hushfile);
|
||||
return (access(buf, F_OK) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is a fully rooted path then go through the file
|
||||
* and see if this user is in there.
|
||||
*/
|
||||
|
||||
if ((fp = fopen(hushfile, "r")) == NULL)
|
||||
return 0;
|
||||
|
||||
for (found = 0;! found && fgets (buf, sizeof buf, fp);) {
|
||||
buf[strlen (buf) - 1] = '\0';
|
||||
found = ! strcmp (buf,
|
||||
buf[0] == '/' ? pw->pw_shell:pw->pw_name);
|
||||
}
|
||||
(void) fclose(fp);
|
||||
return found;
|
||||
}
|
||||
173
libmisc/isexpired.c
Normal file
173
libmisc/isexpired.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Extracted from age.c and made part of libshadow.a - may be useful
|
||||
* in other shadow-aware programs. --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifdef HAVE_USERSEC_H
|
||||
#include <userpw.h>
|
||||
#include <usersec.h>
|
||||
#include <userconf.h>
|
||||
#endif
|
||||
|
||||
#ifndef AGING
|
||||
#if defined(SHADOWPWD) || defined(HAVE_USERSEC_H)
|
||||
#define AGING 1
|
||||
#endif
|
||||
#else
|
||||
#if !defined(SHADOWPWD) && !defined(HAVE_USERSEC_H) && !defined(ATT_AGE)
|
||||
#undef AGING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SHADOWPWD) || defined(AGING) /*{*/
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: isexpired.c,v 1.7 1997/12/07 23:27:05 marekm Exp $")
|
||||
|
||||
/*
|
||||
* isexpired - determine if account is expired yet
|
||||
*
|
||||
* isexpired calculates the expiration date based on the
|
||||
* password expiration criteria.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
int
|
||||
isexpired(const struct passwd *pw, const struct spwd *sp)
|
||||
{
|
||||
#else
|
||||
int
|
||||
isexpired(const struct passwd *pw)
|
||||
{
|
||||
#endif
|
||||
long now;
|
||||
#ifdef HAVE_USERSEC_H
|
||||
int minage = 0;
|
||||
int maxage = 10000;
|
||||
int curage = 0;
|
||||
struct userpw *pu;
|
||||
#endif
|
||||
|
||||
now = time ((time_t *) 0) / SCALE;
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
|
||||
if (!sp)
|
||||
sp = pwd_to_spwd(pw);
|
||||
|
||||
/*
|
||||
* Quick and easy - there is an expired account field
|
||||
* along with an inactive account field. Do the expired
|
||||
* one first since it is worse.
|
||||
*/
|
||||
|
||||
if (sp->sp_expire > 0 && now >= sp->sp_expire)
|
||||
return 3;
|
||||
|
||||
/*
|
||||
* Last changed date 1970-01-01 (not very likely) means that
|
||||
* the password must be changed on next login (passwd -e).
|
||||
*
|
||||
* The check for "x" is a workaround for RedHat NYS libc bug -
|
||||
* if /etc/shadow doesn't exist, getspnam() still succeeds and
|
||||
* returns sp_lstchg==0 (must change password) instead of -1!
|
||||
*/
|
||||
if (sp->sp_lstchg == 0 && !strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING))
|
||||
return 1;
|
||||
|
||||
if (sp->sp_lstchg > 0 && sp->sp_max >= 0 && sp->sp_inact >= 0 &&
|
||||
now >= sp->sp_lstchg + sp->sp_max + sp->sp_inact)
|
||||
return 2;
|
||||
#endif
|
||||
#ifdef HAVE_USERSEC_H /*{*/
|
||||
/*
|
||||
* The aging information lives someplace else. Get it from the
|
||||
* login.cfg file
|
||||
*/
|
||||
|
||||
if (getconfattr (SC_SYS_PASSWD, SC_MINAGE, &minage, SEC_INT))
|
||||
minage = -1;
|
||||
|
||||
if (getconfattr (SC_SYS_PASSWD, SC_MAXAGE, &maxage, SEC_INT))
|
||||
maxage = -1;
|
||||
|
||||
pu = getuserpw (pw->pw_name);
|
||||
curage = (time (0) - pu->upw_lastupdate) / (7*86400L);
|
||||
|
||||
if (maxage != -1 && curage > maxage)
|
||||
return 1;
|
||||
#else /*} !HAVE_USERSEC_H */
|
||||
|
||||
/*
|
||||
* The last and max fields must be present for an account
|
||||
* to have an expired password. A maximum of >10000 days
|
||||
* is considered to be infinite.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
if (sp->sp_lstchg == -1 ||
|
||||
sp->sp_max == -1 || sp->sp_max >= (10000L*DAY/SCALE))
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef ATT_AGE
|
||||
if (pw->pw_age[0] == '\0' || pw->pw_age[0] == '/')
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate today's day and the day on which the password
|
||||
* is going to expire. If that date has already passed,
|
||||
* the password has expired.
|
||||
*/
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
if (now >= sp->sp_lstchg + sp->sp_max)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef ATT_AGE
|
||||
if (a64l (pw->pw_age + 2) + c64i (pw->pw_age[1]) < now / 7)
|
||||
return 1;
|
||||
#endif
|
||||
#endif /*} HAVE_USERSEC_H */
|
||||
return 0;
|
||||
}
|
||||
#endif /*}*/
|
||||
394
libmisc/limits.c
Normal file
394
libmisc/limits.c
Normal file
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
* Resource limits thanks to Cristian Gafton.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: limits.c,v 1.9 1999/03/07 19:14:39 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#define LIMITS
|
||||
#endif
|
||||
|
||||
#ifdef LIMITS
|
||||
|
||||
#ifndef LIMITS_FILE
|
||||
#define LIMITS_FILE "/etc/limits"
|
||||
#endif
|
||||
|
||||
#define LOGIN_ERROR_RLIMIT 1
|
||||
#define LOGIN_ERROR_LOGIN 2
|
||||
|
||||
/* Set a limit on a resource */
|
||||
/*
|
||||
* rlimit - RLIMIT_XXXX
|
||||
* value - string value to be read
|
||||
* multiplier - value*multiplier is the actual limit
|
||||
*/
|
||||
static int
|
||||
setrlimit_value(unsigned int rlimit, const char *value, unsigned int multiplier)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
long limit;
|
||||
char **endptr = (char **) &value;
|
||||
const char *value_orig = value;
|
||||
|
||||
limit = strtol(value, endptr, 10);
|
||||
if (limit == 0 && value_orig == *endptr) /* no chars read */
|
||||
return 0;
|
||||
limit *= multiplier;
|
||||
rlim.rlim_cur = limit;
|
||||
rlim.rlim_max = limit;
|
||||
if (setrlimit(rlimit, &rlim))
|
||||
return LOGIN_ERROR_RLIMIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
set_prio(const char *value)
|
||||
{
|
||||
int prio;
|
||||
char **endptr = (char **) &value;
|
||||
|
||||
prio = strtol(value, endptr, 10);
|
||||
if ((prio == 0) && (value == *endptr))
|
||||
return 0;
|
||||
if (setpriority(PRIO_PROCESS, 0, prio))
|
||||
return LOGIN_ERROR_RLIMIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Counts the number of user logins and check against the limit */
|
||||
static int
|
||||
check_logins(const char *name, const char *maxlogins)
|
||||
{
|
||||
struct utmp *ut;
|
||||
unsigned int limit, count;
|
||||
char **endptr = (char **) &maxlogins;
|
||||
const char *ml_orig = maxlogins;
|
||||
|
||||
limit = strtol(maxlogins, endptr, 10);
|
||||
if (limit == 0 && ml_orig == *endptr) /* no chars read */
|
||||
return 0;
|
||||
|
||||
if (limit == 0) /* maximum 0 logins ? */ {
|
||||
SYSLOG((LOG_WARN, "No logins allowed for `%s'\n", name));
|
||||
return LOGIN_ERROR_LOGIN;
|
||||
}
|
||||
|
||||
setutent();
|
||||
count = 0;
|
||||
while ((ut = getutent())) {
|
||||
#ifdef USER_PROCESS
|
||||
if (ut->ut_type != USER_PROCESS)
|
||||
continue;
|
||||
#endif
|
||||
if (ut->ut_user[0] == '\0')
|
||||
continue;
|
||||
if (strncmp(name, ut->ut_user, sizeof(ut->ut_user)) != 0)
|
||||
continue;
|
||||
if (++count > limit)
|
||||
break;
|
||||
}
|
||||
endutent();
|
||||
/*
|
||||
* This is called after setutmp(), so the number of logins counted
|
||||
* includes the user who is currently trying to log in.
|
||||
*/
|
||||
if (count > limit) {
|
||||
SYSLOG((LOG_WARN, "Too many logins (max %d) for %s\n",
|
||||
limit, name));
|
||||
return LOGIN_ERROR_LOGIN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function setup_user_limits - checks/set limits for the curent login
|
||||
* Original idea from Joel Katz's lshell. Ported to shadow-login
|
||||
* by Cristian Gafton - gafton@sorosis.ro
|
||||
*
|
||||
* We are passed a string of the form ('BASH' constants for ulimit)
|
||||
* [Aa][Cc][Dd][Ff][Mm][Nn][Rr][Ss][Tt][Uu][Ll][Pp]
|
||||
* (eg. 'C2F256D2048N5' or 'C2 F256 D2048 N5')
|
||||
* where:
|
||||
* [Aa]: a = RLIMIT_AS max address space (KB)
|
||||
* [Cc]: c = RLIMIT_CORE max core file size (KB)
|
||||
* [Dd]: d = RLIMIT_DATA max data size (KB)
|
||||
* [Ff]: f = RLIMIT_FSIZE Maximum filesize (KB)
|
||||
* [Mm]: m = RLIMIT_MEMLOCK max locked-in-memory address space (KB)
|
||||
* [Nn]: n = RLIMIT_NOFILE max number of open files
|
||||
* [Rr]: r = RLIMIT_RSS max resident set size (KB)
|
||||
* [Ss]: s = RLIMIT_STACK max stack size (KB)
|
||||
* [Tt]: t = RLIMIT_CPU max CPU time (MIN)
|
||||
* [Uu]: u = RLIMIT_NPROC max number of processes
|
||||
* [Ll]: l = max number of logins for this user
|
||||
* [Pp]: p = process priority -20..20 (negative = high priority)
|
||||
*
|
||||
* Return value:
|
||||
* 0 = okay, of course
|
||||
* LOGIN_ERROR_RLIMIT = error setting some RLIMIT
|
||||
* LOGIN_ERROR_LOGIN = error - too many logins for this user
|
||||
*
|
||||
* buf - the limits string
|
||||
* name - the username
|
||||
*/
|
||||
static int
|
||||
do_user_limits(const char *buf, const char *name)
|
||||
{
|
||||
const char *pp;
|
||||
int retval = 0;
|
||||
|
||||
pp = buf;
|
||||
|
||||
while (*pp != '\0') switch(*pp++) {
|
||||
#ifdef RLIMIT_AS
|
||||
case 'a':
|
||||
case 'A':
|
||||
/* RLIMIT_AS - max address space (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_AS, pp, 1024);
|
||||
#endif
|
||||
#ifdef RLIMIT_CPU
|
||||
case 't':
|
||||
case 'T':
|
||||
/* RLIMIT_CPU - max CPU time (MIN) */
|
||||
retval |= setrlimit_value(RLIMIT_CPU, pp, 60);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_DATA
|
||||
case 'd':
|
||||
case 'D':
|
||||
/* RLIMIT_DATA - max data size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_DATA, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_FSIZE
|
||||
case 'f':
|
||||
case 'F':
|
||||
/* RLIMIT_FSIZE - Maximum filesize (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_FSIZE, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
case 'u':
|
||||
case 'U':
|
||||
/* RLIMIT_NPROC - max number of processes */
|
||||
retval |= setrlimit_value(RLIMIT_NPROC, pp, 1);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_CORE
|
||||
case 'c':
|
||||
case 'C':
|
||||
/* RLIMIT_CORE - max core file size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_CORE, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
case 'm':
|
||||
case 'M':
|
||||
/* RLIMIT_MEMLOCK - max locked-in-memory address space (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_MEMLOCK, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_NOFILE
|
||||
case 'n':
|
||||
case 'N':
|
||||
/* RLIMIT_NOFILE - max number of open files */
|
||||
retval |= setrlimit_value(RLIMIT_NOFILE, pp, 1);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_RSS
|
||||
case 'r':
|
||||
case 'R':
|
||||
/* RLIMIT_RSS - max resident set size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_RSS, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
case 's':
|
||||
case 'S':
|
||||
/* RLIMIT_STACK - max stack size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_STACK, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
case 'l':
|
||||
case 'L':
|
||||
/* LIMIT the number of concurent logins */
|
||||
retval |= check_logins(name, pp);
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
retval |= set_prio(pp);
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
setup_user_limits(const char *uname)
|
||||
{
|
||||
/* TODO: allow and use @group syntax --cristiang */
|
||||
FILE *fil;
|
||||
char buf[1024];
|
||||
char name[1024];
|
||||
char limits[1024];
|
||||
char deflimits[1024];
|
||||
char tempbuf[1024];
|
||||
|
||||
/* init things */
|
||||
memzero(buf, sizeof(buf));
|
||||
memzero(name, sizeof(name));
|
||||
memzero(limits, sizeof(limits));
|
||||
memzero(deflimits, sizeof(deflimits));
|
||||
memzero(tempbuf, sizeof(tempbuf));
|
||||
|
||||
/* start the checks */
|
||||
fil = fopen(LIMITS_FILE, "r");
|
||||
if (fil == NULL) {
|
||||
#if 0 /* no limits file is ok, not everyone is a BOFH :-). --marekm */
|
||||
SYSLOG((LOG_WARN, NO_LIMITS, uname, LIMITS_FILE));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/* The limits file have the following format:
|
||||
* - '#' (comment) chars only as first chars on a line;
|
||||
* - username must start on first column
|
||||
* A better (smarter) checking should be done --cristiang */
|
||||
while (fgets(buf, 1024, fil) != NULL) {
|
||||
if (buf[0]=='#' || buf[0]=='\n')
|
||||
continue;
|
||||
memzero(tempbuf, sizeof(tempbuf));
|
||||
/* a valid line should have a username, then spaces,
|
||||
* then limits
|
||||
* we allow the format:
|
||||
* username L2 D2048 R4096
|
||||
* where spaces={' ',\t}. Also, we reject invalid limits.
|
||||
* Imposing a limit should be done with care, so a wrong
|
||||
* entry means no care anyway :-). A '-' as a limits
|
||||
* strings means no limits --cristiang */
|
||||
if (sscanf(buf, "%s%[ACDFMNRSTULPacdfmnrstulp0-9 \t-]",
|
||||
name, tempbuf) == 2) {
|
||||
if (strcmp(name, uname) == 0) {
|
||||
strcpy(limits, tempbuf);
|
||||
break;
|
||||
} else if (strcmp(name, "*") == 0) {
|
||||
strcpy(deflimits, tempbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fil);
|
||||
if (limits[0] == '\0') {
|
||||
/* no user specific limits */
|
||||
if (deflimits[0] == '\0') /* no default limits */
|
||||
return 0;
|
||||
strcpy(limits, deflimits); /* use the default limits */
|
||||
}
|
||||
return do_user_limits(limits, uname);
|
||||
}
|
||||
#endif /* LIMITS */
|
||||
|
||||
/*
|
||||
* set the process nice, ulimit, and umask from the password file entry
|
||||
*/
|
||||
|
||||
void
|
||||
setup_limits(const struct passwd *info)
|
||||
{
|
||||
char *cp;
|
||||
int i;
|
||||
long l;
|
||||
|
||||
#ifdef USERGROUPS
|
||||
if (info->pw_uid != 0 && info->pw_uid == info->pw_gid) {
|
||||
const struct group *grp;
|
||||
|
||||
grp = getgrgid(info->pw_gid);
|
||||
if (grp && !strcmp(info->pw_name, grp->gr_name)) {
|
||||
umask(umask(0) & ~070);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if the GECOS field contains values for NICE, UMASK or ULIMIT.
|
||||
* If this feature is enabled in /etc/login.defs, we make those
|
||||
* values the defaults for this login session.
|
||||
*/
|
||||
|
||||
if ( getdef_bool("QUOTAS_ENAB") ) {
|
||||
#ifdef LIMITS
|
||||
if (info->pw_uid)
|
||||
if (setup_user_limits(info->pw_name) & LOGIN_ERROR_LOGIN) {
|
||||
fprintf(stderr, _("Too many logins.\n"));
|
||||
sleep(2);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
for (cp = info->pw_gecos ; cp != NULL ; cp = strchr (cp, ',')) {
|
||||
if (*cp == ',')
|
||||
cp++;
|
||||
|
||||
if (strncmp (cp, "pri=", 4) == 0) {
|
||||
i = atoi (cp + 4);
|
||||
if (i >= -20 && i <= 20)
|
||||
(void) nice (i);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (strncmp (cp, "ulimit=", 7) == 0) {
|
||||
l = strtol (cp + 7, (char **) 0, 10);
|
||||
set_filesize_limit(l);
|
||||
continue;
|
||||
}
|
||||
if (strncmp (cp, "umask=", 6) == 0) {
|
||||
i = strtol (cp + 6, (char **) 0, 8) & 0777;
|
||||
(void) umask (i);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
234
libmisc/list.c
Normal file
234
libmisc/list.c
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* Copyright 1991 - 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.
|
||||
*/
|
||||
|
||||
/* Removed duplicated code from gpmain.c, useradd.c, userdel.c and
|
||||
usermod.c. --marekm */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: list.c,v 1.3 1997/12/07 23:27:05 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
/*
|
||||
* add_list - add a member to a list of group members
|
||||
*
|
||||
* the array of member names is searched for the new member
|
||||
* name, and if not present it is added to a freshly allocated
|
||||
* list of users.
|
||||
*/
|
||||
|
||||
char **
|
||||
add_list(char **list, const char *member)
|
||||
{
|
||||
int i;
|
||||
char **tmp;
|
||||
|
||||
/*
|
||||
* Scan the list for the new name. Return the original list
|
||||
* pointer if it is present.
|
||||
*/
|
||||
|
||||
for (i = 0;list[i] != (char *) 0;i++)
|
||||
if (strcmp (list[i], member) == 0)
|
||||
return list;
|
||||
|
||||
/*
|
||||
* Allocate a new list pointer large enough to hold all the
|
||||
* old entries, and the new entries as well.
|
||||
*/
|
||||
|
||||
tmp = (char **) xmalloc ((i + 2) * sizeof member);
|
||||
|
||||
/*
|
||||
* Copy the original list to the new list, then append the
|
||||
* new member and NULL terminate the result. This new list
|
||||
* is returned to the invoker.
|
||||
*/
|
||||
|
||||
for (i = 0;list[i] != (char *) 0;i++)
|
||||
tmp[i] = list[i];
|
||||
|
||||
tmp[i++] = xstrdup (member);
|
||||
tmp[i] = (char *) 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* del_list - delete a member from a list of group members
|
||||
*
|
||||
* the array of member names is searched for the old member
|
||||
* name, and if present it is deleted from a freshly allocated
|
||||
* list of users.
|
||||
*/
|
||||
|
||||
char **
|
||||
del_list(char **list, const char *member)
|
||||
{
|
||||
int i, j;
|
||||
char **tmp;
|
||||
|
||||
/*
|
||||
* Scan the list for the old name. Return the original list
|
||||
* pointer if it is not present.
|
||||
*/
|
||||
|
||||
for (i = j = 0;list[i] != (char *) 0;i++)
|
||||
if (strcmp (list[i], member))
|
||||
j++;
|
||||
|
||||
if (j == i)
|
||||
return list;
|
||||
|
||||
/*
|
||||
* Allocate a new list pointer large enough to hold all the
|
||||
* old entries.
|
||||
*/
|
||||
|
||||
tmp = (char **) xmalloc ((j + 1) * sizeof member);
|
||||
|
||||
/*
|
||||
* Copy the original list except the deleted members to the
|
||||
* new list, then NULL terminate the result. This new list
|
||||
* is returned to the invoker.
|
||||
*/
|
||||
|
||||
for (i = j = 0;list[i] != (char *) 0;i++)
|
||||
if (strcmp (list[i], member))
|
||||
tmp[j++] = list[i];
|
||||
|
||||
tmp[j] = (char *) 0;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char **
|
||||
dup_list(char * const *list)
|
||||
{
|
||||
int i;
|
||||
char **tmp;
|
||||
|
||||
for (i = 0; list[i]; i++)
|
||||
;
|
||||
|
||||
tmp = (char **) xmalloc((i + 1) * sizeof(char *));
|
||||
|
||||
i = 0;
|
||||
while (*list)
|
||||
tmp[i++] = xstrdup(*list++);
|
||||
|
||||
tmp[i] = (char *) 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int
|
||||
is_on_list(char * const *list, const char *member)
|
||||
{
|
||||
while (*list) {
|
||||
if (strcmp(*list, member) == 0)
|
||||
return 1;
|
||||
list++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* comma_to_list - convert comma-separated list to (char *) array
|
||||
*/
|
||||
|
||||
char **
|
||||
comma_to_list(const char *comma)
|
||||
{
|
||||
char *members;
|
||||
char **array;
|
||||
int i;
|
||||
char *cp, *cp2;
|
||||
|
||||
/*
|
||||
* Make a copy since we are going to be modifying the list
|
||||
*/
|
||||
|
||||
members = xstrdup (comma);
|
||||
|
||||
/*
|
||||
* Count the number of commas in the list
|
||||
*/
|
||||
|
||||
for (cp = members, i = 0;;i++)
|
||||
if ((cp2 = strchr (cp, ',')))
|
||||
cp = cp2 + 1;
|
||||
else
|
||||
break;
|
||||
|
||||
/*
|
||||
* Add 2 - one for the ending NULL, the other for the last item
|
||||
*/
|
||||
|
||||
i += 2;
|
||||
|
||||
/*
|
||||
* Allocate the array we're going to store the pointers into.
|
||||
*/
|
||||
|
||||
array = (char **) xmalloc (sizeof (char *) * i);
|
||||
|
||||
/*
|
||||
* Empty list is special - 0 members, not 1 empty member. --marekm
|
||||
*/
|
||||
|
||||
if (!*members) {
|
||||
*array = (char *) 0;
|
||||
return array;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now go walk that list all over again, this time building the
|
||||
* array of pointers.
|
||||
*/
|
||||
|
||||
for (cp = members, i = 0;;i++) {
|
||||
array[i] = cp;
|
||||
if ((cp2 = strchr (cp, ','))) {
|
||||
*cp2++ = '\0';
|
||||
cp = cp2;
|
||||
} else {
|
||||
array[i + 1] = (char *) 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the new array of pointers
|
||||
*/
|
||||
|
||||
return array;
|
||||
}
|
||||
100
libmisc/log.c
Normal file
100
libmisc/log.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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: log.c,v 1.5 1998/04/16 19:57:44 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include "defines.h"
|
||||
#if HAVE_LASTLOG_H
|
||||
#include <lastlog.h>
|
||||
#else
|
||||
#include "lastlog_.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* dolastlog - create lastlog entry
|
||||
*
|
||||
* A "last login" entry is created for the user being logged in. The
|
||||
* UID is extracted from the global (struct passwd) entry and the
|
||||
* TTY information is gotten from the (struct utmp).
|
||||
*/
|
||||
|
||||
void
|
||||
dolastlog(struct lastlog *ll, const struct passwd *pw, const char *line, const char *host)
|
||||
{
|
||||
int fd;
|
||||
off_t offset;
|
||||
struct lastlog newlog;
|
||||
|
||||
/*
|
||||
* If the file does not exist, don't create it.
|
||||
*/
|
||||
|
||||
if ((fd = open(LASTLOG_FILE, O_RDWR)) == -1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* The file is indexed by UID number. Seek to the record
|
||||
* for this UID. Negative UID's will create problems, but ...
|
||||
*/
|
||||
|
||||
offset = (unsigned long) pw->pw_uid * sizeof newlog;
|
||||
|
||||
if (lseek(fd, offset, SEEK_SET) != offset) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the old entry so we can tell the user when they last
|
||||
* logged in. Then construct the new entry and write it out
|
||||
* the way we read the old one in.
|
||||
*/
|
||||
|
||||
if (read(fd, (char *) &newlog, sizeof newlog) != sizeof newlog)
|
||||
memzero(&newlog, sizeof newlog);
|
||||
if (ll)
|
||||
*ll = newlog;
|
||||
|
||||
time(&newlog.ll_time);
|
||||
strncpy(newlog.ll_line, line, sizeof newlog.ll_line);
|
||||
#if HAVE_LL_HOST
|
||||
strncpy(newlog.ll_host, host, sizeof newlog.ll_host);
|
||||
#endif
|
||||
if (lseek(fd, offset, SEEK_SET) == offset)
|
||||
write(fd, (char *) &newlog, sizeof newlog);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
340
libmisc/login_access.c
Normal file
340
libmisc/login_access.c
Normal file
@@ -0,0 +1,340 @@
|
||||
/* Taken from logdaemon-5.0, only minimal changes. --marekm */
|
||||
|
||||
/************************************************************************
|
||||
* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
|
||||
* may be covered by other copyrights (as noted in the file itself.)
|
||||
*
|
||||
* This material was originally written and compiled by Wietse Venema at
|
||||
* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
|
||||
* 1992, 1993, 1994 and 1995.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this entire copyright notice is duplicated in all such
|
||||
* copies.
|
||||
*
|
||||
* This software is provided "as is" and without any expressed or implied
|
||||
* warranties, including, without limitation, the implied warranties of
|
||||
* merchantibility and fitness for any particular purpose.
|
||||
************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef LOGIN_ACCESS
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: login_access.c,v 1.6 1998/01/29 23:22:34 marekm Exp $")
|
||||
#include "prototypes.h"
|
||||
|
||||
/*
|
||||
* This module implements a simple but effective form of login access
|
||||
* control based on login names and on host (or domain) names, internet
|
||||
* addresses (or network numbers), or on terminal line names in case of
|
||||
* non-networked logins. Diagnostics are reported through syslog(3).
|
||||
*
|
||||
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <grp.h>
|
||||
#ifdef PRIMARY_GROUP_MATCH
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* for inet_ntoa() */
|
||||
|
||||
extern struct group *getgrnam();
|
||||
extern int innetgr();
|
||||
#if 0 /* should be defined by <errno.h> */
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64)
|
||||
#undef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
/* Path name of the access control file. */
|
||||
|
||||
#ifndef TABLE
|
||||
#define TABLE "/etc/login.access"
|
||||
#endif
|
||||
|
||||
/* Delimiters for fields and for lists of users, ttys or hosts. */
|
||||
|
||||
static char fs[] = ":"; /* field separator */
|
||||
static char sep[] = ", \t"; /* list-element separator */
|
||||
|
||||
/* Constants to be used in assignments only, not in comparisons... */
|
||||
|
||||
#define YES 1
|
||||
#define NO 0
|
||||
|
||||
static int list_match();
|
||||
static int user_match();
|
||||
static int from_match();
|
||||
static int string_match();
|
||||
|
||||
/* login_access - match username/group and host/tty with access control file */
|
||||
|
||||
int
|
||||
login_access(const char *user, const char *from)
|
||||
{
|
||||
FILE *fp;
|
||||
char line[BUFSIZ];
|
||||
char *perm; /* becomes permission field */
|
||||
char *users; /* becomes list of login names */
|
||||
char *froms; /* becomes list of terminals or hosts */
|
||||
int match = NO;
|
||||
int end;
|
||||
int lineno = 0; /* for diagnostics */
|
||||
|
||||
/*
|
||||
* Process the table one line at a time and stop at the first match.
|
||||
* Blank lines and lines that begin with a '#' character are ignored.
|
||||
* Non-comment lines are broken at the ':' character. All fields are
|
||||
* mandatory. The first field should be a "+" or "-" character. A
|
||||
* non-existing table means no access control.
|
||||
*/
|
||||
|
||||
if ((fp = fopen(TABLE, "r"))) {
|
||||
while (!match && fgets(line, sizeof(line), fp)) {
|
||||
lineno++;
|
||||
if (line[end = strlen(line) - 1] != '\n') {
|
||||
syslog(LOG_ERR, "%s: line %d: missing newline or line too long",
|
||||
TABLE, lineno);
|
||||
continue;
|
||||
}
|
||||
if (line[0] == '#')
|
||||
continue; /* comment line */
|
||||
while (end > 0 && isspace(line[end - 1]))
|
||||
end--;
|
||||
line[end] = 0; /* strip trailing whitespace */
|
||||
if (line[0] == 0) /* skip blank lines */
|
||||
continue;
|
||||
if (!(perm = strtok(line, fs))
|
||||
|| !(users = strtok((char *) 0, fs))
|
||||
|| !(froms = strtok((char *) 0, fs))
|
||||
|| strtok((char *) 0, fs)) {
|
||||
syslog(LOG_ERR, "%s: line %d: bad field count", TABLE, lineno);
|
||||
continue;
|
||||
}
|
||||
if (perm[0] != '+' && perm[0] != '-') {
|
||||
syslog(LOG_ERR, "%s: line %d: bad first field", TABLE, lineno);
|
||||
continue;
|
||||
}
|
||||
match = (list_match(froms, from, from_match)
|
||||
&& list_match(users, user, user_match));
|
||||
}
|
||||
(void) fclose(fp);
|
||||
} else if (errno != ENOENT) {
|
||||
syslog(LOG_ERR, "cannot open %s: %m", TABLE);
|
||||
}
|
||||
return (match == 0 || (line[0] == '+'));
|
||||
}
|
||||
|
||||
/* list_match - match an item against a list of tokens with exceptions */
|
||||
|
||||
static int
|
||||
list_match(char *list, const char *item, int (*match_fn)())
|
||||
{
|
||||
char *tok;
|
||||
int match = NO;
|
||||
|
||||
/*
|
||||
* Process tokens one at a time. We have exhausted all possible matches
|
||||
* when we reach an "EXCEPT" token or the end of the list. If we do find
|
||||
* a match, look for an "EXCEPT" list and recurse to determine whether
|
||||
* the match is affected by any exceptions.
|
||||
*/
|
||||
|
||||
for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
|
||||
if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
|
||||
break;
|
||||
if ((match = (*match_fn) (tok, item))) /* YES */
|
||||
break;
|
||||
}
|
||||
/* Process exceptions to matches. */
|
||||
|
||||
if (match != NO) {
|
||||
while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
|
||||
/* VOID */ ;
|
||||
if (tok == 0 || list_match((char *) 0, item, match_fn) == NO)
|
||||
return (match);
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
|
||||
/* myhostname - figure out local machine name */
|
||||
|
||||
static char *
|
||||
myhostname(void)
|
||||
{
|
||||
static char name[MAXHOSTNAMELEN + 1] = "";
|
||||
|
||||
if (name[0] == 0) {
|
||||
gethostname(name, sizeof(name));
|
||||
name[MAXHOSTNAMELEN] = 0;
|
||||
}
|
||||
return (name);
|
||||
}
|
||||
|
||||
/* netgroup_match - match group against machine or user */
|
||||
|
||||
static int
|
||||
netgroup_match(const char *group, const char *machine, const char *user)
|
||||
{
|
||||
#if 0 /* original code */
|
||||
#ifdef NIS
|
||||
static char *mydomain = 0;
|
||||
|
||||
if (mydomain == 0)
|
||||
yp_get_default_domain(&mydomain);
|
||||
return (innetgr(group, machine, user, mydomain));
|
||||
#else
|
||||
syslog(LOG_ERR, "NIS netgroup support not configured");
|
||||
return (NO);
|
||||
#endif
|
||||
#else /* works better with glibc? */
|
||||
static char *mydomain = 0;
|
||||
|
||||
if (mydomain == 0) {
|
||||
static char domain[MAXHOSTNAMELEN+1];
|
||||
|
||||
getdomainname(domain, MAXHOSTNAMELEN);
|
||||
mydomain = domain;
|
||||
}
|
||||
|
||||
return innetgr(group, machine, user, mydomain);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* user_match - match a username against one token */
|
||||
|
||||
static int
|
||||
user_match(const char *tok, const char *string)
|
||||
{
|
||||
struct group *group;
|
||||
#ifdef PRIMARY_GROUP_MATCH
|
||||
struct passwd *userinf;
|
||||
#endif
|
||||
int i;
|
||||
char *at;
|
||||
|
||||
/*
|
||||
* If a token has the magic value "ALL" the match always succeeds.
|
||||
* Otherwise, return YES if the token fully matches the username, or if
|
||||
* the token is a group that contains the username.
|
||||
*/
|
||||
|
||||
if ((at = strchr(tok + 1, '@')) != 0) { /* split user@host pattern */
|
||||
*at = 0;
|
||||
return (user_match(tok, string) && from_match(at + 1, myhostname()));
|
||||
} else if (tok[0] == '@') { /* netgroup */
|
||||
return (netgroup_match(tok + 1, (char *) 0, string));
|
||||
} else if (string_match(tok, string)) { /* ALL or exact match */
|
||||
return (YES);
|
||||
} else if ((group = getgrnam(tok))) { /* try group membership */
|
||||
for (i = 0; group->gr_mem[i]; i++)
|
||||
if (strcasecmp(string, group->gr_mem[i]) == 0)
|
||||
return (YES);
|
||||
#ifdef PRIMARY_GROUP_MATCH
|
||||
/*
|
||||
* If the sting is an user whose initial GID matches the token,
|
||||
* accept it. May avoid excessively long lines in /etc/group.
|
||||
* Radu-Adrian Feurdean <raf@licj.soroscj.ro>
|
||||
*
|
||||
* XXX - disabled by default for now. Need to verify that
|
||||
* getpwnam() doesn't have some nasty side effects. --marekm
|
||||
*/
|
||||
if ((userinf = getpwnam(string)))
|
||||
if (userinf->pw_gid == group->gr_gid)
|
||||
return (YES);
|
||||
#endif
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
|
||||
static char *
|
||||
resolve_hostname(string)
|
||||
char *string;
|
||||
{
|
||||
#if 1
|
||||
/*
|
||||
* Resolve hostname to numeric IP address, as suggested
|
||||
* by Dave Hagewood <admin@arrowweb.com>. --marekm
|
||||
*/
|
||||
struct hostent *hp;
|
||||
|
||||
hp = gethostbyname(string);
|
||||
if (hp)
|
||||
return inet_ntoa(*((struct in_addr *) *(hp->h_addr_list)));
|
||||
|
||||
syslog(LOG_ERR, "%s - unknown host", string);
|
||||
#endif
|
||||
return string;
|
||||
}
|
||||
|
||||
/* from_match - match a host or tty against a list of tokens */
|
||||
|
||||
static int
|
||||
from_match(const char *tok, const char *string)
|
||||
{
|
||||
int tok_len;
|
||||
int str_len;
|
||||
|
||||
/*
|
||||
* If a token has the magic value "ALL" the match always succeeds. Return
|
||||
* YES if the token fully matches the string. If the token is a domain
|
||||
* name, return YES if it matches the last fields of the string. If the
|
||||
* token has the magic value "LOCAL", return YES if the string does not
|
||||
* contain a "." character. If the token is a network number, return YES
|
||||
* if it matches the head of the string.
|
||||
*/
|
||||
|
||||
if (tok[0] == '@') { /* netgroup */
|
||||
return (netgroup_match(tok + 1, string, (char *) 0));
|
||||
} else if (string_match(tok, string)) { /* ALL or exact match */
|
||||
return (YES);
|
||||
} else if (tok[0] == '.') { /* domain: match last fields */
|
||||
if ((str_len = strlen(string)) > (tok_len = strlen(tok))
|
||||
&& strcasecmp(tok, string + str_len - tok_len) == 0)
|
||||
return (YES);
|
||||
} else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
|
||||
if (strchr(string, '.') == 0)
|
||||
return (YES);
|
||||
} else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */
|
||||
&& strncmp(tok, resolve_hostname(string), tok_len) == 0) {
|
||||
return (YES);
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
|
||||
/* string_match - match a string against one token */
|
||||
|
||||
static int
|
||||
string_match(const char *tok, const char *string)
|
||||
{
|
||||
|
||||
/*
|
||||
* If the token has the magic value "ALL" the match always succeeds.
|
||||
* Otherwise, return YES if the token fully matches the string.
|
||||
*/
|
||||
|
||||
if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
|
||||
return (YES);
|
||||
} else if (strcasecmp(tok, string) == 0) { /* try exact match */
|
||||
return (YES);
|
||||
}
|
||||
return (NO);
|
||||
}
|
||||
#endif /* LOGIN_ACCESS */
|
||||
77
libmisc/login_desrpc.c
Normal file
77
libmisc/login_desrpc.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* Taken from logdaemon-5.0, only minimal changes. --marekm */
|
||||
|
||||
/************************************************************************
|
||||
* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
|
||||
* may be covered by other copyrights (as noted in the file itself.)
|
||||
*
|
||||
* This material was originally written and compiled by Wietse Venema at
|
||||
* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
|
||||
* 1992, 1993, 1994 and 1995.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this entire copyright notice is duplicated in all such
|
||||
* copies.
|
||||
*
|
||||
* This software is provided "as is" and without any expressed or implied
|
||||
* warranties, including, without limitation, the implied warranties of
|
||||
* merchantibility and fitness for any particular purpose.
|
||||
************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef DES_RPC
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: login_desrpc.c,v 1.7 1999/06/07 16:40:44 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
/*
|
||||
* Decrypt the user's secret secure RPC key and stores it into the
|
||||
* keyserver. Returns 0 if successful, -1 on failure.
|
||||
*
|
||||
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/key_prot.h>
|
||||
|
||||
#if !(defined __GLIBC__ && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 0)))
|
||||
/* these don't seem to be in any header file (libc-5.4.33) */
|
||||
/* but will be in glibc 2.1 <rpc/auth.h> and <rpc/auth_des.h> */
|
||||
extern int getnetname(char *);
|
||||
extern int getsecretkey(const char *, char *, const char *);
|
||||
extern int key_setsecret(const char *);
|
||||
#endif
|
||||
|
||||
int
|
||||
login_desrpc(const char *passwd)
|
||||
{
|
||||
char netname[MAXNETNAMELEN + 1];
|
||||
char secretkey[HEXKEYBYTES + 1];
|
||||
|
||||
if (getnetname(netname) == 0)
|
||||
return -1;
|
||||
|
||||
if (getsecretkey(netname, secretkey, passwd) == 0)
|
||||
return -1;
|
||||
|
||||
if (secretkey[0] == 0) {
|
||||
fprintf(stderr,
|
||||
_("Password does not decrypt secret key for %s.\n"),
|
||||
netname);
|
||||
return -1;
|
||||
}
|
||||
if (key_setsecret(secretkey) < 0) {
|
||||
fprintf(stderr,
|
||||
_("Could not set %s's secret key: is the keyserv daemon running?\n"),
|
||||
netname);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif
|
||||
61
libmisc/login_krb.c
Normal file
61
libmisc/login_krb.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* Taken from logdaemon-5.0, only minimal changes. --marekm */
|
||||
|
||||
/************************************************************************
|
||||
* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
|
||||
* may be covered by other copyrights (as noted in the file itself.)
|
||||
*
|
||||
* This material was originally written and compiled by Wietse Venema at
|
||||
* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
|
||||
* 1992, 1993, 1994 and 1995.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this entire copyright notice is duplicated in all such
|
||||
* copies.
|
||||
*
|
||||
* This software is provided "as is" and without any expressed or implied
|
||||
* warranties, including, without limitation, the implied warranties of
|
||||
* merchantibility and fitness for any particular purpose.
|
||||
************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef KERBEROS
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: login_krb.c,v 1.3 1998/01/29 23:22:34 marekm Exp $")
|
||||
|
||||
#include <krb.h>
|
||||
|
||||
/*
|
||||
* Do an equivalent to kinit here. We need to do the kinit before trying to
|
||||
* cd to the home directory, because it might be on a remote filesystem that
|
||||
* uses Kerberos authentication. We also need to do this after we've
|
||||
* setuid() to the user, or krb_get_pw_in_tkt() won't know where to put the
|
||||
* ticket.
|
||||
*
|
||||
* We don't really care about whether or not it succeeds; if it fails, we'll
|
||||
* just carry on bravely.
|
||||
*
|
||||
* NB: we assume: local realm, same username and password as supplied to login.
|
||||
*
|
||||
* Security note: if pp is NULL, login doesn't have the password. This is
|
||||
* common when it's called by rlogind. Since this is almost always a remote
|
||||
* connection, we don't want to risk asking for the password by supplying a
|
||||
* NULL pp to krb_get_pw_in_tkt(), because somebody could be listening. So
|
||||
* we'll just forget the whole thing. -jdd
|
||||
*/
|
||||
|
||||
int
|
||||
login_kerberos(const char *username, const char *password)
|
||||
{
|
||||
char realm[REALM_SZ];
|
||||
|
||||
(void) krb_get_lrealm(realm, 1);
|
||||
if (password != 0)
|
||||
(void) krb_get_pw_in_tkt(username, "", realm, "krbtgt",
|
||||
realm, DEFAULT_TKT_LIFE, password);
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif /* KERBEROS */
|
||||
165
libmisc/loginprompt.c
Normal file
165
libmisc/loginprompt.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright 1989 - 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: loginprompt.c,v 1.5 1998/04/16 19:57:44 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
|
||||
static void
|
||||
login_exit(int sig)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* login_prompt - prompt the user for their login name
|
||||
*
|
||||
* login_prompt() displays the standard login prompt. If ISSUE_FILE
|
||||
* is set in login.defs, this file is displayed before the prompt.
|
||||
*/
|
||||
|
||||
void
|
||||
login_prompt(const char *prompt, char *name, int namesize)
|
||||
{
|
||||
char buf[1024];
|
||||
#define MAX_ENV 32
|
||||
char *envp[MAX_ENV];
|
||||
int envc;
|
||||
char *cp;
|
||||
int i;
|
||||
FILE *fp;
|
||||
RETSIGTYPE (*sigquit) P_((int));
|
||||
#ifdef SIGTSTP
|
||||
RETSIGTYPE (*sigtstp) P_((int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There is a small chance that a QUIT character will be part of
|
||||
* some random noise during a prompt. Deal with this by exiting
|
||||
* instead of core dumping. If SIGTSTP is defined, do the same
|
||||
* thing for that signal.
|
||||
*/
|
||||
|
||||
sigquit = signal(SIGQUIT, login_exit);
|
||||
#ifdef SIGTSTP
|
||||
sigtstp = signal(SIGTSTP, login_exit);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if the user has configured the issue file to
|
||||
* be displayed and display it before the prompt.
|
||||
*/
|
||||
|
||||
if (prompt) {
|
||||
cp = getdef_str("ISSUE_FILE");
|
||||
if (cp && (fp = fopen(cp, "r"))) {
|
||||
while ((i = getc(fp)) != EOF)
|
||||
putc(i, stdout);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
gethostname(buf, sizeof buf);
|
||||
printf(prompt, buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the user's response. The trailing newline will be
|
||||
* removed.
|
||||
*/
|
||||
|
||||
memzero(buf, sizeof buf);
|
||||
if (fgets(buf, sizeof buf, stdin) != buf)
|
||||
exit(1);
|
||||
|
||||
cp = strchr(buf, '\n');
|
||||
if (!cp)
|
||||
exit(1);
|
||||
*cp = '\0'; /* remove \n [ must be there ] */
|
||||
|
||||
/*
|
||||
* Skip leading whitespace. This makes " username" work right.
|
||||
* Then copy the rest (up to the end or the first "non-graphic"
|
||||
* character into the username.
|
||||
*/
|
||||
|
||||
for (cp = buf;*cp == ' ' || *cp == '\t';cp++)
|
||||
;
|
||||
|
||||
for (i = 0; i < namesize - 1 && isgraph(*cp); name[i++] = *cp++)
|
||||
;
|
||||
while (isgraph(*cp))
|
||||
cp++;
|
||||
|
||||
if (*cp)
|
||||
cp++;
|
||||
|
||||
name[i] = '\0';
|
||||
|
||||
/*
|
||||
* This is a disaster, at best. The user may have entered extra
|
||||
* environmental variables at the prompt. There are several ways
|
||||
* to do this, and I just take the easy way out.
|
||||
*/
|
||||
|
||||
if (*cp != '\0') { /* process new variables */
|
||||
char *nvar;
|
||||
int count = 1;
|
||||
|
||||
for (envc = 0; envc < MAX_ENV; envc++) {
|
||||
nvar = strtok(envc ? (char *)0 : cp, " \t,");
|
||||
if (!nvar)
|
||||
break;
|
||||
if (strchr(nvar, '=')) {
|
||||
envp[envc] = nvar;
|
||||
} else {
|
||||
envp[envc] = xmalloc(strlen(nvar) + 32);
|
||||
sprintf(envp[envc], "L%d=%s", count++, nvar);
|
||||
}
|
||||
}
|
||||
set_env(envc, envp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the SIGQUIT handler back to its original value
|
||||
*/
|
||||
|
||||
signal(SIGQUIT, sigquit);
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, sigtstp);
|
||||
#endif
|
||||
}
|
||||
79
libmisc/mail.c
Normal file
79
libmisc/mail.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "getdef.h"
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: mail.c,v 1.7 1998/12/28 20:34:49 marekm Exp $")
|
||||
|
||||
void
|
||||
mailcheck(void)
|
||||
{
|
||||
struct stat statbuf;
|
||||
char *mailbox;
|
||||
|
||||
if (!getdef_bool("MAIL_CHECK_ENAB"))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Check incoming mail in Maildir format - J.
|
||||
*/
|
||||
if ((mailbox = getenv("MAILDIR"))) {
|
||||
char *newmail;
|
||||
|
||||
newmail = xmalloc(strlen(mailbox) + 5);
|
||||
sprintf(newmail, "%s/new", mailbox);
|
||||
if (stat(newmail, &statbuf) != -1 && statbuf.st_size != 0) {
|
||||
if (statbuf.st_mtime > statbuf.st_atime) {
|
||||
free(newmail);
|
||||
puts(_("You have new mail."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
free(newmail);
|
||||
}
|
||||
|
||||
if (!(mailbox = getenv("MAIL")))
|
||||
return;
|
||||
|
||||
if (stat(mailbox, &statbuf) == -1 || statbuf.st_size == 0)
|
||||
puts(_("No mail."));
|
||||
else if (statbuf.st_atime > statbuf.st_mtime)
|
||||
puts(_("You have mail."));
|
||||
else
|
||||
puts(_("You have new mail."));
|
||||
}
|
||||
|
||||
69
libmisc/motd.c
Normal file
69
libmisc/motd.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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: motd.c,v 1.3 1997/12/07 23:27:07 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* motd -- output the /etc/motd file
|
||||
*
|
||||
* motd() determines the name of a login announcement file and outputs
|
||||
* it to the user's terminal at login time. The MOTD_FILE configuration
|
||||
* option is a colon-delimited list of filenames.
|
||||
*/
|
||||
|
||||
void
|
||||
motd(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char motdlist[BUFSIZ], *motdfile, *mb;
|
||||
register int c;
|
||||
|
||||
if ((mb = getdef_str("MOTD_FILE")) == NULL)
|
||||
return;
|
||||
|
||||
strncpy(motdlist, mb, sizeof(motdlist));
|
||||
motdlist[sizeof(motdlist)-1] = '\0';
|
||||
|
||||
for (mb = motdlist ; (motdfile = strtok(mb,":")) != NULL ; mb = NULL) {
|
||||
if ((fp = fopen(motdfile, "r")) != NULL) {
|
||||
while ((c = getc (fp)) != EOF)
|
||||
putchar (c);
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
fflush (stdout);
|
||||
}
|
||||
41
libmisc/myname.c
Normal file
41
libmisc/myname.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* myname.c - determine the current username and get the passwd entry
|
||||
*
|
||||
* Copyright (C) 1996 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>
|
||||
*
|
||||
* This code may be freely used, modified and distributed for any purpose.
|
||||
* There is no warranty, if it breaks you have to keep both pieces, etc.
|
||||
* If you improve it, please send me your changes. Thanks!
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: myname.c,v 1.2 1997/12/07 23:27:07 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include "prototypes.h"
|
||||
|
||||
struct passwd *
|
||||
get_my_pwent(void)
|
||||
{
|
||||
struct passwd *pw;
|
||||
const char *cp = getlogin();
|
||||
uid_t ruid = getuid();
|
||||
|
||||
/*
|
||||
* Try getlogin() first - if it fails or returns a non-existent
|
||||
* username, or a username which doesn't match the real UID, fall
|
||||
* back to getpwuid(getuid()). This should work reasonably with
|
||||
* usernames longer than the utmp limit (8 characters), as well as
|
||||
* shared UIDs - but not both at the same time...
|
||||
*
|
||||
* XXX - when running from su, will return the current user (not
|
||||
* the original user, like getlogin() does). Does this matter?
|
||||
*/
|
||||
if (cp && *cp && (pw = getpwnam(cp)) && pw->pw_uid == ruid)
|
||||
return pw;
|
||||
|
||||
return getpwuid(ruid);
|
||||
}
|
||||
286
libmisc/obscure.c
Normal file
286
libmisc/obscure.c
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* 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: obscure.c,v 1.9 1999/03/07 19:14:40 marekm Exp $")
|
||||
|
||||
/*
|
||||
* This version of obscure.c contains modifications to support "cracklib"
|
||||
* by Alec Muffet (alec.muffett@uk.sun.com). You must obtain the Cracklib
|
||||
* library source code for this function to operate.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* can't be a palindrome - like `R A D A R' or `M A D A M'
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
palindrome(const char *old, const char *new)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
i = strlen (new);
|
||||
|
||||
for (j = 0;j < i;j++)
|
||||
if (new[i - j - 1] != new[j])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* more than half of the characters are different ones.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
similar(const char *old, const char *new)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* XXX - sometimes this fails when changing from a simple password
|
||||
* to a really long one (MD5). For now, I just return success if
|
||||
* the new password is long enough. Please feel free to suggest
|
||||
* something better... --marekm
|
||||
*/
|
||||
if (strlen(new) >= 8)
|
||||
return 0;
|
||||
|
||||
for (i = j = 0; new[i] && old[i]; i++)
|
||||
if (strchr(new, old[i]))
|
||||
j++;
|
||||
|
||||
if (i >= j * 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* a nice mix of characters.
|
||||
*/
|
||||
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
simple(const char *old, const char *new)
|
||||
{
|
||||
int digits = 0;
|
||||
int uppers = 0;
|
||||
int lowers = 0;
|
||||
int others = 0;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
for (i = 0;new[i];i++) {
|
||||
if (isdigit (new[i]))
|
||||
digits++;
|
||||
else if (isupper (new[i]))
|
||||
uppers++;
|
||||
else if (islower (new[i]))
|
||||
lowers++;
|
||||
else
|
||||
others++;
|
||||
}
|
||||
|
||||
/*
|
||||
* The scam is this - a password of only one character type
|
||||
* must be 8 letters long. Two types, 7, and so on.
|
||||
*/
|
||||
|
||||
size = 9;
|
||||
if (digits) size--;
|
||||
if (uppers) size--;
|
||||
if (lowers) size--;
|
||||
if (others) size--;
|
||||
|
||||
if (size <= i)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *
|
||||
str_lower(char *string)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
for (cp = string; *cp; cp++)
|
||||
*cp = tolower(*cp);
|
||||
return string;
|
||||
}
|
||||
|
||||
static const char *
|
||||
password_check(const char *old, const char *new, const struct passwd *pwdp)
|
||||
{
|
||||
const char *msg = NULL;
|
||||
char *oldmono, *newmono, *wrapped;
|
||||
#ifdef HAVE_LIBCRACK
|
||||
char *dictpath;
|
||||
#ifdef HAVE_LIBCRACK_PW
|
||||
char *FascistCheckPw();
|
||||
#else
|
||||
char *FascistCheck();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (strcmp(new, old) == 0)
|
||||
return "no change";
|
||||
|
||||
newmono = str_lower(xstrdup(new));
|
||||
oldmono = str_lower(xstrdup(old));
|
||||
wrapped = xmalloc(strlen(oldmono) * 2 + 1);
|
||||
strcpy (wrapped, oldmono);
|
||||
strcat (wrapped, oldmono);
|
||||
|
||||
if (palindrome(oldmono, newmono))
|
||||
msg = "a palindrome";
|
||||
|
||||
if (!msg && strcmp(oldmono, newmono) == 0)
|
||||
msg = "case changes only";
|
||||
|
||||
if (!msg && similar(oldmono, newmono))
|
||||
msg = "too similar";
|
||||
|
||||
if (!msg && simple(old, new))
|
||||
msg = "too simple";
|
||||
|
||||
if (!msg && strstr(wrapped, newmono))
|
||||
msg = "rotated";
|
||||
|
||||
#ifdef HAVE_LIBCRACK
|
||||
/*
|
||||
* Invoke Alec Muffett's cracklib routines.
|
||||
*/
|
||||
|
||||
if (!msg && (dictpath = getdef_str("CRACKLIB_DICTPATH")))
|
||||
#ifdef HAVE_LIBCRACK_PW
|
||||
msg = FascistCheckPw(new, dictpath, pwdp);
|
||||
#else
|
||||
msg = FascistCheck(new, dictpath);
|
||||
#endif
|
||||
#endif
|
||||
strzero(newmono);
|
||||
strzero(oldmono);
|
||||
strzero(wrapped);
|
||||
free(newmono);
|
||||
free(oldmono);
|
||||
free(wrapped);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
static const char *
|
||||
obscure_msg(const char *old, const char *new, const struct passwd *pwdp)
|
||||
{
|
||||
int maxlen, oldlen, newlen;
|
||||
char *new1, *old1;
|
||||
const char *msg;
|
||||
|
||||
oldlen = strlen(old);
|
||||
newlen = strlen(new);
|
||||
|
||||
#if 0 /* why not check the password when set for the first time? --marekm */
|
||||
if (old[0] == '\0')
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
if ( newlen < getdef_num("PASS_MIN_LEN", 0) )
|
||||
return "too short";
|
||||
|
||||
/*
|
||||
* Remaining checks are optional.
|
||||
*/
|
||||
if (!getdef_bool("OBSCURE_CHECKS_ENAB"))
|
||||
return NULL;
|
||||
|
||||
msg = password_check(old, new, pwdp);
|
||||
if (msg)
|
||||
return msg;
|
||||
|
||||
/* The traditional crypt() truncates passwords to 8 chars. It is
|
||||
possible to circumvent the above checks by choosing an easy
|
||||
8-char password and adding some random characters to it...
|
||||
Example: "password$%^&*123". So check it again, this time
|
||||
truncated to the maximum length. Idea from npasswd. --marekm */
|
||||
|
||||
if (getdef_bool("MD5_CRYPT_ENAB"))
|
||||
return NULL; /* unlimited password length */
|
||||
|
||||
maxlen = getdef_num("PASS_MAX_LEN", 8);
|
||||
if (oldlen <= maxlen && newlen <= maxlen)
|
||||
return NULL;
|
||||
|
||||
new1 = xstrdup(new);
|
||||
old1 = xstrdup(old);
|
||||
if (newlen > maxlen)
|
||||
new1[maxlen] = '\0';
|
||||
if (oldlen > maxlen)
|
||||
old1[maxlen] = '\0';
|
||||
|
||||
msg = password_check(old1, new1, pwdp);
|
||||
|
||||
memzero(new1, newlen);
|
||||
memzero(old1, oldlen);
|
||||
free(new1);
|
||||
free(old1);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Obscure - see if password is obscure enough.
|
||||
*
|
||||
* The programmer is encouraged to add as much complexity to this
|
||||
* routine as desired. Included are some of my favorite ways to
|
||||
* check passwords.
|
||||
*/
|
||||
|
||||
int
|
||||
obscure(const char *old, const char *new, const struct passwd *pwdp)
|
||||
{
|
||||
const char *msg = obscure_msg(old, new, pwdp);
|
||||
if (msg) {
|
||||
printf(_("Bad password: %s. "), msg);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
58
libmisc/pam_pass.c
Normal file
58
libmisc/pam_pass.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include <config.h>
|
||||
|
||||
#ifdef USE_PAM
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pam_pass.c,v 1.6 1999/06/07 16:40:44 marekm Exp $")
|
||||
|
||||
/*
|
||||
* Change the user's password using PAM. Requires libpam and libpam_misc
|
||||
* (for misc_conv). Note: libpam_misc is probably Linux-PAM specific,
|
||||
* so you may have to port it if you want to use this code on non-Linux
|
||||
* systems with PAM (such as Solaris 2.6). --marekm
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include "pam_defs.h"
|
||||
|
||||
static const struct pam_conv conv = {
|
||||
misc_conv,
|
||||
NULL
|
||||
};
|
||||
|
||||
void
|
||||
do_pam_passwd(const char *user, int silent, int change_expired)
|
||||
{
|
||||
pam_handle_t *pamh = NULL;
|
||||
int flags = 0, ret;
|
||||
|
||||
if (silent)
|
||||
flags |= PAM_SILENT;
|
||||
if (change_expired)
|
||||
flags |= PAM_CHANGE_EXPIRED_AUTHTOK;
|
||||
|
||||
ret = pam_start("passwd", user, &conv, &pamh);
|
||||
if (ret != PAM_SUCCESS) {
|
||||
fprintf(stderr, _("passwd: pam_start() failed, error %d\n"),
|
||||
ret);
|
||||
exit(10); /* XXX */
|
||||
}
|
||||
|
||||
ret = pam_chauthtok(pamh, flags);
|
||||
if (ret != PAM_SUCCESS) {
|
||||
fprintf(stderr, _("passwd: %s\n"), PAM_STRERROR(pamh, ret));
|
||||
pam_end(pamh, ret);
|
||||
exit(10); /* XXX */
|
||||
}
|
||||
|
||||
pam_end(pamh, PAM_SUCCESS);
|
||||
}
|
||||
#else /* !USE_PAM */
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif /* !USE_PAM */
|
||||
103
libmisc/pwd2spwd.c
Normal file
103
libmisc/pwd2spwd.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
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pwd2spwd.c,v 1.3 1997/12/07 23:27:07 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
|
||||
extern time_t time ();
|
||||
|
||||
/*
|
||||
* pwd_to_spwd - create entries for new spwd structure
|
||||
*
|
||||
* pwd_to_spwd() creates a new (struct spwd) containing the
|
||||
* information in the pointed-to (struct passwd).
|
||||
*/
|
||||
|
||||
struct spwd *
|
||||
pwd_to_spwd(const struct passwd *pw)
|
||||
{
|
||||
static struct spwd sp;
|
||||
|
||||
/*
|
||||
* Nice, easy parts first. The name and passwd map directly
|
||||
* from the old password structure to the new one.
|
||||
*/
|
||||
sp.sp_namp = pw->pw_name;
|
||||
sp.sp_pwdp = pw->pw_passwd;
|
||||
|
||||
#ifdef ATT_AGE
|
||||
/*
|
||||
* AT&T-style password aging maps the sp_min, sp_max, and
|
||||
* sp_lstchg information from the pw_age field, which appears
|
||||
* after the encrypted password.
|
||||
*/
|
||||
if (pw->pw_age[0]) {
|
||||
sp.sp_max = (c64i(pw->pw_age[0]) * WEEK) / SCALE;
|
||||
|
||||
if (pw->pw_age[1])
|
||||
sp.sp_min = (c64i(pw->pw_age[1]) * WEEK) / SCALE;
|
||||
else
|
||||
sp.sp_min = (10000L * DAY) / SCALE;
|
||||
|
||||
if (pw->pw_age[1] && pw->pw_age[2])
|
||||
sp.sp_lstchg = (a64l(pw->pw_age + 2) * WEEK) / SCALE;
|
||||
else
|
||||
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Defaults used if there is no pw_age information.
|
||||
*/
|
||||
sp.sp_min = 0;
|
||||
sp.sp_max = (10000L * DAY) / SCALE;
|
||||
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
||||
}
|
||||
|
||||
/*
|
||||
* These fields have no corresponding information in the password
|
||||
* file. They are set to uninitialized values.
|
||||
*/
|
||||
sp.sp_warn = -1;
|
||||
sp.sp_expire = -1;
|
||||
sp.sp_inact = -1;
|
||||
sp.sp_flag = -1;
|
||||
|
||||
return &sp;
|
||||
}
|
||||
#endif /* SHADOWPWD */
|
||||
73
libmisc/pwd_init.c
Normal file
73
libmisc/pwd_init.c
Normal file
@@ -0,0 +1,73 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: pwd_init.c,v 1.1 1997/12/07 23:27:07 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* pwd_init - ignore signals, and set resource limits to safe
|
||||
* values. Call this before modifying password files, so that
|
||||
* it is less likely to fail in the middle of operation.
|
||||
*/
|
||||
void
|
||||
pwd_init(void)
|
||||
{
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
struct rlimit rlim;
|
||||
|
||||
#ifdef RLIMIT_CORE
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
setrlimit(RLIMIT_CORE, &rlim);
|
||||
#endif
|
||||
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
|
||||
#ifdef RLIMIT_AS
|
||||
setrlimit(RLIMIT_AS, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_CPU
|
||||
setrlimit(RLIMIT_CPU, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_DATA
|
||||
setrlimit(RLIMIT_DATA, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_FSIZE
|
||||
setrlimit(RLIMIT_FSIZE, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_NOFILE
|
||||
setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_RSS
|
||||
setrlimit(RLIMIT_RSS, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
setrlimit(RLIMIT_STACK, &rlim);
|
||||
#endif
|
||||
#else /* !HAVE_SYS_RESOURCE_H */
|
||||
set_filesize_limit(30000);
|
||||
/* don't know how to set the other limits... */
|
||||
#endif /* !HAVE_SYS_RESOURCE_H */
|
||||
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
|
||||
umask(077);
|
||||
}
|
||||
|
||||
69
libmisc/pwdcheck.c
Normal file
69
libmisc/pwdcheck.c
Normal file
@@ -0,0 +1,69 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id$")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <pwd.h>
|
||||
#include "pwauth.h"
|
||||
|
||||
#ifdef HAVE_SHADOW_H
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
#include "pam_defs.h"
|
||||
#endif
|
||||
|
||||
#define WRONGPWD2 "incorrect password for `%s'"
|
||||
|
||||
void
|
||||
passwd_check(const char *user, const char *passwd, const char *progname)
|
||||
{
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retcode;
|
||||
struct pam_conv conv = { misc_conv, NULL };
|
||||
|
||||
if (pam_start(progname, user, &conv, &pamh)) {
|
||||
bailout:
|
||||
SYSLOG((LOG_WARN, WRONGPWD2, user));
|
||||
sleep(1);
|
||||
fprintf(stderr, _("Incorrect password for %s.\n"), user);
|
||||
exit(1);
|
||||
}
|
||||
if (pam_authenticate(pamh, 0))
|
||||
goto bailout;
|
||||
|
||||
retcode = pam_acct_mgmt(pamh, 0);
|
||||
if (retcode == PAM_NEW_AUTHTOK_REQD) {
|
||||
retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
|
||||
} else if (retcode)
|
||||
goto bailout;
|
||||
|
||||
if (pam_setcred(pamh, 0))
|
||||
goto bailout;
|
||||
|
||||
/* no need to establish a session; this isn't a session-oriented
|
||||
* activity... */
|
||||
|
||||
#else /* !USE_PAM */
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
struct spwd *sp;
|
||||
|
||||
if ((sp = getspnam(user)))
|
||||
passwd = sp->sp_pwdp;
|
||||
endspent();
|
||||
#endif
|
||||
if (pw_auth(passwd, user, PW_LOGIN, (char *) 0) != 0) {
|
||||
SYSLOG((LOG_WARN, WRONGPWD2, user));
|
||||
sleep(1);
|
||||
fprintf(stderr, _("Incorrect password for %s.\n"), user);
|
||||
exit(1);
|
||||
}
|
||||
#endif /* !USE_PAM */
|
||||
}
|
||||
|
||||
170
libmisc/rlogin.c
Normal file
170
libmisc/rlogin.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* 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 RLOGIN
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: rlogin.c,v 1.4 1997/12/14 20:07:20 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
|
||||
extern int ruserok();
|
||||
|
||||
static struct {
|
||||
int spd_name;
|
||||
int spd_baud;
|
||||
} speed_table [] = {
|
||||
#ifdef B50
|
||||
{ B50, 50 },
|
||||
#endif
|
||||
#ifdef B75
|
||||
{ B75, 75 },
|
||||
#endif
|
||||
#ifdef B110
|
||||
{ B110, 110 },
|
||||
#endif
|
||||
#ifdef B134
|
||||
{ B134, 134 },
|
||||
#endif
|
||||
#ifdef B150
|
||||
{ B150, 150 },
|
||||
#endif
|
||||
#ifdef B200
|
||||
{ B200, 200 },
|
||||
#endif
|
||||
#ifdef B300
|
||||
{ B300, 300 },
|
||||
#endif
|
||||
#ifdef B600
|
||||
{ B600, 600 },
|
||||
#endif
|
||||
#ifdef B1200
|
||||
{ B1200, 1200 },
|
||||
#endif
|
||||
#ifdef B1800
|
||||
{ B1800, 1800 },
|
||||
#endif
|
||||
#ifdef B2400
|
||||
{ B2400, 2400 },
|
||||
#endif
|
||||
#ifdef B4800
|
||||
{ B4800, 4800 },
|
||||
#endif
|
||||
#ifdef B9600
|
||||
{ B9600, 9600 },
|
||||
#endif
|
||||
#ifdef B19200
|
||||
{ B19200, 19200 },
|
||||
#endif
|
||||
#ifdef B38400
|
||||
{ B38400, 38400 },
|
||||
#endif
|
||||
{ -1, -1 }
|
||||
};
|
||||
|
||||
static void
|
||||
get_remote_string(char *buf, int size)
|
||||
{
|
||||
for (;;) {
|
||||
if (read (0, buf, 1) != 1)
|
||||
exit (1);
|
||||
if (*buf == '\0')
|
||||
return;
|
||||
if (--size > 0)
|
||||
++buf;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
int
|
||||
do_rlogin(const char *remote_host, char *name, int namelen, char *term, int termlen)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
char remote_name[32];
|
||||
char *cp;
|
||||
int remote_speed = 9600;
|
||||
int speed_name = B9600;
|
||||
int i;
|
||||
TERMIO termio;
|
||||
|
||||
get_remote_string (remote_name, sizeof remote_name);
|
||||
get_remote_string (name, namelen);
|
||||
get_remote_string (term, termlen);
|
||||
|
||||
if ((cp = strchr (term, '/'))) {
|
||||
*cp++ = '\0';
|
||||
|
||||
if (! (remote_speed = atoi (cp)))
|
||||
remote_speed = 9600;
|
||||
}
|
||||
for (i = 0;speed_table[i].spd_baud != remote_speed &&
|
||||
speed_table[i].spd_name != -1;i++)
|
||||
;
|
||||
|
||||
if (speed_table[i].spd_name != -1)
|
||||
speed_name = speed_table[i].spd_name;
|
||||
|
||||
/*
|
||||
* Put the terminal in cooked mode with echo turned on.
|
||||
*/
|
||||
|
||||
GTTY (0, &termio);
|
||||
#ifndef USE_SGTTY
|
||||
termio.c_iflag |= ICRNL|IXON;
|
||||
termio.c_oflag |= OPOST|ONLCR;
|
||||
termio.c_lflag |= ICANON|ECHO|ECHOE;
|
||||
termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
|
||||
#else
|
||||
#endif
|
||||
STTY (0, &termio);
|
||||
|
||||
if (! (pwd = getpwnam (name)))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* ruserok() returns 0 for success on modern systems, and 1 on
|
||||
* older ones. If you are having trouble with people logging
|
||||
* in without giving a required password, THIS is the culprit -
|
||||
* go fix the #define in config.h.
|
||||
*/
|
||||
|
||||
#ifndef RUSEROK
|
||||
return 0;
|
||||
#else
|
||||
return ruserok (remote_host, pwd->pw_uid == 0,
|
||||
remote_name, name) == RUSEROK;
|
||||
#endif
|
||||
}
|
||||
#endif /* RLOGIN */
|
||||
70
libmisc/salt.c
Normal file
70
libmisc/salt.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* salt.c - generate a random salt string for crypt()
|
||||
*
|
||||
* Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
|
||||
* public domain.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: salt.c,v 1.5 1997/12/07 23:27:09 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#if 1
|
||||
#include "getdef.h"
|
||||
|
||||
extern char *l64a();
|
||||
|
||||
/*
|
||||
* Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
|
||||
* in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
|
||||
* (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
|
||||
* version of crypt() instead of the standard one.
|
||||
*/
|
||||
char *
|
||||
crypt_make_salt(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
static char result[40];
|
||||
|
||||
result[0] = '\0';
|
||||
if (getdef_bool("MD5_CRYPT_ENAB")) {
|
||||
strcpy(result, "$1$"); /* magic for the new MD5 crypt() */
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate 8 chars of salt, the old crypt() will use only first 2.
|
||||
*/
|
||||
gettimeofday(&tv, (struct timezone *) 0);
|
||||
strcat(result, l64a(tv.tv_usec));
|
||||
strcat(result, l64a(tv.tv_sec + getpid() + clock()));
|
||||
|
||||
if (strlen(result) > 3 + 8) /* magic+salt */
|
||||
result[11] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* This is the old style random salt generator...
|
||||
*/
|
||||
char *
|
||||
crypt_make_salt(void)
|
||||
{
|
||||
time_t now;
|
||||
static unsigned long x;
|
||||
static char result[3];
|
||||
|
||||
time(&now);
|
||||
x += now + getpid() + clock();
|
||||
result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
|
||||
result[1] = i64c(((x >> 12) ^ x) & 077);
|
||||
result[2] = '\0';
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
134
libmisc/setugid.c
Normal file
134
libmisc/setugid.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: setugid.c,v 1.6 1998/07/23 22:13:16 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* setup_uid_gid() split in two functions for PAM support -
|
||||
* pam_setcred() needs to be called after initgroups(), but
|
||||
* before setuid().
|
||||
*/
|
||||
|
||||
int
|
||||
setup_groups(const struct passwd *info)
|
||||
{
|
||||
/*
|
||||
* Set the real group ID to the primary group ID in the password
|
||||
* file.
|
||||
*/
|
||||
if (setgid (info->pw_gid) == -1) {
|
||||
perror("setgid");
|
||||
SYSLOG((LOG_ERR, "bad group ID `%d' for user `%s': %m\n",
|
||||
info->pw_gid, info->pw_name));
|
||||
closelog();
|
||||
return -1;
|
||||
}
|
||||
#ifdef HAVE_INITGROUPS
|
||||
/*
|
||||
* For systems which support multiple concurrent groups, go get
|
||||
* the group set from the /etc/group file.
|
||||
*/
|
||||
if (initgroups(info->pw_name, info->pw_gid) == -1) {
|
||||
perror("initgroups");
|
||||
SYSLOG((LOG_ERR, "initgroups failed for user `%s': %m\n",
|
||||
info->pw_name));
|
||||
closelog();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
change_uid(const struct passwd *info)
|
||||
{
|
||||
/*
|
||||
* Set the real UID to the UID value in the password file.
|
||||
*/
|
||||
#ifndef BSD
|
||||
if (setuid(info->pw_uid))
|
||||
#else
|
||||
if (setreuid(info->pw_uid, info->pw_uid))
|
||||
#endif
|
||||
{
|
||||
perror("setuid");
|
||||
SYSLOG((LOG_ERR, "bad user ID `%d' for user `%s': %m\n",
|
||||
(int) info->pw_uid, info->pw_name));
|
||||
closelog();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup_uid_gid() performs the following steps -
|
||||
*
|
||||
* set the group ID to the value from the password file entry
|
||||
* set the supplementary group IDs
|
||||
* optionally call specified function which may add more groups
|
||||
* set the user ID to the value from the password file entry
|
||||
*
|
||||
* Returns 0 on success, or -1 on failure.
|
||||
*/
|
||||
|
||||
int
|
||||
setup_uid_gid(const struct passwd *info, int is_console)
|
||||
{
|
||||
if (setup_groups(info) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef HAVE_INITGROUPS
|
||||
if (is_console) {
|
||||
char *cp = getdef_str("CONSOLE_GROUPS");
|
||||
if (cp && add_groups(cp))
|
||||
perror("Warning: add_groups");
|
||||
}
|
||||
#endif /* HAVE_INITGROUPS */
|
||||
|
||||
if (change_uid(info) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
libmisc/setup.c
Normal file
72
libmisc/setup.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: setup.c,v 1.3 1997/12/07 23:27:09 marekm Exp $")
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
|
||||
/*
|
||||
* setup - initialize login environment
|
||||
*
|
||||
* setup() performs the following steps -
|
||||
*
|
||||
* set the process nice, ulimit, and umask from the password file entry
|
||||
* set the group ID to the value from the password file entry
|
||||
* set the supplementary group IDs
|
||||
* set the user ID to the value from the password file entry
|
||||
* change to the user's home directory
|
||||
* set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
|
||||
* variables.
|
||||
*/
|
||||
|
||||
void
|
||||
setup(struct passwd *info)
|
||||
{
|
||||
/*
|
||||
* Set resource limits.
|
||||
*/
|
||||
setup_limits(info);
|
||||
|
||||
/*
|
||||
* Set the real group ID, do initgroups, and set the real user ID
|
||||
* to the value in the password file.
|
||||
*/
|
||||
if (setup_uid_gid(info, 0))
|
||||
exit(1);
|
||||
|
||||
/*
|
||||
* Change to the home directory, and set up environment.
|
||||
*/
|
||||
setup_env(info);
|
||||
}
|
||||
277
libmisc/setupenv.c
Normal file
277
libmisc/setupenv.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: setupenv.c,v 1.9 1999/03/07 19:14:41 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
|
||||
static void
|
||||
addenv_path(const char *varname, const char *dirname, const char *filename)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
buf = xmalloc(strlen(dirname) + strlen(filename) + 2);
|
||||
sprintf(buf, "%s/%s", dirname, filename);
|
||||
addenv(varname, buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
read_env_file(const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024];
|
||||
char *cp, *name, *val;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp)
|
||||
return;
|
||||
while (fgets(buf, sizeof buf, fp) == buf) {
|
||||
cp = strrchr(buf, '\n');
|
||||
if (!cp)
|
||||
break;
|
||||
*cp = '\0';
|
||||
|
||||
cp = buf;
|
||||
/* ignore whitespace and comments */
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
if (*cp == '\0' || *cp == '#')
|
||||
continue;
|
||||
/*
|
||||
* ignore lines which don't follow the name=value format
|
||||
* (for example, the "export NAME" shell commands)
|
||||
*/
|
||||
name = cp;
|
||||
while (*cp && !isspace(*cp) && *cp != '=')
|
||||
cp++;
|
||||
if (*cp != '=')
|
||||
continue;
|
||||
/* NUL-terminate the name */
|
||||
*cp++ = '\0';
|
||||
val = cp;
|
||||
#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
|
||||
/*
|
||||
(state, char_type) -> (state, action)
|
||||
|
||||
state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped
|
||||
char_type: normal, white, backslash, single, double
|
||||
action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX
|
||||
*/
|
||||
no_quote:
|
||||
if (*cp == '\\') {
|
||||
/* remove the backslash */
|
||||
remove_char(cp);
|
||||
/* skip over the next character */
|
||||
if (*cp)
|
||||
cp++;
|
||||
goto no_quote;
|
||||
} else if (*cp == '\'') {
|
||||
/* remove the quote */
|
||||
remove_char(cp);
|
||||
/* now within single quotes */
|
||||
goto s_quote;
|
||||
} else if (*cp == '"') {
|
||||
/* remove the quote */
|
||||
remove_char(cp);
|
||||
/* now within double quotes */
|
||||
goto d_quote;
|
||||
} else if (*cp == '\0') {
|
||||
/* end of string */
|
||||
goto finished;
|
||||
} else if (isspace(*cp)) {
|
||||
/* unescaped whitespace - end of string */
|
||||
*cp = '\0';
|
||||
goto finished;
|
||||
} else {
|
||||
cp++;
|
||||
goto no_quote;
|
||||
}
|
||||
s_quote:
|
||||
if (*cp == '\'') {
|
||||
/* remove the quote */
|
||||
remove_char(cp);
|
||||
/* unquoted again */
|
||||
goto no_quote;
|
||||
} else if (*cp == '\0') {
|
||||
/* end of string */
|
||||
goto finished;
|
||||
} else {
|
||||
/* preserve everything within single quotes */
|
||||
cp++;
|
||||
goto s_quote;
|
||||
}
|
||||
d_quote:
|
||||
if (*cp == '\"') {
|
||||
/* remove the quote */
|
||||
remove_char(cp);
|
||||
/* unquoted again */
|
||||
goto no_quote;
|
||||
} else if (*cp == '\\') {
|
||||
cp++;
|
||||
/* if backslash followed by double quote, remove backslash
|
||||
else skip over the backslash and following char */
|
||||
if (*cp == '"')
|
||||
remove_char(cp - 1);
|
||||
else if (*cp)
|
||||
cp++;
|
||||
goto d_quote;
|
||||
} eise if (*cp == '\0') {
|
||||
/* end of string */
|
||||
goto finished;
|
||||
} else {
|
||||
/* preserve everything within double quotes */
|
||||
goto d_quote;
|
||||
}
|
||||
finished:
|
||||
#endif /* 0 */
|
||||
/*
|
||||
* XXX - should handle quotes, backslash escapes, etc.
|
||||
* like the shell does.
|
||||
*/
|
||||
addenv(name, val);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* change to the user's home directory
|
||||
* set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
|
||||
* variables.
|
||||
*/
|
||||
|
||||
void
|
||||
setup_env(struct passwd *info)
|
||||
{
|
||||
char *cp, *envf;
|
||||
|
||||
/*
|
||||
* Change the current working directory to be the home directory
|
||||
* of the user. It is a fatal error for this process to be unable
|
||||
* to change to that directory. There is no "default" home
|
||||
* directory.
|
||||
*
|
||||
* We no longer do it as root - should work better on NFS-mounted
|
||||
* home directories. Some systems default to HOME=/, so we make
|
||||
* this a configurable option. --marekm
|
||||
*/
|
||||
|
||||
if (chdir(info->pw_dir) == -1) {
|
||||
static char temp_pw_dir[] = "/";
|
||||
if (!getdef_bool("DEFAULT_HOME") || chdir("/") == -1) {
|
||||
fprintf(stderr, _("Unable to cd to \"%s\"\n"),
|
||||
info->pw_dir);
|
||||
SYSLOG((LOG_WARN,
|
||||
"unable to cd to `%s' for user `%s'\n",
|
||||
info->pw_dir, info->pw_name));
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
puts(_("No directory, logging in with HOME=/"));
|
||||
info->pw_dir = temp_pw_dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the HOME environmental variable and export it.
|
||||
*/
|
||||
|
||||
addenv("HOME", info->pw_dir);
|
||||
|
||||
/*
|
||||
* Create the SHELL environmental variable and export it.
|
||||
*/
|
||||
|
||||
if (info->pw_shell == (char *) 0 || ! *info->pw_shell) {
|
||||
static char temp_pw_shell[] = "/bin/sh";
|
||||
info->pw_shell = temp_pw_shell;
|
||||
}
|
||||
|
||||
addenv("SHELL", info->pw_shell);
|
||||
|
||||
/*
|
||||
* Create the PATH environmental variable and export it.
|
||||
*/
|
||||
|
||||
cp = getdef_str( info->pw_uid == 0 ? "ENV_SUPATH" : "ENV_PATH" );
|
||||
addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL);
|
||||
|
||||
/*
|
||||
* Export the user name. For BSD derived systems, it's "USER", for
|
||||
* all others it's "LOGNAME". We set both of them.
|
||||
*/
|
||||
|
||||
addenv("USER", info->pw_name);
|
||||
addenv("LOGNAME", info->pw_name);
|
||||
|
||||
/*
|
||||
* MAILDIR environment variable for Qmail
|
||||
*/
|
||||
if ((cp=getdef_str("QMAIL_DIR")))
|
||||
addenv_path("MAILDIR", info->pw_dir, cp);
|
||||
|
||||
/*
|
||||
* Create the MAIL environmental variable and export it. login.defs
|
||||
* knows the prefix.
|
||||
*/
|
||||
|
||||
if ((cp=getdef_str("MAIL_DIR")))
|
||||
addenv_path("MAIL", cp, info->pw_name);
|
||||
else if ((cp=getdef_str("MAIL_FILE")))
|
||||
addenv_path("MAIL", info->pw_dir, cp);
|
||||
else {
|
||||
#if defined(MAIL_SPOOL_FILE)
|
||||
addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
|
||||
#elif defined(MAIL_SPOOL_DIR)
|
||||
addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Read environment from optional config file. --marekm
|
||||
*/
|
||||
if ((envf = getdef_str("ENVIRON_FILE")))
|
||||
read_env_file(envf);
|
||||
}
|
||||
126
libmisc/shell.c
Normal file
126
libmisc/shell.c
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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: shell.c,v 1.7 1998/12/28 20:34:53 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
|
||||
extern char **newenvp;
|
||||
extern size_t newenvc;
|
||||
|
||||
/*
|
||||
* shell - execute the named program
|
||||
*
|
||||
* shell begins by trying to figure out what argv[0] is going to
|
||||
* be for the named process. The user may pass in that argument,
|
||||
* or it will be the last pathname component of the file with a
|
||||
* '-' prepended. The first attempt is to just execute the named
|
||||
* file. If the errno comes back "ENOEXEC", the file is assumed
|
||||
* at first glance to be a shell script. The first two characters
|
||||
* must be "#!", in which case "/bin/sh" is executed to process
|
||||
* the file. If all that fails, give up in disgust ...
|
||||
*/
|
||||
|
||||
void
|
||||
shell(const char *file, const char *arg)
|
||||
{
|
||||
char arg0[1024];
|
||||
int err;
|
||||
|
||||
if (file == (char *) 0)
|
||||
exit (1);
|
||||
|
||||
/*
|
||||
* The argv[0]'th entry is usually the path name, but
|
||||
* for various reasons the invoker may want to override
|
||||
* that. So, we determine the 0'th entry only if they
|
||||
* don't want to tell us what it is themselves.
|
||||
*/
|
||||
|
||||
if (arg == (char *) 0) {
|
||||
snprintf(arg0, sizeof arg0, "-%s", Basename((char *) file));
|
||||
arg = arg0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf (_("Executing shell %s\n"), file);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First we try the direct approach. The system should be
|
||||
* able to figure out what we are up to without too much
|
||||
* grief.
|
||||
*/
|
||||
|
||||
execle (file, arg, (char *) 0, newenvp);
|
||||
err = errno;
|
||||
|
||||
/* Linux handles #! in the kernel, and bash doesn't make
|
||||
sense of "#!" so it wouldn't work anyway... --marekm */
|
||||
#ifndef __linux__
|
||||
/*
|
||||
* It is perfectly OK to have a shell script for a login
|
||||
* shell, and this code attempts to support that. It
|
||||
* relies on the standard shell being able to make sense
|
||||
* of the "#!" magic number.
|
||||
*/
|
||||
|
||||
if (err == ENOEXEC) {
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen (file, "r"))) {
|
||||
if (getc (fp) == '#' && getc (fp) == '!') {
|
||||
fclose (fp);
|
||||
execle ("/bin/sh", "sh",
|
||||
file, (char *) 0, newenvp);
|
||||
err = errno;
|
||||
} else {
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Obviously something is really wrong - I can't figure out
|
||||
* how to execute this stupid shell, so I might as well give
|
||||
* up in disgust ...
|
||||
*/
|
||||
|
||||
snprintf(arg0, sizeof arg0, _("Cannot execute %s"), file);
|
||||
errno = err;
|
||||
perror(arg0);
|
||||
exit(1);
|
||||
}
|
||||
207
libmisc/strtoday.c
Normal file
207
libmisc/strtoday.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright 1991 - 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.
|
||||
*/
|
||||
|
||||
#if !defined(__GLIBC__)
|
||||
#define _XOPEN_SOURCE 500
|
||||
#endif
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: strtoday.c,v 1.8 1999/03/07 19:14:42 marekm Exp $")
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#ifndef USE_GETDATE
|
||||
#define USE_GETDATE 1
|
||||
#endif
|
||||
|
||||
#if USE_GETDATE
|
||||
|
||||
#include "getdate.h"
|
||||
|
||||
/*
|
||||
* strtoday() now uses get_date() (borrowed from GNU shellutils)
|
||||
* which can handle many date formats, for example:
|
||||
* 1970-09-17 # ISO 8601.
|
||||
* 70-9-17 # This century assumed by default.
|
||||
* 70-09-17 # Leading zeros are ignored.
|
||||
* 9/17/72 # Common U.S. writing.
|
||||
* 24 September 1972
|
||||
* 24 Sept 72 # September has a special abbreviation.
|
||||
* 24 Sep 72 # Three-letter abbreviations always allowed.
|
||||
* Sep 24, 1972
|
||||
* 24-sep-72
|
||||
* 24sep72
|
||||
*/
|
||||
long
|
||||
strtoday(const char *str)
|
||||
{
|
||||
time_t t;
|
||||
|
||||
/*
|
||||
* get_date() interprets an empty string as the current date,
|
||||
* which is not what we expect, unless you're a BOFH :-).
|
||||
* (useradd sets sp_expire = current date for new lusers)
|
||||
*/
|
||||
if (!str || *str == '\0')
|
||||
return -1;
|
||||
|
||||
t = get_date(str, (time_t *) 0);
|
||||
if (t == (time_t) -1)
|
||||
return -1;
|
||||
/* convert seconds to days since 1970-01-01 */
|
||||
return (t + DAY/2)/DAY;
|
||||
}
|
||||
|
||||
#else /* !USE_GETDATE */
|
||||
/*
|
||||
* Old code, just in case get_date() doesn't work as expected...
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef HAVE_STRPTIME
|
||||
/*
|
||||
* for now we allow just one format, but we can define more later
|
||||
* (we try them all until one succeeds). --marekm
|
||||
*/
|
||||
static char *date_formats[] = {
|
||||
"%Y-%m-%d",
|
||||
(char *) 0
|
||||
};
|
||||
#else
|
||||
/*
|
||||
* days and juldays are used to compute the number of days in the
|
||||
* current month, and the cummulative number of days in the preceding
|
||||
* months. they are declared so that january is 1, not 0.
|
||||
*/
|
||||
|
||||
static short days[13] = { 0,
|
||||
31, 28, 31, 30, 31, 30, /* JAN - JUN */
|
||||
31, 31, 30, 31, 30, 31 }; /* JUL - DEC */
|
||||
|
||||
static short juldays[13] = { 0,
|
||||
0, 31, 59, 90, 120, 151, /* JAN - JUN */
|
||||
181, 212, 243, 273, 304, 334 }; /* JUL - DEC */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* strtoday - compute the number of days since 1970.
|
||||
*
|
||||
* the total number of days prior to the current date is
|
||||
* computed. january 1, 1970 is used as the origin with
|
||||
* it having a day number of 0.
|
||||
*/
|
||||
|
||||
long
|
||||
strtoday(const char *str)
|
||||
{
|
||||
#ifdef HAVE_STRPTIME
|
||||
struct tm tp;
|
||||
char * const *fmt;
|
||||
char *cp;
|
||||
time_t result;
|
||||
|
||||
memzero(&tp, sizeof tp);
|
||||
for (fmt = date_formats; *fmt; fmt++) {
|
||||
cp = strptime((char *) str, *fmt, &tp);
|
||||
if (!cp || *cp != '\0')
|
||||
continue;
|
||||
|
||||
result = mktime(&tp);
|
||||
if (result == (time_t) -1)
|
||||
continue;
|
||||
|
||||
return result / DAY; /* success */
|
||||
}
|
||||
return -1;
|
||||
#else
|
||||
char slop[2];
|
||||
int month;
|
||||
int day;
|
||||
int year;
|
||||
long total;
|
||||
|
||||
/*
|
||||
* start by separating the month, day and year. the order
|
||||
* is compiled in ...
|
||||
*/
|
||||
|
||||
if (sscanf (str, "%d/%d/%d%c", &year, &month, &day, slop) != 3)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* the month, day of the month, and year are checked for
|
||||
* correctness and the year adjusted so it falls between
|
||||
* 1970 and 2069.
|
||||
*/
|
||||
|
||||
if (month < 1 || month > 12)
|
||||
return -1;
|
||||
|
||||
if (day < 1)
|
||||
return -1;
|
||||
|
||||
if ((month != 2 || (year % 4) != 0) && day > days[month])
|
||||
return -1;
|
||||
else if ((month == 2 && (year % 4) == 0) && day > 29)
|
||||
return -1;
|
||||
|
||||
if (year < 0)
|
||||
return -1;
|
||||
else if (year <= 69)
|
||||
year += 2000;
|
||||
else if (year <= 99)
|
||||
year += 1900;
|
||||
|
||||
/*
|
||||
* On systems with 32-bit signed time_t, time wraps around in 2038
|
||||
* - for now we just limit the year to 2037 (instead of 2069).
|
||||
* This limit can be removed once no one is using 32-bit systems
|
||||
* anymore :-). --marekm
|
||||
*/
|
||||
if (year < 1970 || year > 2037)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* the total number of days is the total number of days in all
|
||||
* the whole years, plus the number of leap days, plus the
|
||||
* number of days in the whole months preceding, plus the number
|
||||
* of days so far in the month.
|
||||
*/
|
||||
|
||||
total = (long) ((year - 1970) * 365L) + (((year + 1) - 1970) / 4);
|
||||
total += (long) juldays[month] + (month > 2 && (year % 4) == 0 ? 1:0);
|
||||
total += (long) day - 1;
|
||||
|
||||
return total;
|
||||
#endif /* HAVE_STRPTIME */
|
||||
}
|
||||
#endif /* !USE_GETDATE */
|
||||
201
libmisc/suauth.c
Normal file
201
libmisc/suauth.c
Normal file
@@ -0,0 +1,201 @@
|
||||
#include <config.h>
|
||||
|
||||
#ifdef SU_ACCESS
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#ifndef SUAUTHFILE
|
||||
#define SUAUTHFILE "/etc/suauth"
|
||||
#endif
|
||||
|
||||
#define NOACTION 0
|
||||
#define NOPWORD 1
|
||||
#define DENY -1
|
||||
#define OWNPWORD 2
|
||||
|
||||
/* Really, I could do with a few const char's here defining all the
|
||||
* strings output to the user or the syslog. -- chris
|
||||
*/
|
||||
|
||||
static int applies P_((const char *, char *));
|
||||
|
||||
int check_su_auth P_((const char *, const char *));
|
||||
int isgrp P_((const char *, const char *));
|
||||
|
||||
static int lines = 0;
|
||||
|
||||
extern struct passwd pwent;
|
||||
|
||||
int
|
||||
check_su_auth(const char *actual_id, const char *wanted_id)
|
||||
{
|
||||
int posn, endline;
|
||||
const char field[] = ":";
|
||||
FILE *authfile_fd;
|
||||
char temp[1024];
|
||||
char *to_users;
|
||||
char *from_users;
|
||||
char *action;
|
||||
|
||||
if (!(authfile_fd = fopen(SUAUTHFILE, "r"))) {
|
||||
/*
|
||||
* If the file doesn't exist - default to the standard su
|
||||
* behaviour (no access control). If open fails for some
|
||||
* other reason - maybe someone is trying to fool us with
|
||||
* file descriptors limit etc., so deny access. --marekm
|
||||
*/
|
||||
if (errno == ENOENT)
|
||||
return NOACTION;
|
||||
SYSLOG((LOG_ERR, "could not open/read config file '%s': %m\n",
|
||||
SUAUTHFILE));
|
||||
return DENY;
|
||||
}
|
||||
|
||||
while (fgets(temp, sizeof(temp), authfile_fd) != NULL) {
|
||||
lines++;
|
||||
|
||||
if (temp[endline = strlen(temp) - 1] != '\n') {
|
||||
SYSLOG((LOG_ERR,
|
||||
"%s, line %d: line too long or missing newline",
|
||||
SUAUTHFILE, lines));
|
||||
continue;
|
||||
}
|
||||
|
||||
while (endline > 0 && (temp[endline-1] == ' '
|
||||
|| temp[endline-1] == '\t' || temp[endline-1] == '\n'))
|
||||
endline--;
|
||||
temp[endline] = '\0';
|
||||
|
||||
posn = 0;
|
||||
while (temp[posn] == ' ' || temp[posn] == '\t')
|
||||
posn++;
|
||||
|
||||
if (temp[posn] == '\n' || temp[posn] == '#' || temp[posn] == '\0') {
|
||||
continue;
|
||||
}
|
||||
if (!(to_users = strtok(temp + posn, field))
|
||||
|| !(from_users = strtok((char *)NULL, field))
|
||||
|| !(action = strtok((char *)NULL, field))
|
||||
|| strtok((char *)NULL, field)) {
|
||||
SYSLOG((LOG_ERR, "%s, line %d. Bad number of fields.\n",
|
||||
SUAUTHFILE, lines));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!applies(wanted_id, to_users))
|
||||
continue;
|
||||
if (!applies(actual_id, from_users))
|
||||
continue;
|
||||
if (!strcmp(action, "DENY")) {
|
||||
SYSLOG((pwent.pw_uid ? LOG_NOTICE : LOG_WARN,
|
||||
"DENIED su from `%s' to `%s' (%s)\n",
|
||||
actual_id, wanted_id, SUAUTHFILE));
|
||||
fprintf(stderr, _("Access to su to that account DENIED.\n"));
|
||||
fclose(authfile_fd);
|
||||
return DENY;
|
||||
} else if (!strcmp(action, "NOPASS")) {
|
||||
SYSLOG((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
|
||||
"NO password asked for su from `%s' to `%s' (%s)\n",
|
||||
actual_id, wanted_id, SUAUTHFILE));
|
||||
fprintf(stderr, _("Password authentication bypassed.\n"));
|
||||
fclose(authfile_fd);
|
||||
return NOPWORD;
|
||||
} else if (!strcmp(action, "OWNPASS")) {
|
||||
SYSLOG((pwent.pw_uid ? LOG_INFO : LOG_NOTICE,
|
||||
"su from `%s' to `%s': asking for user's own password (%s)\n",
|
||||
actual_id, wanted_id, SUAUTHFILE));
|
||||
fprintf(stderr, _("Please enter your OWN password as authentication.\n"));
|
||||
fclose(authfile_fd);
|
||||
return OWNPWORD;
|
||||
} else {
|
||||
SYSLOG((LOG_ERR, "%s, line %d: unrecognised action!\n",
|
||||
SUAUTHFILE, lines));
|
||||
}
|
||||
}
|
||||
fclose(authfile_fd);
|
||||
return NOACTION;
|
||||
}
|
||||
|
||||
static int
|
||||
applies(const char *single, char *list)
|
||||
{
|
||||
const char split[] = ", ";
|
||||
char *tok;
|
||||
|
||||
int state = 0;
|
||||
|
||||
for (tok = strtok(list, split); tok != NULL; tok = strtok(NULL, split)) {
|
||||
|
||||
if (!strcmp(tok, "ALL")) {
|
||||
if (state != 0) {
|
||||
SYSLOG((LOG_ERR,
|
||||
"%s, line %d: ALL in bad place\n",
|
||||
SUAUTHFILE, lines));
|
||||
return 0;
|
||||
}
|
||||
state = 1;
|
||||
} else if (!strcmp(tok, "EXCEPT")) {
|
||||
if (state != 1) {
|
||||
SYSLOG((LOG_ERR,
|
||||
"%s, line %d: EXCEPT in bas place\n",
|
||||
SUAUTHFILE, lines));
|
||||
return 0;
|
||||
}
|
||||
state = 2;
|
||||
} else if (!strcmp(tok, "GROUP")) {
|
||||
if ((state != 0) && (state != 2)) {
|
||||
SYSLOG((LOG_ERR,
|
||||
"%s, line %d: GROUP in bad place\n",
|
||||
SUAUTHFILE, lines));
|
||||
return 0;
|
||||
}
|
||||
state = (state == 0) ? 3 : 4;
|
||||
} else {
|
||||
switch (state) {
|
||||
case 0: /* No control words yet */
|
||||
if (!strcmp(tok, single))
|
||||
return 1;
|
||||
break;
|
||||
case 1: /* An all */
|
||||
SYSLOG((LOG_ERR, "%s, line %d: expect another token after ALL\n",
|
||||
SUAUTHFILE, lines));
|
||||
return 0;
|
||||
case 2: /* All except */
|
||||
if (!strcmp(tok, single))
|
||||
return 0;
|
||||
break;
|
||||
case 3: /* Group */
|
||||
if (isgrp(single, tok))
|
||||
return 1;
|
||||
break;
|
||||
case 4: /* All except group */
|
||||
if (isgrp(single, tok))
|
||||
return 0;
|
||||
/* FALL THRU */
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((state != 0) && (state != 3))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
isgrp(const char *name, const char *group)
|
||||
{
|
||||
struct group *grp;
|
||||
|
||||
grp = getgrnam(group);
|
||||
|
||||
if (!grp || !grp->gr_mem)
|
||||
return 0;
|
||||
|
||||
return is_on_list(grp->gr_mem, name);
|
||||
}
|
||||
#endif /* SU_ACCESS */
|
||||
78
libmisc/sub.c
Normal file
78
libmisc/sub.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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: sub.c,v 1.6 1999/03/07 19:14:43 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
#define BAD_SUBROOT2 "invalid root `%s' for user `%s'\n"
|
||||
#define NO_SUBROOT2 "no subsystem root `%s' for user `%s'\n"
|
||||
|
||||
/*
|
||||
* subsystem - change to subsystem root
|
||||
*
|
||||
* A subsystem login is indicated by the presense of a "*" as
|
||||
* the first character of the login shell. The given home
|
||||
* directory will be used as the root of a new filesystem which
|
||||
* the user is actually logged into.
|
||||
*/
|
||||
|
||||
void
|
||||
subsystem(const struct passwd *pw)
|
||||
{
|
||||
/*
|
||||
* The new root directory must begin with a "/" character.
|
||||
*/
|
||||
|
||||
if (pw->pw_dir[0] != '/') {
|
||||
printf(_("Invalid root directory \"%s\"\n"), pw->pw_dir);
|
||||
SYSLOG((LOG_WARN, BAD_SUBROOT2, pw->pw_dir, pw->pw_name));
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The directory must be accessible and the current process
|
||||
* must be able to change into it.
|
||||
*/
|
||||
|
||||
if (chdir (pw->pw_dir) || chroot (pw->pw_dir)) {
|
||||
printf(_("Can't change root directory to \"%s\"\n"), pw->pw_dir);
|
||||
SYSLOG((LOG_WARN, NO_SUBROOT2, pw->pw_dir, pw->pw_name));
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
77
libmisc/sulog.c
Normal file
77
libmisc/sulog.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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: sulog.c,v 1.4 1998/04/02 21:51:51 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
|
||||
extern char name[];
|
||||
extern char oldname[];
|
||||
extern struct tm *localtime ();
|
||||
|
||||
/*
|
||||
* sulog - log a SU command execution result
|
||||
*/
|
||||
|
||||
void
|
||||
sulog(const char *tty, int success)
|
||||
{
|
||||
char *sulog_file;
|
||||
time_t now;
|
||||
struct tm *tm;
|
||||
FILE *fp;
|
||||
mode_t oldmask;
|
||||
|
||||
if ((sulog_file = getdef_str("SULOG_FILE")) == (char *) 0)
|
||||
return;
|
||||
|
||||
oldmask = umask(077);
|
||||
fp = fopen(sulog_file, "a+");
|
||||
umask(oldmask);
|
||||
if (fp == (FILE *) 0)
|
||||
return; /* can't open or create logfile */
|
||||
|
||||
time(&now);
|
||||
tm = localtime(&now);
|
||||
|
||||
fprintf(fp, "SU %.02d/%.02d %.02d:%.02d %c %.6s %s-%s\n",
|
||||
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
|
||||
success ? '+':'-', tty, oldname, name);
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
}
|
||||
89
libmisc/ttytype.c
Normal file
89
libmisc/ttytype.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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: ttytype.c,v 1.5 1997/12/07 23:27:10 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
|
||||
extern char *getenv();
|
||||
|
||||
/*
|
||||
* ttytype - set ttytype from port to terminal type mapping database
|
||||
*/
|
||||
|
||||
void
|
||||
ttytype(const char *line)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ];
|
||||
char *typefile;
|
||||
char *cp;
|
||||
char type[BUFSIZ];
|
||||
char port[BUFSIZ];
|
||||
|
||||
if (getenv ("TERM"))
|
||||
return;
|
||||
if ((typefile=getdef_str("TTYTYPE_FILE")) == NULL )
|
||||
return;
|
||||
if (access(typefile, F_OK))
|
||||
return;
|
||||
|
||||
if (! (fp = fopen (typefile, "r"))) {
|
||||
perror (typefile);
|
||||
return;
|
||||
}
|
||||
while (fgets(buf, sizeof buf, fp)) {
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
|
||||
if ((cp = strchr (buf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
#if defined(SUN) || defined(BSD) || defined(SUN4)
|
||||
if ((sscanf (buf, "%s \"%*[^\"]\" %s", port, type) == 2 ||
|
||||
sscanf (buf, "%s %*s %s", port, type) == 2) &&
|
||||
strcmp (line, port) == 0)
|
||||
break;
|
||||
#else /* USG */
|
||||
if (sscanf (buf, "%s %s", type, port) == 2 &&
|
||||
strcmp (line, port) == 0)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
if (! feof (fp) && ! ferror (fp))
|
||||
addenv("TERM", type);
|
||||
|
||||
fclose (fp);
|
||||
}
|
||||
67
libmisc/tz.c
Normal file
67
libmisc/tz.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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: tz.c,v 1.4 1998/01/29 23:22:36 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "defines.h"
|
||||
#include "getdef.h"
|
||||
|
||||
/*
|
||||
* tz - return local timezone name
|
||||
*
|
||||
* tz() determines the name of the local timezone by reading the
|
||||
* contents of the file named by ``fname''.
|
||||
*/
|
||||
|
||||
char *
|
||||
tz(const char *fname)
|
||||
{
|
||||
FILE *fp = 0;
|
||||
static char tzbuf[BUFSIZ];
|
||||
const char *def_tz;
|
||||
|
||||
if ((fp = fopen(fname,"r")) == NULL ||
|
||||
fgets (tzbuf, sizeof (tzbuf), fp) == NULL) {
|
||||
if (! (def_tz = getdef_str ("ENV_TZ")) || def_tz[0] == '/')
|
||||
def_tz = "TZ=CST6CDT";
|
||||
|
||||
strcpy (tzbuf, def_tz);
|
||||
} else
|
||||
tzbuf[strlen(tzbuf) - 1] = '\0';
|
||||
|
||||
if (fp)
|
||||
(void) fclose(fp);
|
||||
|
||||
return tzbuf;
|
||||
}
|
||||
34
libmisc/ulimit.c
Normal file
34
libmisc/ulimit.c
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: ulimit.c,v 1.2 1997/12/07 23:27:11 marekm Exp $")
|
||||
|
||||
#if HAVE_ULIMIT_H
|
||||
#include <ulimit.h>
|
||||
|
||||
#ifndef UL_SETFSIZE
|
||||
#ifdef UL_SFILLIM
|
||||
#define UL_SETFSIZE UL_SFILLIM
|
||||
#else
|
||||
#define UL_SETFSIZE 2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif HAVE_SYS_RESOURCE_H
|
||||
#include <sys/time.h> /* for struct timeval on sunos4 */
|
||||
/* XXX - is the above ok or should it be <time.h> on ultrix? */
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
set_filesize_limit(int blocks)
|
||||
{
|
||||
#if HAVE_ULIMIT_H
|
||||
ulimit(UL_SETFSIZE, blocks);
|
||||
#elif defined(RLIMIT_FSIZE)
|
||||
struct rlimit rlimit_fsize;
|
||||
|
||||
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
|
||||
setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
|
||||
#endif
|
||||
}
|
||||
478
libmisc/utmp.c
Normal file
478
libmisc/utmp.c
Normal file
@@ -0,0 +1,478 @@
|
||||
/*
|
||||
* 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 <utmp.h>
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: utmp.c,v 1.8 1999/06/07 16:40:44 marekm Exp $")
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
extern struct utmpx utxent;
|
||||
#endif
|
||||
extern struct utmp utent;
|
||||
|
||||
extern struct utmp *getutent();
|
||||
extern struct utmp *getutline();
|
||||
extern void setutent();
|
||||
extern void endutent();
|
||||
extern time_t time();
|
||||
extern char *ttyname();
|
||||
extern long lseek();
|
||||
|
||||
#define NO_UTENT \
|
||||
"No utmp entry. You must exec \"login\" from the lowest level \"sh\""
|
||||
#define NO_TTY \
|
||||
"Unable to determine your tty name."
|
||||
|
||||
/*
|
||||
* checkutmp - see if utmp file is correct for this process
|
||||
*
|
||||
* System V is very picky about the contents of the utmp file
|
||||
* and requires that a slot for the current process exist.
|
||||
* The utmp file is scanned for an entry with the same process
|
||||
* ID. If no entry exists the process exits with a message.
|
||||
*
|
||||
* The "picky" flag is for network and other logins that may
|
||||
* use special flags. It allows the pid checks to be overridden.
|
||||
* This means that getty should never invoke login with any
|
||||
* command line flags.
|
||||
*/
|
||||
|
||||
#if defined(__linux__) /* XXX */
|
||||
|
||||
void
|
||||
checkutmp(int picky)
|
||||
{
|
||||
char *line;
|
||||
struct utmp *ut;
|
||||
pid_t pid = getpid();
|
||||
|
||||
setutent();
|
||||
|
||||
/* First, try to find a valid utmp entry for this process. */
|
||||
while ((ut = getutent()))
|
||||
if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
|
||||
(ut->ut_type==LOGIN_PROCESS || ut->ut_type==USER_PROCESS))
|
||||
break;
|
||||
|
||||
/* If there is one, just use it, otherwise create a new one. */
|
||||
if (ut) {
|
||||
utent = *ut;
|
||||
} else {
|
||||
if (picky) {
|
||||
puts(NO_UTENT);
|
||||
exit(1);
|
||||
}
|
||||
line = ttyname(0);
|
||||
if (!line) {
|
||||
puts(NO_TTY);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
memset((void *) &utent, 0, sizeof utent);
|
||||
utent.ut_type = LOGIN_PROCESS;
|
||||
utent.ut_pid = pid;
|
||||
strncpy(utent.ut_line, line, sizeof utent.ut_line);
|
||||
/* XXX - assumes /dev/tty?? */
|
||||
strncpy(utent.ut_id, utent.ut_line + 3, sizeof utent.ut_id);
|
||||
strcpy(utent.ut_user, "LOGIN");
|
||||
time(&utent.ut_time);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(LOGIN_PROCESS)
|
||||
|
||||
void
|
||||
checkutmp(int picky)
|
||||
{
|
||||
char *line;
|
||||
struct utmp *ut;
|
||||
#if HAVE_UTMPX_H
|
||||
struct utmpx *utx;
|
||||
#endif
|
||||
pid_t pid = getpid();
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
setutxent();
|
||||
#endif
|
||||
setutent();
|
||||
|
||||
if (picky) {
|
||||
#if HAVE_UTMPX_H
|
||||
while ((utx = getutxent()))
|
||||
if (utx->ut_pid == pid)
|
||||
break;
|
||||
|
||||
if (utx)
|
||||
utxent = *utx;
|
||||
#endif
|
||||
while ((ut = getutent()))
|
||||
if (ut->ut_pid == pid)
|
||||
break;
|
||||
|
||||
if (ut)
|
||||
utent = *ut;
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
endutxent();
|
||||
#endif
|
||||
endutent();
|
||||
|
||||
if (!ut) {
|
||||
puts(NO_UTENT);
|
||||
exit(1);
|
||||
}
|
||||
#ifndef UNIXPC
|
||||
|
||||
/*
|
||||
* If there is no ut_line value in this record, fill
|
||||
* it in by getting the TTY name and stuffing it in
|
||||
* the structure. The UNIX/PC is broken in this regard
|
||||
* and needs help ...
|
||||
*/
|
||||
|
||||
if (utent.ut_line[0] == '\0')
|
||||
#endif /* !UNIXPC */
|
||||
{
|
||||
if (!(line = ttyname(0))) {
|
||||
puts(NO_TTY);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
strncpy(utent.ut_line, line, sizeof utent.ut_line);
|
||||
#if HAVE_UTMPX_H
|
||||
strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (!(line = ttyname(0))) {
|
||||
puts(NO_TTY);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
|
||||
strncpy (utent.ut_line, line, sizeof utent.ut_line);
|
||||
if ((ut = getutline(&utent)))
|
||||
strncpy(utent.ut_id, ut->ut_id, sizeof ut->ut_id);
|
||||
|
||||
strcpy(utent.ut_user, "LOGIN");
|
||||
utent.ut_pid = getpid();
|
||||
utent.ut_type = LOGIN_PROCESS;
|
||||
time(&utent.ut_time);
|
||||
#if HAVE_UTMPX_H
|
||||
strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
|
||||
if ((utx = getutxline(&utxent)))
|
||||
strncpy(utxent.ut_id, utx->ut_id, sizeof utxent.ut_id);
|
||||
|
||||
strcpy(utxent.ut_user, "LOGIN");
|
||||
utxent.ut_pid = utent.ut_pid;
|
||||
utxent.ut_type = utent.ut_type;
|
||||
gettimeofday((struct timeval *) &utxent.ut_tv, NULL);
|
||||
utent.ut_time = utxent.ut_tv.tv_sec;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !USG */
|
||||
|
||||
void
|
||||
checkutmp(int picky)
|
||||
{
|
||||
char *line;
|
||||
|
||||
/*
|
||||
* Hand-craft a new utmp entry.
|
||||
*/
|
||||
|
||||
memzero(&utent, sizeof utent);
|
||||
if (! (line = ttyname (0))) {
|
||||
puts (NO_TTY);
|
||||
exit (1);
|
||||
}
|
||||
if (strncmp (line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
|
||||
(void) strncpy (utent.ut_line, line, sizeof utent.ut_line);
|
||||
(void) time (&utent.ut_time);
|
||||
}
|
||||
|
||||
#endif /* !USG */
|
||||
|
||||
|
||||
/*
|
||||
* Some systems already have updwtmp() and possibly updwtmpx(). Others
|
||||
* don't, so we re-implement these functions if necessary. --marekm
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UPDWTMP
|
||||
static void
|
||||
updwtmp(const char *filename, const struct utmp *ut)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_APPEND | O_WRONLY, 0);
|
||||
if (fd >= 0) {
|
||||
write(fd, (const char *) ut, sizeof(*ut));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif /* ! HAVE_UPDWTMP */
|
||||
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#ifndef HAVE_UPDWTMPX
|
||||
static void
|
||||
updwtmpx(const char *filename, const struct utmpx *utx)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_APPEND | O_WRONLY, 0);
|
||||
if (fd >= 0) {
|
||||
write(fd, (const char *) utx, sizeof(*utx));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif /* ! HAVE_UPDWTMPX */
|
||||
#endif /* ! HAVE_UTMPX_H */
|
||||
|
||||
|
||||
/*
|
||||
* setutmp - put a USER_PROCESS entry in the utmp file
|
||||
*
|
||||
* setutmp changes the type of the current utmp entry to
|
||||
* USER_PROCESS. the wtmp file will be updated as well.
|
||||
*/
|
||||
|
||||
#if defined(__linux__) /* XXX */
|
||||
|
||||
void
|
||||
setutmp(const char *name, const char *line, const char *host)
|
||||
{
|
||||
utent.ut_type = USER_PROCESS;
|
||||
strncpy(utent.ut_user, name, sizeof utent.ut_user);
|
||||
time(&utent.ut_time);
|
||||
/* other fields already filled in by checkutmp above */
|
||||
setutent();
|
||||
pututline(&utent);
|
||||
endutent();
|
||||
updwtmp(_WTMP_FILE, &utent);
|
||||
}
|
||||
|
||||
#elif HAVE_UTMPX_H
|
||||
|
||||
void
|
||||
setutmp(const char *name, const char *line, const char *host)
|
||||
{
|
||||
struct utmp *utmp, utline;
|
||||
struct utmpx *utmpx, utxline;
|
||||
pid_t pid = getpid ();
|
||||
int found_utmpx = 0, found_utmp = 0;
|
||||
|
||||
/*
|
||||
* The canonical device name doesn't include "/dev/"; skip it
|
||||
* if it is already there.
|
||||
*/
|
||||
|
||||
if (strncmp (line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
|
||||
/*
|
||||
* Update utmpx. We create an empty entry in case there is
|
||||
* no matching entry in the utmpx file.
|
||||
*/
|
||||
|
||||
setutxent ();
|
||||
setutent ();
|
||||
|
||||
while (utmpx = getutxent ()) {
|
||||
if (utmpx->ut_pid == pid) {
|
||||
found_utmpx = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (utmp = getutent ()) {
|
||||
if (utmp->ut_pid == pid) {
|
||||
found_utmp = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the entry matching `pid' cannot be found, create a new
|
||||
* entry with the device name in it.
|
||||
*/
|
||||
|
||||
if (! found_utmpx) {
|
||||
memset ((void *) &utxline, 0, sizeof utxline);
|
||||
strncpy (utxline.ut_line, line, sizeof utxline.ut_line);
|
||||
utxline.ut_pid = getpid ();
|
||||
} else {
|
||||
utxline = *utmpx;
|
||||
if (strncmp (utxline.ut_line, "/dev/", 5) == 0) {
|
||||
memmove (utxline.ut_line, utxline.ut_line + 5,
|
||||
sizeof utxline.ut_line - 5);
|
||||
utxline.ut_line[sizeof utxline.ut_line - 5] = '\0';
|
||||
}
|
||||
}
|
||||
if (! found_utmp) {
|
||||
memset ((void *) &utline, 0, sizeof utline);
|
||||
strncpy (utline.ut_line, utxline.ut_line,
|
||||
sizeof utline.ut_line);
|
||||
utline.ut_pid = utxline.ut_pid;
|
||||
} else {
|
||||
utline = *utmp;
|
||||
if (strncmp (utline.ut_line, "/dev/", 5) == 0) {
|
||||
memmove (utline.ut_line, utline.ut_line + 5,
|
||||
sizeof utline.ut_line - 5);
|
||||
utline.ut_line[sizeof utline.ut_line - 5] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the fields in the utmpx entry and write it out. Do
|
||||
* the utmp entry at the same time to make sure things don't
|
||||
* get messed up.
|
||||
*/
|
||||
|
||||
strncpy (utxline.ut_user, name, sizeof utxline.ut_user);
|
||||
strncpy (utline.ut_user, name, sizeof utline.ut_user);
|
||||
|
||||
utline.ut_type = utxline.ut_type = USER_PROCESS;
|
||||
|
||||
gettimeofday(&utxline.ut_tv, NULL);
|
||||
utline.ut_time = utxline.ut_tv.tv_sec;
|
||||
|
||||
strncpy(utxline.ut_host, host ? host : "", sizeof utxline.ut_host);
|
||||
|
||||
pututxline (&utxline);
|
||||
pututline (&utline);
|
||||
|
||||
updwtmpx(_WTMP_FILE "x", &utxline);
|
||||
updwtmp(_WTMP_FILE, &utline);
|
||||
|
||||
utxent = utxline;
|
||||
utent = utline;
|
||||
}
|
||||
|
||||
#else /* !SVR4 */
|
||||
|
||||
void
|
||||
setutmp(const char *name, const char *line)
|
||||
{
|
||||
struct utmp utmp;
|
||||
int fd;
|
||||
int found = 0;
|
||||
|
||||
if ((fd = open(_UTMP_FILE, O_RDWR)) < 0)
|
||||
return;
|
||||
|
||||
#if !defined(SUN) && !defined(BSD) && !defined(SUN4) /* XXX */
|
||||
while (!found && read(fd, (char *)&utmp, sizeof utmp) == sizeof utmp) {
|
||||
if (! strncmp (line, utmp.ut_line, (int) sizeof utmp.ut_line))
|
||||
found++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! found) {
|
||||
|
||||
/*
|
||||
* This is a brand-new entry. Clear it out and fill it in
|
||||
* later.
|
||||
*/
|
||||
|
||||
memzero(&utmp, sizeof utmp);
|
||||
strncpy(utmp.ut_line, line, (int) sizeof utmp.ut_line);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the parts of the UTMP entry. BSD has just the name,
|
||||
* while System V has the name, PID and a type.
|
||||
*/
|
||||
|
||||
strncpy(utmp.ut_user, name, sizeof utent.ut_user);
|
||||
#ifdef USER_PROCESS
|
||||
utmp.ut_type = USER_PROCESS;
|
||||
utmp.ut_pid = getpid ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Put in the current time (common to everyone)
|
||||
*/
|
||||
|
||||
(void) time (&utmp.ut_time);
|
||||
|
||||
#ifdef UT_HOST
|
||||
/*
|
||||
* Update the host name field for systems with networking support
|
||||
*/
|
||||
|
||||
(void) strncpy (utmp.ut_host, utent.ut_host, (int) sizeof utmp.ut_host);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Locate the correct position in the UTMP file for this
|
||||
* entry.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_TTYSLOT
|
||||
(void) lseek (fd, (off_t) (sizeof utmp) * ttyslot (), SEEK_SET);
|
||||
#else
|
||||
if (found) /* Back up a splot */
|
||||
lseek (fd, (off_t) - sizeof utmp, SEEK_CUR);
|
||||
else /* Otherwise, go to the end of the file */
|
||||
lseek (fd, (off_t) 0, SEEK_END);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Scribble out the new entry and close the file. We're done
|
||||
* with UTMP, next we do WTMP (which is real easy, put it on
|
||||
* the end of the file.
|
||||
*/
|
||||
|
||||
(void) write (fd, (char *) &utmp, sizeof utmp);
|
||||
(void) close (fd);
|
||||
|
||||
updwtmp(_WTMP_FILE, &utmp);
|
||||
utent = utmp;
|
||||
}
|
||||
|
||||
#endif /* SVR4 */
|
||||
101
libmisc/valid.c
Normal file
101
libmisc/valid.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 1989 - 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: valid.c,v 1.4 1999/03/07 19:14:44 marekm Exp $")
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "prototypes.h"
|
||||
#include "defines.h"
|
||||
#include <pwd.h>
|
||||
|
||||
/*
|
||||
* valid - compare encrypted passwords
|
||||
*
|
||||
* Valid() compares the DES encrypted password from the password file
|
||||
* against the password which the user has entered after it has been
|
||||
* encrypted using the same salt as the original. Entries which do
|
||||
* not have a password file entry have a NULL pw_name field and this
|
||||
* is used to indicate that a dummy salt must be used to encrypt the
|
||||
* password anyway.
|
||||
*/
|
||||
|
||||
int
|
||||
valid(const char *password, const struct passwd *ent)
|
||||
{
|
||||
const char *encrypted;
|
||||
const char *salt;
|
||||
|
||||
/*
|
||||
* Start with blank or empty password entries. Always encrypt
|
||||
* a password if no such user exists. Only if the ID exists and
|
||||
* the password is really empty do you return quickly. This
|
||||
* routine is meant to waste CPU time.
|
||||
*/
|
||||
|
||||
if (ent->pw_name && ! ent->pw_passwd[0]) {
|
||||
if (! password[0])
|
||||
return (1); /* user entered nothing */
|
||||
else
|
||||
return (0); /* user entered something! */
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is no entry then we need a salt to use.
|
||||
*/
|
||||
|
||||
if (ent->pw_name == (char *) 0 || ent->pw_passwd[0] == '\0') {
|
||||
salt = "xx";
|
||||
} else {
|
||||
salt = ent->pw_passwd;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, perform the encryption using the salt from before on
|
||||
* the users input. Since we always encrypt the string, it
|
||||
* should be very difficult to determine if the user exists by
|
||||
* looking at execution time.
|
||||
*/
|
||||
|
||||
encrypted = pw_encrypt(password, salt);
|
||||
|
||||
/*
|
||||
* One last time we must deal with there being no password file
|
||||
* entry for the user. We use the pw_name == NULL idiom to
|
||||
* cause non-existent users to not be validated.
|
||||
*/
|
||||
|
||||
if (ent->pw_name && strcmp(encrypted, ent->pw_passwd) == 0)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
38
libmisc/xmalloc.c
Normal file
38
libmisc/xmalloc.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/* Replacements for malloc and strdup with error checking. Too trivial
|
||||
to be worth copyrighting :-). I did that because a lot of code used
|
||||
malloc and strdup without checking for NULL pointer, and I like some
|
||||
message better than a core dump... --marekm
|
||||
|
||||
Yeh, but. Remember that bailing out might leave the system in some
|
||||
bizarre state. You really want to put in error checking, then add
|
||||
some back-out failure recovery code. -- jfh */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "rcsid.h"
|
||||
RCSID("$Id: xmalloc.c,v 1.3 1998/12/28 20:34:56 marekm Exp $")
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
extern char *malloc();
|
||||
|
||||
char *
|
||||
xmalloc(size_t size)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = malloc(size);
|
||||
if (!ptr && size) {
|
||||
fprintf(stderr, _("malloc(%d) failed\n"), (int) size);
|
||||
exit(13);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *
|
||||
xstrdup(const char *str)
|
||||
{
|
||||
return strcpy(xmalloc(strlen(str) + 1), str);
|
||||
}
|
||||
Reference in New Issue
Block a user