[svn-upgrade] Integrating new upstream version, shadow (19990709)

This commit is contained in:
nekral-guest
2007-10-07 11:44:02 +00:00
parent 9c72ed9062
commit 45c6603cc8
350 changed files with 89554 additions and 0 deletions

57
lib/Makefile.am Normal file
View File

@@ -0,0 +1,57 @@
AUTOMAKE_OPTIONS = 1.0 foreign
noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h \
faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h \
pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h \
tcfsio.h
localedir = $(datadir)/locale
DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
# These files are unneeded for some reason, listed in
# order of appearance:
#
# sources which are not really needed (are they in libc???)
# sources for dbm support (not yet used)
# sources for LIBOBJS (which are normally in libc)
# misc header sources
EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c \
grpack.c gspack.c pwpack.c sppack.c \
gshadow_.h shadow_.h lastlog_.h snprintf.h
EXTRA_libshadow_a_SOURCESS = grent.c pwent.c \
mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c \
putgrent.c putpwent.c putspent.c \
sgetgrent.c sgetpwent.c sgetspent.c snprintf.c \
md5.c md5crypt.c
# We build libshadow for our tools.
noinst_LIBRARIES = libshadow.a
libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c \
fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c \
pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c \
tcfsio.c
libshadow_a_LIBADD = @LIBOBJS@
INCLUDES = -I$(top_srcdir)/lib
# shared library support
libdir = ${exec_prefix}/lib
#lib_PROGRAMS = libshadow.la
lib_LTLIBRARIES = libshadow.la
libshadow_la_SOURCES = ${libshadow_a_SOURCES}
#libshadow_la_LIBADD = @LTLIBOBJS@
#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
libshadow_la_LDFLAGS = -version-info 0:0:0
# remove the libshadow.so -> libshadow.so.x.x symlink, because this
# library is for internal use by this package only. Shadow support
# is in libc and no one should be using -lshadow anymore.
install-exec-hook:
rm -f $(libdir)/libshadow.so

430
lib/Makefile.in Normal file
View File

@@ -0,0 +1,430 @@
# Makefile.in generated automatically by automake 1.3 from Makefile.am
# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DISTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_alias = @host_alias@
host_triplet = @host@
CATALOGS = @CATALOGS@
CATOBJEXT = @CATOBJEXT@
CC = @CC@
CPP = @CPP@
DATADIRNAME = @DATADIRNAME@
GENCAT = @GENCAT@
GMOFILES = @GMOFILES@
GMSGFMT = @GMSGFMT@
GT_NO = @GT_NO@
GT_YES = @GT_YES@
INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
INSTOBJEXT = @INSTOBJEXT@
INTLDEPS = @INTLDEPS@
INTLLIBS = @INTLLIBS@
INTLOBJS = @INTLOBJS@
LD = @LD@
LIBCRACK = @LIBCRACK@
LIBCRYPT = @LIBCRYPT@
LIBPAM = @LIBPAM@
LIBSKEY = @LIBSKEY@
LIBTCFS = @LIBTCFS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKINSTALLDIRS = @MKINSTALLDIRS@
MSGFMT = @MSGFMT@
NM = @NM@
PACKAGE = @PACKAGE@
POFILES = @POFILES@
POSUB = @POSUB@
RANLIB = @RANLIB@
U = @U@
USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
YACC = @YACC@
l = @l@
AUTOMAKE_OPTIONS = 1.0 foreign
noinst_HEADERS = commonio.h defines.h dialchk.h dialup.h \
faillog.h getdef.h groupio.h md5.h pam_defs.h port.h prototypes.h \
pwauth.h pwio.h rcsid.h sgroupio.h shadowio.h snprintf.h \
tcfsio.h
localedir = $(datadir)/locale
DEFS = -DLOCALEDIR=\"$(localedir)\" -I. -I$(srcdir) -I.. @DEFS@
# These files are unneeded for some reason, listed in
# order of appearance:
#
# sources which are not really needed (are they in libc???)
# sources for dbm support (not yet used)
# sources for LIBOBJS (which are normally in libc)
# misc header sources
EXTRA_DIST = grdbm.c gsdbm.c pwdbm.c spdbm.c \
grpack.c gspack.c pwpack.c sppack.c \
gshadow_.h shadow_.h lastlog_.h snprintf.h
EXTRA_libshadow_a_SOURCESS = grent.c pwent.c \
mkdir.c rename.c rmdir.c strdup.c strcasecmp.c strerror.c strstr.c \
putgrent.c putpwent.c putspent.c \
sgetgrent.c sgetpwent.c sgetspent.c snprintf.c \
md5.c md5crypt.c
# We build libshadow for our tools.
noinst_LIBRARIES = libshadow.a
libshadow_a_SOURCES = commonio.c dialchk.c dialup.c encrypt.c \
fputsx.c getdef.c getpass.c groupio.c gshadow.c lockpw.c port.c \
pwauth.c pwio.c rad64.c sgroupio.c shadow.c shadowio.c utent.c \
tcfsio.c
libshadow_a_LIBADD = @LIBOBJS@
INCLUDES = -I$(top_srcdir)/lib
# shared library support
libdir = ${exec_prefix}/lib
#lib_PROGRAMS = libshadow.la
lib_LTLIBRARIES = libshadow.la
libshadow_la_SOURCES = ${libshadow_a_SOURCES}
#libshadow_la_LIBADD = @LTLIBOBJS@
#libshadow_la_LDFLAGS = -version-info 0:0:0 -rpath $(libdir)
libshadow_la_LDFLAGS = -version-info 0:0:0
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
LIBRARIES = $(noinst_LIBRARIES)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libshadow_a_DEPENDENCIES = @LIBOBJS@
libshadow_a_OBJECTS = commonio.o dialchk.o dialup.o encrypt.o fputsx.o \
getdef.o getpass.o groupio.o gshadow.o lockpw.o port.o pwauth.o pwio.o \
rad64.o sgroupio.o shadow.o shadowio.o utent.o tcfsio.o
AR = ar
LTLIBRARIES = $(lib_LTLIBRARIES)
libshadow_la_LIBADD =
libshadow_la_OBJECTS = commonio.lo dialchk.lo dialup.lo encrypt.lo \
fputsx.lo getdef.lo getpass.lo groupio.lo gshadow.lo lockpw.lo port.lo \
pwauth.lo pwio.lo rad64.lo sgroupio.lo shadow.lo shadowio.lo utent.lo \
tcfsio.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(LIBTOOL) --mode=link $(CC) $(CFLAGS) $(LDFLAGS) -o $@
HEADERS = $(noinst_HEADERS)
DIST_COMMON = Makefile.am Makefile.in md5.c md5crypt.c mkdir.c \
putgrent.c putpwent.c putspent.c rename.c rmdir.c sgetgrent.c \
sgetpwent.c sgetspent.c snprintf.c strcasecmp.c strdup.c strerror.c \
strstr.c
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP = --best
SOURCES = $(libshadow_a_SOURCES) $(libshadow_la_SOURCES)
OBJECTS = $(libshadow_a_OBJECTS) $(libshadow_la_OBJECTS)
all: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS)
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps lib/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-noinstLIBRARIES:
clean-noinstLIBRARIES:
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
distclean-noinstLIBRARIES:
maintainer-clean-noinstLIBRARIES:
.c.o:
$(COMPILE) -c $<
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.c.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libshadow.a: $(libshadow_a_OBJECTS) $(libshadow_a_DEPENDENCIES)
-rm -f libshadow.a
$(AR) cru libshadow.a $(libshadow_a_OBJECTS) $(libshadow_a_LIBADD)
$(RANLIB) libshadow.a
mostlyclean-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
distclean-libLTLIBRARIES:
maintainer-clean-libLTLIBRARIES:
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libdir)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
echo "$(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p"; \
$(LIBTOOL) --mode=install $(INSTALL_DATA) $$p $(DESTDIR)$(libdir)/$$p; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
list='$(lib_LTLIBRARIES)'; for p in $$list; do \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
done
libshadow.la: $(libshadow_la_OBJECTS) $(libshadow_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libshadow_la_LDFLAGS) $(libshadow_la_OBJECTS) $(libshadow_la_LIBADD) $(LIBS)
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = lib
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file; \
done
commonio.o: commonio.c ../config.h rcsid.h defines.h gshadow_.h \
commonio.h
dialchk.o: dialchk.c ../config.h rcsid.h defines.h gshadow_.h \
prototypes.h dialup.h dialchk.h
dialup.o: dialup.c ../config.h rcsid.h prototypes.h defines.h gshadow_.h \
dialup.h
encrypt.o: encrypt.c ../config.h rcsid.h prototypes.h defines.h \
gshadow_.h
fputsx.lo fputsx.o: fputsx.c ../config.h defines.h gshadow_.h rcsid.h
getdef.lo getdef.o: getdef.c ../config.h rcsid.h prototypes.h defines.h \
gshadow_.h getdef.h
getpass.lo getpass.o: getpass.c ../config.h rcsid.h defines.h gshadow_.h
groupio.lo groupio.o: groupio.c ../config.h rcsid.h prototypes.h \
defines.h gshadow_.h commonio.h groupio.h
gshadow.lo gshadow.o: gshadow.c ../config.h rcsid.h prototypes.h \
defines.h gshadow_.h
lockpw.lo lockpw.o: lockpw.c ../config.h
port.lo port.o: port.c ../config.h rcsid.h defines.h gshadow_.h port.h
putgrent.o: putgrent.c ../config.h prototypes.h defines.h gshadow_.h
pwauth.lo pwauth.o: pwauth.c ../config.h rcsid.h prototypes.h defines.h \
gshadow_.h pwauth.h getdef.h
pwio.lo pwio.o: pwio.c ../config.h rcsid.h prototypes.h defines.h \
gshadow_.h commonio.h pwio.h
rad64.lo rad64.o: rad64.c ../config.h rcsid.h
sgetgrent.o: sgetgrent.c ../config.h rcsid.h defines.h gshadow_.h
sgetpwent.o: sgetpwent.c ../config.h rcsid.h defines.h gshadow_.h
sgroupio.lo sgroupio.o: sgroupio.c ../config.h rcsid.h prototypes.h \
defines.h gshadow_.h commonio.h sgroupio.h
shadowio.lo shadowio.o: shadowio.c ../config.h rcsid.h prototypes.h \
defines.h gshadow_.h commonio.h shadowio.h
shadow.lo shadow.o: shadow.c ../config.h
tcfsio.lo tcfsio.o: tcfsio.c ../config.h
utent.lo utent.o: utent.c ../config.h
info:
dvi:
check: all
$(MAKE)
installcheck:
install-exec: install-libLTLIBRARIES
@$(NORMAL_INSTALL)
$(MAKE) install-exec-hook
install-data:
@$(NORMAL_INSTALL)
install: install-exec install-data all
@:
uninstall: uninstall-libLTLIBRARIES
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
installdirs:
$(mkinstalldirs) $(DATADIR)$(libdir)
mostlyclean-generic:
-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-rm -f Makefile $(DISTCLEANFILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-libLTLIBRARIES \
mostlyclean-tags mostlyclean-generic
clean: clean-noinstLIBRARIES clean-compile clean-libtool \
clean-libLTLIBRARIES clean-tags clean-generic \
mostlyclean
distclean: distclean-noinstLIBRARIES distclean-compile \
distclean-libtool distclean-libLTLIBRARIES \
distclean-tags distclean-generic clean
-rm -f config.status
-rm -f libtool
maintainer-clean: maintainer-clean-noinstLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-libLTLIBRARIES maintainer-clean-tags \
maintainer-clean-generic distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
maintainer-clean-compile mostlyclean-libtool distclean-libtool \
clean-libtool maintainer-clean-libtool mostlyclean-libLTLIBRARIES \
distclean-libLTLIBRARIES clean-libLTLIBRARIES \
maintainer-clean-libLTLIBRARIES uninstall-libLTLIBRARIES \
install-libLTLIBRARIES tags mostlyclean-tags distclean-tags clean-tags \
maintainer-clean-tags distdir info dvi installcheck install-exec \
install-data install uninstall all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# remove the libshadow.so -> libshadow.so.x.x symlink, because this
# library is for internal use by this package only. Shadow support
# is in libc and no one should be using -lshadow anymore.
install-exec-hook:
rm -f $(libdir)/libshadow.so
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

739
lib/commonio.c Normal file
View File

@@ -0,0 +1,739 @@
#include <config.h>
#include "rcsid.h"
RCSID("$Id: commonio.c,v 1.14 1998/07/23 22:13:15 marekm Exp $")
#include "defines.h"
#include <sys/stat.h>
#include <utime.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#ifdef HAVE_SHADOW_H
#include <shadow.h>
#endif
#include "commonio.h"
/* local function prototypes */
static int check_link_count P_((const char *));
static int do_lock_file P_((const char *, const char *));
static FILE *fopen_set_perms P_((const char *, const char *, const struct stat *));
static int create_backup P_((const char *, FILE *));
static void free_linked_list P_((struct commonio_db *));
static void add_one_entry P_((struct commonio_db *, struct commonio_entry *));
static int name_is_nis P_((const char *));
static int write_all P_((const struct commonio_db *));
static struct commonio_entry *find_entry_by_name P_((struct commonio_db *, const char *));
#ifdef HAVE_LCKPWDF
static int lock_count = 0;
#endif
static int
check_link_count(const char *file)
{
struct stat sb;
if (stat(file, &sb) != 0)
return 0;
if (sb.st_nlink != 2)
return 0;
return 1;
}
static int
do_lock_file(const char *file, const char *lock)
{
int fd;
int pid;
int len;
int retval;
char buf[32];
if ((fd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0600)) == -1)
return 0;
pid = getpid();
snprintf(buf, sizeof buf, "%d", pid);
len = strlen(buf) + 1;
if (write(fd, buf, len) != len) {
close(fd);
unlink(file);
return 0;
}
close(fd);
if (link(file, lock) == 0) {
retval = check_link_count(file);
unlink(file);
return retval;
}
if ((fd = open(lock, O_RDWR)) == -1) {
unlink(file);
errno = EINVAL;
return 0;
}
len = read(fd, buf, sizeof(buf) - 1);
close(fd);
if (len <= 0) {
unlink(file);
errno = EINVAL;
return 0;
}
buf[len] = '\0';
if ((pid = strtol(buf, (char **) 0, 10)) == 0) {
unlink(file);
errno = EINVAL;
return 0;
}
if (kill(pid, 0) == 0) {
unlink(file);
errno = EEXIST;
return 0;
}
if (unlink(lock) != 0) {
unlink(file);
return 0;
}
retval = 0;
if (link(file, lock) == 0 && check_link_count(file))
retval = 1;
unlink(file);
return retval;
}
static FILE *
fopen_set_perms(const char *name, const char *mode, const struct stat *sb)
{
FILE *fp;
mode_t mask;
mask = umask(0777);
fp = fopen(name, mode);
umask(mask);
if (!fp)
return NULL;
#ifdef HAVE_FCHOWN
if (fchown(fileno(fp), sb->st_uid, sb->st_gid))
goto fail;
#else
if (chown(name, sb->st_mode))
goto fail;
#endif
#ifdef HAVE_FCHMOD
if (fchmod(fileno(fp), sb->st_mode & 0664))
goto fail;
#else
if (chmod(name, sb->st_mode & 0664))
goto fail;
#endif
return fp;
fail:
fclose(fp);
unlink(name);
return NULL;
}
static int
create_backup(const char *backup, FILE *fp)
{
struct stat sb;
struct utimbuf ub;
FILE *bkfp;
int c;
mode_t mask;
if (fstat(fileno(fp), &sb))
return -1;
mask = umask(077);
bkfp = fopen(backup, "w");
umask(mask);
if (!bkfp)
return -1;
/* TODO: faster copy, not one-char-at-a-time. --marekm */
rewind(fp);
while ((c = getc(fp)) != EOF) {
if (putc(c, bkfp) == EOF)
break;
}
if (c != EOF || fflush(bkfp)) {
fclose(bkfp);
return -1;
}
if (fclose(bkfp))
return -1;
ub.actime = sb.st_atime;
ub.modtime = sb.st_mtime;
utime(backup, &ub);
return 0;
}
static void
free_linked_list(struct commonio_db *db)
{
struct commonio_entry *p;
while (db->head) {
p = db->head;
db->head = p->next;
if (p->line)
free(p->line);
if (p->entry)
db->ops->free(p->entry);
free(p);
}
db->tail = NULL;
}
int
commonio_setname(struct commonio_db *db, const char *name)
{
strcpy(db->filename, name);
return 1;
}
int
commonio_present(const struct commonio_db *db)
{
return (access(db->filename, F_OK) == 0);
}
int
commonio_lock_nowait(struct commonio_db *db)
{
char file[1024];
char lock[1024];
if (db->locked)
return 1;
snprintf(file, sizeof file, "%s.%ld", db->filename, (long) getpid());
snprintf(lock, sizeof lock, "%s.lock", db->filename);
if (do_lock_file(file, lock)) {
db->locked = 1;
return 1;
}
return 0;
}
int
commonio_lock(struct commonio_db *db)
{
int i;
#ifdef HAVE_LCKPWDF
/*
* only if the system libc has a real lckpwdf() - the one from
* lockpw.c calls us and would cause infinite recursion!
*/
if (db->use_lckpwdf) {
/*
* Call lckpwdf() on the first lock.
* If it succeeds, call *_lock() only once
* (no retries, it should always succeed).
*/
if (lock_count == 0) {
if (lckpwdf() == -1)
return 0; /* failure */
}
if (!commonio_lock_nowait(db)) {
ulckpwdf();
return 0; /* failure */
}
lock_count++;
return 1; /* success */
}
#endif
/*
* lckpwdf() not used - do it the old way.
*/
#ifndef LOCK_TRIES
#define LOCK_TRIES 15
#endif
#ifndef LOCK_SLEEP
#define LOCK_SLEEP 1
#endif
for (i = 0; i < LOCK_TRIES; i++) {
if (i > 0)
sleep(LOCK_SLEEP); /* delay between retries */
if (commonio_lock_nowait(db))
return 1; /* success */
/* no unnecessary retries on "permission denied" errors */
if (geteuid() != 0)
return 0;
}
return 0; /* failure */
}
int
commonio_unlock(struct commonio_db *db)
{
char lock[1024];
if (db->isopen) {
db->readonly = 1;
if (!commonio_close(db))
return 0;
}
if (db->locked) {
/*
* Unlock in reverse order: remove the lock file,
* then call ulckpwdf() (if used) on last unlock.
*/
db->locked = 0;
snprintf(lock, sizeof lock, "%s.lock", db->filename);
unlink(lock);
#ifdef HAVE_LCKPWDF
if (db->use_lckpwdf && lock_count > 0) {
lock_count--;
if (lock_count == 0)
ulckpwdf();
}
#endif
return 1;
}
return 0;
}
static void
add_one_entry(struct commonio_db *db, struct commonio_entry *p)
{
p->next = NULL;
p->prev = db->tail;
if (!db->head)
db->head = p;
if (db->tail)
db->tail->next = p;
db->tail = p;
}
static int
name_is_nis(const char *n)
{
return (n[0] == '+' || n[0] == '-');
}
/*
* New entries are inserted before the first NIS entry. Order is preserved
* when db is written out.
*/
#ifndef KEEP_NIS_AT_END
#define KEEP_NIS_AT_END 1
#endif
#if KEEP_NIS_AT_END
/* prototype */
static void add_one_entry_nis P_((struct commonio_db *, struct commonio_entry *));
static void
add_one_entry_nis(struct commonio_db *db, struct commonio_entry *new)
{
struct commonio_entry *p;
for (p = db->head; p; p = p->next) {
if (name_is_nis(p->entry ? db->ops->getname(p->entry) : p->line)) {
new->next = p;
new->prev = p->prev;
if (p->prev)
p->prev->next = new;
else
db->head = new;
p->prev = new;
return;
}
}
add_one_entry(db, new);
}
#endif /* KEEP_NIS_AT_END */
int
commonio_open(struct commonio_db *db, int mode)
{
char buf[8192];
char *cp;
char *line;
struct commonio_entry *p;
void *entry;
int flags = mode;
mode &= ~O_CREAT;
if (db->isopen || (mode != O_RDONLY && mode != O_RDWR)) {
errno = EINVAL;
return 0;
}
db->readonly = (mode == O_RDONLY);
if (!db->readonly && !db->locked) {
errno = EACCES;
return 0;
}
db->head = db->tail = db->cursor = NULL;
db->changed = 0;
db->fp = fopen(db->filename, db->readonly ? "r" : "r+");
/*
* If O_CREAT was specified and the file didn't exist, it will be
* created by commonio_close(). We have no entries to read yet. --marekm
*/
if (!db->fp) {
if ((flags & O_CREAT) && errno == ENOENT) {
db->isopen = 1;
return 1;
}
return 0;
}
while (db->ops->fgets(buf, sizeof buf, db->fp)) {
if ((cp = strrchr(buf, '\n')))
*cp = '\0';
if (!(line = strdup(buf)))
goto cleanup;
if (name_is_nis(line)) {
entry = NULL;
} else if ((entry = db->ops->parse(line))) {
entry = db->ops->dup(entry);
if (!entry)
goto cleanup_line;
}
p = (struct commonio_entry *) malloc(sizeof *p);
if (!p)
goto cleanup_entry;
p->entry = entry;
p->line = line;
p->changed = 0;
add_one_entry(db, p);
}
db->isopen = 1;
return 1;
cleanup_entry:
if (entry)
db->ops->free(entry);
cleanup_line:
free(line);
cleanup:
free_linked_list(db);
fclose(db->fp);
db->fp = NULL;
errno = ENOMEM;
return 0;
}
static int
write_all(const struct commonio_db *db)
{
const struct commonio_entry *p;
void *entry;
for (p = db->head; p; p = p->next) {
if (p->changed) {
entry = p->entry;
if (db->ops->put(entry, db->fp))
return -1;
} else if (p->line) {
if (db->ops->fputs(p->line, db->fp) == EOF)
return -1;
if (putc('\n', db->fp) == EOF)
return -1;
}
}
return 0;
}
int
commonio_close(struct commonio_db *db)
{
char buf[1024];
int errors = 0;
struct stat sb;
if (!db->isopen) {
errno = EINVAL;
return 0;
}
db->isopen = 0;
if (!db->changed || db->readonly) {
fclose(db->fp);
db->fp = NULL;
goto success;
}
memzero(&sb, sizeof sb);
if (db->fp) {
if (fstat(fileno(db->fp), &sb)) {
fclose(db->fp);
db->fp = NULL;
goto fail;
}
/*
* Create backup file.
*/
snprintf(buf, sizeof buf, "%s-", db->filename);
if (create_backup(buf, db->fp))
errors++;
if (fclose(db->fp))
errors++;
if (errors) {
db->fp = NULL;
goto fail;
}
} else {
/*
* Default permissions for new [g]shadow files.
* (passwd and group always exist...)
*/
sb.st_mode = 0400;
sb.st_uid = 0;
sb.st_gid = 0;
}
snprintf(buf, sizeof buf, "%s+", db->filename);
db->fp = fopen_set_perms(buf, "w", &sb);
if (!db->fp)
goto fail;
if (write_all(db))
errors++;
if (fflush(db->fp))
errors++;
#ifdef HAVE_FSYNC
if (fsync(fileno(db->fp)))
errors++;
#else
sync();
#endif
if (fclose(db->fp))
errors++;
db->fp = NULL;
if (errors) {
unlink(buf);
goto fail;
}
if (rename(buf, db->filename))
goto fail;
success:
free_linked_list(db);
return 1;
fail:
free_linked_list(db);
return 0;
}
static struct commonio_entry *
find_entry_by_name(struct commonio_db *db, const char *name)
{
struct commonio_entry *p;
void *ep;
for (p = db->head; p; p = p->next) {
ep = p->entry;
if (ep && strcmp(db->ops->getname(ep), name) == 0)
break;
}
return p;
}
int
commonio_update(struct commonio_db *db, const void *entry)
{
struct commonio_entry *p;
void *nentry;
if (!db->isopen || db->readonly) {
errno = EINVAL;
return 0;
}
if (!(nentry = db->ops->dup(entry))) {
errno = ENOMEM;
return 0;
}
p = find_entry_by_name(db, db->ops->getname(entry));
if (p) {
db->ops->free(p->entry);
p->entry = nentry;
p->changed = 1;
db->cursor = p;
db->changed = 1;
return 1;
}
/* not found, new entry */
p = (struct commonio_entry *) malloc(sizeof *p);
if (!p) {
db->ops->free(nentry);
errno = ENOMEM;
return 0;
}
p->entry = nentry;
p->line = NULL;
p->changed = 1;
#if KEEP_NIS_AT_END
add_one_entry_nis(db, p);
#else
add_one_entry(db, p);
#endif
db->changed = 1;
return 1;
}
void
commonio_del_entry(struct commonio_db *db, const struct commonio_entry *p)
{
if (p == db->cursor)
db->cursor = p->next;
if (p->prev)
p->prev->next = p->next;
else
db->head = p->next;
if (p->next)
p->next->prev = p->prev;
else
db->tail = p->prev;
db->changed = 1;
}
int
commonio_remove(struct commonio_db *db, const char *name)
{
struct commonio_entry *p;
if (!db->isopen || db->readonly) {
errno = EINVAL;
return 0;
}
p = find_entry_by_name(db, name);
if (!p) {
errno = ENOENT;
return 0;
}
commonio_del_entry(db, p);
if (p->line)
free(p->line);
if (p->entry)
db->ops->free(p->entry);
return 1;
}
const void *
commonio_locate(struct commonio_db *db, const char *name)
{
struct commonio_entry *p;
if (!db->isopen) {
errno = EINVAL;
return NULL;
}
p = find_entry_by_name(db, name);
if (!p) {
errno = ENOENT;
return NULL;
}
db->cursor = p;
return p->entry;
}
int
commonio_rewind(struct commonio_db *db)
{
if (!db->isopen) {
errno = EINVAL;
return 0;
}
db->cursor = NULL;
return 1;
}
const void *
commonio_next(struct commonio_db *db)
{
void *entry;
if (!db->isopen) {
errno = EINVAL;
return 0;
}
if (db->cursor == NULL)
db->cursor = db->head;
else
db->cursor = db->cursor->next;
while (db->cursor) {
entry = db->cursor->entry;
if (entry)
return entry;
db->cursor = db->cursor->next;
}
return NULL;
}

101
lib/commonio.h Normal file
View File

@@ -0,0 +1,101 @@
/* $Id: commonio.h,v 1.4 1998/01/29 23:22:27 marekm Exp $ */
/*
* Linked list entry.
*/
struct commonio_entry {
char *line;
void *entry; /* struct passwd, struct spwd, ... */
struct commonio_entry *prev, *next;
int changed:1;
};
/*
* Operations depending on database type: passwd, group, shadow etc.
*/
struct commonio_ops {
/*
* Make a copy of the object (for example, struct passwd)
* and all strings pointed by it, in malloced memory.
*/
void * (*dup) P_((const void *));
/*
* free() the object including any strings pointed by it.
*/
void (*free) P_((void *));
/*
* Return the name of the object (for example, pw_name
* for struct passwd).
*/
const char * (*getname) P_((const void *));
/*
* Parse a string, return object (in static area -
* should be copied using the dup operation above).
*/
void * (*parse) P_((const char *));
/*
* Write the object to the file (this calls putpwent()
* for struct passwd, for example).
*/
int (*put) P_((const void *, FILE *));
/*
* fgets and fputs (can be replaced by versions that
* understand line continuation conventions).
*/
char * (*fgets) P_((char *, int, FILE *));
int (*fputs) P_((const char *, FILE *));
};
/*
* Database structure.
*/
struct commonio_db {
/*
* Name of the data file.
*/
char filename[1024];
/*
* Operations from above.
*/
struct commonio_ops *ops;
/*
* Currently open file stream.
*/
FILE *fp;
/*
* Head, tail, current position in linked list.
*/
struct commonio_entry *head, *tail, *cursor;
/*
* Various flags.
*/
int changed:1;
int isopen:1;
int locked:1;
int readonly:1;
int use_lckpwdf:1;
};
extern int commonio_setname P_((struct commonio_db *, const char *));
extern int commonio_present P_((const struct commonio_db *));
extern int commonio_lock P_((struct commonio_db *));
extern int commonio_lock_nowait P_((struct commonio_db *));
extern int commonio_open P_((struct commonio_db *, int));
extern const void *commonio_locate P_((struct commonio_db *, const char *));
extern int commonio_update P_((struct commonio_db *, const void *));
extern int commonio_remove P_((struct commonio_db *, const char *));
extern int commonio_rewind P_((struct commonio_db *));
extern const void *commonio_next P_((struct commonio_db *));
extern int commonio_close P_((struct commonio_db *));
extern int commonio_unlock P_((struct commonio_db *));
extern void commonio_del_entry P_((struct commonio_db *, const struct commonio_entry *));

319
lib/defines.h Normal file
View File

@@ -0,0 +1,319 @@
/* $Id: defines.h,v 1.14 1999/03/07 19:14:34 marekm Exp $ */
/* some useful defines */
#ifndef _DEFINES_H_
#define _DEFINES_H_
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
/* Take care of NLS matters. */
#if HAVE_LOCALE_H
# include <locale.h>
#endif
#if !HAVE_SETLOCALE
# define setlocale(Category, Locale) /* empty */
#endif
#define gettext_noop(String) (String)
/* #define gettext_def(String) "#define String" */
#if ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
#else
# undef bindtextdomain
# define bindtextdomain(Domain, Directory) /* empty */
# undef textdomain
# define textdomain(Domain) /* empty */
# define _(Text) Text
#endif
#ifndef P_
# ifdef PROTOTYPES
# define P_(x) x
# else
# define P_(x) ()
# endif
#endif
#if STDC_HEADERS
# include <stdlib.h>
# include <string.h>
#else /* not STDC_HEADERS */
# ifndef HAVE_STRCHR
# define strchr index
# define strrchr rindex
# endif
char *strchr(), *strrchr(), *strtok();
# ifndef HAVE_MEMCPY
# define memcpy(d, s, n) bcopy((s), (d), (n))
# endif
#endif /* not STDC_HEADERS */
/* Solaris 2.4 defines __SVR4, but not SVR4 -j. */
#ifdef __SVR4
# ifndef SVR4
# define SVR4 __SVR4
# endif
#endif
#include <sys/stat.h>
#include <sys/types.h>
#if HAVE_SYS_WAIT_H
# include <sys/wait.h>
#endif
#ifndef WEXITSTATUS
# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
#if HAVE_UNISTD_H
# include <unistd.h>
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else /* not TIME_WITH_SYS_TIME */
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif /* not TIME_WITH_SYS_TIME */
#ifdef HAVE_MEMSET
# define memzero(ptr, size) memset((void *)(ptr), 0, (size))
#else
# define memzero(ptr, size) bzero((char *)(ptr), (size))
#endif
#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
#ifdef HAVE_DIRENT_H /* DIR_SYSV */
# include <dirent.h>
# define DIRECT dirent
#else
# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */
# include <sys/ndir.h>
# endif
# ifdef HAVE_SYS_DIR_H /* DIR_??? */
# include <sys/dir.h>
# endif
# ifdef HAVE_NDIR_H /* DIR_BSD */
# include <ndir.h>
# endif
# define DIRECT direct
#endif
#ifdef SHADOWPWD
/*
* Possible cases:
* - /usr/include/shadow.h exists and includes the shadow group stuff.
* - /usr/include/shadow.h exists, but we use our own gshadow.h.
* - /usr/include/shadow.h doesn't exist, use our own shadow.h and gshadow.h.
*/
#if HAVE_SHADOW_H
#include <shadow.h>
#if defined(SHADOWGRP) && !defined(GSHADOW)
#include "gshadow_.h"
#endif
#else /* not HAVE_SHADOW_H */
#include "shadow_.h"
#ifdef SHADOWGRP
#include "gshadow_.h"
#endif
#endif /* not HAVE_SHADOW_H */
#endif /* SHADOWPWD */
#include <limits.h>
#ifndef NGROUPS_MAX
#ifdef NGROUPS
#define NGROUPS_MAX NGROUPS
#else
#define NGROUPS_MAX 64
#endif
#endif
#ifdef USE_SYSLOG
#include <syslog.h>
#ifndef LOG_WARN
#define LOG_WARN LOG_WARNING
#endif
/* cleaner than lots of #ifdefs everywhere - use this as follows:
SYSLOG((LOG_CRIT, "user %s cracked root", user)); */
#if HAVE_SETLOCALE
/* Temporarily set LC_TIME to "C" to avoid strange dates in syslog.
This is a workaround for a more general syslog(d) design problem -
syslogd should log the current system time for each event, and not
trust the formatted time received from the unix domain socket. -MM */
#define SYSLOG(x) \
do { \
char *saved_locale = setlocale(LC_ALL, NULL); \
if (saved_locale) \
saved_locale = strdup(saved_locale); \
if (saved_locale) \
setlocale(LC_TIME, "C"); \
syslog x ; \
if (saved_locale) { \
setlocale(LC_ALL, saved_locale); \
free(saved_locale); \
} \
} while (0)
#else /* !HAVE_SETLOCALE */
#define SYSLOG(x) syslog x
#endif /* !HAVE_SETLOCALE */
#else /* !USE_SYSLOG */
#define SYSLOG(x) /* empty */
#define openlog(a,b,c) /* empty */
#define closelog() /* empty */
#endif /* !USE_SYSLOG */
#ifndef F_OK
# define F_OK 0
# define X_OK 1
# define W_OK 2
# define R_OK 4
#endif
#ifndef SEEK_SET
# define SEEK_SET 0
# define SEEK_CUR 1
# define SEEK_END 2
#endif
#ifdef STAT_MACROS_BROKEN
# define S_ISDIR(x) ((x) & S_IFMT) == S_IFDIR)
# define S_ISREG(x) ((x) & S_IFMT) == S_IFREG)
# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK)
#endif
#if HAVE_TERMIOS_H
# include <termios.h>
# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
# define GTTY(fd, termio) tcgetattr(fd, termio)
# define TERMIO struct termios
# define USE_TERMIOS
#elif HAVE_TERMIO_H
# include <sys/ioctl.h>
# include <termio.h>
# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
# define TEMRIO struct termio
# define USE_TERMIO
#elif HAVE_SGTTY_H
# include <sgtty.h>
# define STTY(fd, termio) stty(fd, termio)
# define GTTY(fd, termio) gtty(fd, termio)
# define TERMIO struct sgttyb
# define USE_SGTTY
#endif
/*
* Password aging constants
*
* DAY - seconds / day
* WEEK - seconds / week
* SCALE - seconds / aging unit
*/
/* Solaris defines this in shadow.h */
#ifndef DAY
#define DAY (24L*3600L)
#endif
#define WEEK (7*DAY)
#ifdef ITI_AGING
#define SCALE 1
#else
#define SCALE DAY
#endif
/* Copy string pointed by B to array A with size checking. It was originally
in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
very sloppy coding used to assume that BUFSIZ will always be enough... */
/* danger - side effects */
#define STRFCPY(A,B) \
(strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
/* get rid of a few ugly repeated #ifdefs in pwent.c and grent.c */
/* XXX - this is ugly too, configure should test it and not check for
any hardcoded system names, if possible. --marekm */
#if defined(SVR4) || defined(AIX) || defined(__linux__)
#define SETXXENT_TYPE void
#define SETXXENT_RET(x) return
#define SETXXENT_TEST(x) x; if (0) /* compiler should optimize this away */
#else
#define SETXXENT_TYPE int
#define SETXXENT_RET(x) return(x)
#define SETXXENT_TEST(x) if (x)
#endif
#ifndef PASSWD_FILE
#define PASSWD_FILE "/etc/passwd"
#endif
#ifndef GROUP_FILE
#define GROUP_FILE "/etc/group"
#endif
#ifdef SHADOWPWD
#ifndef SHADOW_FILE
#define SHADOW_FILE "/etc/shadow"
#endif
#endif
#ifdef SHADOWGRP
#ifndef SGROUP_FILE
#define SGROUP_FILE "/etc/gshadow"
#endif
#endif
#define PASSWD_PAG_FILE PASSWD_FILE ".pag"
#define GROUP_PAG_FILE GROUP_FILE ".pag"
#define SHADOW_PAG_FILE SHADOW_FILE ".pag"
#define SGROUP_PAG_FILE SGROUP_FILE ".pag"
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifdef sun /* hacks for compiling on SunOS */
# ifndef SOLARIS
extern int fputs();
extern char *strdup();
extern char *strerror();
# endif
#endif
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
/*
* string to use for the pw_passwd field in /etc/passwd when using
* shadow passwords - most systems use "x" but there are a few
* exceptions, so it can be changed here if necessary. --marekm
*/
#ifndef SHADOW_PASSWD_STRING
#define SHADOW_PASSWD_STRING "x"
#endif
#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
#else
#define PAM_STRERROR(pamh, err) pam_strerror(err)
#endif
#endif /* _DEFINES_H_ */

77
lib/dialchk.c Normal file
View File

@@ -0,0 +1,77 @@
/*
* Copyright 1989 - 1991, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: dialchk.c,v 1.5 1998/12/28 20:34:34 marekm Exp $")
#include <stdio.h>
#include "defines.h"
#include "prototypes.h"
#include "dialup.h"
#include "dialchk.h"
/*
* Check for dialup password
*
* dialcheck tests to see if tty is listed as being a dialup
* line. If so, a dialup password may be required if the shell
* is listed as one which requires a second password.
*/
int
dialcheck(const char *tty, const char *sh)
{
struct dialup *dialup;
char *pass;
char *cp;
setduent ();
if (! isadialup (tty)) {
endduent ();
return (1);
}
if (! (dialup = getdushell (sh))) {
endduent ();
return (1);
}
endduent ();
if (dialup->du_passwd[0] == '\0')
return (1);
if (! (pass = getpass(_("Dialup Password:"))))
return (0);
cp = pw_encrypt (pass, dialup->du_passwd);
strzero(pass);
return (strcmp (cp, dialup->du_passwd) == 0);
}

16
lib/dialchk.h Normal file
View File

@@ -0,0 +1,16 @@
/* $Id: dialchk.h,v 1.1 1997/12/07 23:26:49 marekm Exp $ */
#ifndef _DIALCHK_H_
#define _DIALCHK_H_
#include "defines.h"
/*
* Check for dialup password
*
* dialcheck tests to see if tty is listed as being a dialup
* line. If so, a dialup password may be required if the shell
* is listed as one which requires a second password.
*/
extern int dialcheck P_((const char *tty, const char *sh));
#endif

169
lib/dialup.c Normal file
View File

@@ -0,0 +1,169 @@
/*
* Copyright 1989 - 1991, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: dialup.c,v 1.3 1997/12/07 23:26:50 marekm Exp $")
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
#include "dialup.h"
static FILE *dialpwd;
void
setduent(void)
{
if (dialpwd)
rewind (dialpwd);
else
dialpwd = fopen (DIALPWD, "r");
}
void
endduent(void)
{
if (dialpwd)
fclose (dialpwd);
dialpwd = (FILE *) 0;
}
struct dialup *
fgetduent(FILE *fp)
{
static struct dialup dialup; /* static structure to point to */
static char sh[128]; /* some space for a login shell */
static char passwd[128]; /* some space for dialup password */
char buf[BUFSIZ];
char *cp;
char *cp2;
if (! fp)
return 0;
if (! fp || feof (fp))
return ((struct dialup *) 0);
while (fgets (buf, sizeof buf, fp) == buf && buf[0] == '#')
;
if (feof (fp))
return ((struct dialup *) 0);
if ((cp = strchr (buf, '\n')))
*cp = '\0';
if (! (cp = strchr (buf, ':')))
return ((struct dialup *) 0);
if (cp - buf > sizeof sh) /* something is fishy ... */
return ((struct dialup *) 0);
*cp++ = '\0';
(void) strcpy (sh, buf);
sh[cp - buf] = '\0';
if ((cp2 = strchr (cp, ':')))
*cp2 = '\0';
if (strlen (cp) + 1 > sizeof passwd) /* something is REALLY fishy */
return ((struct dialup *) 0);
(void) strcpy (passwd, cp);
dialup.du_shell = sh;
dialup.du_passwd = passwd;
return (&dialup);
}
struct dialup *
getduent(void)
{
if (! dialpwd)
setduent ();
return fgetduent (dialpwd);
}
struct dialup *
getdushell(const char *sh)
{
struct dialup *dialup;
while ((dialup = getduent ())) {
if (strcmp (sh, dialup->du_shell) == 0)
return (dialup);
if (strcmp (dialup->du_shell, "*") == 0)
return (dialup);
}
return ((struct dialup *) 0);
}
int
isadialup(const char *tty)
{
FILE *fp;
char buf[BUFSIZ];
int dialup = 0;
if (! (fp = fopen (DIALUPS, "r")))
return (0);
while (fgets (buf, sizeof buf, fp) == buf) {
if (buf[0] == '#')
continue;
buf[strlen (buf) - 1] = '\0';
if (strcmp (buf, tty) == 0) {
dialup = 1;
break;
}
}
fclose (fp);
return (dialup);
}
int
putduent(const struct dialup *dial, FILE *fp)
{
if (! fp || ! dial)
return -1;
if (fprintf (fp, "%s:%s\n", dial->du_shell, dial->du_passwd) == EOF)
return -1;
return 0;
}

66
lib/dialup.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright 1989 - 1991, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* Structure of the /etc/d_passwd file
*
* The d_passwd file contains the names of login shells which require
* dialup passwords. Each line contains the fully qualified path name
* for the shell, followed by an optional password. Each field is
* separated by a ':'.
*
* Structure of the /etc/dialups file
*
* The dialups file contains the names of ports which may be dialup
* lines. Each line consists of the last component of the path
* name. The leading "/dev/" string is removed.
*
* $Id: dialup.h,v 1.2 1997/05/01 23:14:39 marekm Exp $
*/
#ifndef _DIALUP_H
#define _DIALUP_H
struct dialup {
char *du_shell;
char *du_passwd;
};
extern void setduent P_((void));
extern void endduent P_((void));
extern struct dialup *fgetduent P_((FILE *));
extern struct dialup *getduent P_((void));
extern struct dialup *getdushell P_((const char *));
extern int putduent P_((const struct dialup *, FILE *));
extern int isadialup P_((const char *));
#define DIALPWD "/etc/d_passwd"
#define DIALUPS "/etc/dialups"
#endif

123
lib/encrypt.c Normal file
View File

@@ -0,0 +1,123 @@
/*
* Copyright 1990 - 1993, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: encrypt.c,v 1.6 1999/03/07 19:14:35 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
extern char *crypt();
extern char *libshadow_md5_crypt P_((const char *, const char *));
char *
pw_encrypt(const char *clear, const char *salt)
{
static char cipher[128];
char *cp;
#ifdef SW_CRYPT
static int count;
#endif
#ifdef MD5_CRYPT
/*
* If the salt string from the password file or from crypt_make_salt()
* begins with the magic string, use the new algorithm.
*/
if (strncmp(salt, "$1$", 3) == 0)
return libshadow_md5_crypt(clear, salt);
#endif
#ifdef SW_CRYPT
/*
* Copy over the salt. It is always the first two
* characters of the string.
*/
cipher[0] = salt[0];
cipher[1] = salt[1];
cipher[2] = '\0';
/*
* Loop up to ten times on the cleartext password.
* This is because the input limit for passwords is
* 80 characters.
*
* The initial salt is that provided by the user, or the
* one generated above. The subsequent salts are gotten
* from the first two characters of the previous encrypted
* block of characters.
*/
for (count = 0;count < 10;count++) {
cp = crypt(clear, salt);
if (!cp) {
perror("crypt");
exit(1);
}
if (strlen(cp) != 13)
return cp;
strcat(cipher, cp + 2);
salt = cipher + 11 * count + 2;
if (strlen(clear) > 8)
clear += 8;
else
break;
}
#else
cp = crypt(clear, salt);
if (!cp) {
/*
* Single Unix Spec: crypt() may return a null pointer,
* and set errno to indicate an error. The caller doesn't
* expect us to return NULL, so...
*/
perror("crypt");
exit(1);
}
if (strlen(cp) != 13)
return cp; /* nonstandard crypt() in libc, better bail out */
strcpy(cipher, cp);
#ifdef DOUBLESIZE
if (strlen (clear) > 8) {
cp = crypt(clear + 8, salt);
if (!cp) {
perror("crypt");
exit(1);
}
strcat(cipher, cp + 2);
}
#endif /* DOUBLESIZE */
#endif /* SW_CRYPT */
return cipher;
}

55
lib/faillog.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* faillog.h - login failure logging file format
*
* $Id: faillog.h,v 1.3 1997/05/01 23:14:39 marekm Exp $
*
* The login failure file is maintained by login(1) and faillog(8)
* Each record in the file represents a separate UID and the file
* is indexed in that fashion.
*/
#ifndef _FAILLOG_H
#define _FAILLOG_H
struct faillog {
short fail_cnt; /* failures since last success */
short fail_max; /* failures before turning account off */
char fail_line[12]; /* last failure occured here */
time_t fail_time; /* last failure occured then */
/*
* If nonzero, the account will be re-enabled if there are no
* failures for fail_locktime seconds since last failure.
*/
long fail_locktime;
};
#endif

80
lib/fputsx.c Normal file
View File

@@ -0,0 +1,80 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include <stdio.h>
#include "defines.h"
#include "rcsid.h"
RCSID("$Id: fputsx.c,v 1.5 1999/06/07 16:40:44 marekm Exp $")
char *
fgetsx(char *buf, int cnt, FILE *f)
{
char *cp = buf;
char *ep;
while (cnt > 0) {
if (fgets (cp, cnt, f) == 0) {
if (cp == buf)
return 0;
else
break;
}
if ((ep = strrchr (cp, '\\')) && *(ep + 1) == '\n') {
if ((cnt -= ep - cp) > 0)
*(cp = ep) = '\0';
} else
break;
}
return buf;
}
int
fputsx(const char *s, FILE *stream)
{
int i;
for (i = 0;*s;i++, s++) {
if (putc (*s, stream) == EOF)
return EOF;
#if 0 /* The standard getgr*() can't handle that. --marekm */
if (i > (BUFSIZ/2)) {
if (putc ('\\', stream) == EOF ||
putc ('\n', stream) == EOF)
return EOF;
i = 0;
}
#endif
}
return 0;
}

400
lib/getdef.c Normal file
View File

@@ -0,0 +1,400 @@
/*
* Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: getdef.c,v 1.12 1999/03/07 19:14:36 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#include <ctype.h>
#include "getdef.h"
/*
* A configuration item definition.
*/
struct itemdef {
const char *name; /* name of the item */
char *value; /* value given, or NULL if no value */
};
/*
* This list *must* be sorted by the "name" member.
*/
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
static struct itemdef def_table[] = {
{ "CHFN_AUTH", NULL },
{ "CHFN_RESTRICT", NULL },
{ "CONSOLE", NULL },
{ "CONSOLE_GROUPS", NULL },
{ "CRACKLIB_DICTPATH", NULL },
{ "CREATE_HOME", NULL },
{ "DEFAULT_HOME", NULL },
{ "DIALUPS_CHECK_ENAB", NULL },
{ "ENVIRON_FILE", NULL },
{ "ENV_HZ", NULL },
{ "ENV_PATH" , NULL },
{ "ENV_SUPATH", NULL },
{ "ENV_TZ", NULL },
{ "ERASECHAR", NULL },
{ "FAILLOG_ENAB", NULL },
{ "FAIL_DELAY", NULL },
{ "FAKE_SHELL", NULL },
{ "FTMP_FILE", NULL },
{ "GID_MAX", NULL },
{ "GID_MIN", NULL },
{ "HUSHLOGIN_FILE", NULL },
{ "ISSUE_FILE", NULL },
{ "KILLCHAR", NULL },
{ "LASTLOG_ENAB", NULL },
{ "LOGIN_RETRIES", NULL },
{ "LOGIN_STRING", NULL },
{ "LOGIN_TIMEOUT", NULL },
{ "LOG_OK_LOGINS", NULL },
{ "LOG_UNKFAIL_ENAB", NULL },
{ "MAIL_CHECK_ENAB", NULL },
{ "MAIL_DIR", NULL },
{ "MAIL_FILE", NULL },
{ "MD5_CRYPT_ENAB", NULL },
{ "MOTD_FILE", NULL },
{ "NOLOGINS_FILE", NULL },
{ "NOLOGIN_STR", NULL },
{ "NO_PASSWORD_CONSOLE", NULL },
{ "OBSCURE_CHECKS_ENAB", NULL },
{ "PASS_ALWAYS_WARN", NULL },
{ "PASS_CHANGE_TRIES", NULL },
{ "PASS_MAX_DAYS", NULL },
{ "PASS_MAX_LEN", NULL },
{ "PASS_MIN_DAYS", NULL },
{ "PASS_MIN_LEN", NULL },
{ "PASS_WARN_AGE", NULL },
{ "PORTTIME_CHECKS_ENAB", NULL },
{ "QMAIL_DIR", NULL },
{ "QUOTAS_ENAB", NULL },
{ "SULOG_FILE", NULL },
{ "SU_NAME", NULL },
{ "SU_WHEEL_ONLY", NULL },
#ifdef USE_SYSLOG
{ "SYSLOG_SG_ENAB", NULL },
{ "SYSLOG_SU_ENAB", NULL },
#endif
{ "TTYGROUP", NULL },
{ "TTYPERM", NULL },
{ "TTYTYPE_FILE", NULL },
{ "UID_MAX", NULL },
{ "UID_MIN", NULL },
{ "ULIMIT", NULL },
{ "UMASK", NULL },
{ "USERDEL_CMD", NULL },
};
#ifndef LOGINDEFS
#define LOGINDEFS "/etc/login.defs"
#endif
static char def_fname[] = LOGINDEFS; /* login config defs file */
static int def_loaded = 0; /* are defs already loaded? */
extern long strtol();
/* local function prototypes */
static struct itemdef *def_find P_((const char *));
static void def_load P_((void));
/*
* getdef_str - get string value from table of definitions.
*
* Return point to static data for specified item, or NULL if item is not
* defined. First time invoked, will load definitions from the file.
*/
char *
getdef_str(const char *item)
{
struct itemdef *d;
if (!def_loaded)
def_load();
return ((d = def_find(item)) == NULL ? (char *)NULL : d->value);
}
/*
* getdef_bool - get boolean value from table of definitions.
*
* Return TRUE if specified item is defined as "yes", else FALSE.
*/
int
getdef_bool(const char *item)
{
struct itemdef *d;
if (!def_loaded)
def_load();
if ((d = def_find(item)) == NULL || d->value == NULL)
return 0;
return (strcasecmp(d->value, "yes") == 0);
}
/*
* getdef_num - get numerical value from table of definitions
*
* Returns numeric value of specified item, else the "dflt" value if
* the item is not defined. Octal (leading "0") and hex (leading "0x")
* values are handled.
*/
int
getdef_num(const char *item, int dflt)
{
struct itemdef *d;
if (!def_loaded)
def_load();
if ((d = def_find(item)) == NULL || d->value == NULL)
return dflt;
return (int) strtol(d->value, (char **)NULL, 0);
}
/*
* getdef_long - get long integer value from table of definitions
*
* Returns numeric value of specified item, else the "dflt" value if
* the item is not defined. Octal (leading "0") and hex (leading "0x")
* values are handled.
*/
long
getdef_long(const char *item, long dflt)
{
struct itemdef *d;
if (!def_loaded)
def_load();
if ((d = def_find(item)) == NULL || d->value == NULL)
return dflt;
return strtol(d->value, (char **)NULL, 0);
}
/*
* putdef_str - override the value read from /etc/login.defs
* (also used when loading the initial defaults)
*/
int
putdef_str(const char *name, const char *value)
{
struct itemdef *d;
char *cp;
if (!def_loaded)
def_load();
/*
* Locate the slot to save the value. If this parameter
* is unknown then "def_find" will print an err message.
*/
if ((d = def_find(name)) == NULL)
return -1;
/*
* Save off the value.
*/
if ((cp = strdup(value)) == NULL) {
fprintf(stderr,
_("Could not allocate space for config info.\n"));
SYSLOG((LOG_ERR,
"could not allocate space for config info"));
return -1;
}
if (d->value)
free(d->value);
d->value = cp;
return 0;
}
/*
* def_find - locate named item in table
*
* Search through a sorted table of configurable items to locate the
* specified configuration option.
*/
static struct itemdef *
def_find(const char *name)
{
int min, max, curr, n;
/*
* Invariant - desired item in range [min:max].
*/
min = 0;
max = NUMDEFS-1;
/*
* Binary search into the table. Relies on the items being
* sorted by name.
*/
while (min <= max) {
curr = (min+max)/2;
if (! (n = strcmp(def_table[curr].name, name)))
return &def_table[curr];
if (n < 0)
min = curr+1;
else
max = curr-1;
}
/*
* Item was never found.
*/
fprintf(stderr, _("configuration error - unknown item '%s' (notify administrator)\n"), name);
SYSLOG((LOG_CRIT, "unknown configuration item `%s'", name));
return (struct itemdef *) NULL;
}
/*
* def_load - load configuration table
*
* Loads the user-configured options from the default configuration file
*/
static void
def_load(void)
{
int i;
FILE *fp;
char buf[1024], *name, *value, *s;
/*
* Open the configuration definitions file.
*/
if ((fp = fopen(def_fname, "r")) == NULL) {
SYSLOG((LOG_CRIT, "cannot open login definitions %s [%m]",
def_fname));
return;
}
/*
* Set the initialized flag.
* (do it early to prevent recursion in putdef_str())
*/
++def_loaded;
/*
* Go through all of the lines in the file.
*/
while (fgets(buf, sizeof(buf), fp) != NULL) {
/*
* Trim trailing whitespace.
*/
for (i = strlen(buf)-1 ; i >= 0 ; --i) {
if (!isspace(buf[i]))
break;
}
buf[++i] = '\0';
/*
* Break the line into two fields.
*/
name = buf + strspn(buf, " \t"); /* first nonwhite */
if (*name == '\0' || *name == '#')
continue; /* comment or empty */
s = name + strcspn(name, " \t"); /* end of field */
if (*s == '\0')
continue; /* only 1 field?? */
*s++ = '\0';
value = s + strspn(s, " \"\t"); /* next nonwhite */
*(value + strcspn(value, "\"")) = '\0';
/*
* Store the value in def_table.
*/
putdef_str(name, value);
}
(void) fclose(fp);
}
#ifdef CKDEFS
int
main(int argc, char **argv)
{
int i;
char *cp;
struct itemdef *d;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
def_load ();
for (i = 0 ; i < NUMDEFS ; ++i) {
if ((d = def_find(def_table[i].name)) == NULL)
printf(_("error - lookup '%s' failed\n"), def_table[i].name);
else
printf("%4d %-24s %s\n", i+1, d->name, d->value);
}
for (i = 1;i < argc;i++) {
if ((cp = getdef_str (argv[1])) != NULL)
printf ("%s `%s'\n", argv[1], cp);
else
printf (_("%s not found\n"), argv[1]);
}
exit(0);
}
#endif

11
lib/getdef.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef _GETDEF_H
#define _GETDEF_H
/* getdef.c */
extern int getdef_bool P_((const char *));
extern long getdef_long P_((const char *, long));
extern int getdef_num P_((const char *, int));
extern char *getdef_str P_((const char *));
extern int putdef_str P_((const char *, const char *));
#endif /* _GETDEF_H */

268
lib/getpass.c Normal file
View File

@@ -0,0 +1,268 @@
/*
* Copyright 1990 - 1995, Julianne Frances Haugh
* Copyright 1998, Pavel Machek <pavel@ucw.cz>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: getpass.c,v 1.9 1999/06/07 16:40:44 marekm Exp $")
#include "defines.h"
#include <signal.h>
#include <stdio.h>
/* new code, #undef if there are any problems... */
#define USE_SETJMP 1
#ifdef USE_SETJMP
#include <setjmp.h>
static sigjmp_buf intr; /* where to jump on SIGINT */
#endif
static int sig_caught;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
#endif
/*ARGSUSED*/
static RETSIGTYPE
sig_catch(int sig)
{
sig_caught = 1;
#ifdef USE_SETJMP
siglongjmp(intr, 1);
#endif
}
#define MAXLEN 127
#ifndef NEW_READPASS /* ./configure --enable-readpass */
#define OLD_READPASS 1
#endif
#ifndef OLD_READPASS
static char *
readpass(FILE *fp)
{
static char input[MAXLEN + 1], asterix[MAXLEN + 1];
static char once;
char *cp, *ap, c;
int i;
if (!once) {
srandom(time(0)*getpid());
once = 1;
}
cp = input;
ap = asterix;
while (read(fileno(fp), &c, 1)) {
switch (c) {
case '\n':
case '\r':
goto endwhile;
case '\b':
case 127:
if (cp > input) {
cp--; ap--;
for (i = 0; i < (*ap); i++) {
putc('\b', stdout);
putc(' ', stdout);
putc('\b', stdout);
}
} else
putc('\a', stdout); /* BEL */
break;
default:
*cp++ = c;
*ap++ = (random() % 4)+1;
for (i = 0; i < (*(ap-1)); i++)
putc('*', stdout);
break;
}
fflush(stdout);
if (cp == input + MAXLEN)
break;
}
endwhile:
*cp = 0;
putc('\n', stdout);
return input;
}
#else
static char *
readpass(FILE *fp)
{
static char input[MAXLEN + 1];
char *cp;
if (fgets(input, sizeof input, fp) == input) {
if ((cp = strrchr(input, '\n')))
*cp = '\0';
else
input[sizeof input - 1] = '\0';
#ifdef USE_SGTTY
putc('\n', stdout);
#endif
return input;
}
return NULL;
}
#endif
char *
libshadow_getpass(const char *prompt)
{
static char nostring[1] = "";
static char *return_value;
volatile int tty_opened;
static FILE *fp;
volatile int is_tty;
#ifdef HAVE_SIGACTION
struct sigaction old_sigact;
#else
RETSIGTYPE (*old_signal)();
#endif
TERMIO new_modes;
TERMIO old_modes;
/*
* set a flag so the SIGINT signal can be re-sent if it
* is caught
*/
sig_caught = 0;
return_value = NULL;
tty_opened = 0;
/*
* if /dev/tty can't be opened, getpass() needs to read
* from stdin instead.
*/
if ((fp = fopen ("/dev/tty", "r")) == 0) {
fp = stdin;
setbuf (fp, (char *) 0);
} else {
tty_opened = 1;
}
/*
* the current tty modes must be saved so they can be
* restored later on. echo will be turned off, except
* for the newline character (BSD has to punt on this)
*/
is_tty = 1;
if (GTTY(fileno(fp), &old_modes)) {
is_tty = 0;
#if 0 /* to make getpass work with redirected stdin */
return_value = NULL;
goto out2;
#endif
}
#ifdef USE_SETJMP
/*
* If we get a SIGINT, sig_catch() will jump here -
* no need to press Enter after Ctrl-C.
*/
if (sigsetjmp(intr, 1))
goto out;
#endif
#ifdef HAVE_SIGACTION
sigact.sa_handler = sig_catch;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = 0;
sigaction(SIGINT, &sigact, &old_sigact);
#else
old_signal = signal (SIGINT, sig_catch);
#endif
new_modes = old_modes;
#ifdef USE_SGTTY
new_modes.sg_flags &= ~ECHO ;
#else
#ifdef OLD_READPASS
new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK);
#else
new_modes.c_lflag &= ~(ECHO|ECHOE|ECHOK|ICANON);
#endif
new_modes.c_lflag |= ECHONL;
#endif
if (is_tty) {
if (STTY(fileno(fp), &new_modes))
goto out;
}
/*
* the prompt is output, and the response read without
* echoing. the trailing newline must be removed. if
* the fgets() returns an error, a NULL pointer is
* returned.
*/
if ((fputs(prompt, stdout) != EOF) && (fflush(stdout) != EOF))
return_value = readpass(fp);
out:
/*
* the old SIGINT handler is restored after the tty
* modes. then /dev/tty is closed if it was opened in
* the beginning. finally, if a signal was caught it
* is sent to this process for normal processing.
*/
if (is_tty) {
if (STTY(fileno(fp), &old_modes))
return_value = NULL;
}
#ifdef HAVE_SIGACTION
(void) sigaction (SIGINT, &old_sigact, NULL);
#else
(void) signal (SIGINT, old_signal);
#endif
out2:
if (tty_opened)
(void) fclose (fp);
if (sig_caught) {
kill(getpid(), SIGINT);
return_value = NULL;
}
if (!return_value) {
nostring[0] = '\0';
return_value = nostring;
}
return return_value;
}

211
lib/grdbm.c Normal file
View File

@@ -0,0 +1,211 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifdef NDBM
#include "rcsid.h"
RCSID("$Id: grdbm.c,v 1.3 1997/12/07 23:26:52 marekm Exp $")
#include <string.h>
#include <stdio.h>
#include <grp.h>
#include "prototypes.h"
#include <ndbm.h>
extern DBM *gr_dbm;
#define GRP_FRAG 256
/*
* gr_dbm_update
*
* Updates the DBM password files, if they exist.
*/
int
gr_dbm_update(const struct group *gr)
{
datum key;
datum content;
char data[BUFSIZ*8];
char grpkey[60];
char *cp;
int len;
int i;
int cnt;
static int once;
if (! once) {
if (! gr_dbm)
setgrent ();
once++;
}
if (! gr_dbm)
return 0;
len = gr_pack (gr, data);
if (len <= GRP_FRAG) {
content.dsize = len;
content.dptr = data;
key.dsize = strlen (gr->gr_name);
key.dptr = gr->gr_name;
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
return 0;
key.dsize = sizeof gr->gr_gid;
key.dptr = (char *) &gr->gr_gid;
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
return 0;
} else {
content.dsize = sizeof cnt;
content.dptr = (char *) &cnt;
cnt = (len + (GRP_FRAG-1)) / GRP_FRAG;
key.dsize = strlen (gr->gr_name);
key.dptr = gr->gr_name;
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
return 0;
key.dsize = sizeof gr->gr_gid;
key.dptr = (char *) &gr->gr_gid;
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
return 0;
for (cp = data, i = 0;i < cnt;i++) {
content.dsize = len > GRP_FRAG ? GRP_FRAG:len;
len -= content.dsize;
content.dptr = cp;
cp += content.dsize;
key.dsize = sizeof i + strlen (gr->gr_name);
key.dptr = grpkey;
memcpy (grpkey, (char *) &i, sizeof i);
strcpy (grpkey + sizeof i, gr->gr_name);
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
return 0;
key.dsize = sizeof i + sizeof gr->gr_gid;
key.dptr = grpkey;
memcpy (grpkey, (char *) &i, sizeof i);
memcpy (grpkey + sizeof i, (char *) &gr->gr_gid,
sizeof gr->gr_gid);
if (dbm_store (gr_dbm, key, content, DBM_REPLACE))
return 0;
}
}
return 1;
}
/*
* gr_dbm_remove
*
* Deletes the DBM group file entries, if they exist.
*/
int
gr_dbm_remove(const struct group *gr)
{
datum key;
datum content;
char grpkey[60];
int i;
int cnt;
int errors = 0;
static int once;
if (! once) {
if (! gr_dbm)
setgrent ();
once++;
}
if (! gr_dbm)
return 0;
key.dsize = strlen (gr->gr_name);
key.dptr = (char *) gr->gr_name;
content = dbm_fetch (gr_dbm, key);
if (content.dptr == 0)
++errors;
else {
if (content.dsize == sizeof (int)) {
memcpy ((char *) &cnt, content.dptr, sizeof cnt);
for (i = 0;i < cnt;i++) {
key.dsize = sizeof i + strlen (gr->gr_name);
key.dptr = grpkey;
memcpy (grpkey, (char *) &i, sizeof i);
strcpy (grpkey + sizeof i, gr->gr_name);
if (dbm_delete (gr_dbm, key))
++errors;
}
} else {
if (dbm_delete (gr_dbm, key))
++errors;
}
}
key.dsize = sizeof gr->gr_gid;
key.dptr = (char *) &gr->gr_gid;
content = dbm_fetch (gr_dbm, key);
if (content.dptr == 0)
++errors;
else {
if (content.dsize == sizeof (int)) {
memcpy ((char *) &cnt, content.dptr, sizeof cnt);
for (i = 0;i < cnt;i++) {
key.dsize = sizeof i + sizeof gr->gr_gid;
key.dptr = grpkey;
memcpy (grpkey, (char *) &i, sizeof i);
memcpy (grpkey + sizeof i, (char *) &gr->gr_gid,
sizeof gr->gr_gid);
if (dbm_delete (gr_dbm, key))
++errors;
}
} else {
if (dbm_delete (gr_dbm, key))
++errors;
}
}
return errors ? 0:1;
}
int
gr_dbm_present(void)
{
return (access(GROUP_PAG_FILE, F_OK) == 0);
}
#endif

185
lib/groupio.c Normal file
View File

@@ -0,0 +1,185 @@
#include <config.h>
#include "rcsid.h"
RCSID("$Id: groupio.c,v 1.7 1998/01/29 23:22:28 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
#include "groupio.h"
extern int putgrent P_((const struct group *, FILE *));
extern struct group *sgetgrent P_((const char *));
struct group *
__gr_dup(const struct group *grent)
{
struct group *gr;
int i;
if (!(gr = (struct group *) malloc(sizeof *gr)))
return NULL;
*gr = *grent;
if (!(gr->gr_name = strdup(grent->gr_name)))
return NULL;
if (!(gr->gr_passwd = strdup(grent->gr_passwd)))
return NULL;
for (i = 0; grent->gr_mem[i]; i++)
;
gr->gr_mem = (char **) malloc((i + 1) * sizeof(char *));
if (!gr->gr_mem)
return NULL;
for (i = 0; grent->gr_mem[i]; i++) {
gr->gr_mem[i] = strdup(grent->gr_mem[i]);
if (!gr->gr_mem[i])
return NULL;
}
gr->gr_mem[i] = NULL;
return gr;
}
static void *
group_dup(const void *ent)
{
const struct group *gr = ent;
return __gr_dup(gr);
}
static void
group_free(void *ent)
{
struct group *gr = ent;
free(gr->gr_name);
free(gr->gr_passwd);
while(*(gr->gr_mem)) {
free(*(gr->gr_mem));
gr->gr_mem++;
}
free(gr);
}
static const char *
group_getname(const void *ent)
{
const struct group *gr = ent;
return gr->gr_name;
}
static void *
group_parse(const char *line)
{
return (void *) sgetgrent(line);
}
static int
group_put(const void *ent, FILE *file)
{
const struct group *gr = ent;
return (putgrent(gr, file) == -1) ? -1 : 0;
}
static struct commonio_ops group_ops = {
group_dup,
group_free,
group_getname,
group_parse,
group_put,
fgetsx,
fputsx
};
static struct commonio_db group_db = {
GROUP_FILE, /* filename */
&group_ops, /* ops */
NULL, /* fp */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0, /* readonly */
0 /* use_lckpwdf */
};
int
gr_name(const char *filename)
{
return commonio_setname(&group_db, filename);
}
int
gr_lock(void)
{
return commonio_lock(&group_db);
}
int
gr_open(int mode)
{
return commonio_open(&group_db, mode);
}
const struct group *
gr_locate(const char *name)
{
return commonio_locate(&group_db, name);
}
int
gr_update(const struct group *gr)
{
return commonio_update(&group_db, (const void *) gr);
}
int
gr_remove(const char *name)
{
return commonio_remove(&group_db, name);
}
int
gr_rewind(void)
{
return commonio_rewind(&group_db);
}
const struct group *
gr_next(void)
{
return commonio_next(&group_db);
}
int
gr_close(void)
{
return commonio_close(&group_db);
}
int
gr_unlock(void)
{
return commonio_unlock(&group_db);
}
void
__gr_set_changed(void)
{
group_db.changed = 1;
}
struct commonio_entry *
__gr_get_head(void)
{
return group_db.head;
}
void
__gr_del_entry(const struct commonio_entry *ent)
{
commonio_del_entry(&group_db, ent);
}

12
lib/groupio.h Normal file
View File

@@ -0,0 +1,12 @@
extern struct group *__gr_dup P_((const struct group *));
extern void __gr_set_changed P_((void));
extern int gr_close P_((void));
extern const struct group *gr_locate P_((const char *));
extern int gr_lock P_((void));
extern int gr_name P_((const char *));
extern const struct group *gr_next P_((void));
extern int gr_open P_((int));
extern int gr_remove P_((const char *));
extern int gr_rewind P_((void));
extern int gr_unlock P_((void));
extern int gr_update P_((const struct group *));

95
lib/grpack.c Normal file
View File

@@ -0,0 +1,95 @@
/*
* Copyright 1990, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: grpack.c,v 1.3 1997/12/07 23:26:52 marekm Exp $")
#include <stdio.h>
#include <grp.h>
#include "defines.h"
int
gr_pack(const struct group *group, char *buf)
{
char *cp;
int i;
cp = buf;
strcpy (cp, group->gr_name);
cp += strlen (cp) + 1;
strcpy (cp, group->gr_passwd);
cp += strlen (cp) + 1;
memcpy (cp, (const char *) &group->gr_gid, sizeof group->gr_gid);
cp += sizeof group->gr_gid;
for (i = 0;group->gr_mem[i];i++) {
strcpy (cp, group->gr_mem[i]);
cp += strlen (cp) + 1;
}
*cp++ = '\0';
return cp - buf;
}
int
gr_unpack(char *buf, int len, struct group *group)
{
char *org = buf;
int i;
group->gr_name = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
group->gr_passwd = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
memcpy ((char *) &group->gr_gid, (char *) buf, sizeof group->gr_gid);
buf += sizeof group->gr_gid;
if (buf - org > len)
return -1;
for (i = 0;*buf && i < 1024;i++) {
group->gr_mem[i] = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
}
group->gr_mem[i] = (char *) 0;
return 0;
}

167
lib/gsdbm.c Normal file
View File

@@ -0,0 +1,167 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#if defined(NDBM) && defined(SHADOWGRP) /*{*/
#include <string.h>
#include <stdio.h>
#include "prototypes.h"
#include "rcsid.h"
RCSID("$Id: gsdbm.c,v 1.3 1997/12/07 23:26:53 marekm Exp $")
#include <ndbm.h>
extern DBM *sg_dbm;
#define GRP_FRAG 256
/*
* sg_dbm_update
*
* Updates the DBM password files, if they exist.
*/
int
sg_dbm_update(const struct sgrp *sgr)
{
datum key;
datum content;
char data[BUFSIZ*8];
char sgrpkey[60];
char *cp;
int len;
int i;
int cnt;
static int once;
if (! once) {
if (! sg_dbm)
setsgent ();
once++;
}
if (! sg_dbm)
return 0;
len = sgr_pack (sgr, data);
if (len <= GRP_FRAG) {
content.dsize = len;
content.dptr = data;
key.dsize = strlen (sgr->sg_name);
key.dptr = sgr->sg_name;
if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
return 0;
} else {
content.dsize = sizeof cnt;
content.dptr = (char *) &cnt;
cnt = (len + (GRP_FRAG-1)) / GRP_FRAG;
key.dsize = strlen (sgr->sg_name);
key.dptr = sgr->sg_name;
if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
return 0;
for (cp = data, i = 0;i < cnt;i++) {
content.dsize = len > GRP_FRAG ? GRP_FRAG:len;
len -= content.dsize;
content.dptr = cp;
cp += content.dsize;
key.dsize = sizeof i + strlen (sgr->sg_name);
key.dptr = sgrpkey;
memcpy (sgrpkey, (char *) &i, sizeof i);
strcpy (sgrpkey + sizeof i, sgr->sg_name);
if (dbm_store (sg_dbm, key, content, DBM_REPLACE))
return 0;
}
}
return 1;
}
/*
* sg_dbm_remove
*
* Deletes the DBM shadow group file entries, if they exist.
*/
int
sg_dbm_remove(const char *name)
{
datum key;
datum content;
char grpkey[60];
int i;
int cnt;
int errors = 0;
static int once;
if (! once) {
if (! sg_dbm)
setsgent ();
once++;
}
if (! sg_dbm)
return 0;
key.dsize = strlen (name);
key.dptr = name;
content = dbm_fetch (sg_dbm, key);
if (content.dptr == 0)
++errors;
else {
if (content.dsize == sizeof (int)) {
memcpy ((char *) &cnt, content.dptr, sizeof cnt);
for (i = 0;i < cnt;i++) {
key.dsize = sizeof i + strlen (name);
key.dptr = grpkey;
memcpy (grpkey, (char *) &i, sizeof i);
strcpy (grpkey + sizeof i, name);
if (dbm_delete (sg_dbm, key))
++errors;
}
} else {
if (dbm_delete (sg_dbm, key))
++errors;
}
}
return errors ? 0:1;
}
int
sg_dbm_present(void)
{
return (access(SGROUP_PAG_FILE, F_OK) == 0);
}
#endif /*} SHADOWGRP && NDBM */

528
lib/gshadow.c Normal file
View File

@@ -0,0 +1,528 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{*/
#include "rcsid.h"
RCSID("$Id: gshadow.c,v 1.6 1998/04/02 21:51:43 marekm Exp $")
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
#ifdef NDBM
#include <ndbm.h>
#include <fcntl.h>
DBM *sg_dbm;
int sg_dbm_mode = -1;
static int dbmopened;
static int dbmerror;
#endif
#define MAXMEM 1024
static FILE *shadow;
static char sgrbuf[BUFSIZ*4];
static char *members[MAXMEM+1];
static char *admins[MAXMEM+1];
static struct sgrp sgroup;
extern char *fgetsx();
extern int fputsx();
#define FIELDS 4
#ifdef USE_NIS
static int nis_used;
static int nis_ignore;
static enum { native, start, middle, native2 } nis_state;
static int nis_bound;
static char *nis_domain;
static char *nis_key;
static int nis_keylen;
static char *nis_val;
static int nis_vallen;
#define IS_NISCHAR(c) ((c)=='+')
#endif
#ifdef USE_NIS
/*
* __setsgNIS - turn on or off NIS searches
*/
void
__setsgNIS(int flag)
{
nis_ignore = ! flag;
if (nis_ignore)
nis_used = 0;
}
/*
* bind_nis - bind to NIS server
*/
static int
bind_nis(void)
{
if (yp_get_default_domain (&nis_domain))
return -1;
nis_bound = 1;
return 0;
}
#endif
static char **
list(char *s, char **l)
{
int nmembers = 0;
while (s && *s) {
l[nmembers++] = s;
if ((s = strchr (s, ',')))
*s++ = '\0';
}
l[nmembers] = (char *) 0;
return l;
}
void
setsgent(void)
{
#ifdef NDBM
int mode;
#endif /* NDBM */
#ifdef USE_NIS
nis_state = native;
#endif
if (shadow)
rewind (shadow);
else
shadow = fopen(SGROUP_FILE, "r");
/*
* Attempt to open the DBM files if they have never been opened
* and an error has never been returned.
*/
#ifdef NDBM
if (! dbmerror && ! dbmopened) {
char dbmfiles[BUFSIZ];
strcpy (dbmfiles, SGROUP_PAG_FILE);
if (sg_dbm_mode == -1)
mode = O_RDWR;
else
mode = (sg_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY;
if (access(dbmfiles, F_OK) ||
(! (sg_dbm = dbm_open(SGROUP_FILE, mode, 0))))
dbmerror = 1;
else
dbmopened = 1;
}
#endif /* NDBM */
}
void
endsgent(void)
{
if (shadow)
(void) fclose (shadow);
shadow = (FILE *) 0;
#ifdef NDBM
if (dbmopened && sg_dbm) {
dbm_close (sg_dbm);
dbmopened = 0;
sg_dbm = 0;
}
#endif
}
struct sgrp *
sgetsgent(const char *string)
{
char *fields[FIELDS];
char *cp;
int i;
strncpy (sgrbuf, string, (int) sizeof sgrbuf - 1);
sgrbuf[sizeof sgrbuf - 1] = '\0';
if ((cp = strrchr (sgrbuf, '\n')))
*cp = '\0';
/*
* There should be exactly 4 colon separated fields. Find
* all 4 of them and save the starting addresses in fields[].
*/
for (cp = sgrbuf, i = 0;i < FIELDS && cp;i++) {
fields[i] = cp;
if ((cp = strchr (cp, ':')))
*cp++ = '\0';
}
/*
* If there was an extra field somehow, or perhaps not enough,
* the line is invalid.
*/
if (cp || i != FIELDS)
#ifdef USE_NIS
if (! IS_NISCHAR (fields[0][0]))
return 0;
else
nis_used = 1;
#else
return 0;
#endif
sgroup.sg_name = fields[0];
sgroup.sg_passwd = fields[1];
sgroup.sg_adm = list (fields[2], admins);
sgroup.sg_mem = list (fields[3], members);
return &sgroup;
}
/*
* fgetsgent - convert next line in stream to (struct sgrp)
*
* fgetsgent() reads the next line from the provided stream and
* converts it to a (struct sgrp). NULL is returned on EOF.
*/
struct sgrp *
fgetsgent(FILE *fp)
{
char buf[sizeof sgrbuf];
char *cp;
if (! fp)
return (0);
#ifdef USE_NIS
while (fgetsx (buf, sizeof buf, fp) != (char *) 0)
#else
if (fgetsx (buf, sizeof buf, fp) != (char *) 0)
#endif
{
if ((cp = strchr (buf, '\n')))
*cp = '\0';
#ifdef USE_NIS
if (nis_ignore && IS_NISCHAR (buf[0]))
continue;
#endif
return (sgetsgent (buf));
}
return 0;
}
/*
* getsgent - get a single shadow group entry
*/
struct sgrp *
getsgent(void)
{
#ifdef USE_NIS
int nis_1_group = 0;
struct sgrp *val;
char buf[BUFSIZ];
#endif
if (! shadow)
setsgent ();
#ifdef USE_NIS
again:
/*
* See if we are reading from the local file.
*/
if (nis_state == native || nis_state == native2) {
/*
* Get the next entry from the shadow group file. Return
* NULL right away if there is none.
*/
if (! (val = fgetsgent (shadow)))
return 0;
/*
* If this entry began with a NIS escape character, we have
* to see if this is just a single group, or if the entire
* map is being asked for.
*/
if (IS_NISCHAR (val->sg_name[0])) {
if (val->sg_name[1])
nis_1_group = 1;
else
nis_state = start;
}
/*
* If this isn't a NIS group and this isn't an escape to go
* use a NIS map, it must be a regular local group.
*/
if (nis_1_group == 0 && nis_state != start)
return val;
/*
* If this is an escape to use an NIS map, switch over to
* that bunch of code.
*/
if (nis_state == start)
goto again;
/*
* NEEDSWORK. Here we substitute pieces-parts of this entry.
*/
return 0;
} else {
if (nis_bound == 0) {
if (bind_nis ()) {
nis_state = native2;
goto again;
}
}
if (nis_state == start) {
if (yp_first (nis_domain, "gshadow.byname", &nis_key,
&nis_keylen, &nis_val, &nis_vallen)) {
nis_state = native2;
goto again;
}
nis_state = middle;
} else if (nis_state == middle) {
if (yp_next (nis_domain, "gshadow.byname", nis_key,
nis_keylen, &nis_key, &nis_keylen,
&nis_val, &nis_vallen)) {
nis_state = native2;
goto again;
}
}
return sgetsgent (nis_val);
}
#else
return (fgetsgent (shadow));
#endif
}
/*
* getsgnam - get a shadow group entry by name
*/
struct sgrp *
getsgnam(const char *name)
{
struct sgrp *sgrp;
#ifdef NDBM
datum key;
datum content;
#endif
#ifdef USE_NIS
char buf[BUFSIZ];
static char save_name[16];
int nis_disabled = 0;
#endif
setsgent ();
#ifdef NDBM
/*
* If the DBM file are now open, create a key for this group and
* try to fetch the entry from the database. A matching record
* will be unpacked into a static structure and returned to
* the user.
*/
if (dbmopened) {
key.dsize = strlen (name);
key.dptr = (void *) name;
content = dbm_fetch (sg_dbm, key);
if (content.dptr != 0) {
memcpy (sgrbuf, content.dptr, content.dsize);
sgroup.sg_mem = members;
sgroup.sg_adm = admins;
sgr_unpack (sgrbuf, content.dsize, &sgroup);
return &sgroup;
}
}
#endif
#ifdef USE_NIS
if (nis_used) {
again:
/*
* Search the gshadow.byname map for this group.
*/
if (! nis_bound)
bind_nis ();
if (nis_bound) {
char *cp;
if (yp_match (nis_domain, "gshadow.byname", name,
strlen (name), &nis_val, &nis_vallen) == 0) {
if (cp = strchr (nis_val, '\n'))
*cp = '\0';
nis_state = middle;
if (sgrp = sgetsgent (nis_val)) {
strcpy (save_name, sgrp->sg_name);
nis_key = save_name;
nis_keylen = strlen (save_name);
}
return sgrp;
}
}
nis_state = native2;
}
#endif
#ifdef USE_NIS
if (nis_used) {
nis_ignore++;
nis_disabled++;
}
#endif
while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
if (strcmp (name, sgrp->sg_name) == 0)
break;
}
#ifdef USE_NIS
nis_ignore--;
#endif
if (sgrp)
return sgrp;
return (0);
}
/*
* putsgent - output shadow group entry in text form
*
* putsgent() converts the contents of a (struct sgrp) to text and
* writes the result to the given stream. This is the logical
* opposite of fgetsgent.
*/
int
putsgent(const struct sgrp *sgrp, FILE *fp)
{
char *buf, *cp;
int i;
size_t size;
if (! fp || ! sgrp)
return -1;
/* calculate the required buffer size */
size = strlen(sgrp->sg_name) + strlen(sgrp->sg_passwd) + 10;
for (i = 0; sgrp->sg_adm && sgrp->sg_adm[i]; i++)
size += strlen(sgrp->sg_adm[i]) + 1;
for (i = 0; sgrp->sg_mem && sgrp->sg_mem[i]; i++)
size += strlen(sgrp->sg_mem[i]) + 1;
buf = malloc(size);
if (!buf)
return -1;
cp = buf;
/*
* Copy the group name and passwd.
*/
strcpy (cp, sgrp->sg_name);
cp += strlen (cp);
*cp++ = ':';
strcpy (cp, sgrp->sg_passwd);
cp += strlen (cp);
*cp++ = ':';
/*
* Copy the administrators, separating each from the other
* with a ",".
*/
for (i = 0;sgrp->sg_adm[i];i++) {
if (i > 0)
*cp++ = ',';
strcpy (cp, sgrp->sg_adm[i]);
cp += strlen (cp);
}
*cp++ = ':';
/*
* Now do likewise with the group members.
*/
for (i = 0;sgrp->sg_mem[i];i++) {
if (i > 0)
*cp++ = ',';
strcpy (cp, sgrp->sg_mem[i]);
cp += strlen (cp);
}
*cp++ = '\n';
*cp = '\0';
/*
* Output using the function which understands the line
* continuation conventions.
*/
if (fputsx(buf, fp) == EOF) {
free(buf);
return -1;
}
free(buf);
return 0;
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /*} SHADOWGRP */

71
lib/gshadow_.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* Copyright 1988 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: gshadow_.h,v 1.2 1997/05/01 23:14:41 marekm Exp $
*/
#ifndef _H_GSHADOW
#define _H_GSHADOW
/*
* Shadow group security file structure
*/
struct sgrp {
char *sg_name; /* group name */
char *sg_passwd; /* group password */
char **sg_adm; /* group administator list */
char **sg_mem; /* group membership list */
};
/*
* Shadow group security file functions.
*/
#include <stdio.h> /* for FILE */
#if __STDC__
struct sgrp *getsgent (void);
struct sgrp *getsgnam (const char *);
struct sgrp *sgetsgent (const char *);
struct sgrp *fgetsgent (FILE *);
void setsgent (void);
void endsgent (void);
int putsgent (const struct sgrp *, FILE *);
#else
struct sgrp *getsgent ();
struct sgrp *getsgnam ();
struct sgrp *sgetsgent ();
struct sgrp *fgetsgent ();
void setsgent ();
void endsgent ();
int putsgent ();
#endif
#define GSHADOW "/etc/gshadow"
#endif /* ifndef _H_GSHADOW */

150
lib/gspack.c Normal file
View File

@@ -0,0 +1,150 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifdef SHADOWGRP /*{*/
#include "rcsid.h"
RCSID("$Id: gspack.c,v 1.3 1997/12/07 23:26:53 marekm Exp $")
#include <stdio.h>
#include "defines.h"
/*
* sgr_pack - convert a shadow group structure to a packed
* shadow group record
*
* sgr_pack takes the shadow group structure and packs
* the components in a record. this record will be
* unpacked later by sgr_unpack.
*/
int
sgr_pack(const struct sgrp *sgrp, char *buf)
{
char *cp;
int i;
/*
* The name and password are both easy - append each string
* to the buffer. These are always the first two strings
* in a record.
*/
cp = buf;
strcpy (cp, sgrp->sg_name);
cp += strlen (cp) + 1;
strcpy (cp, sgrp->sg_passwd);
cp += strlen (cp) + 1;
/*
* The arrays of administrators and members are slightly
* harder. Each element is appended as a string, with a
* final '\0' appended to serve as a blank string. The
* number of elements is not known in advance, so the
* entire collection of administrators must be scanned to
* find the start of the members.
*/
for (i = 0;sgrp->sg_adm[i];i++) {
strcpy (cp, sgrp->sg_adm[i]);
cp += strlen (cp) + 1;
}
*cp++ = '\0';
for (i = 0;sgrp->sg_mem[i];i++) {
strcpy (cp, sgrp->sg_mem[i]);
cp += strlen (cp) + 1;
}
*cp++ = '\0';
return cp - buf;
}
/*
* sgr_unpack - convert a packed shadow group record to an
* unpacked record
*
* sgr_unpack converts a record which was packed by sgr_pack
* into the normal shadow group structure format.
*/
int
sgr_unpack(char *buf, int len, struct sgrp *sgrp)
{
char *org = buf;
int i;
/*
* The name and password are both easy - they are the first
* two strings in the record.
*/
sgrp->sg_name = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
sgrp->sg_passwd = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
/*
* The administrators and members are slightly more difficult.
* The arrays are lists of strings. Each list is terminated
* by a string of length zero. This string is detected by
* looking for an initial character of '\0'.
*/
for (i = 0;*buf && i < 1024;i++) {
sgrp->sg_adm[i] = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
}
sgrp->sg_adm[i] = (char *) 0;
if (! *buf)
buf++;
for (i = 0;*buf && i < 1024;i++) {
sgrp->sg_mem[i] = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
}
sgrp->sg_mem[i] = (char *) 0;
return 0;
}
#endif /*}*/

50
lib/lastlog_.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* lastlog.h - structure of lastlog file
*
* $Id: lastlog_.h,v 1.2 1997/05/01 23:14:42 marekm Exp $
*
* This file defines a lastlog file structure which should be sufficient
* to hold the information required by login. It should only be used if
* there is no real lastlog.h file.
*/
#ifndef __LASTLOG_H
#define __LASTLOG_H
struct lastlog {
time_t ll_time;
char ll_line[12];
char ll_host[16];
};
#define HAVE_LL_HOST
#endif /* _LASTLOG_H */

114
lib/lockpw.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright 1992, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifndef HAVE_LCKPWDF
#include "rcsid.h"
RCSID("$Id: lockpw.c,v 1.4 1998/01/29 23:22:28 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
#include "pwio.h"
#ifdef SHADOWPWD
#include "shadowio.h"
#endif
/*
* lckpwdf - lock the password files
*/
int
lckpwdf(void)
{
int i;
/*
* We have 15 seconds to lock the whole mess
*/
for (i = 0;i < 15;i++)
if (pw_lock ())
break;
else
sleep (1);
/*
* Did we run out of time?
*/
if (i == 15)
return -1;
/*
* Nope, use any remaining time to lock the shadow password
* file.
*/
for (;i < 15;i++)
if (spw_lock ())
break;
else
sleep (1);
/*
* Out of time yet?
*/
if (i == 15) {
pw_unlock ();
return -1;
}
/*
* Nope - and both files are now locked.
*/
return 0;
}
/*
* ulckpwdf - unlock the password files
*/
int
ulckpwdf(void)
{
/*
* Unlock both files.
*/
return (pw_unlock () && spw_unlock ()) ? 0:-1;
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

261
lib/md5.c Normal file
View File

@@ -0,0 +1,261 @@
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
#include <config.h>
#ifdef MD5_CRYPT
#include <string.h> /* for memcpy() */
#include "md5.h"
#ifndef HIGHFIRST
#define byteReverse(buf, len) /* Nothing */
#else
void byteReverse(unsigned char *buf, unsigned longs);
#ifndef ASM_MD5
/*
* Note: this code is harmless on little-endian machines.
*/
void
byteReverse(unsigned char *buf, unsigned longs)
{
uint32 t;
do {
t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(uint32 *) buf = t;
buf += 4;
} while (--longs);
}
#endif
#endif
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
MD5Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
{
uint32 t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
MD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;
/* Compute number of bytes mod 64 */
count = (ctx->bits[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = ctx->in + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
MD5Transform(ctx->buf, (uint32 *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
((uint32 *) ctx->in)[14] = ctx->bits[0];
((uint32 *) ctx->in)[15] = ctx->bits[1];
MD5Transform(ctx->buf, (uint32 *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset((char *) ctx, 0, sizeof(ctx)); /* In case it's sensitive */
}
#ifndef ASM_MD5
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
MD5Transform(uint32 buf[4], uint32 const in[16])
{
register uint32 a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif
#endif /* MD5_CRYPT */

27
lib/md5.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef MD5_H
#define MD5_H
#ifdef __alpha
typedef unsigned int uint32;
#else
typedef unsigned long uint32;
#endif
struct MD5Context {
uint32 buf[4];
uint32 bits[2];
unsigned char in[64];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf,
unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Transform(uint32 buf[4], uint32 const in[16]);
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
*/
typedef struct MD5Context MD5_CTX;
#endif /* !MD5_H */

151
lib/md5crypt.c Normal file
View File

@@ -0,0 +1,151 @@
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*/
/*
* Ported from FreeBSD to Linux, only minimal changes. --marekm
*/
#include <config.h>
#ifdef MD5_CRYPT
#include "rcsid.h"
RCSID("$Id: md5crypt.c,v 1.3 1998/01/29 23:22:29 marekm Exp $")
#include <unistd.h>
/* #include <stdio.h> */
#include <string.h>
#include "md5.h"
static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static void
to64(char *s, unsigned long v, int n)
{
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
v >>= 6;
}
}
/*
* UNIX password
*
* Use MD5 for what it is best at...
*/
char *
libshadow_md5_crypt(const char *pw, const char *salt)
{
static char *magic = "$1$"; /*
* This string is magic for
* this algorithm. Having
* it this way, we can get
* get better later on
*/
static char passwd[120], *p;
static const char *sp,*ep;
unsigned char final[16];
int sl,pl,i,j;
MD5_CTX ctx,ctx1;
unsigned long l;
/* Refine the Salt first */
sp = salt;
/* If it starts with the magic string, then skip that */
if(!strncmp(sp,magic,strlen(magic)))
sp += strlen(magic);
/* It stops at the first '$', max 8 chars */
for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)
continue;
/* get the length of the true salt */
sl = ep - sp;
MD5Init(&ctx);
/* The password first, since that is what is most unknown */
MD5Update(&ctx,pw,strlen(pw));
/* Then our magic string */
MD5Update(&ctx,magic,strlen(magic));
/* Then the raw salt */
MD5Update(&ctx,sp,sl);
/* Then just as many characters of the MD5(pw,salt,pw) */
MD5Init(&ctx1);
MD5Update(&ctx1,pw,strlen(pw));
MD5Update(&ctx1,sp,sl);
MD5Update(&ctx1,pw,strlen(pw));
MD5Final(final,&ctx1);
for(pl = strlen(pw); pl > 0; pl -= 16)
MD5Update(&ctx,final,pl>16 ? 16 : pl);
/* Don't leave anything around in vm they could use. */
memset(final,0,sizeof final);
/* Then something really weird... */
for (j=0,i = strlen(pw); i ; i >>= 1)
if(i&1)
MD5Update(&ctx, final+j, 1);
else
MD5Update(&ctx, pw+j, 1);
/* Now make the output string */
strcpy(passwd,magic);
strncat(passwd,sp,sl);
strcat(passwd,"$");
MD5Final(final,&ctx);
/*
* and now, just to make sure things don't run too fast
* On a 60 Mhz Pentium this takes 34 msec, so you would
* need 30 seconds to build a 1000 entry dictionary...
*/
for(i=0;i<1000;i++) {
MD5Init(&ctx1);
if(i & 1)
MD5Update(&ctx1,pw,strlen(pw));
else
MD5Update(&ctx1,final,16);
if(i % 3)
MD5Update(&ctx1,sp,sl);
if(i % 7)
MD5Update(&ctx1,pw,strlen(pw));
if(i & 1)
MD5Update(&ctx1,final,16);
else
MD5Update(&ctx1,pw,strlen(pw));
MD5Final(final,&ctx1);
}
p = passwd + strlen(passwd);
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4;
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4;
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4;
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4;
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4;
l = final[11] ; to64(p,l,2); p += 2;
*p = '\0';
/* Don't leave anything around in vm they could use. */
memset(final,0,sizeof final);
return passwd;
}
#endif

60
lib/mkdir.c Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright 1991, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include <fcntl.h>
#include "rcsid.h"
RCSID("$Id: mkdir.c,v 1.4 1998/01/29 23:22:30 marekm Exp $")
/*
* mkdir - create a directory
*
* mkdir is provided for systems which do not include the mkdir()
* system call.
*/
int
mkdir(const char *dir, int mode)
{
int status;
if (fork()) {
while (wait(&status) != -1)
;
return status >> 8;
}
close(2);
open("/dev/null", O_WRONLY);
umask(0777 & ~ mode);
execl("/bin/mkdir", "mkdir", dir, 0);
_exit(127);
/*NOTREACHED*/
}

21
lib/pam_defs.h Normal file
View File

@@ -0,0 +1,21 @@
#include <security/pam_appl.h>
#include <security/pam_misc.h>
/* compatibility with different versions of Linux-PAM */
#ifndef PAM_ESTABLISH_CRED
#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH
#endif
#ifndef PAM_DELETE_CRED
#define PAM_DELETE_CRED PAM_CRED_DELETE
#endif
#ifndef PAM_NEW_AUTHTOK_REQD
#define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD
#endif
#ifndef PAM_DATA_SILENT
#define PAM_DATA_SILENT 0
#endif
#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
#else
#define PAM_STRERROR(pamh, err) pam_strerror(err)
#endif

439
lib/port.c Normal file
View File

@@ -0,0 +1,439 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: port.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "defines.h"
#include "port.h"
extern int errno;
static FILE *ports;
/*
* portcmp - compare the name of a port to a /etc/porttime entry
*
* portcmp works like strcmp, except that if the last character
* in a failing match is a '*', the match is considered to have
* passed. The "*" match is suppressed whenever the port is "SU",
* which is the token the "su" command uses to validate access.
* A match returns 0, failure returns non-zero.
*/
static int
portcmp(const char *pattern, const char *port)
{
const char *orig = port;
while (*pattern && *pattern == *port)
pattern++, port++;
if (*pattern == 0 && *port == 0)
return 0;
if (orig[0] == 'S' && orig[1] == 'U' && orig[2] == '\0')
return 1;
return *pattern == '*' ? 0:1;
}
/*
* setportent - open /etc/porttime file or rewind
*
* the /etc/porttime file is rewound if already open, or
* opened for reading.
*/
static void
setportent(void)
{
if (ports)
rewind (ports);
else
ports = fopen (PORTS, "r");
}
/*
* endportent - close the /etc/porttime file
*
* the /etc/porttime file is closed and the ports variable set
* to NULL to indicate that the /etc/porttime file is no longer
* open.
*/
static void
endportent(void)
{
if (ports)
fclose (ports);
ports = (FILE *) 0;
}
/*
* getportent - read a single entry from /etc/porttime
*
* the next line in /etc/porttime is converted to a (struct port)
* and a pointer to a static (struct port) is returned to the
* invoker. NULL is returned on either EOF or error. errno is
* set to EINVAL on error to distinguish the two conditions.
*/
static struct port *
getportent(void)
{
static struct port port; /* static struct to point to */
static char buf[BUFSIZ]; /* some space for stuff */
static char *ttys[PORT_TTY+1]; /* some pointers to tty names */
static char *users[PORT_IDS+1]; /* some pointers to user ids */
static struct pt_time ptimes[PORT_TIMES+1]; /* time ranges */
char *cp; /* pointer into line */
int dtime; /* scratch time of day */
int i, j;
int saveerr = errno; /* errno value on entry */
/*
* If the ports file is not open, open the file. Do not rewind
* since we want to search from the beginning each time.
*/
if (! ports)
setportent ();
if (! ports) {
errno = saveerr;
return 0;
}
/*
* Common point for beginning a new line -
*
* - read a line, and NUL terminate
* - skip lines which begin with '#'
* - parse off the tty names
* - parse off a list of user names
* - parse off a list of days and times
*/
again:
/*
* Get the next line and remove the last character, which
* is a '\n'. Lines which begin with '#' are all ignored.
*/
if (fgets (buf, sizeof buf, ports) == 0) {
errno = saveerr;
return 0;
}
if (buf[0] == '#')
goto again;
/*
* Get the name of the TTY device. It is the first colon
* separated field, and is the name of the TTY with no
* leading "/dev". The entry '*' is used to specify all
* TTY devices.
*/
buf[strlen (buf) - 1] = 0;
port.pt_names = ttys;
for (cp = buf, j = 0;j < PORT_TTY;j++) {
port.pt_names[j] = cp;
while (*cp && *cp != ':' && *cp != ',')
cp++;
if (! *cp)
goto again; /* line format error */
if (*cp == ':') /* end of tty name list */
break;
if (*cp == ',') /* end of current tty name */
*cp++ = '\0';
}
*cp++ = 0;
port.pt_names[j + 1] = (char *) 0;
/*
* Get the list of user names. It is the second colon
* separated field, and is a comma separated list of user
* names. The entry '*' is used to specify all usernames.
* The last entry in the list is a (char *) 0 pointer.
*/
if (*cp != ':') {
port.pt_users = users;
port.pt_users[0] = cp;
for (j = 1;*cp != ':';cp++) {
if (*cp == ',' && j < PORT_IDS) {
*cp++ = 0;
port.pt_users[j++] = cp;
}
}
port.pt_users[j] = 0;
} else
port.pt_users = 0;
if (*cp != ':')
goto again;
*cp++ = 0;
/*
* Get the list of valid times. The times field is the third
* colon separated field and is a list of days of the week and
* times during which this port may be used by this user. The
* valid days are 'Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', and 'Sa'.
*
* In addition, the value 'Al' represents all 7 days, and 'Wk'
* represents the 5 weekdays.
*
* Times are given as HHMM-HHMM. The ending time may be before
* the starting time. Days are presumed to wrap at 0000.
*/
if (*cp == '\0') {
port.pt_times = 0;
return &port;
}
port.pt_times = ptimes;
/*
* Get the next comma separated entry
*/
for (j = 0;*cp && j < PORT_TIMES;j++) {
/*
* Start off with no days of the week
*/
port.pt_times[j].t_days = 0;
/*
* Check each two letter sequence to see if it is
* one of the abbreviations for the days of the
* week or the other two values.
*/
for (i = 0;cp[i] && cp[i + 1] && isalpha (cp[i]);i += 2) {
switch ((cp[i] << 8) | (cp[i + 1])) {
case ('S' << 8) | 'u':
port.pt_times[j].t_days |= 01;
break;
case ('M' << 8) | 'o':
port.pt_times[j].t_days |= 02;
break;
case ('T' << 8) | 'u':
port.pt_times[j].t_days |= 04;
break;
case ('W' << 8) | 'e':
port.pt_times[j].t_days |= 010;
break;
case ('T' << 8) | 'h':
port.pt_times[j].t_days |= 020;
break;
case ('F' << 8) | 'r':
port.pt_times[j].t_days |= 040;
break;
case ('S' << 8) | 'a':
port.pt_times[j].t_days |= 0100;
break;
case ('W' << 8) | 'k':
port.pt_times[j].t_days |= 076;
break;
case ('A' << 8) | 'l':
port.pt_times[j].t_days |= 0177;
break;
default:
errno = EINVAL;
return 0;
}
}
/*
* The default is 'Al' if no days were seen.
*/
if (i == 0)
port.pt_times[j].t_days = 0177;
/*
* The start and end times are separated from each
* other by a '-'. The times are four digit numbers
* representing the times of day.
*/
for (dtime = 0;cp[i] && isdigit (cp[i]);i++)
dtime = dtime * 10 + cp[i] - '0';
if (cp[i] != '-' || dtime > 2400 || dtime % 100 > 59)
goto again;
port.pt_times[j].t_start = dtime;
cp = cp + i + 1;
for (dtime = i = 0;cp[i] && isdigit (cp[i]);i++)
dtime = dtime * 10 + cp[i] - '0';
if ((cp[i] != ',' && cp[i]) ||
dtime > 2400 || dtime % 100 > 59)
goto again;
port.pt_times[j].t_end = dtime;
cp = cp + i + 1;
}
/*
* The end of the list is indicated by a pair of -1's for the
* start and end times.
*/
port.pt_times[j].t_start = port.pt_times[j].t_end = -1;
return &port;
}
/*
* getttyuser - get ports information for user and tty
*
* getttyuser() searches the ports file for an entry with a TTY
* and user field both of which match the supplied TTY and
* user name. The file is searched from the beginning, so the
* entries are treated as an ordered list.
*/
static struct port *
getttyuser(const char *tty, const char *user)
{
int i, j;
struct port *port;
setportent ();
while ((port = getportent ())) {
if (port->pt_names == 0 || port->pt_users == 0)
continue;
for (i = 0;port->pt_names[i];i++)
if (portcmp (port->pt_names[i], tty) == 0)
break;
if (port->pt_names[i] == 0)
continue;
for (j = 0;port->pt_users[j];j++)
if (strcmp (user, port->pt_users[j]) == 0 ||
strcmp (port->pt_users[j], "*") == 0)
break;
if (port->pt_users[j] != 0)
break;
}
endportent ();
return port;
}
/*
* isttytime - tell if a given user may login at a particular time
*
* isttytime searches the ports file for an entry which matches
* the user name and TTY given.
*/
int
isttytime(const char *id, const char *port, time_t when)
{
int i;
int dtime;
struct port *pp;
struct tm *tm;
/*
* Try to find a matching entry for this user. Default to
* letting the user in - there are pleny of ways to have an
* entry to match all users.
*/
if (! (pp = getttyuser (port, id)))
return 1;
/*
* The entry is there, but has no time entries - don't
* ever let them login.
*/
if (pp->pt_times == 0)
return 0;
/*
* The current time is converted to HHMM format for
* comparision against the time values in the TTY entry.
*/
tm = localtime (&when);
dtime = tm->tm_hour * 100 + tm->tm_min;
/*
* Each time entry is compared against the current
* time. For entries with the start after the end time,
* the comparision is made so that the time is between
* midnight and either the start or end time.
*/
for (i = 0;pp->pt_times[i].t_start != -1;i++) {
if (! (pp->pt_times[i].t_days & PORT_DAY(tm->tm_wday)))
continue;
if (pp->pt_times[i].t_start <= pp->pt_times[i].t_end) {
if (dtime >= pp->pt_times[i].t_start &&
dtime <= pp->pt_times[i].t_end)
return 1;
} else {
if (dtime >= pp->pt_times[i].t_start ||
dtime <= pp->pt_times[i].t_end)
return 1;
}
}
/*
* No matching time entry was found, user shouldn't
* be let in right now.
*/
return 0;
}

81
lib/port.h Normal file
View File

@@ -0,0 +1,81 @@
/*
* Copyright 1989 - 1991, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* port.h - structure of /etc/porttime
*
* $Id: port.h,v 1.2 1997/05/01 23:14:43 marekm Exp $
*
* Each entry in /etc/porttime consists of a TTY device
* name or "*" to indicate all TTY devices, followed by
* a list of 1 or more user IDs or "*" to indicate all
* user names, followed by a list of zero or more valid
* login times. Login time entries consist of zero or
* more day names (Su, Mo, Tu, We, Th, Fr, Sa, Wk, Al)
* followed by a pair of time values in HHMM format
* separated by a "-".
*/
/*
* PORTS - Name of system port access time file.
* PORT_IDS - Allowable number of IDs per entry.
* PORT_TTY - Allowable number of TTYs per entry.
* PORT_TIMES - Allowable number of time entries per entry.
* PORT_DAY - Day of the week to a bit value (0 = Sunday).
*/
#define PORTS "/etc/porttime"
#define PORT_IDS 64
#define PORT_TTY 64
#define PORT_TIMES 24
#define PORT_DAY(day) (1<<(day))
/*
* pt_names - pointer to array of device names in /dev/
* pt_users - pointer to array of applicable user IDs.
* pt_times - pointer to list of allowable time periods.
*/
struct port {
char **pt_names;
char **pt_users;
struct pt_time *pt_times;
};
/*
* t_days - bit array for each day of the week (0 = Sunday)
* t_start - starting time for this entry
* t_end - ending time for this entry
*/
struct pt_time {
short t_days;
short t_start;
short t_end;
};

213
lib/prototypes.h Normal file
View File

@@ -0,0 +1,213 @@
/*
* prototypes.h
*
* Missing function prototypes
*
* Juha Virtanen, <jiivee@hut.fi>; November 1995
*/
/*
* $Id: prototypes.h,v 1.13 1999/07/09 18:02:43 marekm Exp $
*
* Added a macro to work around ancient (non-ANSI) compilers, just in case
* someone ever tries to compile this with SunOS cc... --marekm
*/
#ifndef _PROTOTYPES_H
#define _PROTOTYPES_H
#include <sys/stat.h>
#include <utmp.h>
#include <pwd.h>
#include <grp.h>
#include "defines.h"
/* addgrps.c */
extern int add_groups P_((const char *));
extern void add_cons_grps P_((void));
/* age.c */
#ifdef SHADOWPWD
extern void agecheck P_((const struct passwd *pw, const struct spwd *sp));
extern int expire P_((const struct passwd *pw, const struct spwd *sp));
extern int isexpired P_((const struct passwd *pw, const struct spwd *sp));
#else
extern void agecheck P_((const struct passwd *pw));
extern int expire P_((const struct passwd *pw));
extern int isexpired P_((const struct passwd *pw));
#endif
/* basename() renamed to Basename() to avoid libc name space confusion */
/* basename.c */
extern char *Basename P_((char *str));
/* chkshell.c */
extern int check_shell P_((const char *));
/* chowndir.c */
extern int chown_tree P_((const char *, uid_t, uid_t, gid_t, gid_t));
/* chowntty.c */
extern void chown_tty P_((const char *, const struct passwd *));
/* console.c */
extern int console P_((const char *tty));
extern int is_listed P_((const char *cfgin, const char *tty, int def));
/* copydir.c */
extern int copy_tree P_((const char *, const char *, uid_t, gid_t));
extern int remove_tree P_((const char *));
/* encrypt.c */
extern char *pw_encrypt P_((const char *, const char *));
/* entry.c */
extern void entry P_((const char *name, struct passwd *pwent));
/* env.c */
extern void addenv P_((const char *, const char *));
extern void initenv P_((void));
extern void set_env P_((int, char * const *));
extern void sanitize_env P_((void));
/* fields.c */
extern void change_field P_((char *buf, size_t maxsize, const char *prompt));
extern int valid_field P_((const char *field, const char *illegal));
/* fputsx.c */
extern char *fgetsx P_((char *, int, FILE *));
extern int fputsx P_((const char *, FILE *));
/* grdbm.c */
extern int gr_dbm_remove P_((const struct group *gr));
extern int gr_dbm_update P_((const struct group *gr));
extern int gr_dbm_present P_((void));
/* grent.c */
extern int putgrent P_((const struct group *, FILE *));
/* grpack.c */
extern int gr_pack P_((const struct group *group, char *buf));
extern int gr_unpack P_((char *buf, int len, struct group *group));
#ifdef SHADOWGRP
/* gsdbm.c */
extern int sg_dbm_remove P_((const char *name));
extern int sg_dbm_update P_((const struct sgrp *sgr));
extern int sg_dbm_present P_((void));
/* gspack.c */
extern int sgr_pack P_((const struct sgrp *sgrp, char *buf));
extern int sgr_unpack P_((char *buf, int len, struct sgrp *sgrp));
#endif
/* hushed.c */
extern int hushed P_((const struct passwd *pw));
/* limits.c */
extern void setup_limits P_((const struct passwd *));
/* list.c */
extern char **add_list P_((char **list, const char *member));
extern char **del_list P_((char **list, const char *member));
extern char **dup_list P_((char * const *list));
extern int is_on_list P_((char * const *list, const char *member));
extern char **comma_to_list P_((const char *comma));
/* login.c */
extern void login_prompt P_((const char *, char *, int));
/* login_desrpc.c */
extern int login_desrpc P_((const char *));
/* mail.c */
extern void mailcheck P_((void));
/* motd.c */
extern void motd P_((void));
/* myname.c */
extern struct passwd *get_my_pwent P_((void));
/* obscure.c */
extern int obscure P_((const char *, const char *, const struct passwd *));
/* pam_pass.c */
extern int do_pam_passwd P_((const char *, int, int));
/* port.c */
extern int isttytime P_((const char *, const char *, time_t));
/* pwd2spwd.c */
#ifdef SHADOWPWD
extern struct spwd *pwd_to_spwd P_((const struct passwd *pw));
#endif
/* pwdcheck.c */
extern void passwd_check P_((const char *, const char *, const char *));
/* pwd_init.c */
extern void pwd_init P_((void));
/* pwdbm.c */
extern int pw_dbm_remove P_((const struct passwd *pw));
extern int pw_dbm_update P_((const struct passwd *pw));
extern int pw_dbm_present P_((void));
/* pwpack.c */
extern int pw_pack P_((const struct passwd *passwd, char *buf));
extern int pw_unpack P_((char *buf, int len, struct passwd *passwd));
/* rad64.c */
extern int c64i P_((char c));
extern int i64c P_((int i));
/* rlogin.c */
extern int do_rlogin P_((const char *, char *, int, char *, int));
/* setugid.c */
extern int setup_groups P_((const struct passwd *));
extern int change_uid P_((const struct passwd *));
extern int setup_uid_gid P_((const struct passwd *, int));
/* setup.c */
extern void setup P_((struct passwd *info));
/* setupenv.c */
extern void setup_env P_((struct passwd *));
/* shell.c */
extern void shell P_((const char *file, const char *arg));
#ifdef SHADOWPWD
/* spdbm.c */
extern int sp_dbm_remove P_((const char *user));
extern int sp_dbm_update P_((const struct spwd *sp));
extern int sp_dbm_present P_((void));
/* sppack.c */
extern int spw_pack P_((const struct spwd *spwd, char *buf));
extern int spw_unpack P_((char *buf, int len, struct spwd *spwd));
#endif
/* strtoday.c */
extern long strtoday P_((const char *str));
/* ttytype.c */
extern void ttytype P_((const char *line));
/* ulimit.c */
extern void set_filesize_limit P_((int));
/* utmp.c */
extern void checkutmp P_((int));
extern void setutmp P_((const char *, const char *, const char *));
/* valid.c */
extern int valid P_((const char *, const struct passwd *));
/* xmalloc.c */
extern char *xmalloc P_((size_t size));
extern char *xstrdup P_((const char *str));
#endif /* _PROTOTYPES_H */

75
lib/putgrent.c Normal file
View File

@@ -0,0 +1,75 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include <stdio.h>
#include <grp.h>
#include "prototypes.h"
#include "defines.h"
int
putgrent(const struct group *g, FILE *f)
{
char *buf, *cp;
int i;
size_t size;
if (!g || !f)
return -1;
/* calculate the required buffer size (40 is added for the
numeric GID, colons, newline, and terminating NUL). */
size = strlen(g->gr_name) + strlen(g->gr_passwd) + 40;
for (i = 0; g->gr_mem && g->gr_mem[i]; i++)
size += strlen(g->gr_mem[i]) + 1;
buf = malloc(size);
if (!buf)
return -1;
sprintf(buf, "%s:%s:%ld:", g->gr_name, g->gr_passwd, (long) g->gr_gid);
cp = buf + strlen(buf);
for (i = 0; g->gr_mem && g->gr_mem[i]; i++) {
if (i > 0)
*cp++ = ',';
strcpy(cp, g->gr_mem[i]);
cp += strlen(cp);
}
*cp++ = '\n';
*cp = '\0';
if (fputsx(buf, f) == EOF || ferror(f)) {
free(buf);
return -1;
}
free(buf);
return 0;
}

72
lib/putpwent.c Normal file
View File

@@ -0,0 +1,72 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: putpwent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
#include "defines.h"
#include <stdio.h>
#include <pwd.h>
/*
* putpwent - Output a (struct passwd) in character format
*
* putpwent() writes out a (struct passwd) in the format it appears
* in in flat ASCII files.
*
* (Author: Dr. Micheal Newberry)
*/
int
putpwent(const struct passwd *p, FILE *f)
{
int status;
#if defined(SUN) || defined(BSD) || defined(SUN4)
status = fprintf (f, "%s:%s:%d:%d:%s,%s:%s:%s\n",
p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid,
p->pw_gecos, p->pw_comment, p->pw_dir, p->pw_shell) == EOF;
#else
status = fprintf (f, "%s:%s", p->pw_name, p->pw_passwd) == EOF;
#ifdef ATT_AGE
if (p->pw_age && p->pw_age[0])
status |= fprintf (f, ",%s", p->pw_age) == EOF;
#endif
status |= fprintf (f, ":%d:%d:%s", p->pw_uid, p->pw_gid,
p->pw_gecos) == EOF;
#ifdef ATT_COMMENT
if (p->pw_comment && p->pw_comment[0])
status |= fprintf (f, ",%s", p->pw_comment) == EOF;
#endif
status |= fprintf (f, ":%s:%s\n", p->pw_dir, p->pw_shell) == EOF;
#endif
return status;
}

103
lib/putspent.c Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifdef SHADOWPWD /*{*/
#ifndef HAVE_PUTSPENT
#include "rcsid.h"
RCSID("$Id: putspent.c,v 1.3 1997/12/07 23:26:54 marekm Exp $")
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
int
putspent(const struct spwd *sp, FILE *fp)
{
int errors = 0;
if (! fp || ! sp)
return -1;
if (fprintf (fp, "%s:%s:", sp->sp_namp, sp->sp_pwdp) < 0)
errors++;
if (sp->sp_lstchg != -1) {
if (fprintf (fp, "%ld:", sp->sp_lstchg) < 0)
errors++;
} else if (putc (':', fp) == EOF)
errors++;
if (sp->sp_min != -1) {
if (fprintf (fp, "%ld:", sp->sp_min) < 0)
errors++;
} else if (putc (':', fp) == EOF)
errors++;
if (sp->sp_max != -1) {
if (fprintf (fp, "%ld:", sp->sp_max) < 0)
errors++;
} else if (putc (':', fp) == EOF)
errors++;
if (sp->sp_warn != -1) {
if (fprintf (fp, "%ld:", sp->sp_warn) < 0)
errors++;
} else if (putc (':', fp) == EOF)
errors++;
if (sp->sp_inact != -1) {
if (fprintf (fp, "%ld:", sp->sp_inact) < 0)
errors++;
} else if (putc (':', fp) == EOF)
errors++;
if (sp->sp_expire != -1) {
if (fprintf (fp, "%ld:", sp->sp_expire) < 0)
errors++;
} else if (putc (':', fp) == EOF)
errors++;
if (sp->sp_flag != -1) {
if (fprintf (fp, "%ld", sp->sp_flag) < 0)
errors++;
}
if (putc ('\n', fp) == EOF)
errors++;
if (errors)
return -1;
else
return 0;
}
#endif
#endif /*}*/

548
lib/pwauth.c Normal file
View File

@@ -0,0 +1,548 @@
/*
* Copyright 1992 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: pwauth.c,v 1.9 1998/12/28 20:34:38 marekm Exp $")
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include "prototypes.h"
#include "defines.h"
#include "pwauth.h"
#include "getdef.h"
#ifdef SKEY
#include <skey.h>
#endif
#ifdef OPIE
#include <opie.h>
#endif
#ifdef __linux__ /* standard password prompt by default */
static const char *PROMPT = gettext_noop("Password: ");
#else
static const char *PROMPT = gettext_noop("%s's Password:");
#endif
extern char *getpass();
#ifdef AUTH_METHODS
/*
* Look-up table for bound-in methods. Put the name that the
* method is known by in the password field as "name" and a
* pointer to the function
*/
struct method {
char *name;
int (*func) P_((const char *, int, const char *));
};
#ifdef PAD_AUTH
int pad_auth();
#endif
static struct method methods[] = {
#ifdef PAD_AUTH
{ "pad", pad_auth },
#endif
{ "", 0 }
};
#endif /* AUTH_METHODS */
int wipe_clear_pass = 1;
char *clear_pass = NULL;
/*
* _old_auth - perform getpass/crypt authentication
*
* _old_auth gets the user's cleartext password and encrypts it
* using the salt in the encrypted password. The results are
* compared.
*/
static int
_old_auth(const char *cipher, const char *user, int reason, const char *input)
{
char prompt[1024];
char *clear = NULL;
const char *cp;
int retval;
#ifdef SKEY
int use_skey = 0;
char challenge_info[40];
struct skey skey;
#endif
#ifdef OPIE
int use_opie = 0;
char o_challenge_info[OPIE_CHALLENGE_MAX + 1];
struct opie opie;
/*
* This implementation is based almost entirely on the SKEY code
* above. Thus the opie struct is called skey, etc. I am unaware
* if the system works at the same time, but I cannot imagine why
* anyone would want to do this....
* -- A.R.
* Mod: 5/14/98 A.R.
* Made the OPIE code separate from the S/Key code. Now
* (conceivably) both can be compiled in and function apart from
* one another (assuming a sysadmin really wants to maintain OPIE
* and an S/Key databases....).
*
* Also cleaned up the code a bit. Will be adding second-prompt
* support (the traditional Echo-on S/Key/OPIE-only prompts to let
* the users see the one-time passwords they are typing/pasting
* in....
* -- A.R.
*/
#endif
/*
* There are programs for adding and deleting authentication data.
*/
if (reason == PW_ADD || reason == PW_DELETE)
return 0;
/*
* There are even programs for changing the user name ...
*/
if (reason == PW_CHANGE && input != (char *) 0)
return 0;
/*
* WARNING:
*
* When we change a password and we are root, we don't prompt.
* This is so root can change any password without having to
* know it. This is a policy decision that might have to be
* revisited.
*/
if (reason == PW_CHANGE && getuid () == 0)
return 0;
/*
* WARNING:
*
* When we are logging in a user with no ciphertext password,
* we don't prompt for the password or anything. In reality
* the user could just hit <ENTER>, so it doesn't really
* matter.
*/
if (cipher == (char *) 0 || *cipher == '\0')
return 0;
#ifdef SKEY
/*
* If the user has an S/KEY entry show them the pertinent info
* and then we can try validating the created cyphertext and the SKEY.
* If there is no SKEY information we default to not using SKEY.
*/
if (skeychallenge (&skey, user, challenge_info) == 0)
use_skey = 1;
#endif
#ifdef OPIE
/*
* Ditto above, for OPIE passwords.
* -- AR
*/
o_challenge_info[0] = '\0';
if (opiechallenge(&opie, user, o_challenge_info) == 0)
use_opie = 1;
if (use_opie == 0)
opieverify(&opie, (char *)NULL);
/*
* This call to opieverify is necessary within OPIE's interface:
* Every call to opiechallenge(), which checks to see if the user
* has an OPIE password, and if so get the challenge, must be
* accompanied by exactly one call to opieverify, which clears
* any outstanding locks, and otherwise cleans up.
* -- AR
*/
#endif
/*
* Prompt for the password as required. FTPD and REXECD both
* get the cleartext password for us.
*/
if (reason != PW_FTP && reason != PW_REXEC && !input) {
if (! (cp = getdef_str ("LOGIN_STRING")))
cp = PROMPT;
#ifdef SKEY
if (use_skey)
printf ("[%s]\n", challenge_info);
#endif
#ifdef OPIE
if (use_opie)
printf("[ %s ]\n", o_challenge_info);
#endif
snprintf(prompt, sizeof prompt, cp, user);
clear = getpass(_(prompt));
if (!clear) {
static char c[1];
c[0] = '\0';
clear = c;
}
input = clear;
}
/*
* Convert the cleartext password into a ciphertext string.
* If the two match, the return value will be zero, which is
* SUCCESS. Otherwise we see if SKEY is being used and check
* the results there as well.
*/
retval = strcmp(pw_encrypt(input, cipher), cipher);
#ifdef OPIE
/*
* This is required because using OPIE, opieverify() MUST be called
* opiechallenge() above even if OPIE isn't being used in this case,
* so locks get released, etc.
* -- AR
*/
if ((retval == 0) && use_opie)
opieverify(&opie, (char *)NULL);
#endif
#ifdef SKEY
if (retval && use_skey) {
int passcheck = -1;
#if 0 /* some skey libs don't have skey_passcheck. --marekm */
passcheck = skey_passcheck(user, input);
#else
if (skeyverify(&skey, input) == 0)
passcheck = skey.n;
#endif /* if 0 */
if (passcheck > 0)
retval = 0;
}
#endif
#ifdef OPIE
if (retval && use_opie) {
if (opieverify(&opie, input) == 0)
retval = 0;
}
#endif /* OPIE */
/*
* Things like RADIUS authentication may need the password -
* if the external variable wipe_clear_pass is zero, we will
* not wipe it (the caller should wipe clear_pass when it is
* no longer needed). --marekm
*/
clear_pass = clear;
if (wipe_clear_pass && clear && *clear)
strzero(clear);
return retval;
}
#ifdef AUTH_METHODS
/*
* _pw_auth - perform alternate password authentication
*
* pw_auth executes the alternate password authentication method
* described in the user's password entry. _pw_auth does the real
* work, pw_auth splits the authentication string into individual
* command names.
*/
static int
_pw_auth(const char *command, const char *user, int reason, const char *input)
{
RETSIGTYPE (*sigint)();
RETSIGTYPE (*sigquit)();
#ifdef SIGTSTP
RETSIGTYPE (*sigtstp)();
#endif
int pid;
int status;
int i;
char * const argv[5];
int argc = 0;
int pipes[2];
char *empty_env = NULL;
int use_pipe;
/*
* Start with a quick sanity check. ALL command names must
* be fully-qualified path names.
*/
if (command[0] != '/')
return -1;
/*
* Set the keyboard signals to be ignored. When the user kills
* the child we don't want the parent dying as well.
*/
sigint = signal (SIGINT, SIG_IGN);
sigquit = signal (SIGQUIT, SIG_IGN);
#ifdef SIGTSTP
sigtstp = signal (SIGTSTP, SIG_IGN);
#endif
/*
* FTP and REXEC reasons don't give the program direct access
* to the user. This means that the program can only get input
* from this function. So we set up a pipe for that purpose.
*/
use_pipe = (reason == PW_FTP || reason == PW_REXEC);
if (use_pipe)
if (pipe (pipes))
return -1;
/*
* The program will be forked off with the parent process waiting
* on the child to tell it how successful it was.
*/
switch (pid = fork ()) {
/*
* The fork() failed completely. Clean up as needed and
* return to the caller.
*/
case -1:
if (use_pipe) {
close (pipes[0]);
close (pipes[1]);
}
return -1;
case 0:
/*
* Let the child catch the SIGINT and SIGQUIT
* signals. The parent, however, will continue
* to ignore them.
*/
signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
/*
* Set up the command line. The first argument is
* the name of the command being executed. The
* second is the command line option for the reason,
* and the third is the user name.
*/
argv[argc++] = command;
switch (reason) {
case PW_SU: argv[argc++] = "-s"; break;
case PW_LOGIN: argv[argc++] = "-l"; break;
case PW_ADD: argv[argc++] = "-a"; break;
case PW_CHANGE: argv[argc++] = "-c"; break;
case PW_DELETE: argv[argc++] = "-d"; break;
case PW_TELNET: argv[argc++] = "-t"; break;
case PW_RLOGIN: argv[argc++] = "-r"; break;
case PW_FTP: argv[argc++] = "-f"; break;
case PW_REXEC: argv[argc++] = "-x"; break;
}
if (reason == PW_CHANGE && input)
argv[argc++] = input;
argv[argc++] = user;
argv[argc] = (char *) 0;
/*
* The FTP and REXEC reasons use a pipe to communicate
* with the parent. The other standard I/O descriptors
* are closed and re-opened as /dev/null.
*/
if (use_pipe) {
close (0);
close (1);
close (2);
if (dup (pipes[0]) != 0)
exit (1);
close (pipes[0]);
close (pipes[1]);
if (open ("/dev/null", O_WRONLY) != 1)
exit (1);
if (open ("/dev/null", O_WRONLY) != 2)
exit (1);
}
/*
* Now we execute the command directly.
* Do it with empty environment for safety. --marekm
*/
execve(command, argv, &empty_env);
_exit((errno == ENOENT) ? 127 : 126);
/*NOTREACHED*/
default:
/*
* FTP and REXEC cause a single line of text to be
* sent to the child over a pipe that was set up
* earlier.
*/
if (use_pipe) {
close (pipes[0]);
if (input)
write (pipes[1], input, strlen (input));
write (pipes[1], "\n", 1);
close (pipes[1]);
}
/*
* Wait on the child to die. When it does you will
* get the exit status and use that to determine if
* the authentication program was successful.
*/
while ((i = wait (&status)) != pid && i != -1)
;
/*
* Re-set the signals to their earlier values.
*/
signal (SIGINT, sigint);
signal (SIGQUIT, sigquit);
#ifdef SIGTSTP
signal (SIGTSTP, sigtstp);
#endif
/*
* Make sure we found the right process!
*/
if (i == -1)
return -1;
if (status == 0)
return 0;
else
return -1;
}
/*NOTREACHED*/
}
/*
* _builtin_auth - lookup routine in table and execute
*/
static int
_builtin_auth(const char *command, const char *user, int reason, const char *input)
{
int i;
/*
* Scan the table, looking for a match. If we fall off
* the end, it must mean that this method isn't supported,
* so we fail the authentication.
*/
for (i = 0;methods[i].name[0];i++) {
if (! strcmp (command, methods[i].name))
break;
}
if (methods[i].name[0] == '\0')
return -1;
/*
* Call the pointed to function with the other three
* arguments.
*/
return (methods[i].func) (user, reason, input);
}
#endif /* AUTH_METHODS */
/*
* This function does the real work. It splits the list of program names
* up into individual programs and executes them one at a time.
*/
int
pw_auth(const char *command, const char *user, int reason, const char *input)
{
#ifdef AUTH_METHODS
char buf[256];
char *cmd, *end;
int rc;
/*
* Quick little sanity check ...
*/
if (strlen (command) >= sizeof buf)
return -1;
strcpy (buf, command); /* safe (because of the above check) --marekm */
/*
* Find each command and make sure it is NUL-terminated. Then
* invoke _pw_auth to actually run the program. The first
* failing program ends the whole mess.
*/
for (cmd = buf;cmd;cmd = end) {
if ((end = strchr (cmd, ';')))
*end++ = '\0';
if (cmd[0] != '@')
rc = _old_auth (cmd, user, reason, input);
else if (cmd[1] == '/')
rc = _pw_auth (cmd + 1, user, reason, input);
else
rc = _builtin_auth (cmd + 1, user, reason, input);
if (rc)
return -1;
}
return 0;
#else
return _old_auth(command, user, reason, input);
#endif
}

60
lib/pwauth.h Normal file
View File

@@ -0,0 +1,60 @@
/*
* Copyright 1992 - 1993, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: pwauth.h,v 1.2 1997/05/01 23:14:44 marekm Exp $
*/
#if __STDC__
int pw_auth(const char *program,const char *user,int flag,const char *input);
#else
int pw_auth ();
#endif
/*
* Local access
*/
#define PW_SU 1
#define PW_LOGIN 2
/*
* Administrative functions
*/
#define PW_ADD 101
#define PW_CHANGE 102
#define PW_DELETE 103
/*
* Network access
*/
#define PW_TELNET 201
#define PW_RLOGIN 202
#define PW_FTP 203
#define PW_REXEC 204

143
lib/pwdbm.c Normal file
View File

@@ -0,0 +1,143 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifdef NDBM /*{*/
#include "rcsid.h"
RCSID("$Id: pwdbm.c,v 1.4 1997/12/14 20:07:19 marekm Exp $")
#include <sys/types.h>
#include <stdio.h>
#include <pwd.h>
#include "prototypes.h"
#include "defines.h"
#include <ndbm.h>
extern DBM *pw_dbm;
/*
* pw_dbm_update
*
* Updates the DBM password files, if they exist.
*/
int
pw_dbm_update(const struct passwd *pw)
{
datum key;
datum content;
char data[BUFSIZ];
int len;
static int once;
if (! once) {
if (! pw_dbm)
setpwent ();
once++;
}
if (! pw_dbm)
return 0;
len = pw_pack (pw, data);
content.dsize = len;
content.dptr = data;
key.dsize = strlen (pw->pw_name);
key.dptr = pw->pw_name;
if (dbm_store(pw_dbm, key, content, DBM_REPLACE))
return 0;
/*
* XXX - on systems with 16-bit UIDs (such as Linux/x86)
* name "aa" and UID 24929 will give the same key. This
* happens only rarely, but code which only "works most
* of the time" is not good enough...
*
* This needs to be fixed in several places (pwdbm.c,
* grdbm.c, pwent.c, grent.c). Fixing it will cause
* incompatibility with existing dbm files.
*
* Summary: don't use this stuff for now. --marekm
*/
key.dsize = sizeof pw->pw_uid;
key.dptr = (char *) &pw->pw_uid;
if (dbm_store(pw_dbm, key, content, DBM_REPLACE))
return 0;
return 1;
}
/*
* pw_dbm_remove
*
* Removes the DBM password entry, if it exists.
*/
int
pw_dbm_remove(const struct passwd *pw)
{
datum key;
static int once;
char data[BUFSIZ];
if (! once) {
if (! pw_dbm)
setpwent ();
once++;
}
if (! pw_dbm)
return 0;
key.dsize = strlen (pw->pw_name);
key.dptr = pw->pw_name;
if (dbm_delete (pw_dbm, key))
return 0;
key.dsize = sizeof pw->pw_uid;
key.dptr = (char *) &pw->pw_uid;
if (dbm_delete (pw_dbm, key))
return 0;
return 1;
}
int
pw_dbm_present(void)
{
return (access(PASSWD_PAG_FILE, F_OK) == 0);
}
#endif /* NDBM */

187
lib/pwio.c Normal file
View File

@@ -0,0 +1,187 @@
#include <config.h>
#include "rcsid.h"
RCSID("$Id: pwio.c,v 1.9 1998/01/29 23:22:31 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
#include <stdio.h>
#include "commonio.h"
#include "pwio.h"
extern struct passwd *sgetpwent P_((const char *));
extern int putpwent P_((const struct passwd *, FILE *));
struct passwd *
__pw_dup(const struct passwd *pwent)
{
struct passwd *pw;
if (!(pw = (struct passwd *) malloc(sizeof *pw)))
return NULL;
*pw = *pwent;
if (!(pw->pw_name = strdup(pwent->pw_name)))
return NULL;
if (!(pw->pw_passwd = strdup(pwent->pw_passwd)))
return NULL;
#ifdef ATT_AGE
if (!(pw->pw_age = strdup(pwent->pw_age)))
return NULL;
#endif
#ifdef ATT_COMMENT
if (!(pw->pw_comment = strdup(pwent->pw_comment)))
return NULL;
#endif
if (!(pw->pw_gecos = strdup(pwent->pw_gecos)))
return NULL;
if (!(pw->pw_dir = strdup(pwent->pw_dir)))
return NULL;
if (!(pw->pw_shell = strdup(pwent->pw_shell)))
return NULL;
return pw;
}
static void *
passwd_dup(const void *ent)
{
const struct passwd *pw = ent;
return __pw_dup(pw);
}
static void
passwd_free(void *ent)
{
struct passwd *pw = ent;
free(pw->pw_name);
free(pw->pw_passwd);
#ifdef ATT_AGE
free(pw->pw_age);
#endif
#ifdef ATT_COMMENT
free(pw->pw_comment);
#endif
free(pw->pw_gecos);
free(pw->pw_dir);
free(pw->pw_shell);
free(pw);
}
static const char *
passwd_getname(const void *ent)
{
const struct passwd *pw = ent;
return pw->pw_name;
}
static void *
passwd_parse(const char *line)
{
return (void *) sgetpwent(line);
}
static int
passwd_put(const void *ent, FILE *file)
{
const struct passwd *pw = ent;
return (putpwent(pw, file) == -1) ? -1 : 0;
}
static struct commonio_ops passwd_ops = {
passwd_dup,
passwd_free,
passwd_getname,
passwd_parse,
passwd_put,
fgets,
fputs
};
static struct commonio_db passwd_db = {
PASSWD_FILE, /* filename */
&passwd_ops, /* ops */
NULL, /* fp */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0, /* readonly */
1 /* use_lckpwdf */
};
int
pw_name(const char *filename)
{
return commonio_setname(&passwd_db, filename);
}
int
pw_lock(void)
{
return commonio_lock(&passwd_db);
}
int
pw_open(int mode)
{
return commonio_open(&passwd_db, mode);
}
const struct passwd *
pw_locate(const char *name)
{
return commonio_locate(&passwd_db, name);
}
int
pw_update(const struct passwd *pw)
{
return commonio_update(&passwd_db, (const void *) pw);
}
int
pw_remove(const char *name)
{
return commonio_remove(&passwd_db, name);
}
int
pw_rewind(void)
{
return commonio_rewind(&passwd_db);
}
const struct passwd *
pw_next(void)
{
return commonio_next(&passwd_db);
}
int
pw_close(void)
{
return commonio_close(&passwd_db);
}
int
pw_unlock(void)
{
return commonio_unlock(&passwd_db);
}
struct commonio_entry *
__pw_get_head(void)
{
return passwd_db.head;
}
void
__pw_del_entry(const struct commonio_entry *ent)
{
commonio_del_entry(&passwd_db, ent);
}

12
lib/pwio.h Normal file
View File

@@ -0,0 +1,12 @@
extern struct passwd *__pw_dup P_((const struct passwd *));
extern void __pw_set_changed P_((void));
extern int pw_close P_((void));
extern const struct passwd *pw_locate P_((const char *));
extern int pw_lock P_((void));
extern int pw_name P_((const char *));
extern const struct passwd *pw_next P_((void));
extern int pw_open P_((int));
extern int pw_remove P_((const char *));
extern int pw_rewind P_((void));
extern int pw_unlock P_((void));
extern int pw_update P_((const struct passwd *));

163
lib/pwpack.c Normal file
View File

@@ -0,0 +1,163 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: pwpack.c,v 1.4 1998/04/16 19:57:42 marekm Exp $")
#include <sys/types.h>
#include "defines.h"
#include <stdio.h>
#include <pwd.h>
/*
* pw_pack - convert a (struct pwd) to a packed record
* WARNING: buf must be large enough, no check for overrun!
*/
int
pw_pack(const struct passwd *passwd, char *buf)
{
char *cp;
cp = buf;
strcpy (cp, passwd->pw_name);
cp += strlen (cp) + 1;
strcpy (cp, passwd->pw_passwd);
#ifdef ATT_AGE
if (passwd->pw_age[0]) {
*cp++ = ',';
strcat (cp, passwd->pw_age);
}
#endif
cp += strlen (cp) + 1;
memcpy (cp, (const char *) &passwd->pw_uid, sizeof passwd->pw_uid);
cp += sizeof passwd->pw_uid;
memcpy (cp, (const char *) &passwd->pw_gid, sizeof passwd->pw_gid);
cp += sizeof passwd->pw_gid;
#ifdef BSD_QUOTA
memcpy (cp, (const char *) &passwd->pw_quota, sizeof passwd->pw_quota);
cp += sizeof passwd->pw_quota;
#endif
#ifdef ATT_COMMENT
if (passwd->pw_comment) {
strcpy (cp, passwd->pw_comment);
cp += strlen (cp) + 1;
} else
*cp++ = '\0';
#endif
strcpy (cp, passwd->pw_gecos);
cp += strlen (cp) + 1;
strcpy (cp, passwd->pw_dir);
cp += strlen (cp) + 1;
strcpy (cp, passwd->pw_shell);
cp += strlen (cp) + 1;
return cp - buf;
}
/*
* pw_unpack - convert a packed (struct pwd) record to a (struct pwd)
*/
int
pw_unpack(char *buf, int len, struct passwd *passwd)
{
char *org = buf;
#ifdef ATT_AGE
char *cp;
#endif
memzero(passwd, sizeof *passwd);
passwd->pw_name = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
passwd->pw_passwd = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
#ifdef ATT_AGE
if (cp = strchr (passwd->pw_passwd, ',')) {
*cp++ = '\0';
passwd->pw_age = cp;
} else
passwd->pw_age = "";
#endif
memcpy ((void *) &passwd->pw_uid, (void *) buf, sizeof passwd->pw_uid);
buf += sizeof passwd->pw_uid;
if (buf - org > len)
return -1;
memcpy ((void *) &passwd->pw_gid, (void *) buf, sizeof passwd->pw_gid);
buf += sizeof passwd->pw_gid;
if (buf - org > len)
return -1;
#ifdef BSD_QUOTA
memcpy ((void *) &passwd->pw_quota, (void *) buf,
sizeof passwd->pw_quota);
buf += sizeof passwd->pw_quota;
if (buf - org > len)
return -1;
#endif
#ifdef ATT_COMMENT
passwd->pw_comment = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
#endif
passwd->pw_gecos = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
passwd->pw_dir = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
passwd->pw_shell = buf;
buf += strlen (buf) + 1;
if (buf - org > len)
return -1;
return 0;
}

126
lib/rad64.c Normal file
View File

@@ -0,0 +1,126 @@
/*
* Copyright 1989 - 1992, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: rad64.c,v 1.4 1997/12/07 23:26:56 marekm Exp $")
/*
* c64i - convert a radix 64 character to an integer
*/
int
c64i(char c)
{
if (c == '.')
return (0);
if (c == '/')
return (1);
if (c >= '0' && c <= '9')
return (c - '0' + 2);
if (c >= 'A' && c <= 'Z')
return (c - 'A' + 12);
if (c >= 'a' && c <= 'z')
return (c - 'a' + 38);
else
return (-1);
}
/*
* i64c - convert an integer to a radix 64 character
*/
int
i64c(int i)
{
if (i <= 0)
return ('.');
if (i == 1)
return ('/');
if (i >= 2 && i < 12)
return ('0' - 2 + i);
if (i >= 12 && i < 38)
return ('A' - 12 + i);
if (i >= 38 && i < 63)
return ('a' - 38 + i);
return ('z');
}
#ifndef HAVE_A64L
/*
* l64a - convert a long to a string of radix 64 characters
*/
char *
l64a(long l)
{
static char buf[8];
int i = 0;
if (l < 0L)
return ((char *) 0);
do {
buf[i++] = i64c ((int) (l % 64));
buf[i] = '\0';
} while (l /= 64L, l > 0 && i < 6);
return (buf);
}
/*
* a64l - convert a radix 64 string to a long integer
*/
long
a64l(const char *s)
{
int i;
long value;
long shift = 0;
for (i = 0, value = 0L;i < 6 && *s;s++) {
value += (c64i (*s) << shift);
shift += 6;
}
return (value);
}
#endif /* !HAVE_A64L */

22
lib/rcsid.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* $Id: rcsid.h,v 1.2 1999/06/07 16:40:44 marekm Exp $
*/
#define PKG_VER " $Package: " PACKAGE " $ $Version: " VERSION " $ "
#if defined(NO_RCSID) || defined(lint)
#define RCSID(x) /* empty */
#else
#if __STDC__
/*
* This function is never called from anywhere, but it calls itself
* recursively only to fool gcc to not generate warnings :-).
*/
static const char *rcsid(const char *);
#define RCSID(x) \
static const char *rcsid(const char *s) { \
return rcsid(x); }
#else /* ! __STDC__ */
#define RCSID(x) \
static char *rcsid(s) char *s; { \
return rcsid(x); }
#endif /* ! __STDC__ */
#endif

91
lib/rename.c Normal file
View File

@@ -0,0 +1,91 @@
/*
* Copyright 1993 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: rename.c,v 1.3 1997/12/07 23:26:57 marekm Exp $")
#include "defines.h"
#include <sys/stat.h>
#include <errno.h>
/*
* rename - rename a file to another name
*
* rename is provided for systems which do not include the rename()
* system call.
*/
int
rename(const char *begin, const char *end)
{
struct stat s1, s2;
extern int errno;
int orig_err = errno;
if (stat (begin, &s1))
return -1;
if (stat (end, &s2)) {
errno = orig_err;
} else {
/*
* See if this is a cross-device link. We do this to
* insure that the link below has a chance of working.
*/
if (s1.st_dev != s2.st_dev) {
errno = EXDEV;
return -1;
}
/*
* See if we can unlink the existing destination
* file. If the unlink works the directory is writable,
* so there is no need here to figure that out.
*/
if (unlink (end))
return -1;
}
/*
* Now just link the original name to the final name. If there
* was no file previously, this link will fail if the target
* directory isn't writable. The unlink will fail if the source
* directory isn't writable, but life stinks ...
*/
if (link (begin, end) || unlink (begin))
return -1;
return 0;
}

59
lib/rmdir.c Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright 1991, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include <fcntl.h>
#include "rcsid.h"
RCSID("$Id: rmdir.c,v 1.4 1998/01/29 23:22:31 marekm Exp $")
/*
* rmdir - remove a directory
*
* rmdir is provided for systems which do not include the rmdir()
* system call.
*/
int
rmdir(const char *dir)
{
int status;
if (fork()) {
while (wait(&status) != -1)
;
return status >> 8;
}
close(2);
open("/dev/null", O_WRONLY);
execl("/bin/rmdir", "rmdir", dir, 0);
_exit(127);
/*NOTREACHED*/
}

140
lib/sgetgrent.c Normal file
View File

@@ -0,0 +1,140 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: sgetgrent.c,v 1.4 1998/04/02 21:51:45 marekm Exp $")
#include <stdio.h>
#include <grp.h>
#include "defines.h"
#define NFIELDS 4
/*
* list - turn a comma-separated string into an array of (char *)'s
*
* list() converts the comma-separated list of member names into
* an array of character pointers.
*
* WARNING: I profiled this once with and without strchr() calls
* and found that using a register variable and an explicit loop
* works best. For large /etc/group files, this is a major win.
*
* FINALLY added dynamic allocation. Still need to fix sgetsgent().
* --marekm
*/
static char **
list(char *s)
{
static char **members = 0;
static int size = 0; /* max members + 1 */
int i;
char **rbuf;
i = 0;
for (;;) {
/* check if there is room for another pointer (to a group
member name, or terminating NULL). */
if (i >= size) {
size = i + 100; /* at least: i + 1 */
if (members) {
rbuf = realloc(members, size * sizeof(char *));
} else {
/* for old (before ANSI C) implementations of
realloc() that don't handle NULL properly */
rbuf = malloc(size * sizeof(char *));
}
if (!rbuf) {
if (members)
free(members);
members = 0;
size = 0;
return (char **) 0;
}
members = rbuf;
}
if (!s || s[0] == '\0')
break;
members[i++] = s;
while (*s && *s != ',')
s++;
if (*s)
*s++ = '\0';
}
members[i] = (char *) 0;
return members;
}
struct group *
sgetgrent(const char *buf)
{
static char *grpbuf = 0;
static size_t size = 0;
static char *grpfields[NFIELDS];
static struct group grent;
int i;
char *cp;
if (strlen(buf) + 1 > size) {
/* no need to use realloc() here - just free it and
allocate a larger block */
if (grpbuf)
free(grpbuf);
size = strlen(buf) + 1000; /* at least: strlen(buf) + 1 */
grpbuf = malloc(size);
if (!grpbuf) {
size = 0;
return 0;
}
}
strcpy(grpbuf, buf);
if ((cp = strrchr(grpbuf, '\n')))
*cp = '\0';
for (cp = grpbuf, i = 0; i < NFIELDS && cp; i++) {
grpfields[i] = cp;
if ((cp = strchr(cp, ':')))
*cp++ = 0;
}
if (i < (NFIELDS-1) || *grpfields[2] == '\0')
return 0;
grent.gr_name = grpfields[0];
grent.gr_passwd = grpfields[1];
grent.gr_gid = atoi(grpfields[2]);
grent.gr_mem = list(grpfields[3]);
if (!grent.gr_mem)
return (struct group *) 0; /* out of memory */
return &grent;
}

136
lib/sgetpwent.c Normal file
View File

@@ -0,0 +1,136 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "rcsid.h"
RCSID("$Id: sgetpwent.c,v 1.5 1998/04/02 21:51:46 marekm Exp $")
#include <sys/types.h>
#include "defines.h"
#include <stdio.h>
#include <pwd.h>
#define NFIELDS 7
/*
* sgetpwent - convert a string to a (struct passwd)
*
* sgetpwent() parses a string into the parts required for a password
* structure. Strict checking is made for the UID and GID fields and
* presence of the correct number of colons. Any failing tests result
* in a NULL pointer being returned.
*
* NOTE: This function uses hard-coded string scanning functions for
* performance reasons. I am going to come up with some conditional
* compilation glarp to improve on this in the future.
*/
struct passwd *
sgetpwent(const char *buf)
{
static struct passwd pwent;
static char pwdbuf[1024];
register int i;
register char *cp;
char *ep;
char *fields[NFIELDS];
/*
* Copy the string to a static buffer so the pointers into
* the password structure remain valid.
*/
if (strlen(buf) >= sizeof pwdbuf)
return 0; /* fail if too long */
strcpy(pwdbuf, buf);
/*
* Save a pointer to the start of each colon separated
* field. The fields are converted into NUL terminated strings.
*/
for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
fields[i] = cp;
while (*cp && *cp != ':')
++cp;
if (*cp)
*cp++ = '\0';
else
cp = 0;
}
/*
* There must be exactly NFIELDS colon separated fields or
* the entry is invalid. Also, the UID and GID must be non-blank.
*/
if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
return 0;
/*
* Each of the fields is converted the appropriate data type
* and the result assigned to the password structure. If the
* UID or GID does not convert to an integer value, a NULL
* pointer is returned.
*/
pwent.pw_name = fields[0];
pwent.pw_passwd = fields[1];
if (fields[2][0] == '\0' ||
((pwent.pw_uid = strtol (fields[2], &ep, 10)) == 0 && *ep)) {
return 0;
}
if (fields[3][0] == '\0' ||
((pwent.pw_gid = strtol (fields[3], &ep, 10)) == 0 && *ep)) {
return 0;
}
#ifdef ATT_AGE
cp = pwent.pw_passwd;
while (*cp && *cp != ',')
++cp;
if (*cp) {
*cp++ = '\0';
pwent.pw_age = cp;
} else {
cp = 0;
pwent.pw_age = "";
}
#endif
pwent.pw_gecos = fields[4];
#ifdef ATT_COMMENT
pwent.pw_comment = "";
#endif
pwent.pw_dir = fields[5];
pwent.pw_shell = fields[6];
return &pwent;
}

198
lib/sgetspent.c Normal file
View File

@@ -0,0 +1,198 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifdef SHADOWPWD /*{*/
#include "rcsid.h"
RCSID("$Id: sgetspent.c,v 1.5 1998/04/02 21:51:47 marekm Exp $")
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#define FIELDS 9
#define OFIELDS 5
/*
* sgetspent - convert string in shadow file format to (struct spwd *)
*/
struct spwd *
sgetspent(const char *string)
{
static char spwbuf[1024];
static struct spwd spwd;
char *fields[FIELDS];
char *cp;
char *cpp;
int i;
/*
* Copy string to local buffer. It has to be tokenized and we
* have to do that to our private copy.
*/
if (strlen(string) >= sizeof spwbuf)
return 0; /* fail if too long */
strcpy(spwbuf, string);
if ((cp = strrchr (spwbuf, '\n')))
*cp = '\0';
/*
* Tokenize the string into colon separated fields. Allow up to
* FIELDS different fields.
*/
for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) {
fields[i] = cp;
while (*cp && *cp != ':')
cp++;
if (*cp)
*cp++ = '\0';
}
/*
* It is acceptable for the last SVR4 field to be blank. This
* results in the loop being terminated early. In which case,
* we just make the last field be blank and be done with it.
*/
if (i == (FIELDS-1))
fields[i++] = cp;
if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
return 0;
/*
* Start populating the structure. The fields are all in
* static storage, as is the structure we pass back.
*/
spwd.sp_namp = fields[0];
spwd.sp_pwdp = fields[1];
/*
* Get the last changed date. For all of the integer fields,
* we check for proper format. It is an error to have an
* incorrectly formatted number.
*/
if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[2][0] == '\0')
spwd.sp_lstchg = -1;
/*
* Get the minimum period between password changes.
*/
if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[3][0] == '\0')
spwd.sp_min = -1;
/*
* Get the maximum number of days a password is valid.
*/
if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[4][0] == '\0')
spwd.sp_max = -1;
/*
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
* formatted file), initialize the other field members to -1.
*/
#if 0 /* SVR4 */
if (i == OFIELDS)
return 0;
#else
if (i == OFIELDS) {
spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
spwd.sp_flag = -1;
return &spwd;
}
#endif
/*
* The rest of the fields are mandatory for SVR4, but optional
* for anything else. However, if one is present the others
* must be as well.
*/
/*
* Get the number of days of password expiry warning.
*/
if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[5][0] == '\0')
spwd.sp_warn = -1;
/*
* Get the number of days of inactivity before an account is
* disabled.
*/
if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[6][0] == '\0')
spwd.sp_inact = -1;
/*
* Get the number of days after the epoch before the account is
* set to expire.
*/
if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[7][0] == '\0')
spwd.sp_expire = -1;
/*
* This field is reserved for future use. But it isn't supposed
* to have anything other than a valid integer in it.
*/
if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
return 0;
} else if (fields[8][0] == '\0')
spwd.sp_flag = -1;
return (&spwd);
}
#endif /*}*/

213
lib/sgroupio.c Normal file
View File

@@ -0,0 +1,213 @@
#include <config.h>
#ifdef SHADOWGRP
#include "rcsid.h"
RCSID("$Id: sgroupio.c,v 1.9 1998/01/29 23:22:31 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
#include "sgroupio.h"
extern int putsgent P_((const struct sgrp *, FILE *));
extern struct sgrp *sgetsgent P_((const char *));
struct sgrp *
__sgr_dup(const struct sgrp *sgent)
{
struct sgrp *sg;
int i;
if (!(sg = (struct sgrp *) malloc(sizeof *sg)))
return NULL;
*sg = *sgent;
if (!(sg->sg_name = strdup(sgent->sg_name)))
return NULL;
if (!(sg->sg_passwd = strdup(sgent->sg_passwd)))
return NULL;
for (i = 0; sgent->sg_adm[i]; i++)
;
sg->sg_adm = (char **) malloc((i + 1) * sizeof(char *));
if (!sg->sg_adm)
return NULL;
for (i = 0; sgent->sg_adm[i]; i++) {
sg->sg_adm[i] = strdup(sgent->sg_adm[i]);
if (!sg->sg_adm[i])
return NULL;
}
sg->sg_adm[i] = NULL;
for (i = 0; sgent->sg_mem[i]; i++)
;
sg->sg_mem = (char **) malloc((i + 1) * sizeof(char *));
if (!sg->sg_mem)
return NULL;
for (i = 0; sgent->sg_mem[i]; i++) {
sg->sg_mem[i] = strdup(sgent->sg_mem[i]);
if (!sg->sg_mem[i])
return NULL;
}
sg->sg_mem[i] = NULL;
return sg;
}
static void *
gshadow_dup(const void *ent)
{
const struct sgrp *sg = ent;
return __sgr_dup(sg);
}
static void
gshadow_free(void *ent)
{
struct sgrp *sg = ent;
free(sg->sg_name);
free(sg->sg_passwd);
while(*(sg->sg_adm)) {
free(*(sg->sg_adm));
sg->sg_adm++;
}
while(*(sg->sg_mem)) {
free(*(sg->sg_mem));
sg->sg_mem++;
}
free(sg);
}
static const char *
gshadow_getname(const void *ent)
{
const struct sgrp *gr = ent;
return gr->sg_name;
}
static void *
gshadow_parse(const char *line)
{
return (void *) sgetsgent(line);
}
static int
gshadow_put(const void *ent, FILE *file)
{
const struct sgrp *sg = ent;
return (putsgent(sg, file) == -1) ? -1 : 0;
}
static struct commonio_ops gshadow_ops = {
gshadow_dup,
gshadow_free,
gshadow_getname,
gshadow_parse,
gshadow_put,
fgetsx,
fputsx
};
static struct commonio_db gshadow_db = {
SGROUP_FILE, /* filename */
&gshadow_ops, /* ops */
NULL, /* fp */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0, /* readonly */
0 /* use_lckpwdf */
};
int
sgr_name(const char *filename)
{
return commonio_setname(&gshadow_db, filename);
}
int
sgr_file_present(void)
{
return commonio_present(&gshadow_db);
}
int
sgr_lock(void)
{
return commonio_lock(&gshadow_db);
}
int
sgr_open(int mode)
{
return commonio_open(&gshadow_db, mode);
}
const struct sgrp *
sgr_locate(const char *name)
{
return commonio_locate(&gshadow_db, name);
}
int
sgr_update(const struct sgrp *sg)
{
return commonio_update(&gshadow_db, (const void *) sg);
}
int
sgr_remove(const char *name)
{
return commonio_remove(&gshadow_db, name);
}
int
sgr_rewind(void)
{
return commonio_rewind(&gshadow_db);
}
const struct sgrp *
sgr_next(void)
{
return commonio_next(&gshadow_db);
}
int
sgr_close(void)
{
return commonio_close(&gshadow_db);
}
int
sgr_unlock(void)
{
return commonio_unlock(&gshadow_db);
}
void
__sgr_set_changed(void)
{
gshadow_db.changed = 1;
}
struct commonio_entry *
__sgr_get_head(void)
{
return gshadow_db.head;
}
void
__sgr_del_entry(const struct commonio_entry *ent)
{
commonio_del_entry(&gshadow_db, ent);
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif

13
lib/sgroupio.h Normal file
View File

@@ -0,0 +1,13 @@
extern struct sgrp *__sgr_dup P_((const struct sgrp *));
extern void __sgr_set_changed P_((void));
extern int sgr_close P_((void));
extern int sgr_file_present P_((void));
extern const struct sgrp *sgr_locate P_((const char *));
extern int sgr_lock P_((void));
extern int sgr_name P_((const char *));
extern const struct sgrp *sgr_next P_((void));
extern int sgr_open P_((int));
extern int sgr_remove P_((const char *));
extern int sgr_rewind P_((void));
extern int sgr_unlock P_((void));
extern int sgr_update P_((const struct sgrp *));

592
lib/shadow.c Normal file
View File

@@ -0,0 +1,592 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#if defined(SHADOWPWD) && !defined(HAVE_GETSPNAM) /*{*/
#include "rcsid.h"
RCSID("$Id: shadow.c,v 1.6 1998/01/29 23:22:32 marekm Exp $")
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#ifdef NDBM
#include <ndbm.h>
#include <fcntl.h>
DBM *sp_dbm;
int sp_dbm_mode = -1;
static int dbmopened;
static int dbmerror;
#endif
#ifdef USE_NIS
static int nis_used;
static int nis_ignore;
static enum { native, start, middle, native2 } nis_state;
static int nis_bound;
static char *nis_domain;
static char *nis_key;
static int nis_keylen;
static char *nis_val;
static int nis_vallen;
#define IS_NISCHAR(c) ((c)=='+')
#endif
static FILE *shadow;
static char spwbuf[BUFSIZ];
static struct spwd spwd;
#define FIELDS 9
#define OFIELDS 5
#ifdef USE_NIS
/*
* __setspNIS - turn on or off NIS searches
*/
void
__setspNIS(int flag)
{
nis_ignore = ! flag;
if (nis_ignore)
nis_used = 0;
}
/*
* bind_nis - bind to NIS server
*/
static int
bind_nis(void)
{
if (yp_get_default_domain (&nis_domain))
return -1;
nis_bound = 1;
return 0;
}
#endif
/*
* setspent - initialize access to shadow text and DBM files
*/
void
setspent(void)
{
if (shadow)
rewind(shadow);
else
shadow = fopen(SHADOW_FILE, "r");
#ifdef USE_NIS
nis_state = native;
#endif
/*
* Attempt to open the DBM files if they have never been opened
* and an error has never been returned.
*/
#ifdef NDBM
if (! dbmerror && ! dbmopened) {
int mode;
char dbmfiles[BUFSIZ];
strcpy (dbmfiles, SHADOW_PAG_FILE);
if (sp_dbm_mode == -1)
mode = O_RDWR;
else
mode = (sp_dbm_mode == O_RDWR) ? O_RDWR:O_RDONLY;
if (! (sp_dbm = dbm_open (SHADOW_FILE, mode, 0)))
dbmerror = 1;
else
dbmopened = 1;
}
#endif
}
/*
* endspent - terminate access to shadow text and DBM files
*/
void
endspent(void)
{
if (shadow)
(void) fclose (shadow);
shadow = (FILE *) 0;
#ifdef NDBM
if (dbmopened && sp_dbm) {
dbm_close (sp_dbm);
sp_dbm = 0;
}
dbmopened = 0;
dbmerror = 0;
#endif
}
/*
* my_sgetspent - convert string in shadow file format to (struct spwd *)
*/
static struct spwd *
my_sgetspent(const char *string)
{
char *fields[FIELDS];
char *cp;
char *cpp;
int i;
/*
* Copy string to local buffer. It has to be tokenized and we
* have to do that to our private copy.
*/
if (strlen(string) >= sizeof spwbuf)
return 0;
strcpy(spwbuf, string);
if ((cp = strrchr (spwbuf, '\n')))
*cp = '\0';
/*
* Tokenize the string into colon separated fields. Allow up to
* FIELDS different fields.
*/
for (cp = spwbuf, i = 0;*cp && i < FIELDS;i++) {
fields[i] = cp;
while (*cp && *cp != ':')
cp++;
if (*cp)
*cp++ = '\0';
}
/*
* It is acceptable for the last SVR4 field to be blank. This
* results in the loop being terminated early. In which case,
* we just make the last field be blank and be done with it.
*/
if (i == (FIELDS-1))
fields[i++] = cp;
if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
return 0;
/*
* Start populating the structure. The fields are all in
* static storage, as is the structure we pass back. If we
* ever see a name with '+' as the first character, we try
* to turn on NIS processing.
*/
spwd.sp_namp = fields[0];
#ifdef USE_NIS
if (IS_NISCHAR (fields[0][0]))
nis_used = 1;
#endif
spwd.sp_pwdp = fields[1];
/*
* Get the last changed date. For all of the integer fields,
* we check for proper format. It is an error to have an
* incorrectly formatted number, unless we are using NIS.
*/
if ((spwd.sp_lstchg = strtol (fields[2], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_lstchg = -1;
#else
return 0;
#endif
} else if (fields[2][0] == '\0')
spwd.sp_lstchg = -1;
/*
* Get the minimum period between password changes.
*/
if ((spwd.sp_min = strtol (fields[3], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_min = -1;
#else
return 0;
#endif
} else if (fields[3][0] == '\0')
spwd.sp_min = -1;
/*
* Get the maximum number of days a password is valid.
*/
if ((spwd.sp_max = strtol (fields[4], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_max = -1;
#else
return 0;
#endif
} else if (fields[4][0] == '\0')
spwd.sp_max = -1;
/*
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
* formatted file), initialize the other field members to -1.
*/
#if 0 /* SVR4 */
if (i == OFIELDS)
return 0;
#else
if (i == OFIELDS) {
spwd.sp_warn = spwd.sp_inact = spwd.sp_expire =
spwd.sp_flag = -1;
return &spwd;
}
#endif
/*
* The rest of the fields are mandatory for SVR4, but optional
* for anything else. However, if one is present the others
* must be as well.
*/
/*
* Get the number of days of password expiry warning.
*/
if ((spwd.sp_warn = strtol (fields[5], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_warn = -1;
#else
return 0;
#endif
} else if (fields[5][0] == '\0')
spwd.sp_warn = -1;
/*
* Get the number of days of inactivity before an account is
* disabled.
*/
if ((spwd.sp_inact = strtol (fields[6], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_inact = -1;
#else
return 0;
#endif
} else if (fields[6][0] == '\0')
spwd.sp_inact = -1;
/*
* Get the number of days after the epoch before the account is
* set to expire.
*/
if ((spwd.sp_expire = strtol (fields[7], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_expire = -1;
#else
return 0;
#endif
} else if (fields[7][0] == '\0')
spwd.sp_expire = -1;
/*
* This field is reserved for future use. But it isn't supposed
* to have anything other than a valid integer in it.
*/
if ((spwd.sp_flag = strtol (fields[8], &cpp, 10)) == 0 && *cpp) {
#ifdef USE_NIS
if (! nis_used)
return 0;
else
spwd.sp_flag = -1;
#else
return 0;
#endif
} else if (fields[8][0] == '\0')
spwd.sp_flag = -1;
return (&spwd);
}
/*
* fgetspent - get an entry from a /etc/shadow formatted stream
*/
struct spwd *
fgetspent(FILE *fp)
{
char buf[BUFSIZ];
char *cp;
if (! fp)
return (0);
#ifdef USE_NIS
while (fgets (buf, sizeof buf, fp) != (char *) 0)
#else
if (fgets (buf, sizeof buf, fp) != (char *) 0)
#endif
{
if ((cp = strchr (buf, '\n')))
*cp = '\0';
#ifdef USE_NIS
if (nis_ignore && IS_NISCHAR (buf[0]))
continue;
#endif
return my_sgetspent(buf);
}
return 0;
}
/*
* getspent - get a (struct spwd *) from the current shadow file
*/
struct spwd *
getspent(void)
{
#ifdef USE_NIS
int nis_1_user = 0;
struct spwd *val;
char buf[BUFSIZ];
#endif
if (! shadow)
setspent ();
#ifdef USE_NIS
again:
/*
* See if we are reading from the local file.
*/
if (nis_state == native || nis_state == native2) {
/*
* Get the next entry from the shadow file. Return NULL
* right away if there is none.
*/
if (! (val = fgetspent (shadow)))
return 0;
/*
* If this entry began with a NIS escape character, we have
* to see if this is just a single user, or if the entire
* map is being asked for.
*/
if (IS_NISCHAR (val->sp_namp[0])) {
if (val->sp_namp[1])
nis_1_user = 1;
else
nis_state = start;
}
/*
* If this isn't a NIS user and this isn't an escape to go
* use a NIS map, it must be a regular local user.
*/
if (nis_1_user == 0 && nis_state != start)
return val;
/*
* If this is an escape to use an NIS map, switch over to
* that bunch of code.
*/
if (nis_state == start)
goto again;
/*
* NEEDSWORK. Here we substitute pieces-parts of this entry.
*/
return 0;
} else {
if (nis_bound == 0) {
if (bind_nis ()) {
nis_state = native2;
goto again;
}
}
if (nis_state == start) {
if (yp_first (nis_domain, "shadow.bynam", &nis_key,
&nis_keylen, &nis_val, &nis_vallen)) {
nis_state = native2;
goto again;
}
nis_state = middle;
} else if (nis_state == middle) {
if (yp_next (nis_domain, "shadow.bynam", nis_key,
nis_keylen, &nis_key, &nis_keylen,
&nis_val, &nis_vallen)) {
nis_state = native2;
goto again;
}
}
return my_sgetspent(nis_val);
}
#else
return (fgetspent (shadow));
#endif
}
/*
* getspnam - get a shadow entry by name
*/
struct spwd *
getspnam(const char *name)
{
struct spwd *sp;
#ifdef NDBM
datum key;
datum content;
#endif
#ifdef USE_NIS
char buf[BUFSIZ];
static char save_name[16];
int nis_disabled = 0;
#endif
setspent ();
#ifdef NDBM
/*
* If the DBM file are now open, create a key for this UID and
* try to fetch the entry from the database. A matching record
* will be unpacked into a static structure and returned to
* the user.
*/
if (dbmopened) {
key.dsize = strlen (name);
key.dptr = (char *) name;
content = dbm_fetch (sp_dbm, key);
if (content.dptr != 0) {
memcpy (spwbuf, content.dptr, content.dsize);
spw_unpack (spwbuf, content.dsize, &spwd);
endspent();
return &spwd;
}
}
#endif
#ifdef USE_NIS
/*
* Search the shadow.byname map for this user.
*/
if (! nis_ignore && ! nis_bound)
bind_nis ();
if (! nis_ignore && nis_bound) {
char *cp;
if (yp_match (nis_domain, "shadow.byname", name,
strlen (name), &nis_val, &nis_vallen) == 0) {
if (cp = strchr (nis_val, '\n'))
*cp = '\0';
nis_state = middle;
if ((sp = my_sgetspent(nis_val))) {
strcpy (save_name, sp->sp_namp);
nis_key = save_name;
nis_keylen = strlen (save_name);
}
endspent();
return sp;
} else
nis_state = native2;
}
#endif
#ifdef USE_NIS
/*
* NEEDSWORK -- this is a mess, and it is the same mess in the
* other three files. I can't just blindly turn off NIS because
* this might be the first pass through the local files. In
* that case, I never discover that NIS is present.
*/
if (nis_used) {
nis_ignore++;
nis_disabled++;
}
#endif
while ((sp = getspent ()) != (struct spwd *) 0) {
if (strcmp (name, sp->sp_namp) == 0)
break;
}
#ifdef USE_NIS
if (nis_disabled)
nis_ignore--;
#endif
endspent();
return (sp);
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /*}*/

89
lib/shadow_.h Normal file
View File

@@ -0,0 +1,89 @@
/*
* Copyright 1988 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _H_SHADOW
#define _H_SHADOW
/*
* This information is not derived from AT&T licensed sources. Posted
* to the USENET 11/88, and updated 11/90 with information from SVR4.
*
* $Id: shadow_.h,v 1.2 1997/05/01 23:14:48 marekm Exp $
*/
#ifdef ITI_AGING
typedef time_t sptime;
#else
typedef long sptime;
#endif
/*
* Shadow password security file structure.
*/
struct spwd {
char *sp_namp; /* login name */
char *sp_pwdp; /* encrypted password */
sptime sp_lstchg; /* date of last change */
sptime sp_min; /* minimum number of days between changes */
sptime sp_max; /* maximum number of days between changes */
sptime sp_warn; /* number of days of warning before password
expires */
sptime sp_inact; /* number of days after password expires
until the account becomes unusable. */
sptime sp_expire; /* days since 1/1/70 until account expires */
unsigned long sp_flag; /* reserved for future use */
};
/*
* Shadow password security file functions.
*/
#include <stdio.h> /* for FILE */
#if defined(__STDC__)
struct spwd *getspent (void);
struct spwd *getspnam (const char *);
struct spwd *sgetspent (const char *);
struct spwd *fgetspent (FILE *);
void setspent (void);
void endspent (void);
int putspent (const struct spwd *, FILE *);
#else
struct spwd *getspent ();
struct spwd *getspnam ();
struct spwd *sgetspent ();
struct spwd *fgetspent ();
void setspent ();
void endspent ();
int putspent ();
#endif
#define SHADOW "/etc/shadow"
#endif

172
lib/shadowio.c Normal file
View File

@@ -0,0 +1,172 @@
#include <config.h>
#ifdef SHADOWPWD
#include "rcsid.h"
RCSID("$Id: shadowio.c,v 1.11 1998/01/29 23:22:32 marekm Exp $")
#include "prototypes.h"
#include "defines.h"
#ifdef HAVE_SHADOW_H
# include <shadow.h>
#endif
#include <stdio.h>
#include "commonio.h"
#include "shadowio.h"
struct spwd *
__spw_dup(const struct spwd *spent)
{
struct spwd *sp;
if (!(sp = (struct spwd *) malloc(sizeof *sp)))
return NULL;
*sp = *spent;
if (!(sp->sp_namp = strdup(spent->sp_namp)))
return NULL;
if (!(sp->sp_pwdp = strdup(spent->sp_pwdp)))
return NULL;
return sp;
}
static void *
shadow_dup(const void *ent)
{
const struct spwd *sp = ent;
return __spw_dup(sp);
}
static void
shadow_free(void *ent)
{
struct spwd *sp = ent;
free(sp->sp_namp);
free(sp->sp_pwdp);
free(sp);
}
static const char *
shadow_getname(const void *ent)
{
const struct spwd *sp = ent;
return sp->sp_namp;
}
static void *
shadow_parse(const char *line)
{
return (void *) sgetspent(line);
}
static int
shadow_put(const void *ent, FILE *file)
{
const struct spwd *sp = ent;
return (putspent(sp, file) == -1) ? -1 : 0;
}
static struct commonio_ops shadow_ops = {
shadow_dup,
shadow_free,
shadow_getname,
shadow_parse,
shadow_put,
fgets,
fputs
};
static struct commonio_db shadow_db = {
SHADOW_FILE, /* filename */
&shadow_ops, /* ops */
NULL, /* fp */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
0, /* changed */
0, /* isopen */
0, /* locked */
0, /* readonly */
1 /* use_lckpwdf */
};
int
spw_name(const char *filename)
{
return commonio_setname(&shadow_db, filename);
}
int
spw_file_present(void)
{
return commonio_present(&shadow_db);
}
int
spw_lock(void)
{
return commonio_lock(&shadow_db);
}
int
spw_open(int mode)
{
return commonio_open(&shadow_db, mode);
}
const struct spwd *
spw_locate(const char *name)
{
return commonio_locate(&shadow_db, name);
}
int
spw_update(const struct spwd *sp)
{
return commonio_update(&shadow_db, (const void *) sp);
}
int
spw_remove(const char *name)
{
return commonio_remove(&shadow_db, name);
}
int
spw_rewind(void)
{
return commonio_rewind(&shadow_db);
}
const struct spwd *
spw_next(void)
{
return commonio_next(&shadow_db);
}
int
spw_close(void)
{
return commonio_close(&shadow_db);
}
int
spw_unlock(void)
{
return commonio_unlock(&shadow_db);
}
struct commonio_entry *
__spw_get_head(void)
{
return shadow_db.head;
}
void
__spw_del_entry(const struct commonio_entry *ent)
{
commonio_del_entry(&shadow_db, ent);
}
#endif

13
lib/shadowio.h Normal file
View File

@@ -0,0 +1,13 @@
extern struct spwd *__spw_dup P_((const struct spwd *));
extern void __spw_set_changed P_((void));
extern int spw_close P_((void));
extern int spw_file_present P_((void));
extern const struct spwd *spw_locate P_((const char *));
extern int spw_lock P_((void));
extern int spw_name P_((const char *));
extern const struct spwd *spw_next P_((void));
extern int spw_open P_((int));
extern int spw_remove P_((const char *));
extern int spw_rewind P_((void));
extern int spw_unlock P_((void));
extern int spw_update P_((const struct spwd *));

320
lib/snprintf.c Normal file
View File

@@ -0,0 +1,320 @@
/**************************************************************
* Original:
* Patrick Powell Tue Apr 11 09:48:21 PDT 1995
* A bombproof version of doprnt (dopr) included.
* Sigh. This sort of thing is always nasty do deal with. Note that
* the version here does not include floating point...
*
* snprintf() is used instead of sprintf() as it does limit checks
* for string length. This covers a nasty loophole.
*
* The other functions are there to prevent NULL pointers from
* causing nast effects.
**************************************************************/
/* $XFree86: xc/lib/misc/snprintf.c,v 3.0 1996/08/26 06:19:23 dawes Exp $ */
#include <ctype.h>
#include "snprintf.h"
static void dopr();
static char *end;
/* varargs declarations: */
#if defined(HAVE_STDARG_H)
# include <stdarg.h>
# define HAVE_STDARGS /* let's hope that works everywhere (mj) */
# define VA_LOCAL_DECL va_list ap;
# define VA_START(f) va_start(ap, f)
# define VA_SHIFT(v,t) ; /* no-op for ANSI */
# define VA_END va_end(ap)
#else
# if defined(HAVE_VARARGS_H)
# include <varargs.h>
# undef HAVE_STDARGS
# define VA_LOCAL_DECL va_list ap;
# define VA_START(f) va_start(ap) /* f is ignored! */
# define VA_SHIFT(v,t) v = va_arg(ap,t)
# define VA_END va_end(ap)
# else
/*XX ** NO VARARGS ** XX*/
# endif
#endif
#ifdef HAVE_STDARGS
int snprintf (char *str, size_t count, const char *fmt, ...);
int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
#else
int snprintf ();
int vsnprintf ();
#endif
int
vsnprintf(str, count, fmt, args)
char *str;
size_t count;
const char *fmt;
va_list args;
{
str[0] = 0;
end = str+count-1;
dopr( str, fmt, args );
if( count>0 ){
end[0] = 0;
}
return(strlen(str));
}
/* VARARGS3 */
#ifdef HAVE_STDARGS
int
snprintf (char *str,size_t count,const char *fmt,...)
#else
int
snprintf (va_alist) va_dcl
#endif
{
#ifndef HAVE_STDARGS
char *str;
size_t count;
char *fmt;
#endif
VA_LOCAL_DECL
VA_START (fmt);
VA_SHIFT (str, char *);
VA_SHIFT (count, size_t );
VA_SHIFT (fmt, char *);
(void) vsnprintf ( str, count, fmt, ap);
VA_END;
return( strlen( str ) );
}
/*
* dopr(): poor man's version of doprintf
*/
static void fmtstr(
#if NeedFunctionPrototypes
char *value, int ljust, int len, int zpad
#endif
);
static void fmtnum(
#if NeedFunctionPrototypes
long value, int base, int dosign, int ljust, int len, int zpad
#endif
);
static void dostr(
#if NeedFunctionPrototypes
char *
#endif
);
static char *output;
static void dopr_outch(
#if NeedFunctionPrototypes
int c
#endif
);
static void
dopr( buffer, format, args )
char *buffer;
char *format;
va_list args;
{
int ch;
long value;
int longflag = 0;
char *strvalue;
int ljust;
int len;
int zpad;
output = buffer;
while( (ch = *format++) ){
switch( ch ){
case '%':
ljust = len = zpad = 0;
nextch:
ch = *format++;
switch( ch ){
case 0:
dostr( "**end of format**" );
return;
case '-': ljust = 1; goto nextch;
case '0': /* set zero padding if len not set */
if(len==0) zpad = '0';
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
len = len*10 + ch - '0';
goto nextch;
case 'l': longflag = 1; goto nextch;
case 'u': case 'U':
/*fmtnum(value,base,dosign,ljust,len,zpad) */
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 10,0, ljust, len, zpad ); break;
case 'o': case 'O':
/*fmtnum(value,base,dosign,ljust,len,zpad) */
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 8,0, ljust, len, zpad ); break;
case 'd': case 'D':
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 10,1, ljust, len, zpad ); break;
case 'x':
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value, 16,0, ljust, len, zpad ); break;
case 'X':
if( longflag ){
value = va_arg( args, long );
} else {
value = va_arg( args, int );
}
fmtnum( value,-16,0, ljust, len, zpad ); break;
case 's':
strvalue = va_arg( args, char *);
fmtstr( strvalue,ljust,len,zpad ); break;
case 'c':
ch = va_arg( args, int );
dopr_outch( ch ); break;
case '%': dopr_outch( ch ); continue;
default:
dostr( "???????" );
}
longflag = 0;
break;
default:
dopr_outch( ch );
break;
}
}
*output = 0;
}
static void
fmtstr( value, ljust, len, zpad )
char *value;
int ljust, len, zpad;
{
int padlen, strlen; /* amount to pad */
if( value == 0 ){
value = "<NULL>";
}
for( strlen = 0; value[strlen]; ++ strlen ); /* strlen */
padlen = len - strlen;
if( padlen < 0 ) padlen = 0;
if( ljust ) padlen = -padlen;
while( padlen > 0 ) {
dopr_outch( ' ' );
--padlen;
}
dostr( value );
while( padlen < 0 ) {
dopr_outch( ' ' );
++padlen;
}
}
static void
fmtnum( value, base, dosign, ljust, len, zpad )
long value;
int base, dosign, ljust, len, zpad;
{
int signvalue = 0;
unsigned long uvalue;
char convert[20];
int place = 0;
int padlen = 0; /* amount to pad */
int caps = 0;
/* DEBUGP(("value 0x%x, base %d, dosign %d, ljust %d, len %d, zpad %d\n",
value, base, dosign, ljust, len, zpad )); */
uvalue = value;
if( dosign ){
if( value < 0 ) {
signvalue = '-';
uvalue = -value;
}
}
if( base < 0 ){
caps = 1;
base = -base;
}
do{
convert[place++] =
(caps? "0123456789ABCDEF":"0123456789abcdef")
[uvalue % (unsigned)base ];
uvalue = (uvalue / (unsigned)base );
}while(uvalue);
convert[place] = 0;
padlen = len - place;
if( padlen < 0 ) padlen = 0;
if( ljust ) padlen = -padlen;
/* DEBUGP(( "str '%s', place %d, sign %c, padlen %d\n",
convert,place,signvalue,padlen)); */
if( zpad && padlen > 0 ){
if( signvalue ){
dopr_outch( signvalue );
--padlen;
signvalue = 0;
}
while( padlen > 0 ){
dopr_outch( zpad );
--padlen;
}
}
while( padlen > 0 ) {
dopr_outch( ' ' );
--padlen;
}
if( signvalue ) dopr_outch( signvalue );
while( place > 0 ) dopr_outch( convert[--place] );
while( padlen < 0 ){
dopr_outch( ' ' );
++padlen;
}
}
static void
dostr( str )
char *str;
{
while(*str) dopr_outch(*str++);
}
static void
dopr_outch( c )
int c;
{
if( iscntrl(c) && c != '\n' && c != '\t' ){
c = '@' + (c & 0x1F);
if( end == 0 || output < end ){
*output++ = '^';
}
}
if( end == 0 || output < end ){
*output++ = c;
}
}

51
lib/snprintf.h Normal file
View File

@@ -0,0 +1,51 @@
/* $XFree86: xc/lib/misc/snprintf.h,v 3.1 1996/08/26 14:42:33 dawes Exp $ */
#ifndef SNPRINTF_H
#define SNPRINTF_H
#ifdef HAS_SNPRINTF
#ifdef LIBXT
#define _XtSnprintf snprintf
#define _XtVsnprintf vsnprintf
#endif
#ifdef LIBX11
#define _XSnprintf snprintf
#define _XVsnprintf vsnprintf
#endif
#else /* !HAS_SNPRINTF */
#ifdef LIBXT
#define snprintf _XtSnprintf
#define vsnprintf _XtVsnprintf
#endif
#ifdef LIBX11
#define snprintf _XSnprintf
#define vsnprintf _XVsnprintf
#endif
#if 1 /* the system might have no X11 headers. -MM */
#include <X11/Xos.h>
#include <X11/Xlib.h>
#else /* but we still need this... */
#include <sys/types.h>
/* adjust the following defines if necessary (pre-ANSI) */
#define NeedFunctionPrototypes 1
#define NeedVarargsPrototypes 1
#endif
#if NeedVarargsPrototypes
#define HAVE_STDARG_H
#endif
#ifdef HAVE_STDARG_H
#include <stdarg.h>
extern int snprintf (char *str, size_t count, const char *fmt, ...);
extern int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
#else
extern int snprintf ();
extern int vsnprintf ();
#endif
#endif /* HAS_SNPRINTF */
#endif /* SNPRINTF_H */

116
lib/spdbm.c Normal file
View File

@@ -0,0 +1,116 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#if defined(SHADOWPWD) && defined(NDBM) /*{*/
#include "rcsid.h"
RCSID("$Id: spdbm.c,v 1.3 1997/12/07 23:26:58 marekm Exp $")
#include <string.h>
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
#include <ndbm.h>
extern DBM *sp_dbm;
/*
* sp_dbm_update
*
* Updates the DBM password files, if they exist.
*/
int
sp_dbm_update(struct spwd *sp)
{
datum key;
datum content;
char data[BUFSIZ];
int len;
static int once;
if (! once) {
if (! sp_dbm)
setspent ();
once++;
}
if (! sp_dbm)
return 0;
len = spw_pack (sp, data);
content.dsize = len;
content.dptr = data;
key.dsize = strlen (sp->sp_namp);
key.dptr = sp->sp_namp;
if (dbm_store (sp_dbm, key, content, DBM_REPLACE))
return 0;
return 1;
}
/*
* sp_dbm_remove
*
* Updates the DBM password files, if they exist.
*/
int
sp_dbm_remove(char *user)
{
datum key;
static int once;
if (! once) {
if (! sp_dbm)
setspent ();
once++;
}
if (! sp_dbm)
return 0;
key.dsize = strlen (user);
key.dptr = user;
if (dbm_delete (sp_dbm, key))
return 0;
return 1;
}
int
sp_dbm_present(void)
{
return (access(SHADOW_PAG_FILE, F_OK) == 0);
}
#endif /*} SHADOWPWD && NDBM */

113
lib/sppack.c Normal file
View File

@@ -0,0 +1,113 @@
/*
* Copyright 1990 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifdef SHADOWPWD /*{*/
#include "rcsid.h"
RCSID("$Id: sppack.c,v 1.3 1997/12/07 23:26:58 marekm Exp $")
#include <stdio.h>
#include <sys/types.h>
#include "defines.h"
int
spw_pack(const struct spwd *spwd, char *buf)
{
char *cp;
cp = buf;
strcpy (cp, spwd->sp_namp);
cp += strlen (cp) + 1;
strcpy (cp, spwd->sp_pwdp);
cp += strlen (cp) + 1;
memcpy (cp, &spwd->sp_min, sizeof spwd->sp_min);
cp += sizeof spwd->sp_min;
memcpy (cp, &spwd->sp_max, sizeof spwd->sp_max);
cp += sizeof spwd->sp_max;
memcpy (cp, &spwd->sp_lstchg, sizeof spwd->sp_lstchg);
cp += sizeof spwd->sp_lstchg;
memcpy (cp, &spwd->sp_warn, sizeof spwd->sp_warn);
cp += sizeof spwd->sp_warn;
memcpy (cp, &spwd->sp_inact, sizeof spwd->sp_inact);
cp += sizeof spwd->sp_inact;
memcpy (cp, &spwd->sp_expire, sizeof spwd->sp_expire);
cp += sizeof spwd->sp_expire;
memcpy (cp, &spwd->sp_flag, sizeof spwd->sp_flag);
cp += sizeof spwd->sp_flag;
return cp - buf;
}
int
spw_unpack(char *buf, int len, struct spwd *spwd)
{
char *org = buf;
spwd->sp_namp = buf;
buf += strlen (buf) + 1;
spwd->sp_pwdp = buf;
buf += strlen (buf) + 1;
memcpy (&spwd->sp_min, buf, sizeof spwd->sp_min);
buf += sizeof spwd->sp_min;
memcpy (&spwd->sp_max, buf, sizeof spwd->sp_max);
buf += sizeof spwd->sp_max;
memcpy (&spwd->sp_lstchg, buf, sizeof spwd->sp_lstchg);
buf += sizeof spwd->sp_lstchg;
memcpy (&spwd->sp_warn, buf, sizeof spwd->sp_warn);
buf += sizeof spwd->sp_warn;
memcpy (&spwd->sp_inact, buf, sizeof spwd->sp_inact);
buf += sizeof spwd->sp_inact;
memcpy (&spwd->sp_expire, buf, sizeof spwd->sp_expire);
buf += sizeof spwd->sp_expire;
memcpy (&spwd->sp_flag, buf, sizeof spwd->sp_flag);
buf += sizeof spwd->sp_flag;
if (buf - org > len)
return -1;
return 0;
}
#endif /*}*/

25
lib/strcasecmp.c Normal file
View File

@@ -0,0 +1,25 @@
#include <config.h>
#include "defines.h"
#include <ctype.h>
#include "rcsid.h"
RCSID("$Id: strcasecmp.c,v 1.1 1999/07/09 18:02:43 marekm Exp $")
/*
* strcasecmp - compare strings, ignoring case
*/
char *
strcasecmp(const char *s1, const char *s2)
{
int ret;
for (;;) {
ret = tolower(*s1) - tolower(*s2);
if (ret || *s1 == '\0' || *s2 == '\0')
break;
s1++;
s2++;
}
return ret;
}

16
lib/strdup.c Normal file
View File

@@ -0,0 +1,16 @@
#include <config.h>
#include "defines.h"
#include "rcsid.h"
RCSID("$Id: strdup.c,v 1.2 1997/12/07 23:26:59 marekm Exp $")
extern char *malloc();
char *
strdup(const char *str)
{
char *s = malloc(strlen(str) + 1);
if (s)
strcpy(s, str);
return s;
}

23
lib/strerror.c Normal file
View File

@@ -0,0 +1,23 @@
#include <config.h>
#include <errno.h>
#include "defines.h"
#include "rcsid.h"
RCSID("$Id: strerror.c,v 1.3 1998/12/28 20:34:39 marekm Exp $")
#include <stdio.h>
extern int sys_nerr;
extern char *sys_errlist[];
char *
strerror(int err)
{
static char unknown[80];
if (err >= 0 && err < sys_nerr)
return sys_errlist[err];
snprintf(unknown, sizeof unknown, _("Unknown error %d"), err);
errno = EINVAL;
return unknown;
}

55
lib/strstr.c Normal file
View File

@@ -0,0 +1,55 @@
/*
* Copyright 1989 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#include "defines.h"
#include "rcsid.h"
RCSID("$Id: strstr.c,v 1.4 1998/01/29 23:22:32 marekm Exp $")
/*
* strstr - find substring in string
*/
char *
strstr(const char *string, const char *pattern)
{
char *cp;
int len;
len = strlen (pattern);
for (cp = string;cp = strchr (cp, *pattern);) {
if (strncmp (cp, pattern, len) == 0)
return cp;
cp++;
}
return 0;
}

90
lib/tcfsio.c Normal file
View File

@@ -0,0 +1,90 @@
#include <config.h>
#ifdef HAVE_TCFS
#include "prototypes.h"
#include "defines.h"
#ifdef TCFS_GDBM_SUPPORT
#undef GDBM_SUPPORT
#define GDBM_SUPPORT
#endif
#include <tcfslib.h>
#include <stdio.h>
#include "commonio.h"
#include "tcfsio.h"
static struct commonio_db tcfs_db = {
TCFSPWDFILE, /* filename */
NULL, /* ops */
NULL,
NULL,
NULL,
NULL,
0,
0,
0,
0,
1
};
int
tcfs_file_present(void)
{
return commonio_present(&tcfs_db);
}
int
tcfs_lock(void)
{
return commonio_lock(&tcfs_db);
}
int
tcfs_open(int mode)
{
return 1;
/* return tcfs_open(); */
}
tcfspwdb *
tcfs_locate(char *name)
{
return tcfs_getpwnam(name, NULL);
}
int
tcfs_update(char *user, struct tcfspwd *tcfspword)
{
char *o, *p;
o=(char*)calloc(128,sizeof(char));
p=(char*)calloc(128,sizeof(char));
strcpy (o, tcfspword->tcfsorig);
strcpy (p, tcfspword->tcfspass);
return tcfs_chgkey(user,o,p);
}
int
tcfs_remove(char *name)
{
return tcfs_putpwnam(name, NULL, U_DEL);
}
int
tcfs_close(void)
{
return 1;
/* return tcfs_close(&shadow_db); */
}
int
tcfs_unlock(void)
{
return commonio_unlock(&tcfs_db);
}
#endif

14
lib/tcfsio.h Normal file
View File

@@ -0,0 +1,14 @@
struct tcfspwd {
char tcfspass[200]; /* new password */
char tcfsorig[200]; /* old password */
};
extern int tcfs_close P_((void));
extern int tcfs_file_present P_((void));
extern tcfspwdb *tcfs_locate P_((char *));
extern int tcfs_lock P_((void));
extern int tcfs_name P_((char *));
extern int tcfs_open P_((int));
extern int tcfs_remove P_((char *));
extern int tcfs_unlock P_((void));
extern int tcfs_update P_((char *, struct tcfspwd *));

114
lib/utent.c Normal file
View File

@@ -0,0 +1,114 @@
/*
* Copyright 1993 - 1994, Julianne Frances Haugh
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#ifndef HAVE_GETUTENT
#include "defines.h"
#include <stdio.h>
#include <fcntl.h>
#include <utmp.h>
#ifndef lint
static char rcsid[] = "$Id: utent.c,v 1.4 1998/01/29 23:22:32 marekm Exp $";
#endif
static int utmp_fd = -1;
static struct utmp utmp_buf;
/*
* setutent - open or rewind the utmp file
*/
void
setutent(void)
{
if (utmp_fd == -1)
if ((utmp_fd = open (_UTMP_FILE, O_RDWR)) == -1)
utmp_fd = open (_UTMP_FILE, O_RDONLY);
if (utmp_fd != -1)
lseek (utmp_fd, (off_t) 0L, SEEK_SET);
}
/*
* endutent - close the utmp file
*/
void
endutent(void)
{
if (utmp_fd != -1)
close (utmp_fd);
utmp_fd = -1;
}
/*
* getutent - get the next record from the utmp file
*/
struct utmp *
getutent(void)
{
if (utmp_fd == -1)
setutent ();
if (utmp_fd == -1)
return 0;
if (read (utmp_fd, &utmp_buf, sizeof utmp_buf) != sizeof utmp_buf)
return 0;
return &utmp_buf;
}
/*
* getutline - get the utmp entry matching ut_line
*/
struct utmp *
getutline(const struct utmp *utent)
{
struct utmp save;
struct utmp *new;
save = *utent;
while (new = getutent ())
if (strncmp (new->ut_line, save.ut_line, sizeof new->ut_line))
continue;
else
return new;
return (struct utmp *) 0;
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif