Compare commits

..

25 Commits

Author SHA1 Message Date
Chris Hofstaedtler 4c944d236c pristine-tar data for shadow_4.19.3.orig.tar.xz 2026-02-02 07:32:37 +01:00
Chris Hofstaedtler 46cc41933b pristine-tar data for shadow_4.19.2.orig.tar.xz 2026-01-25 14:17:30 +01:00
Chris Hofstaedtler 388cb97893 pristine-tar data for shadow_4.19.0.orig.tar.xz 2026-01-06 00:37:55 +01:00
Chris Hofstaedtler 81c4e06c3b pristine-tar data for shadow_4.18.0.orig.tar.xz 2025-08-26 22:55:39 +02:00
Chris Hofstaedtler 4fcb8d510b pristine-tar data for shadow_4.17.4.orig.tar.xz 2025-03-29 13:24:40 +01:00
Chris Hofstaedtler 2ff61e3c80 pristine-tar data for shadow_4.17.3.orig.tar.xz 2025-03-16 14:48:45 +01:00
Chris Hofstaedtler 61472718df pristine-tar data for shadow_4.15.3.orig.tar.xz 2024-07-06 16:54:26 +02:00
Chris Hofstaedtler b63aced4b3 pristine-tar data for shadow_4.16.0.orig.tar.xz 2024-06-25 20:10:09 +02:00
Chris Hofstaedtler b532614a3b pristine-tar data for shadow_4.15.2.orig.tar.xz 2024-06-22 17:35:40 +02:00
Chris Hofstaedtler 02f8995749 pristine-tar data for shadow_4.15.1.orig.tar.xz 2024-06-13 04:22:50 +02:00
Balint Reczey cb56b9d10e pristine-tar data for shadow_4.13+dfsg1.orig.tar.xz 2022-11-10 16:24:14 +01:00
Balint Reczey bdb2aa7202 pristine-tar data for shadow_4.12.3+dfsg1.orig.tar.xz 2022-08-24 00:06:47 +02:00
Balint Reczey 7a3935ef98 pristine-tar data for shadow_4.12.2+dfsg1.orig.tar.xz 2022-08-20 18:17:23 +02:00
Balint Reczey 9d0f797494 pristine-tar data for shadow_4.11.1+dfsg1.orig.tar.xz 2022-01-21 23:41:20 +01:00
Balint Reczey 862809e6de pristine-tar data for shadow_4.9.orig.tar.xz 2021-11-07 15:19:02 +01:00
Balint Reczey 0e71b4600c pristine-tar data for shadow_4.8.1.orig.tar.xz 2020-02-06 23:15:00 +01:00
Andreas Henriksson fcee2d4028 pristine-tar data for shadow_4.8.orig.tar.xz 2019-12-05 13:30:32 +01:00
Balint Reczey 3ee8ec58bb pristine-tar data for shadow_4.7.orig.tar.xz 2019-06-23 22:06:49 +02:00
Balint Reczey d20c220441 pristine-tar data for shadow_4.6.orig.tar.gz 2019-03-03 23:31:35 +01:00
Balint Reczey 451264e2b2 pristine-tar data for shadow_4.5.orig.tar.gz 2017-08-10 18:26:48 -04:00
Balint Reczey d2ea0055d4 pristine-tar data for shadow_4.4.orig.tar.gz 2016-11-30 02:36:08 +01:00
Christian Perrier d48226e507 pristine-tar data for shadow_4.2.1.orig.tar.xz 2014-05-09 19:06:08 +02:00
Christian Perrier 1a19ece5ee pristine-tar data for shadow_4.2.orig.tar.xz 2014-03-14 21:57:28 +01:00
Christian Perrier a70f9f8694 pristine-tar data for shadow_4.2.orig.tar.xz 2014-03-01 19:59:51 +01:00
Christian Perrier 02ea908972 pristine-tar data for shadow_4.1.5.1.orig.tar.xz 2013-07-27 18:42:28 +02:00
10602 changed files with 111 additions and 685809 deletions
-48
View File
@@ -1,48 +0,0 @@
*~
lib*.a
*.o
*.lo
*.la
*.gmo
.deps
.libs
*.patch
*.rej
*.orig
Makefile
Makefile.in
/ABOUT-NLS
/aclocal.m4
/autom4te.cache
/compile
/config.guess
/config.h
/config.h.in
/config.log
/config.rpath
/config.status
/config.sub
/configure
/depcomp
/install-sh
/libtool
/ltmain.sh
/m4
/missing
/stamp-h1
/ylwrap
/po/*.header
/po/*.sed
/po/*.sin
/po/Makefile.in.in
/po/Makevars.template
/po/POTFILES
/po/Rules-quot
/po/stamp-po
/shadow.spec
/libmisc/getdate.c
-118
View File
@@ -1,118 +0,0 @@
NOTE:
This license has been obsoleted by the change to the BSD-style copyright.
You may continue to use this license if you wish, but you are under no
obligation to do so.
(*
This document is freely plagiarised from the 'Artistic Licence',
distributed as part of the Perl v4.0 kit by Larry Wall, which is
available from most major archive sites. I stole it from CrackLib.
$Id$
*)
This documents purpose is to state the conditions under which this
Package (See definition below) viz: "Shadow", the Shadow Password Suite
which is held by Julianne Frances Haugh, may be copied, such that the
copyright holder maintains some semblance of artistic control over the
development of the package, while giving the users of the package the
right to use and distribute the Package in a more-or-less customary
fashion, plus the right to make reasonable modifications.
So there.
***************************************************************************
Definitions:
A "Package" refers to the collection of files distributed by the
Copyright Holder, and derivatives of that collection of files created
through textual modification, or segments thereof.
"Standard Version" refers to such a Package if it has not been modified,
or has been modified in accordance with the wishes of the Copyright
Holder.
"Copyright Holder" is whoever is named in the copyright or copyrights
for the package.
"You" is you, if you're thinking about copying or distributing this
Package.
"Reasonable copying fee" is whatever you can justify on the basis of
media cost, duplication charges, time of people involved, and so on.
(You will not be required to justify it to the Copyright Holder, but
only to the computing community at large as a market that must bear the
fee.)
"Freely Available" means that no fee is charged for the item itself,
though there may be fees involved in handling the item. It also means
that recipients of the item may redistribute it under the same
conditions they received it.
1. You may make and give away verbatim copies of the source form of the
Standard Version of this Package without restriction, provided that you
duplicate all of the original copyright notices and associated
disclaimers.
2. You may apply bug fixes, portability fixes and other modifications
derived from the Public Domain or from the Copyright Holder. A Package
modified in such a way shall still be considered the Standard Version.
3. You may otherwise modify your copy of this Package in any way,
provided that you insert a prominent notice in each changed file stating
how and when AND WHY you changed that file, and provided that you do at
least ONE of the following:
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet or an
equivalent medium, or placing the modifications on a major archive site
such as uunet.uu.net, or by allowing the Copyright Holder to include
your modifications in the Standard Version of the Package.
b) use the modified Package only within your corporation or organization.
c) rename any non-standard executables so the names do not conflict with
standard executables, which must also be provided, and provide separate
documentation for each non-standard executable that clearly documents
how it differs from the Standard Version.
d) make other distribution arrangements with the Copyright Holder.
4. You may distribute the programs of this Package in object code or
executable form, provided that you do at least ONE of the following:
a) distribute a Standard Version of the executables and library files,
together with instructions (in the manual page or equivalent) on where
to get the Standard Version.
b) accompany the distribution with the machine-readable source of the
Package with your modifications.
c) accompany any non-standard executables with their corresponding
Standard Version executables, giving the non-standard executables
non-standard names, and clearly documenting the differences in manual
pages (or equivalent), together with instructions on where to get the
Standard Version.
d) make other distribution arrangements with the Copyright Holder.
5. You may charge a reasonable copying fee for any distribution of this
Package. You may charge any fee you choose for support of this Package.
YOU MAY NOT CHARGE A FEE FOR THIS PACKAGE ITSELF. However, you may
distribute this Package in aggregate with other (possibly commercial)
programs as part of a larger (possibly commercial) software distribution
provided that YOU DO NOT ADVERTISE this package as a product of your
own.
6. The name of the Copyright Holder may not be used to endorse or
promote products derived from this software without specific prior
written permission.
7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The End
-15081
View File
File diff suppressed because it is too large Load Diff
-8
View File
@@ -1,8 +0,0 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = NEWS README TODO shadow.spec.in
AUTOMAKE_OPTIONS = 1.5 dist-bzip2 foreign
SUBDIRS = po man libmisc lib src \
contrib doc etc
-2166
View File
File diff suppressed because it is too large Load Diff
-121
View File
@@ -1,121 +0,0 @@
Shadow SITES
============
Homepage
http://pkg-shadow.alioth.debian.org/
FTP site
ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow
SVN repository
anonymous read only access: svn://svn.debian.org/pkg-shadow/upstream
SVN web interface
http://svn.debian.org/wsvn/pkg-shadow/upstream
or
http://svn.debian.org/viewsvn/pkg-shadow/upstream
Mailing lists
for general discuss: pkg-shadow-devel@lists.alioth.debian.org
commit list: pkg-shadow-commits@lists.alioth.debian.org
Mailing lists subscription
http://lists.alioth.debian.org/mailman/listinfo/pkg-shadow-devel
http://lists.alioth.debian.org/mailman/listinfo/pkg-shadow-commits
Mailing lists archives:
http://lists.alioth.debian.org/pipermail/pkg-shadow-devel/
http://lists.alioth.debian.org/pipermail/pkg-shadow-commits/
S/Key support:
Shadow can be built with S/Key support using the S/Key package from:
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libskey/
or
http://gentoo.osuosl.org/distfiles/skey-1.1.5.tar.bz2
Authors and contributors
========================
Thanks to at least the following people for sending patches, bug
reports and various comments. This list may be incomplete, I received
a lot of mail...
Adam Rudnicki <adam@v-lo.krakow.pl>
Alan Curry <pacman@tardis.mars.net>
Alexander O. Yuriev <alex@bach.cis.temple.edu>
Algis Rudys <arudys@rice.edu>
Andreas Jaeger <aj@arthur.rhein-neckar.de>
Aniello Del Sorbo <anidel@edu-gw.dia.unisa.it>
Anton Gluck <gluc@midway.uchicago.edu>
Arkadiusz Miskiewicz <misiek@pld.org.pl>
Ben Collins <bcollins@debian.org>
Brian R. Gaeke <brg@dgate.org>
Calle Karlsson <ckn@kash.se>
Chip Rosenthal <chip@unicom.com>
Chris Evans <lady0110@sable.ox.ac.uk>
Cristian Gafton <gafton@sorosis.ro>
Dan Walsh <dwalsh@redhat.com>
Darcy Boese <possum@chardonnay.niagara.com>
Dave Hagewood <admin@arrowweb.com>
David A. Holland <dholland@hcs.harvard.edu>
David Frey <David.Frey@lugs.ch>
Ed Carp <ecarp@netcom.com>
Floody <flood@evcom.net>
Frank Denis <j@4u.net>
George Kraft IV <gk4@us.ibm.com>
Greg Mortensen <loki@world.std.com>
Guido van Rooij
Guy Maor <maor@debian.org>
Hrvoje Dogan <hdogan@bjesomar.srce.hr>
Jakub Hrozek <jhrozek@redhat.com>
Janos Farkas <chexum@bankinf.banki.hu>
Jay Soffian <jay@lw.net>
Jesse Thilo <Jesse.Thilo@pobox.com>
Joey Hess <joey@kite.ml.org>
John Adelsberger <jja@umr.edu>
Jonathan Hankins <jhankins@mailserv.homewood.k12.al.us>
Jon Lewis <jlewis@lewis.org>
Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
Judd Bourgeois <shagboy@bluesky.net>
Juergen Heinzl <unicorn@noris.net>
Juha Virtanen <jiivee@iki.fi>
Julian Pidancet <julian.pidancet@gmail.com>
Julianne Frances Haugh <jockgrrl@ix.netcom.com>
Leonard N. Zubkoff <lnz@dandelion.com>
Luca Berra <bluca@www.polimi.it>
Lukáš Kuklínek <lkukline@redhat.com>
Lutz Schwalowsky <schwalow@mineralogie.uni-hamburg.de>
Marc Ewing <marc@redhat.com>
Martin Bene <mb@sime.com>
Martin Mares <mj@gts.cz>
Michael Meskes <meskes@topsystem.de>
Michael Talbot-Wilson <mike@calypso.bns.com.au>
Mike Frysinger <vapier@gentoo.org>
Mike Pakovic <mpakovic@users.southeast.net>
Nicolas François <nicolas.francois@centraliens.net>
Nikos Mavroyanopoulos <nmav@i-net.paiko.gr>
Pavel Machek <pavel@bug.ucw.cz>
Peter Vrabec <pvrabec@redhat.com>
Phillip Street
Rafał Maszkowski <rzm@icm.edu.pl>
Rani Chouha <ranibey@smartec.com>
Sami Kerola <kerolasa@rocketmail.com>
Scott Garman <scott.a.garman@intel.com>
Sebastian Rick Rijkers <srrijkers@gmail.com>
Seraphim Mellos <mellos@ceid.upatras.gr>
Shane Watts <shane@nexus.mlckew.edu.au>
Steve M. Robbins <steve@nyongwa.montreal.qc.ca>
Thorsten Kukuk <kukuk@suse.de>
Tim Hockin <thockin@eagle.ais.net>
Timo Karjalainen <timok@iki.fi>
Ulisses Alonso Camaro <ulisses@pusa.eleinf.uv.es>
Werner Fink <werner@suse.de>
Maintainers
===========
Tomasz Kłoczko <kloczek@pld.org.pl> (2000-2007)
Nicolas François <nicolas.francois@centraliens.net> (2007-now)
-127
View File
@@ -1,127 +0,0 @@
* Create a common usage function that'd take the array of
long options and an array of descriptions and output that so things would
be standardized across the utils.
Usage strings should be normalized and split first.
Investigate optparse.
/etc/default/useradd
* GROUP=1000 should accept a group name.
Check when RLOGIN is enabled if ruserok() exists
Move selinux_file_context out of libmisc/copydir.c
Review hardcoded root account?
review all call to strto
libmisc/cleanup_user.c
cleanup needed (cleanup_report_add_user* not used)
libxcrypt support
* http://wiki.linuxfromscratch.org/patches/browser/trunk/shadow/shadow-4.0.18.1-owl_blowfish-1.patch
implement getlong, getulong.
avoid atoi, atol, atoul, strtol, strtoul, ...
manpages: comment the RLOGIN parts
Replace build_list (in lib/gshadow.c) and list (in lib/sgetgrent.c) by
comma_to_list()
Revert the modified files if all files could not be changed.
* or warn and indicate which files were modified and which were not.
* check the order the files are modified.
report nscd_flush_cache failures?
call nscd from the programs or from lib (commonio?)
PAM: check if a non-interactive conversation function could be used to set
the password in chpasswd and newusers
WITH_SELINUX
- review all tools to check that the strategies are consistent
chage, chfn, chsh: same change needed as in passwd.
- probably need moving check_selinux_access to a separate file.
testsuite
- newgrp
- test with unknown user's GID
newusers
- add logging to SYSLOG & AUDIT
- use CREATE_HOME
- Add a -Z option (see useradd / usermod)
Document when/where option appeared, document whether an option is standard
or not.
Check all the expiry semantics
ALL:
- move base passwd/shadow/group/gshadow operation to module for allow write
different backend modules for db, NIS, LDAP and others. Default backend it
will be goot if will be chosen depending on /etc/nsswitch.conf and allow
override this by -r <repository> options (where the <repository> can be
file, db, nis nisplus, ldap .. like on /etc/nsswitch.conf in service column).
passwd have old piece of code with handling -r option and it will be good
finish this and propagate on other shadow tools for allow operate on other
user databases by well known tools.
- Protect against signals. Register do_cleanups in a signal handler.
- login.defs
- generate depending on configuration
- useradd:
- add handle create user mail spool in maildir format.
- Add support for -k in -D mode
- Add support for -K in -D mode
- Add option to create or not the mail spool (and set the default in -D
mode)
- Change -l to reset the entry if an entry was already there
- set the mask in mkdir?
- userdel:
- add backup option for the removal of user resources,
- user_busy: check that the user is not running any processes.
- missing "deleting group" FAILED
- home dir removed, but userdel may fail and may leave the user
=> warning needed
- usermod
- add an option equivalent to useradd's -l (only when uid is changed)
- the mode of new home directories should be set according to the
original mode. Does copy_tree does this?
- user renamed, order is not kept in /etc/group (see
47_usermod-l_no_shadow_file). This is a problem when the first user is
considered as the admin.
- see mail "user ID change" on April, 15
+ fix call to chown (combination of -m and -u/-g)
+ add tests
- passwd:
- check combination of options (e.g. -u/-l)
- when -u refuse to unlock because it would create an empty password, it
should not display "Password changed."
exit instead?
- newgrp: check the USE_PAM section.
- pwck
- Add check to move passwd passwords to shadow if there is a shadow
entry (with a password).
- Add check to move passwd passwords to shadow if there is a shadow
file.
- Support an alternative /etc/tcb directory as second parameter.
- add options -g / -G to specify alternative group / gshadow files
- su
- add a login.defs configuration parameter to add variables to keep in
the environment with "su -l" (TERM/TERMCOLOR/...)
- vipw
- set ACLs and XATTRs on the temporary file (and backups?)
- vipw + selinux -> use lib/selinux.c
-54
View File
@@ -1,54 +0,0 @@
# Checks the location of the XML Catalog
# Usage:
# JH_PATH_XML_CATALOG([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# Defines XMLCATALOG and XML_CATALOG_FILE substitutions
AC_DEFUN([JH_PATH_XML_CATALOG],
[
# check for the presence of the XML catalog
AC_ARG_WITH([xml-catalog],
AC_HELP_STRING([--with-xml-catalog=CATALOG],
[path to xml catalog to use]),,
[with_xml_catalog=/etc/xml/catalog])
jh_found_xmlcatalog=true
XML_CATALOG_FILE="$with_xml_catalog"
AC_SUBST([XML_CATALOG_FILE])
AC_MSG_CHECKING([for XML catalog ($XML_CATALOG_FILE)])
if test -f "$XML_CATALOG_FILE"; then
AC_MSG_RESULT([found])
else
jh_found_xmlcatalog=false
AC_MSG_RESULT([not found])
fi
# check for the xmlcatalog program
AC_PATH_PROG(XMLCATALOG, xmlcatalog, no)
if test "x$XMLCATALOG" = xno; then
jh_found_xmlcatalog=false
fi
if $jh_found_xmlcatalog; then
ifelse([$1],,[:],[$1])
else
ifelse([$2],,[AC_MSG_ERROR([could not find XML catalog])],[$2])
fi
])
# Checks if a particular URI appears in the XML catalog
# Usage:
# JH_CHECK_XML_CATALOG(URI, [FRIENDLY-NAME], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
AC_DEFUN([JH_CHECK_XML_CATALOG],
[
AC_REQUIRE([JH_PATH_XML_CATALOG],[JH_PATH_XML_CATALOG(,[:])])dnl
AC_MSG_CHECKING([for ifelse([$2],,[$1],[$2]) in XML catalog])
if $jh_found_xmlcatalog && \
AC_RUN_LOG([$XMLCATALOG --noout "$XML_CATALOG_FILE" "$1" >&2]); then
AC_MSG_RESULT([found])
ifelse([$3],,,[$3
])dnl
else
AC_MSG_RESULT([not found])
ifelse([$4],,
[AC_MSG_ERROR([could not find ifelse([$2],,[$1],[$2]) in XML catalog])],
[$4])
fi
])
-12
View File
@@ -1,12 +0,0 @@
#! /bin/sh
autoreconf -v -f --install || exit 1
./configure \
CFLAGS="-O2 -Wall" \
--enable-man \
--enable-maintainer-mode \
--disable-shared \
--without-libpam \
--with-selinux \
"$@"
-679
View File
@@ -1,679 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT
AM_INIT_AUTOMAKE(shadow, 4.4)
AC_CONFIG_HEADERS([config.h])
dnl Some hacks...
test "$prefix" = "NONE" && prefix="/usr"
test "$prefix" = "/usr" && exec_prefix=""
AC_GNU_SOURCE
AM_DISABLE_SHARED
AM_ENABLE_STATIC
AM_MAINTAINER_MODE
dnl Checks for programs.
AC_PROG_CC
AC_ISC_POSIX
AC_PROG_LN_S
AC_PROG_YACC
AM_PROG_LIBTOOL
dnl Checks for libraries.
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_HEADER_STDBOOL
AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
utime.h ulimit.h sys/resource.h gshadow.h lastlog.h \
locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h \
attr/error_context.h)
dnl shadow now uses the libc's shadow implementation
AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \
gettimeofday getusershell getutent initgroups lchown lckpwdf lstat \
lutimes memcpy memset setgroups sigaction strchr updwtmp updwtmpx innetgr \
getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo \
ruserok)
AC_SYS_LARGEFILE
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_UID_T
AC_TYPE_OFF_T
AC_TYPE_PID_T
AC_TYPE_MODE_T
AC_HEADER_STAT
AC_CHECK_MEMBERS([struct stat.st_rdev])
AC_CHECK_MEMBERS([struct stat.st_atim])
AC_CHECK_MEMBERS([struct stat.st_atimensec])
AC_CHECK_MEMBERS([struct stat.st_mtim])
AC_CHECK_MEMBERS([struct stat.st_mtimensec])
AC_HEADER_TIME
AC_STRUCT_TM
AC_CHECK_MEMBERS([struct utmp.ut_type,
struct utmp.ut_id,
struct utmp.ut_name,
struct utmp.ut_user,
struct utmp.ut_host,
struct utmp.ut_syslen,
struct utmp.ut_addr,
struct utmp.ut_addr_v6,
struct utmp.ut_time,
struct utmp.ut_xtime,
struct utmp.ut_tv],,,[[#include <utmp.h>]])
dnl There are dependencies:
dnl If UTMPX has to be used, the utmp structure shall have a ut_id field.
if test "$ac_cv_header_utmpx_h" = "yes" &&
test "$ac_cv_member_struct_utmp_ut_id" != "yes"; then
AC_MSG_ERROR(Systems with UTMPX and no ut_id field in the utmp structure are not supported)
fi
AC_CHECK_MEMBERS([struct utmpx.ut_name,
struct utmpx.ut_host,
struct utmpx.ut_syslen,
struct utmpx.ut_addr,
struct utmpx.ut_addr_v6,
struct utmpx.ut_time,
struct utmpx.ut_xtime],,,[[#include <utmpx.h>]])
if test "$ac_cv_header_lastlog_h" = "yes"; then
AC_CACHE_CHECK(for ll_host in struct lastlog,
ac_cv_struct_lastlog_ll_host,
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <lastlog.h>],
[struct lastlog ll; char *cp = ll.ll_host;]
)],
[ac_cv_struct_lastlog_ll_host=yes],
[ac_cv_struct_lastlog_ll_host=no]
)
)
if test "$ac_cv_struct_lastlog_ll_host" = "yes"; then
AC_DEFINE(HAVE_LL_HOST, 1,
[Define if struct lastlog has ll_host])
fi
fi
dnl Checks for library functions.
AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL
AC_FUNC_UTIME_NULL
AC_FUNC_STRFTIME
AC_REPLACE_FUNCS(mkdir putgrent putpwent putspent rename rmdir)
AC_REPLACE_FUNCS(sgetgrent sgetpwent sgetspent)
AC_REPLACE_FUNCS(snprintf strcasecmp strdup strerror strstr)
AC_CHECK_FUNC(setpgrp)
if test "$ac_cv_header_shadow_h" = "yes"; then
AC_CACHE_CHECK(for working shadow group support,
ac_cv_libc_shadowgrp,
AC_RUN_IFELSE([AC_LANG_SOURCE([
#include <shadow.h>
main()
{
struct sgrp *sg = sgetsgent("test:x::");
/* NYS libc on Red Hat 3.0.3 has broken shadow group support */
return !sg || !sg->sg_adm || !sg->sg_mem;
}]
)],
[ac_cv_libc_shadowgrp=yes],
[ac_cv_libc_shadowgrp=no],
[ac_cv_libc_shadowgrp=no]
)
)
if test "$ac_cv_libc_shadowgrp" = "yes"; then
AC_DEFINE(HAVE_SHADOWGRP, 1, [Have working shadow group support in libc])
fi
fi
AC_CACHE_CHECK([location of shared mail directory], shadow_cv_maildir,
[for shadow_cv_maildir in /var/mail /var/spool/mail /usr/spool/mail /usr/mail none; do
if test -d $shadow_cv_maildir; then
break
fi
done])
if test $shadow_cv_maildir != none; then
AC_DEFINE_UNQUOTED(MAIL_SPOOL_DIR, "$shadow_cv_maildir",
[Location of system mail spool directory.])
fi
AC_CACHE_CHECK([location of user mail file], shadow_cv_mailfile,
[for shadow_cv_mailfile in Mailbox mailbox Mail mail .mail none; do
if test -f $HOME/$shadow_cv_mailfile; then
break
fi
done])
if test $shadow_cv_mailfile != none; then
AC_DEFINE_UNQUOTED(MAIL_SPOOL_FILE, "$shadow_cv_mailfile",
[Name of user's mail spool file if stored in user's home directory.])
fi
AC_CACHE_CHECK([location of utmp], shadow_cv_utmpdir,
[for shadow_cv_utmpdir in /var/run /var/adm /usr/adm /etc none; do
if test -f $shadow_cv_utmpdir/utmp; then
break
fi
done])
if test "$shadow_cv_utmpdir" = "none"; then
AC_MSG_WARN(utmp file not found)
fi
AC_DEFINE_UNQUOTED(_UTMP_FILE, "$shadow_cv_utmpdir/utmp",
[Path for utmp file.])
AC_CACHE_CHECK([location of faillog/lastlog/wtmp], shadow_cv_logdir,
[for shadow_cv_logdir in /var/log /var/adm /usr/adm /etc; do
if test -d $shadow_cv_logdir; then
break
fi
done])
AC_DEFINE_UNQUOTED(_WTMP_FILE, "$shadow_cv_logdir/wtmp",
[Path for wtmp file.])
AC_DEFINE_UNQUOTED(LASTLOG_FILE, "$shadow_cv_logdir/lastlog",
[Path for lastlog file.])
AC_DEFINE_UNQUOTED(FAILLOG_FILE, "$shadow_cv_logdir/faillog",
[Path for faillog file.])
AC_CACHE_CHECK([location of the passwd program], shadow_cv_passwd_dir,
[if test -f /usr/bin/passwd; then
shadow_cv_passwd_dir=/usr/bin
else
shadow_cv_passwd_dir=/bin
fi])
AC_DEFINE_UNQUOTED(PASSWD_PROGRAM, "$shadow_cv_passwd_dir/passwd",
[Path to passwd program.])
dnl XXX - quick hack, should disappear before anyone notices :).
AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog().])
if test "$ac_cv_func_ruserok" = "yes"; then
AC_DEFINE(RLOGIN, 1, [Define if login should support the -r flag for rlogind.])
AC_DEFINE(RUSEROK, 0, [Define to the ruserok() "success" return value (0 or 1).])
fi
AC_ARG_ENABLE(shadowgrp,
[AC_HELP_STRING([--enable-shadowgrp], [enable shadow group support @<:@default=yes@:>@])],
[case "${enableval}" in
yes) enable_shadowgrp="yes" ;;
no) enable_shadowgrp="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-shadowgrp) ;;
esac],
[enable_shadowgrp="yes"]
)
AC_ARG_ENABLE(man,
[AC_HELP_STRING([--enable-man],
[regenerate roff man pages from Docbook @<:@default=no@:>@])],
[enable_man="${enableval}"],
[enable_man="no"]
)
AC_ARG_ENABLE(account-tools-setuid,
[AC_HELP_STRING([--enable-account-tools-setuid],
[Install the user and group management tools setuid and authenticate the callers. This requires --with-pam.])],
[case "${enableval}" in
yes) enable_acct_tools_setuid="yes" ;;
no) enable_acct_tools_setuid="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-account-tools-setuid)
;;
esac],
[enable_acct_tools_setuid="maybe"]
)
AC_ARG_ENABLE(utmpx,
[AC_HELP_STRING([--enable-utmpx],
[enable loggin in utmpx / wtmpx @<:@default=no@:>@])],
[case "${enableval}" in
yes) enable_utmpx="yes" ;;
no) enable_utmpx="no" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-utmpx) ;;
esac],
[enable_utmpx="no"]
)
AC_ARG_ENABLE(subordinate-ids,
[AC_HELP_STRING([--enable-subordinate-ids],
[support subordinate ids @<:@default=yes@:>@])],
[enable_subids="${enableval}"],
[enable_subids="maybe"]
)
AC_ARG_WITH(audit,
[AC_HELP_STRING([--with-audit], [use auditing support @<:@default=yes if found@:>@])],
[with_audit=$withval], [with_audit=maybe])
AC_ARG_WITH(libpam,
[AC_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])],
[with_libpam=$withval], [with_libpam=maybe])
AC_ARG_WITH(selinux,
[AC_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
[with_selinux=$withval], [with_selinux=maybe])
AC_ARG_WITH(acl,
[AC_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
[with_acl=$withval], [with_acl=maybe])
AC_ARG_WITH(attr,
[AC_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
[with_attr=$withval], [with_attr=maybe])
AC_ARG_WITH(skey,
[AC_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
[with_skey=$withval], [with_skey=no])
AC_ARG_WITH(tcb,
[AC_HELP_STRING([--with-tcb], [use tcb support (incomplete) @<:@default=yes if found@:>@])],
[with_tcb=$withval], [with_tcb=maybe])
AC_ARG_WITH(libcrack,
[AC_HELP_STRING([--with-libcrack], [use libcrack @<:@default=no@:>@])],
[with_libcrack=$withval], [with_libcrack=no])
AC_ARG_WITH(sha-crypt,
[AC_HELP_STRING([--with-sha-crypt], [allow the SHA256 and SHA512 password encryption algorithms @<:@default=yes@:>@])],
[with_sha_crypt=$withval], [with_sha_crypt=yes])
AC_ARG_WITH(nscd,
[AC_HELP_STRING([--with-nscd], [enable support for nscd @<:@default=yes@:>@])],
[with_nscd=$withval], [with_nscd=yes])
AC_ARG_WITH(group-name-max-length,
[AC_HELP_STRING([--with-group-name-max-length], [set max group name length @<:@default=16@:>@])],
[with_group_name_max_length=$withval], [with_group_name_max_length=yes])
if test "$with_group_name_max_length" = "no" ; then
with_group_name_max_length=0
elif test "$with_group_name_max_length" = "yes" ; then
with_group_name_max_length=16
fi
AC_DEFINE_UNQUOTED(GROUP_NAME_MAX_LENGTH, $with_group_name_max_length, [max group name length])
AC_SUBST(GROUP_NAME_MAX_LENGTH)
GROUP_NAME_MAX_LENGTH="$with_group_name_max_length"
AM_CONDITIONAL(USE_SHA_CRYPT, test "x$with_sha_crypt" = "xyes")
if test "$with_sha_crypt" = "yes"; then
AC_DEFINE(USE_SHA_CRYPT, 1, [Define to allow the SHA256 and SHA512 password encryption algorithms])
fi
if test "$with_nscd" = "yes"; then
AC_CHECK_FUNC(posix_spawn,
[AC_DEFINE(USE_NSCD, 1, [Define to support flushing of nscd caches])],
[AC_MSG_ERROR([posix_spawn is needed for nscd support])])
fi
dnl Check for some functions in libc first, only if not found check for
dnl other libraries. This should prevent linking libnsl if not really
dnl needed (Linux glibc, Irix), but still link it if needed (Solaris).
AC_SEARCH_LIBS(inet_ntoa, inet)
AC_SEARCH_LIBS(socket, socket)
AC_SEARCH_LIBS(gethostbyname, nsl)
if test "$enable_shadowgrp" = "yes"; then
AC_DEFINE(SHADOWGRP, 1, [Define to support the shadow group file.])
fi
AM_CONDITIONAL(SHADOWGRP, test "x$enable_shadowgrp" = "xyes")
if test "$enable_man" = "yes"; then
dnl
dnl Check for xsltproc
dnl
AC_PATH_PROG([XSLTPROC], [xsltproc])
if test -z "$XSLTPROC"; then
enable_man=no
fi
dnl check for DocBook DTD and stylesheets in the local catalog.
JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN],
[DocBook XML DTD V4.1.2], [], enable_man=no)
JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl],
[DocBook XSL Stylesheets >= 1.70.1], [], enable_man=no)
fi
AM_CONDITIONAL(ENABLE_REGENERATE_MAN, test "x$enable_man" != "xno")
if test "$enable_subids" != "no"; then
dnl
dnl FIXME: check if 32 bit UIDs/GIDs are supported by libc
dnl
AC_CHECK_SIZEOF([uid_t],, [#include "sys/types.h"])
AC_CHECK_SIZEOF([gid_t],, [#include "sys/types.h"])
if test "$ac_cv_sizeof_uid_t" -ge 4 && test "$ac_cv_sizeof_gid_t" -ge 4; then
AC_DEFINE(ENABLE_SUBIDS, 1, [Define to support the subordinate IDs.])
enable_subids="yes"
else
if test "x$enable_subids" = "xyes"; then
AC_MSG_ERROR([Cannot enable support the subordinate IDs on systems where gid_t or uid_t has less than 32 bits])
fi
enable_subids="no"
fi
fi
AM_CONDITIONAL(ENABLE_SUBIDS, test "x$enable_subids" != "xno")
AC_SUBST(LIBCRYPT)
AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
[AC_MSG_ERROR([crypt() not found])])
AC_SUBST(LIBACL)
if test "$with_acl" != "no"; then
AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
if test "$acl_header$with_acl" = "noyes" ; then
AC_MSG_ERROR([acl/libacl.h or attr/error_context.h is missing])
elif test "$acl_header" = "yes" ; then
AC_CHECK_LIB(acl, perm_copy_file,
[AC_CHECK_LIB(acl, perm_copy_fd,
[acl_lib="yes"],
[acl_lib="no"])],
[acl_lib="no"])
if test "$acl_lib$with_acl" = "noyes" ; then
AC_MSG_ERROR([libacl not found])
elif test "$acl_lib" = "no" ; then
with_acl="no"
else
AC_DEFINE(WITH_ACL, 1,
[Build shadow with ACL support])
LIBACL="-lacl"
with_acl="yes"
fi
else
with_acl="no"
fi
fi
AC_SUBST(LIBATTR)
if test "$with_attr" != "no"; then
AC_CHECK_HEADERS(attr/libattr.h attr/error_context.h, [attr_header="yes"], [attr_header="no"])
if test "$attr_header$with_attr" = "noyes" ; then
AC_MSG_ERROR([attr/libattr.h or attr/error_context.h is missing])
elif test "$attr_header" = "yes" ; then
AC_CHECK_LIB(attr, attr_copy_file,
[AC_CHECK_LIB(attr, attr_copy_fd,
[attr_lib="yes"],
[attr_lib="no"])],
[attr_lib="no"])
if test "$attr_lib$with_attr" = "noyes" ; then
AC_MSG_ERROR([libattr not found])
elif test "$attr_lib" = "no" ; then
with_attr="no"
else
AC_DEFINE(WITH_ATTR, 1,
[Build shadow with Extended Attributes support])
LIBATTR="-lattr"
with_attr="yes"
fi
else
with_attr="no"
fi
fi
AC_SUBST(LIBAUDIT)
if test "$with_audit" != "no"; then
AC_CHECK_HEADER(libaudit.h, [audit_header="yes"], [audit_header="no"])
if test "$audit_header$with_audit" = "noyes" ; then
AC_MSG_ERROR([libaudit.h is missing])
elif test "$audit_header" = "yes"; then
AC_CHECK_DECL(AUDIT_ADD_USER,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_DEL_USER,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_ADD_GROUP,,[audit_header="no"],[#include <libaudit.h>])
AC_CHECK_DECL(AUDIT_DEL_GROUP,,[audit_header="no"],[#include <libaudit.h>])
if test "$audit_header$with_audit" = "noyes" ; then
AC_MSG_ERROR([AUDIT_ADD_USER AUDIT_DEL_USER AUDIT_ADD_GROUP or AUDIT_DEL_GROUP missing from libaudit.h])
fi
fi
if test "$audit_header" = "yes"; then
AC_CHECK_LIB(audit, audit_log_acct_message,
[audit_lib="yes"], [audit_lib="no"])
if test "$audit_lib$with_audit" = "noyes" ; then
AC_MSG_ERROR([libaudit not found])
elif test "$audit_lib" = "no" ; then
with_audit="no"
else
AC_DEFINE(WITH_AUDIT, 1,
[Define if you want to enable Audit messages])
LIBAUDIT="-laudit"
with_audit="yes"
fi
else
with_audit="no"
fi
fi
AC_SUBST(LIBCRACK)
if test "$with_libcrack" = "yes"; then
echo "checking cracklib flavour, don't be surprised by the results"
AC_CHECK_LIB(crack, FascistCheck,
[LIBCRACK=-lcrack AC_DEFINE(HAVE_LIBCRACK, 1, [Defined if you have libcrack.])])
AC_CHECK_LIB(crack, FascistHistory,
AC_DEFINE(HAVE_LIBCRACK_HIST, 1, [Defined if you have the ts&szs cracklib.]))
AC_CHECK_LIB(crack, FascistHistoryPw,
AC_DEFINE(HAVE_LIBCRACK_PW, 1, [Defined if it includes *Pw functions.]))
fi
AC_SUBST(LIBSELINUX)
AC_SUBST(LIBSEMANAGE)
if test "$with_selinux" != "no"; then
AC_CHECK_HEADERS(selinux/selinux.h, [selinux_header="yes"], [selinux_header="no"])
if test "$selinux_header$with_selinux" = "noyes" ; then
AC_MSG_ERROR([selinux/selinux.h is missing])
fi
AC_CHECK_HEADERS(semanage/semanage.h, [semanage_header="yes"], [semanage_header="no"])
if test "$semanage_header$with_selinux" = "noyes" ; then
AC_MSG_ERROR([semanage/semanage.h is missing])
fi
if test "$selinux_header$semanage_header" = "yesyes" ; then
AC_CHECK_LIB(selinux, is_selinux_enabled, [selinux_lib="yes"], [selinux_lib="no"])
if test "$selinux_lib$with_selinux" = "noyes" ; then
AC_MSG_ERROR([libselinux not found])
fi
AC_CHECK_LIB(semanage, semanage_connect, [semanage_lib="yes"], [semanage_lib="no"])
if test "$semanage_lib$with_selinux" = "noyes" ; then
AC_MSG_ERROR([libsemanage not found])
fi
if test "$selinux_lib$semanage_lib" == "yesyes" ; then
AC_DEFINE(WITH_SELINUX, 1,
[Build shadow with SELinux support])
LIBSELINUX="-lselinux"
LIBSEMANAGE="-lsemanage"
with_selinux="yes"
else
with_selinux="no"
fi
else
with_selinux="no"
fi
fi
AC_SUBST(LIBTCB)
if test "$with_tcb" != "no"; then
AC_CHECK_HEADERS(tcb.h, [tcb_header="yes"], [tcb_header="no"])
if test "$tcb_header$with_tcb" = "noyes" ; then
AC_MSG_ERROR([tcb.h is missing])
elif test "$tcb_header" = "yes" ; then
AC_CHECK_LIB(tcb, tcb_is_suspect, [tcb_lib="yes"], [tcb_lib="no"])
if test "$tcb_lib$with_tcb" = "noyes" ; then
AC_MSG_ERROR([libtcb not found])
elif test "$tcb_lib" = "no" ; then
with_tcb="no"
else
AC_DEFINE(WITH_TCB, 1, [Build shadow with tcb support (incomplete)])
LIBTCB="-ltcb"
with_tcb="yes"
fi
else
with_tcb="no"
fi
fi
AM_CONDITIONAL(WITH_TCB, test x$with_tcb = xyes)
AC_SUBST(LIBPAM)
if test "$with_libpam" != "no"; then
AC_CHECK_LIB(pam, pam_start,
[pam_lib="yes"], [pam_lib="no"])
if test "$pam_lib$with_libpam" = "noyes" ; then
AC_MSG_ERROR(libpam not found)
fi
LIBPAM="-lpam"
pam_conv_function="no"
AC_CHECK_LIB(pam, openpam_ttyconv,
[pam_conv_function="openpam_ttyconv"],
AC_CHECK_LIB(pam_misc, misc_conv,
[pam_conv_function="misc_conv"; LIBPAM="$LIBPAM -lpam_misc"])
)
if test "$pam_conv_function$with_libpam" = "noyes" ; then
AC_MSG_ERROR(PAM conversation function not found)
fi
pam_headers_found=no
AC_CHECK_HEADERS( [security/openpam.h security/pam_misc.h],
[ pam_headers_found=yes ; break ], [],
[ #include <security/pam_appl.h> ] )
if test "$pam_headers_found$with_libpam" = "noyes" ; then
AC_MSG_ERROR(PAM headers not found)
fi
if test "$pam_lib$pam_headers_found" = "yesyes" -a "$pam_conv_function" != "no" ; then
with_libpam="yes"
else
with_libpam="no"
unset LIBPAM
fi
fi
dnl Now with_libpam is either yes or no
if test "$with_libpam" = "yes"; then
AC_CHECK_DECLS([PAM_ESTABLISH_CRED,
PAM_DELETE_CRED,
PAM_NEW_AUTHTOK_REQD,
PAM_DATA_SILENT],
[], [], [#include <security/pam_appl.h>])
save_libs=$LIBS
LIBS="$LIBS $LIBPAM"
# We do not use AC_CHECK_FUNCS to avoid duplicated definition with
# Linux PAM.
AC_CHECK_FUNC(pam_fail_delay, [AC_DEFINE(HAS_PAM_FAIL_DELAY, 1, [Define to 1 if you have the declaration of 'pam_fail_delay'])])
LIBS=$save_libs
AC_DEFINE(USE_PAM, 1, [Define to support Pluggable Authentication Modules])
AC_DEFINE_UNQUOTED(SHADOW_PAM_CONVERSATION, [$pam_conv_function],[PAM converstation to use])
AM_CONDITIONAL(USE_PAM, [true])
AC_MSG_CHECKING(use login and su access checking if PAM not used)
AC_MSG_RESULT(no)
else
AC_DEFINE(SU_ACCESS, 1, [Define to support /etc/suauth su access control.])
AM_CONDITIONAL(USE_PAM, [false])
AC_MSG_CHECKING(use login and su access checking if PAM not used)
AC_MSG_RESULT(yes)
fi
if test "$enable_acct_tools_setuid" != "no"; then
if test "$with_libpam" != "yes"; then
if test "$enable_acct_tools_setuid" = "yes"; then
AC_MSG_ERROR(PAM support is required for --enable-account-tools-setuid)
else
enable_acct_tools_setuid="no"
fi
else
enable_acct_tools_setuid="yes"
fi
if test "$enable_acct_tools_setuid" = "yes"; then
AC_DEFINE(ACCT_TOOLS_SETUID,
1,
[Define if account management tools should be installed setuid and authenticate the callers])
fi
fi
AM_CONDITIONAL(ACCT_TOOLS_SETUID, test "x$enable_acct_tools_setuid" = "xyes")
AC_SUBST(LIBSKEY)
AC_SUBST(LIBMD)
if test "$with_skey" = "yes"; then
AC_CHECK_LIB(md, MD5Init, [LIBMD=-lmd])
AC_CHECK_LIB(skey, skeychallenge, [LIBSKEY=-lskey],
[AC_MSG_ERROR([liskey missing. You can download S/Key source code from http://rsync1.it.gentoo.org/gentoo/distfiles/skey-1.1.5.tar.bz2])])
AC_DEFINE(SKEY, 1, [Define to support S/Key logins.])
AC_TRY_COMPILE([
#include <stdio.h>
#include <skey.h>
],[
skeychallenge((void*)0, (void*)0, (void*)0, 0);
],[AC_DEFINE(SKEY_BSD_STYLE, 1, [Define to support newer BSD S/Key API])])
fi
if test "$enable_utmpx" = "yes"; then
if test "$ac_cv_header_utmpx_h" != "yes"; then
AC_MSG_ERROR([The utmpx.h header file is required for utmpx support.])
fi
AC_DEFINE(USE_UTMPX,
1,
[Define if utmpx should be used])
fi
AC_DEFINE_UNQUOTED(SHELL, ["$SHELL"], [The default shell.])
AM_GNU_GETTEXT_VERSION(0.16)
AM_GNU_GETTEXT([external], [need-ngettext])
AM_CONDITIONAL(USE_NLS, test "x$USE_NLS" = "xyes")
AC_CONFIG_FILES([
Makefile
po/Makefile.in
doc/Makefile
man/Makefile
man/config.xml
man/po/Makefile
man/cs/Makefile
man/da/Makefile
man/de/Makefile
man/es/Makefile
man/fi/Makefile
man/fr/Makefile
man/hu/Makefile
man/id/Makefile
man/it/Makefile
man/ja/Makefile
man/ko/Makefile
man/pl/Makefile
man/pt_BR/Makefile
man/ru/Makefile
man/sv/Makefile
man/tr/Makefile
man/zh_CN/Makefile
man/zh_TW/Makefile
libmisc/Makefile
lib/Makefile
src/Makefile
contrib/Makefile
etc/Makefile
etc/pam.d/Makefile
shadow.spec
])
AC_OUTPUT
echo
echo "shadow will be compiled with the following features:"
echo
echo " auditing support: $with_audit"
echo " CrackLib support: $with_libcrack"
echo " PAM support: $with_libpam"
if test "$with_libpam" = "yes"; then
echo " suid account management tools: $enable_acct_tools_setuid"
fi
echo " SELinux support: $with_selinux"
echo " ACL support: $with_acl"
echo " Extended Attributes support: $with_attr"
echo " tcb support (incomplete): $with_tcb"
echo " shadow group support: $enable_shadowgrp"
echo " S/Key support: $with_skey"
echo " SHA passwords encryption: $with_sha_crypt"
echo " nscd support: $with_nscd"
echo " subordinate IDs support: $enable_subids"
echo
-6
View File
@@ -1,6 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
EXTRA_DIST = README adduser.c adduser-old.c adduser.sh adduser2.sh \
atudel groupmems.shar pwdauth.c shadow-anonftp.patch \
udbachk.tgz
-10
View File
@@ -1,10 +0,0 @@
People keep sending various adduser programs and scripts... They are
all in this directory. I haven't tested them, use at your own risk.
Anyway, the best one I've seen so far is adduser-3.x from Debian.
atudel is a perl script to remove at jobs owned by the specified user
(atrm in at-2.9 for Linux can't do that).
udbachk.tgz is a passwd/group/shadow file integrity checker.
--marekm
-300
View File
@@ -1,300 +0,0 @@
/****
** 03/17/96
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
** --marekm
**
** 02/26/96
** modified to call shadow utils (useradd,chage,passwd) on shadowed
** systems - Cristian Gafton, gafton@sorosis.ro
**
** 6/27/95
** shadow-adduser 1.4:
**
** now it copies the /etc/skel dir into the person's dir,
** makes the mail folders, changed some defaults and made a 'make
** install' just for the hell of it.
**
** Greg Gallagher
** CIN.Net
**
** 1/28/95
** shadow-adduser 1.3:
**
** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
** It was such a stupid bug that I would have never seen it myself.
**
** Brandon
*****
** 01/27/95
**
** shadow-adduser 1.2:
** I took the C source from adduser-shadow (credits are below) and made
** it a little more worthwhile. Many small changes... Here's
** the ones I can remember:
**
** Removed support for non-shadowed systems (if you don't have shadow,
** use the original adduser, don't get this shadow version!)
** Added support for the correct /etc/shadow fields (Min days before
** password change, max days before password change, Warning days,
** and how many days from expiry date does the account go invalid)
** The previous version just left all of those fields blank.
** There is still one field left (expiry date for the account, period)
** which I have left blank because I do not use it and didn't want to
** spend any more time on this. I'm sure someone will put it in and
** tack another plethora of credits on here. :)
** Added in the password date field, which should always reflect the last
** date the password was changed, for expiry purposes. "passwd" always
** updates this field, so the adduser program should set it up right
** initially (or a user could keep thier initial password forever ;)
** The number is in days since Jan 1st, 1970.
**
** Have fun with it, and someone please make
** a real version(this is still just a hack)
** for us all to use (and Email it to me???)
**
** Brandon
** photon@usis.com
**
*****
** adduser 1.0: add a new user account (For systems not using shadow)
** With a nice little interface and a will to do all the work for you.
**
** Craig Hagan
** hagan@opine.cs.umass.edu
**
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
** chris@slinky.cs.umass.edu
**
*****
**
** 01/19/95
**
** FURTHER modifications to enable shadow passwd support (kludged, but
** no more so than the original) by Dan Crowson - dcrowson@mo.net
**
** Search on DAN for all changes...
**
*****
**
** cc -O -o adduser adduser.c
** Use gcc if you have it... (political reasons beyond my control) (chris)
**
** I've gotten this program to work with success under Linux (without
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
** on any system that uses no shadow. (chris)
**
** If you have no crypt() then try
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
** I'm not sure how login operates with no crypt()... I guess
** the same way we're doing it here.
*/
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/stat.h>
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
#define DEFAULT_HOME "/home"
#define USERADD_PATH "/usr/sbin/useradd"
#define CHAGE_PATH "/usr/sbin/chage"
#define PASSWD_PATH "/usr/bin/passwd"
#define DEFAULT_GROUP 100
#define DEFAULT_MAX_PASS 60
#define DEFAULT_WARN_PASS 10
/* if you use this feature, you will get a lot of complaints from users
who rarely use their accounts :) (something like 3 months would be
more reasonable) --marekm */
#define DEFAULT_USER_DIE /* 10 */ 0
void main()
{
char foo[32];
char uname[9],person[32],dir[32],shell[32];
unsigned int group,min_pass,max_pass,warn_pass,user_die;
/* the group and uid of the new user */
int bad=0,done=0,correct=0,gets_warning=0;
char cmd[255];
struct group *grp;
/* flags, in order:
* bad to see if the username is in /etc/passwd, or if strange stuff has
* been typed if the user might be put in group 0
* done allows the program to exit when a user has been added
* correct loops until a password is found that isn't in /etc/passwd
* gets_warning allows the fflush to be skipped for the first gets
* so that output is still legible
*/
/* The real program starts HERE! */
if(geteuid()!=0)
{
printf("It seems you don't have access to add a new user. Try\n");
printf("logging in as root or su root to gain super-user access.\n");
exit(1);
}
/* Sanity checks
*/
if (!(grp=getgrgid(DEFAULT_GROUP))){
printf("Error: the default group %d does not exist on this system!\n",
DEFAULT_GROUP);
printf("adduser must be recompiled.\n");
exit(1);
};
while(!correct) { /* loop until a "good" uname is chosen */
while(!done) {
printf("\nLogin to add (^C to quit): ");
if(gets_warning) /* if the warning was already shown */
fflush(stdout); /* fflush stdout, otherwise set the flag */
else
gets_warning=1;
gets(uname);
if(!strlen(uname)) {
printf("Empty input.\n");
done=0;
continue;
};
/* what I saw here before made me think maybe I was running DOS */
/* might this be a solution? (chris) */
if (getpwnam(uname) != NULL) {
printf("That name is in use, choose another.\n");
done=0;
} else
done=1;
}; /* done, we have a valid new user name */
/* all set, get the rest of the stuff */
printf("\nEditing information for new user [%s]\n",uname);
printf("\nFull Name [%s]: ",uname);
gets(person);
if (!strlen(person)) {
bzero(person,sizeof(person));
strcpy(person,uname);
};
do {
bad=0;
printf("GID [%d]: ",DEFAULT_GROUP);
gets(foo);
if (!strlen(foo))
group=DEFAULT_GROUP;
else
if (isdigit (*foo)) {
group = atoi(foo);
if (! (grp = getgrgid (group))) {
printf("unknown gid %s\n",foo);
group=DEFAULT_GROUP;
bad=1;
};
} else
if ((grp = getgrnam (foo)))
group = grp->gr_gid;
else {
printf("unknown group %s\n",foo);
group=DEFAULT_GROUP;
bad=1;
}
if (group==0){ /* You're not allowed to make root group users! */
printf("Creation of root group users not allowed (must be done by hand)\n");
group=DEFAULT_GROUP;
bad=1;
};
} while(bad);
fflush(stdin);
printf("\nIf home dir ends with a / then [%s] will be appended to it\n",uname);
printf("Home Directory [%s/%s]: ",DEFAULT_HOME,uname);
fflush(stdout);
gets(dir);
if (!strlen(dir)) { /* hit return */
sprintf(dir,"%s/%s",DEFAULT_HOME,uname);
fflush(stdin);
} else
if (dir[strlen(dir)-1]=='/')
sprintf(dir+strlen(dir),"%s",uname);
printf("\nShell [%s]: ",DEFAULT_SHELL);
fflush(stdout);
gets(shell);
if (!strlen(shell))
sprintf(shell,"%s",DEFAULT_SHELL);
printf("\nMin. Password Change Days [0]: ");
gets(foo);
min_pass=atoi(foo);
printf("Max. Password Change Days [%d]: ",DEFAULT_MAX_PASS);
gets(foo);
if (strlen(foo) > 1)
max_pass = atoi(foo);
else
max_pass = DEFAULT_MAX_PASS;
printf("Password Warning Days [%d]: ",DEFAULT_WARN_PASS);
gets(foo);
warn_pass = atoi(foo);
if (warn_pass==0)
warn_pass = DEFAULT_WARN_PASS;
printf("Days after Password Expiry for Account Locking [%d]: ",DEFAULT_USER_DIE);
gets(foo);
user_die = atoi(foo);
if (user_die == 0)
user_die = DEFAULT_USER_DIE;
printf("\nInformation for new user [%s] [%s]:\n",uname,person);
printf("Home directory: [%s] Shell: [%s]\n",dir,shell);
printf("GID: [%d]\n",group);
printf("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
min_pass,max_pass,warn_pass,user_die);
printf("\nIs this correct? [y/N]: ");
fflush(stdout);
gets(foo);
done=bad=correct=(foo[0]=='y'||foo[0]=='Y');
if(bad!=1)
printf("\nUser [%s] not added\n",uname);
}
bzero(cmd,sizeof(cmd));
sprintf(cmd,"%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
USERADD_PATH,group,dir,shell,person,uname);
printf("Calling useradd to add new user:\n%s\n",cmd);
if(system(cmd)){
printf("User add failed!\n");
exit(errno);
};
bzero(cmd,sizeof(cmd));
sprintf(cmd,"%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
min_pass,max_pass,warn_pass,user_die,uname);
printf("%s\n",cmd);
if(system(cmd)){
printf("There was an error setting password expire values\n");
exit(errno);
};
bzero(cmd,sizeof(cmd));
sprintf(cmd,"%s %s",PASSWD_PATH,uname);
system(cmd);
printf("\nDone.\n");
}
-502
View File
@@ -1,502 +0,0 @@
/****
** 04/21/96
** hacked even more, replaced gets() with something slightly harder to buffer
** overflow. Added support for setting a default quota on new account, with
** edquota -p. Other cleanups for security, I let some users run adduser suid
** root to add new accounts. (overflow checks, clobber environment, valid
** shell checks, restrictions on gid + home dir settings).
** Added max. username length. Used syslog() a bit for important events.
** Support to immediately expire account with passwd -e.
** Called it version 2.0! Because I felt like it!
** -- Chris, chris@ferret.lmh.ox.ac.uk
** 03/17/96
** hacked a bit more, removed unused code, cleaned up for gcc -Wall.
** --marekm
**
** 02/26/96
** modified to call shadow utils (useradd,chage,passwd) on shadowed
** systems - Cristian Gafton, gafton@sorosis.ro
**
** 6/27/95
** shadow-adduser 1.4:
**
** now it copies the /etc/skel dir into the person's dir,
** makes the mail folders, changed some defaults and made a 'make
** install' just for the hell of it.
**
** Greg Gallagher
** CIN.Net
**
** 1/28/95
** shadow-adduser 1.3:
**
** Basically a bug-fix on my additions in 1.2. Thanx to Terry Stewart
** (stew@texas.net) for pointing out one of the many idiotic bugs I introduced.
** It was such a stupid bug that I would have never seen it myself.
**
** Brandon
*****
** 01/27/95
**
** shadow-adduser 1.2:
** I took the C source from adduser-shadow (credits are below) and made
** it a little more worthwhile. Many small changes... Here's
** the ones I can remember:
**
** Removed support for non-shadowed systems (if you don't have shadow,
** use the original adduser, don't get this shadow version!)
** Added support for the correct /etc/shadow fields (Min days before
** password change, max days before password change, Warning days,
** and how many days from expiry date does the account go invalid)
** The previous version just left all of those fields blank.
** There is still one field left (expiry date for the account, period)
** which I have left blank because I do not use it and didn't want to
** spend any more time on this. I'm sure someone will put it in and
** tack another plethora of credits on here. :)
** Added in the password date field, which should always reflect the last
** date the password was changed, for expiry purposes. "passwd" always
** updates this field, so the adduser program should set it up right
** initially (or a user could keep thier initial password forever ;)
** The number is in days since Jan 1st, 1970.
**
** Have fun with it, and someone please make
** a real version(this is still just a hack)
** for us all to use (and Email it to me???)
**
** Brandon
** photon@usis.com
**
*****
** adduser 1.0: add a new user account (For systems not using shadow)
** With a nice little interface and a will to do all the work for you.
**
** Craig Hagan
** hagan@opine.cs.umass.edu
**
** Modified to really work, look clean, and find unused uid by Chris Cappuccio
** chris@slinky.cs.umass.edu
**
*****
**
** 01/19/95
**
** FURTHER modifications to enable shadow passwd support (kludged, but
** no more so than the original) by Dan Crowson - dcrowson@mo.net
**
** Search on DAN for all changes...
**
*****
**
** cc -O -o adduser adduser.c
** Use gcc if you have it... (political reasons beyond my control) (chris)
**
** I've gotten this program to work with success under Linux (without
** shadow) and SunOS 4.1.3. I would assume it should work pretty well
** on any system that uses no shadow. (chris)
**
** If you have no crypt() then try
** cc -DNO_CRYPT -O -o adduser adduser.c xfdes.c
** I'm not sure how login operates with no crypt()... I guess
** the same way we're doing it here.
*/
#include <unistd.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <syslog.h>
#define IMMEDIATE_CHANGE /* Expire newly created password, must be changed
* immediately upon next login */
#define HAVE_QUOTAS /* Obvious */
#define EXPIRE_VALS_SET /* If defined, 'normal' users can't change
* password expiry values (if running suid root) */
#define HAVE_GETUSERSHELL /* FIXME: Isn't this defined in config.h too? */
#define LOGGING /* If we want to log various things to syslog */
#define MAX_USRNAME 8 /* Longer usernames seem to work on my system....
* But they're probably a poor idea */
#define DEFAULT_SHELL "/bin/bash" /* because BASH is your friend */
#define DEFAULT_HOME "/home"
#define USERADD_PATH "/usr/sbin/useradd"
#define CHAGE_PATH "/usr/bin/chage"
#define PASSWD_PATH "/usr/bin/passwd"
#define EDQUOTA_PATH "/usr/sbin/edquota"
#define QUOTA_DEFAULT "defuser"
#define DEFAULT_GROUP 100
#define DEFAULT_MIN_PASS 0
#define DEFAULT_MAX_PASS 100
#define DEFAULT_WARN_PASS 14
#define DEFAULT_USER_DIE 366
void safeget (char *, int);
void
main (void)
{
char foo[32];
char usrname[32], person[32], dir[32], shell[32];
unsigned int group, min_pass, max_pass, warn_pass, user_die;
/* the group and uid of the new user */
int bad = 0, done = 0, correct = 0, olduid;
char cmd[255];
struct group *grp;
/* flags, in order:
* bad to see if the username is in /etc/passwd, or if strange stuff has
* been typed if the user might be put in group 0
* done allows the program to exit when a user has been added
* correct loops until a username is found that isn't in /etc/passwd
*/
/* The real program starts HERE! */
if (geteuid () != 0)
{
printf ("It seems you don't have access to add a new user. Try\n");
printf ("logging in as root or su root to gain superuser access.\n");
exit (1);
}
/* Sanity checks
*/
#ifdef LOGGING
openlog ("adduser", LOG_PID | LOG_CONS | LOG_NOWAIT, LOG_AUTH);
syslog (LOG_INFO, "invoked by user %s\n", getpwuid (getuid ())->pw_name);
#endif
if (!(grp = getgrgid (DEFAULT_GROUP)))
{
printf ("Error: the default group %d does not exist on this system!\n",
DEFAULT_GROUP);
printf ("adduser must be recompiled.\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: failed. no such default group\n");
closelog ();
#endif
exit (1);
};
while (!correct)
{ /* loop until a "good" usrname is chosen */
while (!done)
{
printf ("\nLogin to add (^C to quit): ");
fflush (stdout);
safeget (usrname, sizeof (usrname));
if (!strlen (usrname))
{
printf ("Empty input.\n");
done = 0;
continue;
};
/* what I saw here before made me think maybe I was running DOS */
/* might this be a solution? (chris) */
if (strlen (usrname) > MAX_USRNAME)
{
printf ("That name is longer than the maximum of %d characters. Choose another.\n", MAX_USRNAME);
done = 0;
}
else if (getpwnam (usrname) != NULL)
{
printf ("That name is in use, choose another.\n");
done = 0;
}
else if (strchr (usrname, ' ') != NULL)
{
printf ("No spaces in username!!\n");
done = 0;
}
else
done = 1;
}; /* done, we have a valid new user name */
/* all set, get the rest of the stuff */
printf ("\nEditing information for new user [%s]\n", usrname);
printf ("\nFull Name [%s]: ", usrname);
fflush (stdout);
safeget (person, sizeof (person));
if (!strlen (person))
{
bzero (person, sizeof (person));
strcpy (person, usrname);
};
if (getuid () == 0)
{
do
{
bad = 0;
printf ("GID [%d]: ", DEFAULT_GROUP);
fflush (stdout);
safeget (foo, sizeof (foo));
if (!strlen (foo))
group = DEFAULT_GROUP;
else if (isdigit (*foo))
{
group = atoi (foo);
if (!(grp = getgrgid (group)))
{
printf ("unknown gid %s\n", foo);
group = DEFAULT_GROUP;
bad = 1;
};
}
else if ((grp = getgrnam (foo)))
group = grp->gr_gid;
else
{
printf ("unknown group %s\n", foo);
group = DEFAULT_GROUP;
bad = 1;
}
if (group == 0)
{ /* You're not allowed to make root group users! */
printf ("Creation of root group users not allowed (must be done by hand)\n");
group = DEFAULT_GROUP;
bad = 1;
};
}
while (bad);
}
else
{
printf ("Group will be default of: %d\n", DEFAULT_GROUP);
group = DEFAULT_GROUP;
}
if (getuid () == 0)
{
printf ("\nIf home dir ends with a / then '%s' will be appended to it\n", usrname);
printf ("Home Directory [%s/%s]: ", DEFAULT_HOME, usrname);
fflush (stdout);
safeget (dir, sizeof (dir));
if (!strlen (dir))
{ /* hit return */
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
else if (dir[strlen (dir) - 1] == '/')
sprintf (dir+strlen(dir), "%s", usrname);
}
else
{
printf ("\nHome directory will be %s/%s\n", DEFAULT_HOME, usrname);
sprintf (dir, "%s/%s", DEFAULT_HOME, usrname);
}
printf ("\nShell [%s]: ", DEFAULT_SHELL);
fflush (stdout);
safeget (shell, sizeof (shell));
if (!strlen (shell))
sprintf (shell, "%s", DEFAULT_SHELL);
else
{
char *sh;
int ok = 0;
#ifdef HAVE_GETUSERSHELL
setusershell ();
while ((sh = getusershell ()) != NULL)
if (!strcmp (shell, sh))
ok = 1;
endusershell ();
#endif
if (!ok)
{
if (getuid () == 0)
printf ("Warning: root allowed non standard shell\n");
else
{
printf ("Shell NOT in /etc/shells, DEFAULT used\n");
sprintf (shell, "%s", DEFAULT_SHELL);
}
}
}
#ifdef EXPIRE_VALS_SET
if (getuid () == 0)
{
#endif
printf ("\nMin. Password Change Days [%d]: ", DEFAULT_MIN_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
if (strlen (foo) > 1)
min_pass = DEFAULT_MIN_PASS;
else
min_pass = atoi (foo);
printf ("Max. Password Change Days [%d]: ", DEFAULT_MAX_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
if (strlen (foo) > 1)
max_pass = atoi (foo);
else
max_pass = DEFAULT_MAX_PASS;
printf ("Password Warning Days [%d]: ", DEFAULT_WARN_PASS);
fflush (stdout);
safeget (foo, sizeof (foo));
warn_pass = atoi (foo);
if (warn_pass == 0)
warn_pass = DEFAULT_WARN_PASS;
printf ("Days after Password Expiry for Account Locking [%d]: ", DEFAULT_USER_DIE);
fflush (stdout);
safeget (foo, sizeof (foo));
user_die = atoi (foo);
if (user_die == 0)
user_die = DEFAULT_USER_DIE;
#ifdef EXPIRE_VALS_SET
}
else
{
printf ("\nSorry, account expiry values are set.\n");
user_die = DEFAULT_USER_DIE;
warn_pass = DEFAULT_WARN_PASS;
max_pass = DEFAULT_MAX_PASS;
min_pass = DEFAULT_MIN_PASS;
}
#endif
printf ("\nInformation for new user [%s] [%s]:\n", usrname, person);
printf ("Home directory: [%s] Shell: [%s]\n", dir, shell);
printf ("GID: [%d]\n", group);
printf ("MinPass: [%d] MaxPass: [%d] WarnPass: [%d] UserExpire: [%d]\n",
min_pass, max_pass, warn_pass, user_die);
printf ("\nIs this correct? [y/N]: ");
fflush (stdout);
safeget (foo, sizeof (foo));
done = bad = correct = (foo[0] == 'y' || foo[0] == 'Y');
if (bad != 1)
printf ("\nUser [%s] not added\n", usrname);
}
/* Clobber the environment, I run this suid root sometimes to let
* non root privileged accounts add users --chris */
*environ = NULL;
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -g %d -d %s -s %s -c \"%s\" -m -k /etc/skel %s",
USERADD_PATH, group, dir, shell, person, usrname);
printf ("Calling useradd to add new user:\n%s\n", cmd);
if (system (cmd))
{
printf ("User add failed!\n");
#ifdef LOGGING
syslog (LOG_ERR, "could not add new user\n");
closelog ();
#endif
exit (errno);
};
olduid = getuid (); /* chage, passwd, edquota etc. require ruid = root
*/
setuid (0);
bzero (cmd, sizeof (cmd));
/* Chage runs suid root. => we need ruid root to run it with
* anything other than chage -l
*/
sprintf (cmd, "%s -m %d -M %d -W %d -I %d %s", CHAGE_PATH,
min_pass, max_pass, warn_pass, user_die, usrname);
printf ("%s\n", cmd);
if (system (cmd))
{
printf ("There was an error setting password expire values\n");
#ifdef LOGGING
syslog (LOG_ERR, "password expire values could not be set\n");
#endif
};
/* I want to add a user completely with one easy command --chris */
#ifdef HAVE_QUOTAS
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -p %s -u %s", EDQUOTA_PATH, QUOTA_DEFAULT, usrname);
printf ("%s\n", cmd);
if (system (cmd))
{
printf ("\nWarning: error setting quota\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: account created but NO quotas set!\n");
#endif /* LOGGING */
}
else
printf ("\nDefault quota set.\n");
#endif /* HAVE_QUOTAS */
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s %s", PASSWD_PATH, usrname);
if (system (cmd))
{
printf ("\nWarning: error setting password\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: password set failed!\n");
#endif
}
#ifdef IMMEDIATE_CHANGE
bzero (cmd, sizeof (cmd));
sprintf (cmd, "%s -e %s", PASSWD_PATH, usrname);
if (system (cmd))
{
printf ("\nWarning: error expiring password\n");
#ifdef LOGGING
syslog (LOG_ERR, "warning: password expire failed!\n");
#endif /* LOGGING */
}
#endif /* IMMEDIATE_CHANGE */
setuid (olduid);
#ifdef LOGGING
closelog ();
#endif
printf ("\nDone.\n");
}
void
safeget (char *buf, int maxlen)
{
int c, i = 0, bad = 0;
char *bstart = buf;
while ((c = getc (stdin)) != EOF && (c != '\n') && (++i < maxlen))
{
bad = (!isalnum (c) && (c != '_') && (c != ' '));
*(buf++) = (char) c;
}
*buf = '\0';
if (bad)
{
printf ("\nString contained banned character. Please stick to alphanumerics.\n");
*bstart = '\0';
}
}
-90
View File
@@ -1,90 +0,0 @@
#!/bin/sh
# adduser script for use with shadow passwords and useradd command.
# by Hrvoje Dogan <hdogan@student.math.hr>, Dec 1995.
echo -n "Login name for new user []:"
read LOGIN
if [ -z $LOGIN ]
then echo "Come on, man, you can't leave the login field empty...";exit
fi
echo
echo -n "User id for $LOGIN [ defaults to next available]:"
read ID
GUID="-u $ID"
if [ -z $ID ]
then GUID=""
fi
echo
echo -n "Initial group for $LOGIN [users]:"
read GID
GGID="-g $GID"
if [ -z $GID ]
then GGID=""
fi
echo
echo -n "Additional groups for $LOGIN []:"
read AGID
GAGID="-G $AGID"
if [ -z $AGID ]
then GAGID=""
fi
echo
echo -n "$LOGIN's home directory [/home/$LOGIN]:"
read HME
GHME="-d $HME"
if [ -z $HME ]
then GHME=""
fi
echo
echo -n "$LOGIN's shell [/bin/bash]:"
read SHL
GSHL="-s $SHL"
if [ -z $SHL ]
then GSHL=""
fi
echo
echo -n "$LOGIN's account expiry date (MM/DD/YY) []:"
read EXP
GEXP="-e $EXP"
if [ -z $EXP ]
then GEXP=""
fi
echo
echo OK, I'm about to make a new account. Here's what you entered so far:
echo New login name: $LOGIN
if [ -z $GUID ]
then echo New UID: [Next available]
else echo New UID: $UID
fi
if [ -z $GGID ]
then echo Initial group: users
else echo Initial group: $GID
fi
if [ -z $GAGID ]
then echo Additional groups: [none]
else echo Additional groups: $AGID
fi
if [ -z $GHME ]
then echo Home directory: /home/$LOGIN
else echo Home directory: $HME
fi
if [ -z $GSHL ]
then echo Shell: /bin/bash
else echo Shell: $SHL
fi
if [ -z $GEXP ]
then echo Expiry date: [no expiration]
else echo Expiry date: $EXP
fi
echo "This is it... if you want to bail out, you'd better do it now."
read FOO
echo Making new account...
/usr/sbin/useradd $GHME -m $GEXP $GGID $GAGID $GSHL $GUID $LOGIN
/usr/bin/chfn $LOGIN
/usr/bin/passwd $LOGIN
echo "Done..."
-743
View File
@@ -1,743 +0,0 @@
#!/bin/bash
#
# adduser Interactive user adding program.
#
# Copyright (C) 1996 Petri Mattila, Prihateam Networks
# petri@prihateam.fi
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# Changes:
# 220496 v0.01 Initial version
# 230496 v0.02 More checks, embolden summary
# 240496 Even more checks
# 250496 Help with ?
# 040596 v0.03 Cleanups
# 050596 v0.04 Bug fixes, expire date checks
# 070596 v0.05 Iso-latin-1 names
#
## Defaults
# default groups
def_group="users"
def_other_groups=""
# default home directory
def_home_dir=/home/users
# default shell
def_shell=/bin/tcsh
# Defaul expiration date (mm/dd/yy)
def_expire=""
# default dates
def_pwd_min=0
def_pwd_max=90
def_pwd_warn=14
def_pwd_iact=14
# possible UIDs
uid_low=1000
uid_high=64000
# skel directory
skel=/etc/skel
# default mode for home directory
def_mode=711
# Regex, that the login name must meet, only ANSI characters
login_regex='^[0-9a-zA-Z_-]*$'
# Regex, that the user name must meet
# ANSI version
##name_regex='^[0-9a-zA-Z_-\ ]*$'
# ISO-LATIN-1 version
name_regex='^[0-9a-zA-ZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöùúûüýþÿ_-\ ]*$'
# set PATH
export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
# Some special characters
case "$TERM" in
vt*|ansi*|con*|xterm*|linux*)
S='' # start embolden
E='' # end embolden
;;
*)
S=''
E=''
;;
esac
## Functions
check_root() {
if test "$EUID" -ne 0
then
echo "You must be root to run this program."
exit 1
fi
}
check_user() {
local usr pwd uid gid name home sh
cat /etc/passwd | (
while IFS=":" read usr pwd uid gid name home sh
do
if test "$1" = "${usr}"
then
return 1
fi
done
return 0
)
}
check_group() {
local read grp pwd gid members
cat /etc/group | (
while IFS=":" read grp pwd gid members
do
if test "$1" = "${grp}"
then
return 1
fi
done
return 0
)
}
check_other_groups() {
local grp check IFS
check="$1"
IFS=","
set ${check}
for grp
do
if check_group "${grp}"
then
echo "Group ${grp} does not exist."
return 1
fi
done
return 0
}
check_uid() {
local usr pwd uid gid name home sh
cat /etc/passwd | (
while IFS=":" read usr pwd uid gid name home sh
do
if test "$1" = "${uid}"
then
return 1
fi
done
return 0
)
}
read_yn() {
local ans ynd
ynd="$1"
while :
do
read ans
case "${ans}" in
"") return ${ynd} ;;
[nN]) return 1 ;;
[yY]) return 0 ;;
*) echo -n "Y or N, please ? " ;;
esac
done
}
read_login() {
echo
while :
do
echo -n "Login: ${def_login:+[${def_login}] }"
read login
if test "${login}" = '?'
then
less /etc/passwd
echo
continue
fi
if test -z "${login}" -a -n "${def_login}"
then
login="${def_login}"
echo "Using ${login}"
return
fi
if test "${#login}" -gt 8
then
echo "Login must be at most 8 characters long"
continue
fi
if test "${#login}" -lt 2
then
echo "Login must be at least 2 characters long"
continue
fi
if ! expr "${login}" : "${login_regex}" &> /dev/null
then
echo "Please use letters, numbers and special characters _-,."
continue
fi
if ! check_user "${login}"
then
echo "Username ${login} is already in use"
continue
fi
def_login="${login}"
return
done
}
read_name () {
echo
while :
do
echo -n "Real name: ${def_name:+[${def_name}] }"
read name
if test "${name}" = '?'
then
less /etc/passwd
echo
continue
fi
if test -z "${name}" -a -n "${def_name}"
then
name="${def_name}"
echo "Using ${name}"
fi
if test "${#name}" -gt 32
then
echo "Name should be at most 32 characters long"
continue
fi
if ! expr "${name}" : "${name_regex}" &> /dev/null
then
echo "Please use letters, numbers, spaces and special characters ,._-"
continue
fi
def_name="${name}"
return
done
}
read_home() {
local x
echo
while :
do
echo -n "Home Directory: [${def_home_dir}/${login}] "
read home
if test -z "${home}"
then
home="${def_home_dir}/${login}"
echo "Using ${home}"
fi
if ! expr "${home}" : '^[0-9a-zA-Z,._-\/]*$' &> /dev/null
then
echo "Please use letters, numbers, spaces and special characters ,._-/"
continue
fi
x="$(basename ${home})"
if test "${x}" != "${login}"
then
echo "Warning: you are about to use different login name and home directory."
fi
x="$(dirname ${home})"
if ! test -d "${x}"
then
echo "Directory ${x} does not exist."
echo "If you still want to use it, please make it manually."
continue
fi
def_home_dir="${x}"
return
done
}
read_shell () {
local x
echo
while :
do
echo -n "Shell: [${def_shell}] "
read shell
if test -z "${shell}"
then
shell="${def_shell}"
echo "Using ${shell}"
fi
for x in $(cat /etc/shells)
do
if test "${x}" = "${shell}"
then
def_shell="${shell}"
return
fi
done
echo "Possible shells are:"
cat /etc/shells
done
}
read_group () {
echo
while :
do
echo -n "Group: [${def_group}] "
read group
if test -z "${group}"
then
group="${def_group}"
echo "Using ${group}"
fi
if test "${group}" = '?'
then
less /etc/group
echo
continue
fi
if check_group "${group}"
then
echo "Group ${group} does not exist."
continue
fi
def_group="${group}"
return
done
}
read_other_groups () {
echo
while :
do
echo -n "Other groups: [${def_og:-none}] "
read other_groups
if test "${other_groups}" = '?'
then
less /etc/group
echo
continue
fi
if test -z "${other_groups}"
then
if test -n "${def_og}"
then
other_groups="${def_og}"
echo "Using ${other_groups}"
else
echo "No other groups"
return
fi
fi
if ! check_other_groups "${other_groups}"
then
continue
fi
def_og="${other_groups}"
return
done
}
read_uid () {
echo
while :
do
echo -n "uid: [first free] "
read uid
if test -z "${uid}"
then
echo "Using first free UID."
return
fi
if test "${uid}" = '?'
then
less /etc/passwd
echo
continue
fi
if ! expr "${uid}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${uid}" -lt "${uid_low}"
then
echo "UID must be greater than ${uid_low}"
continue
fi
if test "${uid}" -gt "${uid_high}"
then
echo "UID must be smaller than ${uid_high}"
continue
fi
if ! check_uid "${uid}"
then
echo "UID ${uid} is already in use"
continue
fi
return
done
}
read_max_valid_days() {
echo
while :
do
echo -en "Maximum days between password changes: [${def_pwd_max}] "
read max_days
if test -z "${max_days}"
then
max_days="${def_pwd_max}"
echo "Using ${max_days}"
return
fi
if ! expr "${max_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${max_days}" -lt 7
then
echo "Warning: you are using a value shorter than a week."
fi
def_pwd_max="${max_days}"
return
done
}
read_min_valid_days() {
echo
while :
do
echo -en "Minimum days between password changes: [${def_pwd_min}] "
read min_days
if test -z "${min_days}"
then
min_days="${def_pwd_min}"
echo "Using ${min_days}"
return
fi
if ! expr "${min_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${min_days}" -gt 7
then
echo "Warning: you are using a value longer than a week."
fi
def_pwd_min="${min_days}"
return
done
}
read_warning_days() {
echo
while :
do
echo -en "Number of warning days before password expires: [${def_pwd_warn}] "
read warn_days
if test -z "${warn_days}"
then
warn_days="${def_pwd_warn}"
echo "Using ${warn_days}"
fi
if ! expr "${warn_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${warn_days}" -gt 14
then
echo "Warning: you are using a value longer than two week."
fi
def_pwd_warn="${warn_days}"
return
done
}
read_inactive_days() {
echo
while :
do
echo -en "Number of usable days after expiration: [${def_pwd_iact}] "
read iact_days
if test -z "${iact_days}"
then
iact_days="${def_pwd_iact}"
echo "Using ${iact_days}"
return
fi
if ! expr "${iact_days}" : '^[0-9]+$' &> /dev/null
then
echo "Please use numbers only."
continue
fi
if test "${iact_days}" -gt 14
then
echo "Warning: you are using a value that is more than two weeks."
fi
def_pwd_iact="${iact_days}"
return
done
}
read_expire_date() {
local ans
echo
while :
do
echo -en "Expire date of this account (mm/dd/yy): [${def_expire:-never}] "
read ans
if test -z "${ans}"
then
if test -z "${def_expire}"
then
ans="never"
else
ans="${def_expire}"
echo "Using ${def_expire}"
fi
fi
if test "${ans}" = "never"
then
echo "Account will never expire."
def_expire=""
expire=""
return
fi
if ! expr "${ans}" : '^[0-9][0-9]/[0-9][0-9]/[0-9][0-9]$' &> /dev/null
then
echo "Please use format mm/dd/yy"
continue
fi
if ! expire_date="$(date -d ${ans} '+%A, %B %d %Y')"
then
continue
fi
def_expire="${expire}"
return
done
}
read_passwd_yn() {
echo -en "\nDo you want to set password [Y/n] ? "
if read_yn 0
then
set_pwd="YES"
else
set_pwd=""
fi
}
print_values() {
clear
cat << EOM
Login: ${S}${login}${E}
Group: ${S}${group}${E}
Other groups: ${S}${other_groups:-[none]}${E}
Real Name: ${S}${name}${E}
uid: ${S}${uid:-[first free]}${E}
home: ${S}${home}${E}
shell: ${S}${shell}${E}
Account expiration date: ${S}${expire_date:-never}${E}
Minimum days between password changes: ${S}${min_days}${E}
Maximum days between password changes: ${S}${max_days}${E}
Number of usable days after expiration: ${S}${iact_days}${E}
Number of warning days before expiration: ${S}${warn_days}${E}
${S}${set_pwd:+Set password for this account.}${E}
EOM
}
set_user() {
if ! useradd \
-c "${name}" \
-d "${home}" \
-g "${group}" \
-s "${shell}" \
${expire:+-e ${expire}} \
${uid:+-u ${uid}} \
${other_groups:+-G ${other_groups}} \
${login}
then
echo "Error ($?) in useradd...exiting..."
exit 1
fi
}
set_aging() {
if ! passwd \
-x ${max_days} \
-n ${min_days} \
-w ${warn_days} \
-i ${iact_days} \
${login}
then
echo "Error ($?) in setting password aging...exiting..."
exit 1
fi
}
set_password() {
if test -n "${set_pwd}"
then
echo
passwd ${login}
echo
fi
}
set_system() {
if test -d "${home}"
then
echo "Directory ${home} already exists."
echo "Skeleton files not copied."
return
fi
echo -n "Copying skeleton files..."
(
mkdir ${home}
cd ${skel} && cp -af . ${home}
chmod ${def_mode} ${home}
chown -R ${login}:${group} ${home}
)
echo "done."
## Add your own stuff here:
echo -n "Setting up other files..."
(
mailbox="/var/spool/mail/${login}"
touch ${mailbox}
chown "${login}:mail" ${mailbox}
chmod 600 ${mailbox}
)
echo "done."
}
read_values() {
clear
echo -e "\nPlease answer the following questions about the new user to be added."
while :
do
read_login
read_name
read_group
read_other_groups
read_home
read_shell
read_uid
read_expire_date
read_max_valid_days
read_min_valid_days
read_warning_days
read_inactive_days
read_passwd_yn
print_values
echo -n "Is this correct [N/y] ? "
read_yn 1 && return
done
}
main() {
check_root
read_values
set_user
set_aging
set_system
set_password
}
## Run it 8-)
main
# End.
-85
View File
@@ -1,85 +0,0 @@
#!/usr/bin/perl
#
# Copyright (c) 1996 Brian R. Gaeke
# 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. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Brian R. Gaeke.
# 4. The name of the author, Brian R. Gaeke, may not be used to endorse
# or promote products derived from this software without specific
# prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY BRIAN R. GAEKE ``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 BRIAN R. GAEKE 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.
#
# Additionally:
#
# This software is provided without support and without any obligation
# on the part of Brian R. Gaeke to assist in its use, correction,
# modification or enhancement.
#
#######################################################################
#
# this is atudel, version 2, by Brian R. Gaeke <brg@dgate.org>
#
require "getopts.pl";
&Getopts('v');
$username = shift(@ARGV);
&usage unless $username;
sub usage
{
print STDERR "atudel - remove all at jobs owned by a user\n";
print STDERR "usage: $0 [-v] username\n";
exit(1);
}
# odd. unless getpwnam($uname) doesn't seem to work for $uname eq "root" on
# my linux system. but this does.
die "user $username does not exist; stopping"
unless defined(getpwnam($username));
print "searching for at jobs owned by user $username ..." if $opt_v;
chdir "/var/spool/atjobs" ||
die "can't chdir to /var/spool/atjobs: $!\nstopping";
opendir(DIR,".") || die "can't opendir(/var/spool/atjobs): $!\nstopping";
@files = grep(!/^\./,grep(-f,readdir(DIR)));
closedir DIR;
foreach $x (@files)
{
$owner = (getpwuid((stat($x))[4]))[0];
push(@nuke_bait,$x) if $owner eq $username;
}
if (@nuke_bait)
{
print "removed jobIDs: @{nuke_bait}.\n" if $opt_v;
unlink @nuke_bait;
}
elsif ($opt_v)
{
print "\n";
}
exit 0;
-546
View File
@@ -1,546 +0,0 @@
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2000-05-25 14:41 CDT by <gk4@gnu.austin.ibm.com>.
# Source directory was `/home/gk4/src/groupmem'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 1960 -rw-r--r-- Makefile
# 6348 -rw-r--r-- groupmems.c
# 3372 -rw------- groupmems.8
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
shar_touch='touch -am $3$4$5$6$2 "$8"'
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
if mkdir _sh10937; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
$echo 'x -' extracting 'Makefile' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
/*
# Copyright 2000, International Business Machines, Inc.
# All rights reserved.
#
# original author: George Kraft IV, gk4@us.ibm.com
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. Neither the name of International Business Machines, Inc., 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 INTERNATIONAL BUSINESS MACHINES, INC. 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
# INTERNATIONAL BUSINESS MACHINES, INC. 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.
#
X
all: groupmems
X
groupmems: groupmems.c
X cc -g -o groupmems groupmems.c -L. -lshadow
X
install: groupmems
X -/usr/sbin/groupadd groups
X install -o root -g groups -m 4770 groupmems /usr/bin
X
install.man: groupmems.8
X install -o root -g root -m 644 groupmems.8 /usr/man/man8
X
SHAR_EOF
(set 20 00 05 25 14 40 28 'Makefile'; eval "$shar_touch") &&
chmod 0644 'Makefile' ||
$echo 'restore of' 'Makefile' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'Makefile:' 'MD5 check failed'
b46cf7ef8d59149093c011ced3f3103c Makefile
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'Makefile'`"
test 1960 -eq "$shar_count" ||
$echo 'Makefile:' 'original size' '1960,' 'current size' "$shar_count!"
fi
fi
# ============= groupmems.c ==============
if test -f 'groupmems.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'groupmems.c' '(file already exists)'
else
$echo 'x -' extracting 'groupmems.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.c' &&
/*
X * Copyright 2000, International Business Machines, Inc.
X * All rights reserved.
X *
X * original author: George Kraft IV, gk4@us.ibm.com
X *
X * Redistribution and use in source and binary forms, with or without
X * modification, are permitted provided that the following conditions
X * are met:
X *
X * 1. Redistributions of source code must retain the above copyright
X * notice, this list of conditions and the following disclaimer.
X * 2. Redistributions in binary form must reproduce the above copyright
X * notice, this list of conditions and the following disclaimer in the
X * documentation and/or other materials provided with the distribution.
X * 3. Neither the name of International Business Machines, Inc., nor the
X * names of its contributors may be used to endorse or promote products
X * derived from this software without specific prior written permission.
X *
X * THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
X * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
X * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
X * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
X * INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X * SUCH DAMAGE.
X */
/*
**
** Utility "groupmem" adds and deletes members from a user's group.
**
** Setup (as "root"):
**
** groupadd -r groups
** chmod 2770 groupmems
** chown root.groups groupmems
** groupmems -g groups -a gk4
**
** Usage (as "gk4"):
**
** groupmems -a olive
** groupmems -a jordan
** groupmems -a meghan
** groupmems -a morgan
** groupmems -a jake
** groupmems -l
** groupmems -d jake
** groupmems -l
*/
X
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "defines.h"
#include "groupio.h"
X
/* Exit Status Values */
X
#define EXIT_SUCCESS 0 /* success */
#define EXIT_USAGE 1 /* invalid command syntax */
#define EXIT_GROUP_FILE 2 /* group file access problems */
#define EXIT_NOT_ROOT 3 /* not superuser */
#define EXIT_NOT_EROOT 4 /* not effective superuser */
#define EXIT_NOT_PRIMARY 5 /* not primary owner of group */
#define EXIT_NOT_MEMBER 6 /* member of group does not exist */
#define EXIT_MEMBER_EXISTS 7 /* member of group already exists */
X
#define TRUE 1
#define FALSE 0
X
/* Globals */
X
extern int optind;
extern char *optarg;
static char *adduser = NULL;
static char *deluser = NULL;
static char *thisgroup = NULL;
static int purge = FALSE;
static int list = FALSE;
static int exclusive = 0;
X
static int isroot(void) {
X return getuid() ? FALSE : TRUE;
}
X
static int isgroup(void) {
X gid_t g = getgid();
X struct group *grp = getgrgid(g);
X
X return TRUE;
}
X
static char *whoami(void) {
X struct group *grp = getgrgid(getgid());
X struct passwd *usr = getpwuid(getuid());
X
X if (0 == strcmp(usr->pw_name, grp->gr_name)) {
X return (char *)strdup(usr->pw_name);
X } else {
X return NULL;
X }
}
X
static void
addtogroup(char *user, char **members) {
X int i;
X char **pmembers;
X
X for (i = 0; NULL != members[i]; i++ ) {
X if (0 == strcmp(user, members[i])) {
X fprintf(stderr, "Member already exists\n");
X exit(EXIT_MEMBER_EXISTS);
X }
X }
X
X if (0 == i) {
X pmembers = (char **)calloc(2, sizeof(char *));
X } else {
X pmembers = (char **)realloc(members, sizeof(char *)*(i+1));
X }
X
X *members = *pmembers;
X members[i] = user;
X members[i+1] = NULL;
}
X
static void
rmfromgroup(char *user, char **members) {
X int i;
X int found = FALSE;
X
X i = 0;
X while (!found && NULL != members[i]) {
X if (0 == strcmp(user, members[i])) {
X found = TRUE;
X } else {
X i++;
X }
X }
X
X while (found && NULL != members[i]) {
X members[i] = members[++i];
X }
X
X if (!found) {
X fprintf(stderr, "Member to remove could not be found\n");
X exit(EXIT_NOT_MEMBER);
X }
}
X
static void
nomembers(char **members) {
X int i;
X
X for (i = 0; NULL != members[i]; i++ ) {
X members[i] = NULL;
X }
}
X
static void
members(char **members) {
X int i;
X
X for (i = 0; NULL != members[i]; i++ ) {
X printf("%s ", members[i]);
X
X if (NULL == members[i+1]) {
X printf("\n");
X } else {
X printf(" ");
X }
X }
}
X
static void usage(void) {
X fprintf(stderr, "usage: groupmems -a username | -d username | -D | -l [-g groupname]\n");
X exit(EXIT_USAGE);
}
X
main(int argc, char **argv) {
X int arg, i;
X char *name;
X struct group *grp;
X
X while ((arg = getopt(argc, argv, "a:d:g:Dl")) != EOF) {
X switch (arg) {
X case 'a':
X adduser = strdup(optarg);
X ++exclusive;
X break;
X case 'd':
X deluser = strdup(optarg);
X ++exclusive;
X break;
X case 'g':
X thisgroup = strdup(optarg);
X break;
X case 'D':
X purge = TRUE;
X ++exclusive;
X break;
X case 'l':
X list = TRUE;
X ++exclusive;
X break;
X default:
X usage();
X }
X }
X
X if (exclusive > 1 || optind < argc) {
X usage();
X }
X
X if (!isroot() && NULL != thisgroup) {
X fprintf(stderr, "Only root can add members to different groups\n");
X exit(EXIT_NOT_ROOT);
X } else if (isroot() && NULL != thisgroup) {
X name = thisgroup;
X } else if (!isgroup()) {
X fprintf(stderr, "Group access is required\n");
X exit(EXIT_NOT_EROOT);
X } else if (NULL == (name = whoami())) {
X fprintf(stderr, "Not primary owner of current group\n");
X exit(EXIT_NOT_PRIMARY);
X }
X
X if (!gr_lock()) {
X fprintf(stderr, "Unable to lock group file\n");
X exit(EXIT_GROUP_FILE);
X }
X
X if (!gr_open(O_RDWR)) {
X fprintf(stderr, "Unable to open group file\n");
X exit(EXIT_GROUP_FILE);
X }
X
X grp = (struct group *)gr_locate(name);
X
X if (NULL != adduser) {
X addtogroup(adduser, grp->gr_mem);
X gr_update(grp);
X } else if (NULL != deluser) {
X rmfromgroup(deluser, grp->gr_mem);
X gr_update(grp);
X } else if (purge) {
X nomembers(grp->gr_mem);
X gr_update(grp);
X } else if (list) {
X members(grp->gr_mem);
X }
X
X if (!gr_close()) {
X fprintf(stderr, "Cannot close group file\n");
X exit(EXIT_GROUP_FILE);
X }
X
X gr_unlock();
X
X exit(EXIT_SUCCESS);
}
X
/* EOF */
SHAR_EOF
(set 20 00 05 25 14 36 38 'groupmems.c'; eval "$shar_touch") &&
chmod 0644 'groupmems.c' ||
$echo 'restore of' 'groupmems.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'groupmems.c:' 'MD5 check failed'
f0dd68f8d762d89d24d3ce1f4141f981 groupmems.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.c'`"
test 6348 -eq "$shar_count" ||
$echo 'groupmems.c:' 'original size' '6348,' 'current size' "$shar_count!"
fi
fi
# ============= groupmems.8 ==============
if test -f 'groupmems.8' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'groupmems.8' '(file already exists)'
else
$echo 'x -' extracting 'groupmems.8' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'groupmems.8' &&
X.\"
X.\" Copyright 2000, International Business Machines, Inc.
X.\" All rights reserved.
X.\"
X.\" original author: George Kraft IV, gk4@us.ibm.com
X.\"
X.\" Redistribution and use in source and binary forms, with or without
X.\" modification, are permitted provided that the following conditions
X.\" are met:
X.\"
X.\" 1. Redistributions of source code must retain the above copyright
X.\" notice, this list of conditions and the following disclaimer.
X.\" 2. Redistributions in binary form must reproduce the above copyright
X.\" notice, this list of conditions and the following disclaimer in the
X.\" documentation and/or other materials provided with the distribution.
X.\" 3. Neither the name of International Business Machines, Inc., nor the
X.\" names of its contributors may be used to endorse or promote products
X.\" derived from this software without specific prior written permission.
X.\"
X.\" THIS SOFTWARE IS PROVIDED BY INTERNATIONAL BUSINESS MACHINES, INC. AND
X.\" CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
X.\" BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
X.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
X.\" INTERNATIONAL BUSINESS MACHINES, INC. OR CONTRIBUTORS BE LIABLE
X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
X.\" SUCH DAMAGE.
X.\"
X.\" $Id$
X.\"
X.TH GROUPMEMS 8
X.SH NAME
groupmems \- Administer members of a user's primary group
X.SH SYNOPSIS
X.B groupmems
\fB-a\fI user_name \fR |
\fB-d\fI user_name \fR |
\fB-l\fR |
\fB-D\fR |
[\fB-g\fI group_name \fR]
X.SH DESCRIPTION
The \fBgroupmems\fR utility allows a user to administer his/her own
group membership list without the requirement of superuser privileges.
The \fBgroupmems\fR utility is for systems that configure its users to
be in their own name sake primary group (i.e., guest / guest).
X.P
Only the superuser, as administrator, can use \fBgroupmems\fR to alter
the memberships of other groups.
X.IP "\fB-a \fIuser_name\fR"
Add a new user to the group membership list.
X.IP "\fB-d \fIuser_name\fR"
Delete a user from the group membership list.
X.IP "\fB-l\fR"
List the group membership list.
X.IP "\fB-D\fR"
Delete all users from the group membership list.
X.IP "\fB-g \fIgroup_name\fR"
The superuser can specify which group membership list to modify.
X.SH SETUP
The \fBgroupmems\fR executable should be in mode \fB2770\fR as user \fBroot\fR
and in group \fBgroups\fR. The system administrator can add users to
group groups to allow or disallow them using the \fBgroupmems\fR utility
to manager their own group membership list.
X.P
X $ groupadd -r groups
X.br
X $ chmod 2770 groupmems
X.br
X $ chown root.groups groupmems
X.br
X $ groupmems -g groups -a gk4
X.SH FILES
/etc/group
X.br
/etc/gshadow
X.SH SEE ALSO
X.BR chfn (1),
X.BR chsh (1),
X.BR useradd (8),
X.BR userdel (8),
X.BR usermod (8),
X.BR passwd (1),
X.BR groupadd (8),
X.BR groupdel (8)
X.SH AUTHOR
George Kraft IV (gk4@us.ibm.com)
X.\" EOF
SHAR_EOF
(set 20 00 05 25 14 38 23 'groupmems.8'; eval "$shar_touch") &&
chmod 0600 'groupmems.8' ||
$echo 'restore of' 'groupmems.8' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'groupmems.8:' 'MD5 check failed'
181e6cd3a3c9d3df320197fa2cde2b4a groupmems.8
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'groupmems.8'`"
test 3372 -eq "$shar_count" ||
$echo 'groupmems.8:' 'original size' '3372,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh10937
exit 0
-308
View File
@@ -1,308 +0,0 @@
/*
* pwdauth.c - program to verify a given username/password pair.
*
* Run it with username in argv[1] (may be omitted - default is the
* current user), and send it the password over a pipe on stdin.
* Exit status: 0 - correct password, 1 - wrong password, >1 - other
* errors. For use with shadow passwords, this program should be
* installed setuid root.
*
* This can be used, for example, by xlock - you don't have to install
* this large and complex (== possibly insecure) program setuid root,
* just modify it to run this simple program to do the authentication.
*
* Recent versions (xlockmore-3.9) are cleaner, and drop privileges as
* soon as possible after getting the user's encrypted password.
* Using this program probably doesn't make it more secure, and has one
* disadvantage: since we don't get the encrypted user's password at
* startup (but at the time the user is authenticated), it is not clear
* how we should handle errors (like getpwnam() returning NULL).
* - fail the authentication? Problem: no way to unlock (other than kill
* the process from somewhere else) if the NIS server stops responding.
* - succeed and unlock? Problem: it's too easy to unlock by unplugging
* the box from the network and waiting until NIS times out...
*
* This program is Copyright (C) 1996 Marek Michalkiewicz
* <marekm@i17linuxb.ists.pwr.wroc.pl>.
*
* It may be used and distributed freely for any purposes. There is no
* warranty - use at your own risk. I am not liable for any damages etc.
* If you improve it, please send me your changes.
*/
static char rcsid[] = "$Id$";
/*
* Define USE_SYSLOG to use syslog() to log successful and failed
* authentication. This should be safe even if your system has
* the infamous syslog buffer overrun security problem...
*/
#define USE_SYSLOG
/*
* Define HAVE_GETSPNAM to get shadow passwords using getspnam().
* Some systems don't have getspnam(), but getpwnam() returns
* encrypted passwords only if running as root.
*
* According to the xlock source (not tested, except Linux) -
* define: Linux, Solaris 2.x, SVR4, ...
* undef: HP-UX with Secured Passwords, FreeBSD, NetBSD, QNX.
* Known not supported (yet): Ultrix, OSF/1, SCO.
*/
#define HAVE_GETSPNAM
/*
* Define HAVE_PW_ENCRYPT to use pw_encrypt() instead of crypt().
* pw_encrypt() is like the standard crypt(), except that it may
* support better password hashing algorithms.
*
* Define if linking with libshadow.a from the shadow password
* suite (Linux, SunOS 4.x?).
*/
#undef HAVE_PW_ENCRYPT
/*
* Define HAVE_AUTH_METHODS to support the shadow suite specific
* extension: the encrypted password field contains a list of
* administrator defined authentication methods, separated by
* semicolons. This program only supports the standard password
* authentication method (a string that doesn't start with '@').
*/
#undef HAVE_AUTH_METHODS
/*
* FAIL_DELAY - number of seconds to sleep before exiting if the
* password was wrong, to slow down password guessing attempts.
*/
#define FAIL_DELAY 2
/* No user-serviceable parts below :-). */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <pwd.h>
#ifdef USE_SYSLOG
#include <syslog.h>
#ifndef LOG_AUTHPRIV
#define LOG_AUTHPRIV LOG_AUTH
#endif
#endif
#ifdef HAVE_GETSPNAM
#include <shadow.h>
#endif
#ifdef HAVE_PW_ENCRYPT
extern char *pw_encrypt();
#define crypt pw_encrypt
#endif
/*
* Read the password (one line) from fp. We don't turn off echo
* because we expect input from a pipe.
*/
static char *
get_line(fp)
FILE *fp;
{
static char buf[128];
char *cp;
int ch;
cp = buf;
while ((ch = getc(fp)) != EOF && ch != '\0' && ch != '\n') {
if (cp >= buf + sizeof buf - 1)
break;
*cp++ = ch;
}
*cp = '\0';
return buf;
}
/*
* Get the password file entry for the current user. If the name
* returned by getlogin() is correct (matches the current real uid),
* return the entry for that user. Otherwise, return the entry (if
* any) matching the current real uid. Return NULL on failure.
*/
static struct passwd *
get_my_pwent()
{
uid_t uid = getuid();
char *name = getlogin();
if (name && *name) {
struct passwd *pw = getpwnam(name);
if (pw && pw->pw_uid == uid)
return pw;
}
return getpwuid(uid);
}
/*
* Verify the password. The system-dependent shadow support is here.
*/
static int
password_auth_ok(pw, pass)
const struct passwd *pw;
const char *pass;
{
int result;
char *cp;
#ifdef HAVE_AUTH_METHODS
char *buf;
#endif
#ifdef HAVE_GETSPNAM
struct spwd *sp;
#endif
if (pw) {
#ifdef HAVE_GETSPNAM
sp = getspnam(pw->pw_name);
if (sp)
cp = sp->sp_pwdp;
else
#endif
cp = pw->pw_passwd;
} else
cp = "xx";
#ifdef HAVE_AUTH_METHODS
buf = strdup(cp); /* will be modified by strtok() */
if (!buf) {
fprintf(stderr, "Out of memory.\n");
exit(13);
}
cp = strtok(buf, ";");
while (cp && *cp == '@')
cp = strtok(NULL, ";");
/* fail if no password authentication for this user */
if (!cp)
cp = "xx";
#endif
if (*pass || *cp)
result = (strcmp(crypt(pass, cp), cp) == 0);
else
result = 1; /* user with no password */
#ifdef HAVE_AUTH_METHODS
free(buf);
#endif
return result;
}
/*
* Main program.
*/
int
main(argc, argv)
int argc;
char **argv;
{
struct passwd *pw;
char *pass, *name;
char myname[32];
#ifdef USE_SYSLOG
openlog("pwdauth", LOG_PID | LOG_CONS, LOG_AUTHPRIV);
#endif
pw = get_my_pwent();
if (!pw) {
#ifdef USE_SYSLOG
syslog(LOG_ERR, "can't get login name for uid %d.\n",
(int) getuid());
#endif
fprintf(stderr, "Who are you?\n");
exit(2);
}
strncpy(myname, pw->pw_name, sizeof myname - 1);
myname[sizeof myname - 1] = '\0';
name = myname;
if (argc > 1) {
name = argv[1];
pw = getpwnam(name);
}
pass = get_line(stdin);
if (password_auth_ok(pw, pass)) {
#ifdef USE_SYSLOG
syslog(pw->pw_uid ? LOG_INFO : LOG_NOTICE,
"user `%s' entered correct password for `%.32s'.\n",
myname, name);
#endif
exit(0);
}
#ifdef USE_SYSLOG
/* be careful not to overrun the syslog buffer */
syslog((!pw || pw->pw_uid) ? LOG_NOTICE : LOG_WARNING,
"user `%s' entered incorrect password for `%.32s'.\n",
myname, name);
#endif
#ifdef FAIL_DELAY
sleep(FAIL_DELAY);
#endif
fprintf(stderr, "Wrong password.\n");
exit(1);
}
#if 0
/*
* You can use code similar to the following to run this program.
* Return values: >=0 - program exit status (use the <sys/wait.h>
* macros to get the exit code, it is shifted left by 8 bits),
* -1 - check errno.
*/
int
verify_password(const char *username, const char *password)
{
int pipe_fd[2];
int pid, wpid, status;
if (pipe(pipe_fd))
return -1;
if ((pid = fork()) == 0) {
char *arg[3];
char *env[1];
/* child */
close(pipe_fd[1]);
if (pipe_fd[0] != 0) {
if (dup2(pipe_fd[0], 0) != 0)
_exit(127);
close(pipe_fd[0]);
}
arg[0] = "/usr/bin/pwdauth";
arg[1] = username;
arg[2] = NULL;
env[0] = NULL;
execve(arg[0], arg, env);
_exit(127);
} else if (pid == -1) {
/* error */
close(pipe_fd[0]);
close(pipe_fd[1]);
return -1;
}
/* parent */
close(pipe_fd[0]);
write(pipe_fd[1], password, strlen(password));
write(pipe_fd[1], "\n", 1);
close(pipe_fd[1]);
while ((wpid = wait(&status)) != pid) {
if (wpid == -1)
return -1;
}
return status;
}
#endif
-147
View File
@@ -1,147 +0,0 @@
Hello Marek,
I have created a diffile against the 980403 release that adds
functionality to newusers for automatic handling of users with only
anonomous ftp login (using the guestgroup feature in ftpaccess, which
means that the users home directory looks like '/home/user/./'). It also
adds a commandline argument to specify an initial directory structure
for such users, with a tarball normally containing the bin,lib,etc
directories used in the chrooted environment.
I am using it to automatically create chunks of users with only ftp
access for a webserver.
I have tried to follow your coding standards and I believe it is bug
free but.. well, who knows. :) It's not much code however.
I hope you find it useful. Do what you like with it, feel free to ask if
anything is unclear.
Best rgds,
Calle Karlsson
ckn@kash.se
diff -uNr shadow-980403.orig/src/newusers.c shadow-980403/src/newusers.c
--- shadow-980403.orig/src/newusers.c Fri Jan 30 00:22:43 1998
+++ shadow-980403/src/newusers.c Fri Apr 17 16:55:33 1998
@@ -76,11 +76,35 @@
static void
usage(void)
{
- fprintf(stderr, "Usage: %s [ input ]\n", Prog);
+ fprintf (stderr, "Usage: %s [-p prototype tarfile] [ input ]\n", Prog);
+ fprintf (stderr, "The prototype tarfile is only used for users\n");
+ fprintf (stderr, "marked as anonymous ftp users. It must be a full pathname.\n");
exit(1);
}
/*
+ * createuserdir - create a directory and chmod it
+ */
+
+static int
+createuserdir (char * dir, int uid, int gid, int line)
+{
+ if (mkdir (dir, 0777 & ~getdef_num("UMASK", 077))) {
+ fprintf (stderr, "%s: line %d: mkdir %s failed\n",
+ Prog, line, dir);
+ return -1;
+ }
+
+ if (chown (dir, uid, gid)) {
+ fprintf (stderr, "%s: line %d: chown %s failed\n",
+ Prog, line, dir);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
* add_group - create a new group or add a user to an existing group
*/
@@ -328,6 +352,8 @@
main(int argc, char **argv)
{
char buf[BUFSIZ];
+ char anonproto[BUFSIZ];
+ int flag;
char *fields[8];
int nfields;
char *cp;
@@ -340,12 +366,23 @@
Prog = Basename(argv[0]);
- if (argc > 1 && argv[1][0] == '-')
- usage ();
+ * anonproto = '\0';
+
+ while ((flag = getopt (argc, argv, "p:h")) != EOF) {
+ switch (flag) {
+ case 'p':
+ STRFCPY(anonproto, optarg);
+ break;
+ case 'h':
+ default:
+ usage ();
+ break;
+ }
+ }
- if (argc == 2) {
- if (! freopen (argv[1], "r", stdin)) {
- snprintf(buf, sizeof buf, "%s: %s", Prog, argv[1]);
+ if (optind < argc) {
+ if (! freopen (argv[optind], "r", stdin)) {
+ snprintf(buf, sizeof buf, "%s: %s", Prog, argv[optind]);
perror (buf);
exit (1);
}
@@ -499,15 +536,36 @@
if (fields[6][0])
newpw.pw_shell = fields[6];
- if (newpw.pw_dir[0] && access(newpw.pw_dir, F_OK)) {
- if (mkdir (newpw.pw_dir,
- 0777 & ~getdef_num("UMASK", 077)))
- fprintf (stderr, "%s: line %d: mkdir failed\n",
- Prog, line);
- else if (chown (newpw.pw_dir,
- newpw.pw_uid, newpw.pw_gid))
- fprintf (stderr, "%s: line %d: chown failed\n",
- Prog, line);
+ if (newpw.pw_dir[0]) {
+ char * userdir = strdup (newpw.pw_dir);
+ char * anonpart;
+ int rc;
+
+ if ((anonpart = strstr (userdir, "/./"))) {
+ * anonpart = '\0';
+ anonpart += 2;
+ }
+
+ if (access(userdir, F_OK))
+ rc = createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line);
+ else
+ rc = 0;
+
+ if (rc == 0 && anonpart) {
+ if (* anonproto) {
+ char cmdbuf [BUFSIZ];
+ snprintf(cmdbuf, sizeof cmdbuf,
+ "cd %s; tar xf %s",
+ userdir, anonproto);
+ system (cmdbuf);
+ }
+ if (strlen (anonpart) > 1) {
+ strcat (userdir, anonpart);
+ if (access (userdir, F_OK))
+ createuserdir (userdir, newpw.pw_uid, newpw.pw_gid, line);
+ }
+ }
+ free (userdir);
}
/*
Binary file not shown.
-1918
View File
File diff suppressed because it is too large Load Diff
-5
View File
@@ -1,5 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
EXTRA_DIST = HOWTO README.limits \
README.platforms WISHLIST console.c.spec.txt cracklib26.diff
-66
View File
@@ -1,66 +0,0 @@
ABOUT shadow-login limits:
This code is merged into shadow login program from the original LShell 2.01
written by Joel Katz. The port and some additional features have been added
by Cristian Gafton (gafton@sorosis.ro).
Changes:
- 96/04/16
- {spaces,tabs} allowed within limits string
- Warn via syslog multiple default limits
- added few paragraphs to the login man page
- 96/04/14
- code merged into lmain.c --cristiang
TODO: - support groups in the limits file
(only usernames are supported at this momment :-( )
Setting user limits for shadow login program
First, make a root-only-readable file (/etc/limits by default or LIMITS_FILE
defined config.h) that describes the resource limits you wish to impose. By
default no quotas are imposed on 'root'. In fact, there is no way to impose
limits via this procedure to root-equiv accounts (accounts with UID 0).
Each line describes a limit for a user in the form:
user LIMITS_STRING
The LIMITS_STRING is a string of a concatenated list of resource limits.
Each limit consists of a letter identifier followed by a numerical limit.
The valid identifiers are:
A: max address space (KB)
C: max core file size (KB)
D: max data size (KB)
F: maximum filesize (KB)
M: max locked-in-memory address space (KB)
N: max number of open files
R: max resident set size (KB)
S: max stack size (KB)
T: max CPU time (MIN)
U: max number of processes
L: max number of logins for this user
For example, L2D2048N5 is a valid LIMITS_STRING. For reading convenience,
the following entries are equivalent:
username L2D2048N5
username L2 D2048 N5
Be aware that after <username> the rest of the line is considered a limit
string, thus comments are not allowed. A invalid limits string will be
rejected (not considered) by the login program.
The default entry is denoted by username '*'. If you have multiple 'default'
entries in your LIMITS_FILE, then the last one will be used as the default
entry.
To completely disable limits for a user, a single dash (-) will do.
Also, please note that all limit settings are set PER LOGIN. They are
not global, nor are they permanent. Perhaps global limits will come, but
for now this will have to do ;)
-33
View File
@@ -1,33 +0,0 @@
# $Id$
#
# This is the current (still incomplete) list of platforms this
# package has been verified to work on. Additions (preferably
# in the format as described below) are welcome. Thanks!
#
# V: last version reported to work
# H: host type
# L: Linux libc version
# D: Linux distribution, or other OS name and version
# C: changes (if any)
# R: reported by
V: 980529
H: sparc-unknown-linux-gnu
L: glibc-2.0.7
D: Ultrapenguin-1.0.9
C: had to explicitly disable desrpc.
R: Bjorn Christianson <bjorn@cascade.psychology.mcmaster.ca>
V: 980724
H: i486-pc-linux-gnulibc1
L: libc-5.4.33
D: Debian-1.3.1.r6
C: none (use dpkg-buildpackage)
R: Marek Michalkiewicz <marekm@linux.org.pl>
V: current
H: i686-pc-linux-gnu
L: glibc-2.0.7.19981211
D: Debian-2.1
C: none (use dpkg-buildpackage)
R: Marek Michalkiewicz <marekm@linux.org.pl>
-40
View File
@@ -1,40 +0,0 @@
$Id$
This is my wishlist for the shadow suite, in no particular order. Feel
free to do anything from this list and mail me the diffs :-).
Patches in diff -u format, against the latest version (sometimes in the
"beta" directory) are preferred and make my job easier. Please, no
MIME, base64, quoted-printable, or HTML. For very big patches, or if
your mailer can corrupt them, please use gzip and uuencode. Thanks!
New ideas to add to this list are welcome, too. --marekm
- fix all the bugs, of course
- implement "su only" accounts (no logins, only su from other account)
- rewrite getdef.c to be more general? (no hardcoded names)
- patch for rlogind/telnetd to create utmp entry and fill in ut_addr
- option to specify encrypted password in passwd (for yppasswdd, so it
doesn't need to know about shadow/non-shadow); should probably use a pipe
(less insecure than command line arguments)
- add support for changing NIS passwords
- add option to check passwords by piping them to external programs
- add functionality of the contrib/rpasswd.c wrapper to passwd
- option to generate pronounceable passwords (like on SCO), external program?
- poppassd (remote password change for eudora etc.)
- add support for passwd/shadow db files (glibc)
- vipw: check password files for errors after editing
- add "maximum time users allowed to stay logged in" limit option to logoutd
- handle quotes in /etc/environment like the shell does (but sshd doesn't...)
- better utmpx support (logoutd, ...)
- better OPIE support (report number of logins left, etc.)
- new option for /etc/suauth: don't load user's environment (force "su -")
suggested by Ulisses Alonso Camaro
- find out why recent releases won't compile on Solaris
- newusers should be able to copy /etc/skel to the new home directory
(like useradd)
- add directories where other packages can add hooks for package-specific
per-user configuration, to be executed with run-parts. Some hooks should
be executed at package install time for existing users, likewise for
package removal and possibly modification. (Debian Bug#36019)
-36
View File
@@ -1,36 +0,0 @@
$Id$
Specification for console.c source file --
input values --
tty -- character pointer to device name with leading "/dev/"
removed.
return values --
0 -- false
1 -- true
int console (char * tty)
if "CONSOLE" string value is not present in login.defs
return true
if the first character of "CONSOLE" string value is not "/"
treat the string as a ":" delimited list of device
names and search for the value of tty in that
tokenized list.
if a match is found
return true
return false
if the file named by "CONSOLE" cannot be opened
return true
scan the file looking for a match between the input line
and the value of tty
if a match is found
return true
return false
-340
View File
@@ -1,340 +0,0 @@
diff -ur orig/cracklib26_small/cracklib/fascist.c cracklib26_small/cracklib/fascist.c
--- orig/cracklib26_small/cracklib/fascist.c Mon Dec 15 02:56:55 1997
+++ cracklib26_small/cracklib/fascist.c Sat Apr 4 22:14:45 1998
@@ -12,6 +12,7 @@
#include <ctype.h>
#include <sys/types.h>
#include <pwd.h>
+#include <string.h>
#define ISSKIP(x) (isspace(x) || ispunct(x))
@@ -460,28 +461,27 @@
}
char *
-FascistGecos(password, uid)
+FascistGecosPw(password, pwd)
char *password;
- int uid;
+ struct passwd *pwd;
{
int i;
int j;
int wc;
char *ptr;
- struct passwd *pwp;
char gbuffer[STRINGSIZE];
char tbuffer[STRINGSIZE];
char *uwords[STRINGSIZE];
char longbuffer[STRINGSIZE * 2];
- if (!(pwp = getpwuid(uid)))
+ if (!pwd)
{
return ("you are not registered in the password file");
}
/* lets get really paranoid and assume a dangerously long gecos entry */
- strncpy(tbuffer, pwp->pw_name, STRINGSIZE);
+ strncpy(tbuffer, pwd->pw_name, STRINGSIZE);
tbuffer[STRINGSIZE-1] = '\0';
if (GTry(tbuffer, password))
{
@@ -490,12 +490,13 @@
/* it never used to be that you got passwd strings > 1024 chars, but now... */
- strncpy(tbuffer, pwp->pw_gecos, STRINGSIZE);
+ strncpy(tbuffer, pwd->pw_gecos, STRINGSIZE);
tbuffer[STRINGSIZE-1] = '\0';
strcpy(gbuffer, Lowercase(tbuffer));
wc = 0;
ptr = gbuffer;
+ uwords[0] = (char *) 0;
while (*ptr)
{
@@ -530,6 +531,8 @@
*(ptr++) = '\0';
}
}
+ if (!uwords[0])
+ return ((char *) 0); /* empty gecos */
#ifdef DEBUG
for (i = 0; uwords[i]; i++)
{
@@ -586,9 +589,10 @@
}
char *
-FascistLook(pwp, instring)
+FascistLookPw(pwp, instring, pwd)
PWDICT *pwp;
char *instring;
+ struct passwd *pwd;
{
int i;
char *ptr;
@@ -667,7 +671,7 @@
return ("it looks like a National Insurance number.");
}
- if (ptr = FascistGecos(password, getuid()))
+ if (ptr = FascistGecosPw(password, pwd ? pwd : getpwuid(getuid())))
{
return (ptr);
}
@@ -715,9 +719,10 @@
}
char *
-FascistCheck(password, path)
+FascistCheckPw(password, path, pwd)
char *password;
char *path;
+ struct passwd *pwd;
{
static char lastpath[STRINGSIZE];
static PWDICT *pwp;
@@ -750,5 +755,29 @@
strncpy(lastpath, path, STRINGSIZE);
}
- return (FascistLook(pwp, pwtrunced));
+ return (FascistLookPw(pwp, pwtrunced, pwd));
+}
+
+char *
+FascistGecos(password, uid)
+ char *password;
+ int uid;
+{
+ return (FascistGecosPw(password, getpwuid(uid)));
+}
+
+char *
+FascistLook(pwp, instring)
+ PWDICT *pwp;
+ char *instring;
+{
+ return (FascistLookPw(pwp, instring, (char *) 0));
+}
+
+char *
+FascistCheck(password, path)
+ char *password;
+ char *path;
+{
+ return (FascistCheckPw(password, path, (char *) 0));
}
diff -ur orig/cracklib26_small/cracklib/packer.h cracklib26_small/cracklib/packer.h
--- orig/cracklib26_small/cracklib/packer.h Mon Dec 15 00:09:30 1997
+++ cracklib26_small/cracklib/packer.h Sat Jan 10 22:13:46 1998
@@ -34,6 +34,7 @@
FILE *dfp;
FILE *wfp;
+ int canfree;
int32 flags;
#define PFOR_WRITE 0x0001
#define PFOR_FLUSH 0x0002
diff -ur orig/cracklib26_small/cracklib/packlib.c cracklib26_small/cracklib/packlib.c
--- orig/cracklib26_small/cracklib/packlib.c Fri Jul 9 22:22:58 1993
+++ cracklib26_small/cracklib/packlib.c Sat Jan 10 22:28:49 1998
@@ -16,7 +16,7 @@
char *mode;
{
int32 i;
- static PWDICT pdesc;
+ PWDICT *pdesc;
char iname[STRINGSIZE];
char dname[STRINGSIZE];
char wname[STRINGSIZE];
@@ -25,92 +25,94 @@
FILE *ifp;
FILE *wfp;
- if (pdesc.header.pih_magic == PIH_MAGIC)
- {
- fprintf(stderr, "%s: another dictionary already open\n", prefix);
+ if ((pdesc = (PWDICT *) malloc(sizeof(PWDICT))) == 0)
return ((PWDICT *) 0);
- }
- memset(&pdesc, '\0', sizeof(pdesc));
+ memset(pdesc, '\0', sizeof(*pdesc));
sprintf(iname, "%s.pwi", prefix);
sprintf(dname, "%s.pwd", prefix);
sprintf(wname, "%s.hwm", prefix);
- if (!(pdesc.dfp = fopen(dname, mode)))
+ if (!(pdesc->dfp = fopen(dname, mode)))
{
perror(dname);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (!(pdesc.ifp = fopen(iname, mode)))
+ if (!(pdesc->ifp = fopen(iname, mode)))
{
- fclose(pdesc.dfp);
+ fclose(pdesc->dfp);
perror(iname);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.wfp = fopen(wname, mode))
+ if (pdesc->wfp = fopen(wname, mode))
{
- pdesc.flags |= PFOR_USEHWMS;
+ pdesc->flags |= PFOR_USEHWMS;
}
- ifp = pdesc.ifp;
- dfp = pdesc.dfp;
- wfp = pdesc.wfp;
+ ifp = pdesc->ifp;
+ dfp = pdesc->dfp;
+ wfp = pdesc->wfp;
if (mode[0] == 'w')
{
- pdesc.flags |= PFOR_WRITE;
- pdesc.header.pih_magic = PIH_MAGIC;
- pdesc.header.pih_blocklen = NUMWORDS;
- pdesc.header.pih_numwords = 0;
+ pdesc->flags |= PFOR_WRITE;
+ pdesc->header.pih_magic = PIH_MAGIC;
+ pdesc->header.pih_blocklen = NUMWORDS;
+ pdesc->header.pih_numwords = 0;
- fwrite((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp);
+ fwrite((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp);
} else
{
- pdesc.flags &= ~PFOR_WRITE;
+ pdesc->flags &= ~PFOR_WRITE;
- if (!fread((char *) &pdesc.header, sizeof(pdesc.header), 1, ifp))
+ if (!fread((char *) &pdesc->header, sizeof(pdesc->header), 1, ifp))
{
fprintf(stderr, "%s: error reading header\n", prefix);
- pdesc.header.pih_magic = 0;
+ pdesc->header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.header.pih_magic != PIH_MAGIC)
+ if (pdesc->header.pih_magic != PIH_MAGIC)
{
fprintf(stderr, "%s: magic mismatch\n", prefix);
- pdesc.header.pih_magic = 0;
+ pdesc->header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.header.pih_blocklen != NUMWORDS)
+ if (pdesc->header.pih_blocklen != NUMWORDS)
{
fprintf(stderr, "%s: size mismatch\n", prefix);
- pdesc.header.pih_magic = 0;
+ pdesc->header.pih_magic = 0;
fclose(ifp);
fclose(dfp);
+ free(pdesc);
return ((PWDICT *) 0);
}
- if (pdesc.flags & PFOR_USEHWMS)
+ if (pdesc->flags & PFOR_USEHWMS)
{
- if (fread(pdesc.hwms, 1, sizeof(pdesc.hwms), wfp) != sizeof(pdesc.hwms))
+ if (fread(pdesc->hwms, 1, sizeof(pdesc->hwms), wfp) != sizeof(pdesc->hwms))
{
- pdesc.flags &= ~PFOR_USEHWMS;
+ pdesc->flags &= ~PFOR_USEHWMS;
}
}
}
-
- return (&pdesc);
+ pdesc->canfree = 1;
+ return (pdesc);
}
int
@@ -159,8 +161,13 @@
fclose(pwp->ifp);
fclose(pwp->dfp);
+ if (pwp->wfp)
+ fclose(pwp->wfp);
- pwp->header.pih_magic = 0;
+ if (pwp->canfree)
+ free(pwp);
+ else
+ pwp->header.pih_magic = 0;
return (0);
}
@@ -307,6 +314,11 @@
register char *this;
int idx;
+/*
+ * comment in npasswd-2.0beta4 says this:
+ * This does not work under all circumstances, so don't bother
+ */
+#if 0
if (pwp->flags & PFOR_USEHWMS)
{
idx = string[0] & 0xff;
@@ -317,6 +329,10 @@
lwm = 0;
hwm = PW_WORDS(pwp) - 1;
}
+#else
+ lwm = 0;
+ hwm = PW_WORDS(pwp);
+#endif
#ifdef DEBUG
printf("---- %lu, %lu ----\n", lwm, hwm);
diff -ur orig/cracklib26_small/util/mkdict cracklib26_small/util/mkdict
--- orig/cracklib26_small/util/mkdict Fri Jul 9 22:23:03 1993
+++ cracklib26_small/util/mkdict Sat Apr 4 22:31:45 1998
@@ -14,9 +14,16 @@
SORT="sort"
###SORT="sort -T /tmp"
-cat $* |
+### Use zcat to read compressed (as well as uncompressed) dictionaries.
+### Compressed dictionaries can save quite a lot of disk space.
+
+CAT="gzip -cdf"
+###CAT="zcat"
+###CAT="cat"
+
+$CAT $* |
tr '[A-Z]' '[a-z]' |
- tr -cd '[\012a-z0-9]' |
+ tr -cd '\012[a-z][0-9]' |
$SORT |
uniq |
grep -v '^#' |
-24
View File
@@ -1,24 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
sysconf_DATA = login.defs
defaultdir = $(sysconfdir)/default
default_DATA = \
useradd
nonpam_files = \
limits \
login.access
if !USE_PAM
nonpamdir = $(sysconfdir)
nonpam_DATA = $(nonpam_files)
endif
EXTRA_DIST = \
$(nonpam_files) \
$(sysconf_DATA) \
$(default_DATA)
SUBDIRS = pam.d
-30
View File
@@ -1,30 +0,0 @@
# /etc/limits contains user resource limits.
# See limits(5).
#
# Format:
# <username> <limits-string>
#
# default entry is '*' for username
#
# Valid flags are:
# A: max address space (KB)
# C: max core file size (KB)
# D: max data size (KB)
# F: maximum filesize (KB)
# M: max locked-in-memory address space (KB) [only for root on Linux 2.0.x]
# N: max number of open files
# R: max resident set size (KB) [no effect on Linux 2.0.x]
# S: max stack size (KB)
# T: max CPU time (MIN)
# U: max number of processes
# L: max number of logins for this user
# I: max nice value (0..39 translates to 20..-19)
# O: max real time priority (0..MAX_RT_PRIO)
#
# Examples:
# the default entry
#* L2 D6144 R2048 S2048 U32 N32 F16384 T5 C0 I20 O0
# another way of suspending a user login
#guest L0
# this account has no limits
#sysadm -
-54
View File
@@ -1,54 +0,0 @@
# $Id$
#
# Login access control table.
#
# When someone logs in, the table is scanned for the first entry that
# matches the (user, host) combination, or, in case of non-networked
# logins, the first entry that matches the (user, tty) combination. The
# permissions field of that table entry determines whether the login will
# be accepted or refused.
#
# Format of the login access control table is three fields separated by a
# ":" character:
#
# permission : users : origins
#
# The first field should be a "+" (access granted) or "-" (access denied)
# character.
#
# The second field should be a list of one or more login names, group
# names, or ALL (always matches). A pattern of the form user@host is
# matched when the login name matches the "user" part, and when the
# "host" part matches the local machine name.
#
# The third field should be a list of one or more tty names (for
# non-networked logins), host names, domain names (begin with "."), host
# addresses, internet network numbers (end with "."), ALL (always
# matches) or LOCAL (matches any string that does not contain a "."
# character).
#
# If you run NIS you can use @netgroupname in host or user patterns; this
# even works for @usergroup@@hostgroup patterns. Weird.
#
# The EXCEPT operator makes it possible to write very compact rules.
#
# The group file is searched only when a name does not match that of the
# logged-in user. Only groups are matched in which users are explicitly
# listed: the program does not look at a user's primary group id value.
#
##############################################################################
#
# Disallow console logins to all but a few accounts.
#
#-:ALL EXCEPT wheel shutdown sync:console
#
# Disallow non-local logins to privileged accounts (group wheel).
#
#-:wheel:ALL EXCEPT LOCAL .win.tue.nl
#
# Some accounts are not allowed to login from anywhere:
#
#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL
#
# All other accounts are allowed to login from anywhere.
#
-400
View File
@@ -1,400 +0,0 @@
#
# /etc/login.defs - Configuration control definitions for the shadow package.
#
# $Id$
#
#
# Delay in seconds before being allowed another attempt after a login failure
# Note: When PAM is used, some modules may enforce a minimum delay (e.g.
# pam_unix(8) enforces a 2s delay)
#
FAIL_DELAY 3
#
# Enable logging and display of /var/log/faillog login(1) failure info.
#
FAILLOG_ENAB yes
#
# Enable display of unknown usernames when login(1) failures are recorded.
#
LOG_UNKFAIL_ENAB no
#
# Enable logging of successful logins
#
LOG_OK_LOGINS no
#
# Enable logging and display of /var/log/lastlog login(1) time info.
#
LASTLOG_ENAB yes
#
# Enable checking and display of mailbox status upon login.
#
# Disable if the shell startup files already check for mail
# ("mailx -e" or equivalent).
#
MAIL_CHECK_ENAB yes
#
# Enable additional checks upon password changes.
#
OBSCURE_CHECKS_ENAB yes
#
# Enable checking of time restrictions specified in /etc/porttime.
#
PORTTIME_CHECKS_ENAB yes
#
# Enable setting of ulimit, umask, and niceness from passwd(5) gecos field.
#
QUOTAS_ENAB yes
#
# Enable "syslog" logging of su(1) activity - in addition to sulog file logging.
# SYSLOG_SG_ENAB does the same for newgrp(1) and sg(1).
#
SYSLOG_SU_ENAB yes
SYSLOG_SG_ENAB yes
#
# If defined, either full pathname of a file containing device names or
# a ":" delimited list of device names. Root logins will be allowed only
# from these devices.
#
CONSOLE /etc/securetty
#CONSOLE console:tty01:tty02:tty03:tty04
#
# If defined, all su(1) activity is logged to this file.
#
#SULOG_FILE /var/log/sulog
#
# If defined, ":" delimited list of "message of the day" files to
# be displayed upon login.
#
MOTD_FILE /etc/motd
#MOTD_FILE /etc/motd:/usr/lib/news/news-motd
#
# If defined, this file will be output before each login(1) prompt.
#
#ISSUE_FILE /etc/issue
#
# If defined, file which maps tty line to TERM environment parameter.
# Each line of the file is in a format similar to "vt100 tty01".
#
#TTYTYPE_FILE /etc/ttytype
#
# If defined, login(1) failures will be logged here in a utmp format.
# last(1), when invoked as lastb(1), will read /var/log/btmp, so...
#
FTMP_FILE /var/log/btmp
#
# If defined, name of file whose presence will inhibit non-root
# logins. The content of this file should be a message indicating
# why logins are inhibited.
#
NOLOGINS_FILE /etc/nologin
#
# If defined, the command name to display when running "su -". For
# example, if this is defined as "su" then ps(1) will display the
# command as "-su". If not defined, then ps(1) will display the
# name of the shell actually being run, e.g. something like "-sh".
#
SU_NAME su
#
# *REQUIRED*
# Directory where mailboxes reside, _or_ name of file, relative to the
# home directory. If you _do_ define both, MAIL_DIR takes precedence.
#
MAIL_DIR /var/spool/mail
#MAIL_FILE .mail
#
# If defined, file which inhibits all the usual chatter during the login
# sequence. If a full pathname, then hushed mode will be enabled if the
# user's name or shell are found in the file. If not a full pathname, then
# hushed mode will be enabled if the file exists in the user's home directory.
#
HUSHLOGIN_FILE .hushlogin
#HUSHLOGIN_FILE /etc/hushlogins
#
# If defined, either a TZ environment parameter spec or the
# fully-rooted pathname of a file containing such a spec.
#
#ENV_TZ TZ=CST6CDT
#ENV_TZ /etc/tzname
#
# If defined, an HZ environment parameter spec.
#
# for Linux/x86
ENV_HZ HZ=100
# For Linux/Alpha...
#ENV_HZ HZ=1024
#
# *REQUIRED* The default PATH settings, for superuser and normal users.
#
# (they are minimal, add the rest in the shell startup files)
ENV_SUPATH PATH=/sbin:/bin:/usr/sbin:/usr/bin
ENV_PATH PATH=/bin:/usr/bin
#
# Terminal permissions
#
# TTYGROUP Login tty will be assigned this group ownership.
# TTYPERM Login tty will be set to this permission.
#
# If you have a write(1) program which is "setgid" to a special group
# which owns the terminals, define TTYGROUP as the number of such group
# and TTYPERM as 0620. Otherwise leave TTYGROUP commented out and
# set TTYPERM to either 622 or 600.
#
TTYGROUP tty
TTYPERM 0600
#
# Login configuration initializations:
#
# ERASECHAR Terminal ERASE character ('\010' = backspace).
# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
# ULIMIT Default "ulimit" value.
#
# The ERASECHAR and KILLCHAR are used only on System V machines.
# The ULIMIT is used only if the system supports it.
# (now it works with setrlimit too; ulimit is in 512-byte units)
#
# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
#
ERASECHAR 0177
KILLCHAR 025
#ULIMIT 2097152
# Default initial "umask" value used by login(1) on non-PAM enabled systems.
# Default "umask" value for pam_umask(8) on PAM enabled systems.
# UMASK is also used by useradd(8) and newusers(8) to set the mode for new
# home directories.
# 022 is the default value, but 027, or even 077, could be considered
# for increased privacy. There is no One True Answer here: each sysadmin
# must make up his/her mind.
UMASK 022
#
# Password aging controls:
#
# PASS_MAX_DAYS Maximum number of days a password may be used.
# PASS_MIN_DAYS Minimum number of days allowed between password changes.
# PASS_MIN_LEN Minimum acceptable password length.
# PASS_WARN_AGE Number of days warning given before a password expires.
#
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
PASS_MIN_LEN 5
PASS_WARN_AGE 7
#
# If "yes", the user must be listed as a member of the first gid 0 group
# in /etc/group (called "root" on most Linux systems) to be able to "su"
# to uid 0 accounts. If the group doesn't exist or is empty, no one
# will be able to "su" to uid 0.
#
SU_WHEEL_ONLY no
#
# If compiled with cracklib support, sets the path to the dictionaries
#
CRACKLIB_DICTPATH /var/cache/cracklib/cracklib_dict
#
# Min/max values for automatic uid selection in useradd(8)
#
UID_MIN 1000
UID_MAX 60000
# System accounts
SYS_UID_MIN 101
SYS_UID_MAX 999
# Extra per user uids
SUB_UID_MIN 100000
SUB_UID_MAX 600100000
SUB_UID_COUNT 65536
#
# Min/max values for automatic gid selection in groupadd(8)
#
GID_MIN 1000
GID_MAX 60000
# System accounts
SYS_GID_MIN 101
SYS_GID_MAX 999
# Extra per user group ids
SUB_GID_MIN 100000
SUB_GID_MAX 600100000
SUB_GID_COUNT 65536
#
# Max number of login(1) retries if password is bad
#
LOGIN_RETRIES 5
#
# Max time in seconds for login(1)
#
LOGIN_TIMEOUT 60
#
# Maximum number of attempts to change password if rejected (too easy)
#
PASS_CHANGE_TRIES 5
#
# Warn about weak passwords (but still allow them) if you are root.
#
PASS_ALWAYS_WARN yes
#
# Number of significant characters in the password for crypt().
# Default is 8, don't change unless your crypt() is better.
# Ignored if MD5_CRYPT_ENAB set to "yes".
#
#PASS_MAX_LEN 8
#
# Require password before chfn(1)/chsh(1) can make any changes.
#
CHFN_AUTH yes
#
# Which fields may be changed by regular users using chfn(1) - use
# any combination of letters "frwh" (full name, room number, work
# phone, home phone). If not defined, no changes are allowed.
# For backward compatibility, "yes" = "rwh" and "no" = "frwh".
#
CHFN_RESTRICT rwh
#
# Password prompt (%s will be replaced by user name).
#
# XXX - it doesn't work correctly yet, for now leave it commented out
# to use the default which is just "Password: ".
#LOGIN_STRING "%s's Password: "
#
# Only works if compiled with MD5_CRYPT defined:
# If set to "yes", new passwords will be encrypted using the MD5-based
# algorithm compatible with the one used by recent releases of FreeBSD.
# It supports passwords of unlimited length and longer salt strings.
# Set to "no" if you need to copy encrypted passwords to other systems
# which don't understand the new algorithm. Default is "no".
#
# Note: If you use PAM, it is recommended to use a value consistent with
# the PAM modules configuration.
#
# This variable is deprecated. You should use ENCRYPT_METHOD instead.
#
#MD5_CRYPT_ENAB no
#
# Only works if compiled with ENCRYPTMETHOD_SELECT defined:
# If set to MD5, MD5-based algorithm will be used for encrypting password
# If set to SHA256, SHA256-based algorithm will be used for encrypting password
# If set to SHA512, SHA512-based algorithm will be used for encrypting password
# If set to DES, DES-based algorithm will be used for encrypting password (default)
# Overrides the MD5_CRYPT_ENAB option
#
# Note: If you use PAM, it is recommended to use a value consistent with
# the PAM modules configuration.
#
#ENCRYPT_METHOD DES
#
# Only works if ENCRYPT_METHOD is set to SHA256 or SHA512.
#
# Define the number of SHA rounds.
# With a lot of rounds, it is more difficult to brute-force the password.
# However, more CPU resources will be needed to authenticate users if
# this value is increased.
#
# If not specified, the libc will choose the default number of rounds (5000).
# The values must be within the 1000-999999999 range.
# If only one of the MIN or MAX values is set, then this value will be used.
# If MIN > MAX, the highest value will be used.
#
# SHA_CRYPT_MIN_ROUNDS 5000
# SHA_CRYPT_MAX_ROUNDS 5000
#
# List of groups to add to the user's supplementary group set
# when logging in from the console (as determined by the CONSOLE
# setting). Default is none.
#
# Use with caution - it is possible for users to gain permanent
# access to these groups, even when not logged in from the console.
# How to do it is left as an exercise for the reader...
#
#CONSOLE_GROUPS floppy:audio:cdrom
#
# Should login be allowed if we can't cd to the home directory?
# Default is no.
#
DEFAULT_HOME yes
#
# If this file exists and is readable, login environment will be
# read from it. Every line should be in the form name=value.
#
ENVIRON_FILE /etc/environment
#
# If defined, this command is run when removing a user.
# It should remove any at/cron/print jobs etc. owned by
# the user to be removed (passed as the first argument).
#
#USERDEL_CMD /usr/sbin/userdel_local
#
# Enable setting of the umask group bits to be the same as owner bits
# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
# the same as gid, and username is the same as the primary group name.
#
# This also enables userdel(8) to remove user groups if no members exist.
#
USERGROUPS_ENAB yes
#
# If set to a non-zero number, the shadow utilities will make sure that
# groups never have more than this number of users on one line.
# This permits to support split groups (groups split into multiple lines,
# with the same group ID, to avoid limitation of the line length in the
# group file).
#
# 0 is the default value and disables this feature.
#
#MAX_MEMBERS_PER_GROUP 0
#
# If useradd(8) should create home directories for users by default (non
# system users only).
# This option is overridden with the -M or -m flags on the useradd(8)
# command-line.
#
#CREATE_HOME yes
#
# Force use shadow, even if shadow passwd & shadow group files are
# missing.
#
#FORCE_SHADOW yes
-32
View File
@@ -1,32 +0,0 @@
# This is a dummy Makefile.am to get automake work flawlessly,
# and also cooperate to make a distribution for `make dist'
pamd_files = \
chfn \
chsh \
groupmems \
login \
passwd \
su
pamd_acct_tools_files = \
chage \
chgpasswd \
chpasswd \
groupadd \
groupdel \
groupmod \
newusers \
useradd \
userdel \
usermod
if USE_PAM
pamddir = $(sysconfdir)/pam.d
pamd_DATA = $(pamd_files)
if ACCT_TOOLS_SETUID
pamd_DATA += $(pamd_acct_tools_files)
endif
endif
EXTRA_DIST = $(pamd_files) $(pamd_acct_tools_files)
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-11
View File
@@ -1,11 +0,0 @@
#%PAM-1.0
auth required pam_securetty.so
auth include system-auth
account required pam_nologin.so
account include system-auth
password include system-auth
session required pam_selinux.so close
session include system-auth
session required pam_loginuid.so
session optional pam_console.so
session required pam_selinux.so open
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth include system-auth
account include system-auth
password include system-auth
-13
View File
@@ -1,13 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
auth required pam_wheel.so use_uid
auth include system-auth
account include system-auth
password include system-auth
session required pam_selinux.so close
session include system-auth
session required pam_selinux.so open multiple
session optional pam_xauth.so
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-4
View File
@@ -1,4 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
account required pam_permit.so
password include system-auth
-8
View File
@@ -1,8 +0,0 @@
# useradd defaults file
GROUP=1000
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
-5
View File
@@ -1,5 +0,0 @@
-kr
-i8
-bad
-pcs
-l80
-69
View File
@@ -1,69 +0,0 @@
AUTOMAKE_OPTIONS = 1.0 foreign
DEFS =
noinst_LTLIBRARIES = libshadow.la
libshadow_la_LDFLAGS = -version-info 0:0:0
libshadow_la_SOURCES = \
commonio.c \
commonio.h \
defines.h \
encrypt.c \
exitcodes.h \
faillog.h \
fields.c \
fputsx.c \
getdef.c \
getdef.h \
get_gid.c \
getlong.c \
get_pid.c \
get_uid.c \
getulong.c \
groupio.c \
groupmem.c \
groupio.h \
gshadow.c \
lockpw.c \
nscd.c \
nscd.h \
pam_defs.h \
port.c \
port.h \
prototypes.h \
pwauth.c \
pwauth.h \
pwio.c \
pwio.h \
pwmem.c \
subordinateio.h \
subordinateio.c \
selinux.c \
semanage.c \
sgetgrent.c \
sgetpwent.c \
sgetspent.c \
sgroupio.c \
sgroupio.h\
shadow.c \
shadowio.c \
shadowio.h \
shadowmem.c \
spawn.c \
utent.c
if WITH_TCB
libshadow_la_SOURCES += tcbfuncs.c tcbfuncs.h
endif
# These files are unneeded for some reason, listed in
# order of appearance:
#
# sources for dbm support (not yet used)
EXTRA_DIST = \
.indent.pro \
gshadow_.h
-1274
View File
File diff suppressed because it is too large Load Diff
-170
View File
@@ -1,170 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _COMMONIO_H
#define _COMMONIO_H
#ifdef WITH_SELINUX
#include <selinux/selinux.h>
#endif
#include "defines.h" /* bool */
/*
* Linked list entry.
*/
struct commonio_entry {
/*@null@*/char *line;
/*@null@*/void *eptr; /* struct passwd, struct spwd, ... */
/*@dependent@*/ /*@null@*/struct commonio_entry *prev;
/*@owned@*/ /*@null@*/struct commonio_entry *next;
bool 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.
*/
/*@null@*/ /*@only@*/void *(*dup) (const void *);
/*
* free() the object including any strings pointed by it.
*/
void (*free) (/*@out@*/ /*@only@*/void *);
/*
* Return the name of the object (for example, pw_name
* for struct passwd).
*/
const char *(*getname) (const void *);
/*
* Parse a string, return object (in static area -
* should be copied using the dup operation above).
*/
void *(*parse) (const char *);
/*
* Write the object to the file (this calls putpwent()
* for struct passwd, for example).
*/
int (*put) (const void *, FILE *);
/*
* fgets and fputs (can be replaced by versions that
* understand line continuation conventions).
*/
/*@null@*/char *(*fgets) (/*@returned@*/ /*@out@*/char *s, int n, FILE *stream);
int (*fputs) (const char *, FILE *);
/*
* open_hook and close_hook.
* If non NULL, these functions will be called after the database
* is open or before it is closed.
* They return 0 on failure and 1 on success.
*/
/*@null@*/int (*open_hook) (void);
/*@null@*/int (*close_hook) (void);
};
/*
* Database structure.
*/
struct commonio_db {
/*
* Name of the data file.
*/
char filename[1024];
/*
* Operations from above.
*/
/*@observer@*/const struct commonio_ops *ops;
/*
* Currently open file stream.
*/
/*@dependent@*/ /*@null@*/FILE *fp;
#ifdef WITH_SELINUX
/*@null@*/security_context_t scontext;
#endif
/*
* Default permissions and owner for newly created data file.
*/
mode_t st_mode;
uid_t st_uid;
gid_t st_gid;
/*
* Head, tail, current position in linked list.
*/
/*@owned@*/ /*@null@*/struct commonio_entry *head;
/*@dependent@*/ /*@null@*/struct commonio_entry *tail;
/*@dependent@*/ /*@null@*/struct commonio_entry *cursor;
/*
* Various flags.
*/
bool changed:1;
bool isopen:1;
bool locked:1;
bool readonly:1;
};
extern int commonio_setname (struct commonio_db *, const char *);
extern bool commonio_present (const struct commonio_db *db);
extern int commonio_lock (struct commonio_db *);
extern int commonio_lock_nowait (struct commonio_db *, bool log);
extern int commonio_open (struct commonio_db *, int);
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
extern int commonio_update (struct commonio_db *, const void *);
#ifdef ENABLE_SUBIDS
extern int commonio_append (struct commonio_db *, const void *);
#endif /* ENABLE_SUBIDS */
extern int commonio_remove (struct commonio_db *, const char *);
extern int commonio_rewind (struct commonio_db *);
extern /*@observer@*/ /*@null@*/const void *commonio_next (struct commonio_db *);
extern int commonio_close (struct commonio_db *);
extern int commonio_unlock (struct commonio_db *);
extern void commonio_del_entry (struct commonio_db *,
const struct commonio_entry *);
extern int commonio_sort_wrt (struct commonio_db *shadow,
const struct commonio_db *passwd);
extern int commonio_sort (struct commonio_db *db,
int (*cmp) (const void *, const void *));
#endif
-385
View File
@@ -1,385 +0,0 @@
/* $Id$ */
/* some useful defines */
#ifndef _DEFINES_H_
#define _DEFINES_H_
#if HAVE_STDBOOL_H
# include <stdbool.h>
#else
# if ! HAVE__BOOL
# ifdef __cplusplus
typedef bool _Bool;
# else
typedef unsigned char _Bool;
# endif
# endif
# define bool _Bool
# define false (0)
# define true (1)
# define __bool_true_false_are_defined 1
#endif
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
/* Take care of NLS matters. */
#ifdef S_SPLINT_S
extern char *setlocale(int categorie, const char *locale);
# define LC_ALL (6)
extern char * bindtextdomain (const char * domainname, const char * dirname);
extern char * textdomain (const char * domainname);
# define _(Text) Text
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#else
#ifdef HAVE_LOCALE_H
# include <locale.h>
#else
# undef setlocale
# define setlocale(category, locale) (NULL)
# ifndef LC_ALL
# define LC_ALL 6
# endif
#endif
#define gettext_noop(String) (String)
/* #define gettext_def(String) "#define String" */
#ifdef ENABLE_NLS
# include <libintl.h>
# define _(Text) gettext (Text)
#else
# undef bindtextdomain
# define bindtextdomain(Domain, Directory) (NULL)
# undef textdomain
# define textdomain(Domain) (NULL)
# define _(Text) Text
# define ngettext(Msgid1, Msgid2, N) \
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
#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 */
#if HAVE_ERRNO_H
# include <errno.h>
#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
/*
* 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.
*/
#include <shadow.h>
#if defined(SHADOWGRP) && !defined(GSHADOW)
#include "gshadow_.h"
#endif
#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
/* LOG_NOWAIT is deprecated */
#ifndef LOG_NOWAIT
#define LOG_NOWAIT 0
#endif
/* LOG_AUTH is deprecated, use LOG_AUTHPRIV instead */
#ifndef LOG_AUTHPRIV
#define LOG_AUTHPRIV LOG_AUTH
#endif
/* cleaner than lots of #ifdefs everywhere - use this as follows:
SYSLOG((LOG_CRIT, "user %s cracked root", user)); */
#ifdef ENABLE_NLS
/* 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 (or worse,
UDP) socket. -MM */
/* Avoid translated PAM error messages: Set LC_ALL to "C".
* --Nekral */
#define SYSLOG(x) \
do { \
char *old_locale = setlocale (LC_ALL, NULL); \
char *saved_locale = NULL; \
if (NULL != old_locale) { \
saved_locale = strdup (old_locale); \
} \
if (NULL != saved_locale) { \
(void) setlocale (LC_ALL, "C"); \
} \
syslog x ; \
if (NULL != saved_locale) { \
(void) setlocale (LC_ALL, saved_locale); \
free (saved_locale); \
} \
} while (false)
#else /* !ENABLE_NLS */
#define SYSLOG(x) syslog x
#endif /* !ENABLE_NLS */
#else /* !USE_SYSLOG */
#define SYSLOG(x) /* empty */
#define openlog(a,b,c) /* empty */
#define closelog() /* empty */
#endif /* !USE_SYSLOG */
/* The default syslog settings can now be changed here,
in just one place. */
#ifndef SYSLOG_OPTIONS
/* #define SYSLOG_OPTIONS (LOG_PID | LOG_CONS | LOG_NOWAIT) */
#define SYSLOG_OPTIONS (LOG_PID)
#endif
#ifndef SYSLOG_FACILITY
#define SYSLOG_FACILITY LOG_AUTHPRIV
#endif
#define OPENLOG(progname) openlog(progname, SYSLOG_OPTIONS, SYSLOG_FACILITY)
#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)
# ifdef S_IFLNK
# define S_ISLNK(x) ((x) & S_IFMT) == S_IFLNK)
# endif
#endif
#ifndef S_ISLNK
#define S_ISLNK(x) (0)
#endif
#if HAVE_LCHOWN
#define LCHOWN lchown
#else
#define LCHOWN chown
#endif
#if HAVE_LSTAT
#define LSTAT lstat
#else
#define LSTAT stat
#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
#else /* assumed 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
#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')
#ifndef PASSWD_FILE
#define PASSWD_FILE "/etc/passwd"
#endif
#ifndef GROUP_FILE
#define GROUP_FILE "/etc/group"
#endif
#ifndef SHADOW_FILE
#define SHADOW_FILE "/etc/shadow"
#endif
#ifdef SHADOWGRP
#ifndef SGROUP_FILE
#define SGROUP_FILE "/etc/gshadow"
#endif
#endif
#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
/*
* 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
#define SHADOW_SP_FLAG_UNSET ((unsigned long int)-1)
#ifdef WITH_AUDIT
#ifdef __u8 /* in case we use pam < 0.80 */
#undef __u8
#endif
#ifdef __u32
#undef __u32
#endif
#include <libaudit.h>
#endif
/* To be used for verified unused parameters */
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
# define unused __attribute__((unused))
#else
# define unused
#endif
/* ! Arguments evaluated twice ! */
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
/* Maximum length of usernames */
#ifdef HAVE_UTMPX_H
# include <utmpx.h>
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmpx *)NULL)->ut_user))
#else
# include <utmp.h>
# ifdef HAVE_STRUCT_UTMP_UT_USER
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_user))
# else
# ifdef HAVE_STRUCT_UTMP_UT_NAME
# define USER_NAME_MAX_LENGTH (sizeof (((struct utmp *)NULL)->ut_name))
# else
# define USER_NAME_MAX_LENGTH 32
# endif
# endif
#endif
#endif /* _DEFINES_H_ */
-95
View File
@@ -1,95 +0,0 @@
/*
* Copyright (c) 1990 - 1993, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <unistd.h>
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
/*@exposed@*//*@null@*/char *pw_encrypt (const char *clear, const char *salt)
{
static char cipher[128];
char *cp;
cp = crypt (clear, salt);
if (NULL == cp) {
/*
* Single Unix Spec: crypt() may return a null pointer,
* and set errno to indicate an error. In this case return
* the NULL so the caller can handle appropriately.
*/
return NULL;
}
/* Some crypt() do not return NULL if the algorithm is not
* supported, and return a DES encrypted password. */
if ((NULL != salt) && (salt[0] == '$') && (strlen (cp) <= 13))
{
/*@observer@*/const char *method;
switch (salt[1])
{
case '1':
method = "MD5";
break;
case '5':
method = "SHA256";
break;
case '6':
method = "SHA512";
break;
default:
{
static char nummethod[4] = "$x$";
nummethod[1] = salt[1];
method = &nummethod[0];
}
}
(void) fprintf (stderr,
_("crypt method not supported by libcrypt? (%s)\n"),
method);
exit (EXIT_FAILURE);
}
if (strlen (cp) != 13) {
return cp; /* nonstandard crypt() in libc, better bail out */
}
strcpy (cipher, cp);
return cipher;
}
-49
View File
@@ -1,49 +0,0 @@
/*
* Copyright (c) 2005 - 2006, Tomasz Kłoczko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
/*
* Exit codes used by shadow programs
*/
#define E_SUCCESS EXIT_SUCCESS /* success */
/*
* FIXME: other values should differ from EXIT_FAILURE (and EXIT_SUCCESS).
*
* FIXME: reserve EXIT_FAILURE for internal failures.
*/
#define E_NOPERM 1 /* permission denied */
#define E_USAGE 2 /* invalid command syntax */
#define E_BAD_ARG 3 /* invalid argument to option */
#define E_PASSWD_NOTFOUND 14 /* not found password file */
#define E_SHADOW_NOTFOUND 15 /* not found shadow password file */
#define E_GROUP_NOTFOUND 16 /* not found group file */
#define E_GSHADOW_NOTFOUND 17 /* not found shadow group file */
#define E_CMD_NOEXEC 126 /* can't run command/shell */
#define E_CMD_NOTFOUND 127 /* can't find command/shell to run */
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* faillog.h - login failure logging file format
*
* $Id$
*
* The login failure file is maintained by login(1) and faillog(8)
* Each record in the file represents a separate UID and the file
* 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
-130
View File
@@ -1,130 +0,0 @@
/*
* Copyright (c) 1990 , Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "prototypes.h"
/*
* valid_field - insure that a field contains all legal characters
*
* The supplied field is scanned for non-printable and other illegal
* characters.
* + -1 is returned if an illegal character is present.
* + 1 is returned if no illegal characters are present, but the field
* contains a non-printable character.
* + 0 is returned otherwise.
*/
int valid_field (const char *field, const char *illegal)
{
const char *cp;
int err = 0;
if (NULL == field) {
return -1;
}
/* For each character of field, search if it appears in the list
* of illegal characters. */
for (cp = field; '\0' != *cp; cp++) {
if (strchr (illegal, *cp) != NULL) {
err = -1;
break;
}
}
if (0 == err) {
/* Search if there are some non-printable characters */
for (cp = field; '\0' != *cp; cp++) {
if (!isprint (*cp)) {
err = 1;
break;
}
}
}
return err;
}
/*
* change_field - change a single field if a new value is given.
*
* prompt the user with the name of the field being changed and the
* current value.
*/
void change_field (char *buf, size_t maxsize, const char *prompt)
{
char newf[200];
char *cp;
if (maxsize > sizeof (newf)) {
maxsize = sizeof (newf);
}
printf ("\t%s [%s]: ", prompt, buf);
(void) fflush (stdout);
if (fgets (newf, (int) maxsize, stdin) != newf) {
return;
}
cp = strchr (newf, '\n');
if (NULL == cp) {
return;
}
*cp = '\0';
if ('\0' != newf[0]) {
/*
* Remove leading and trailing whitespace. This also
* makes it possible to change the field to empty, by
* entering a space. --marekm
*/
while (--cp >= newf && isspace (*cp));
cp++;
*cp = '\0';
cp = newf;
while (('\0' != *cp) && isspace (*cp)) {
cp++;
}
strncpy (buf, cp, maxsize - 1);
buf[maxsize - 1] = '\0';
}
}
-90
View File
@@ -1,90 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1999, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <stdio.h>
#include "defines.h"
#include "prototypes.h"
#ident "$Id$"
/*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *buf, int cnt, FILE * f)
{
char *cp = buf;
char *ep;
while (cnt > 0) {
if (fgets (cp, cnt, f) != cp) {
if (cp == buf) {
return 0;
} else {
break;
}
}
ep = strrchr (cp, '\\');
if ((NULL != ep) && (*(ep + 1) == '\n')) {
cnt -= ep - cp;
if (cnt > 0) {
cp = ep;
*cp = '\0';
}
} else {
break;
}
}
return buf;
}
int fputsx (const char *s, FILE * stream)
{
int i;
for (i = 0; '\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;
}
-54
View File
@@ -1,54 +0,0 @@
/*
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int get_gid (const char *gidstr, gid_t *gid)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (gidstr, &endptr, 10);
if ( ('\0' == *gidstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (gid_t)val)/*@=longintegral@*/) {
return 0;
}
*gid = (gid_t)val;
return 1;
}
-54
View File
@@ -1,54 +0,0 @@
/*
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int get_pid (const char *pidstr, pid_t *pid)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (pidstr, &endptr, 10);
if ( ('\0' == *pidstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (pid_t)val)/*@=longintegral@*/) {
return 0;
}
*pid = (pid_t)val;
return 1;
}
-54
View File
@@ -1,54 +0,0 @@
/*
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
int get_uid (const char *uidstr, uid_t *uid)
{
long long int val;
char *endptr;
errno = 0;
val = strtoll (uidstr, &endptr, 10);
if ( ('\0' == *uidstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
|| (/*@+longintegral@*/val != (uid_t)val)/*@=longintegral@*/) {
return 0;
}
*uid = (uid_t)val;
return 1;
}
-538
View File
@@ -1,538 +0,0 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2002 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2008, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include "getdef.h"
/*
* A configuration item definition.
*/
struct itemdef {
/*@null@*/const char *name; /* name of the item */
/*@null@*/char *value; /* value given, or NULL if no value */
};
#define PAMDEFS \
{"CHFN_AUTH", NULL}, \
{"CHSH_AUTH", NULL}, \
{"CRACKLIB_DICTPATH", NULL}, \
{"ENV_HZ", NULL}, \
{"ENVIRON_FILE", NULL}, \
{"ENV_TZ", NULL}, \
{"FAILLOG_ENAB", NULL}, \
{"FTMP_FILE", NULL}, \
{"ISSUE_FILE", NULL}, \
{"LASTLOG_ENAB", NULL}, \
{"LOGIN_STRING", NULL}, \
{"MAIL_CHECK_ENAB", NULL}, \
{"MOTD_FILE", NULL}, \
{"NOLOGINS_FILE", NULL}, \
{"OBSCURE_CHECKS_ENAB", NULL}, \
{"PASS_ALWAYS_WARN", NULL}, \
{"PASS_CHANGE_TRIES", NULL}, \
{"PASS_MAX_LEN", NULL}, \
{"PASS_MIN_LEN", NULL}, \
{"PORTTIME_CHECKS_ENAB", NULL}, \
{"QUOTAS_ENAB", NULL}, \
{"SU_WHEEL_ONLY", NULL}, \
{"ULIMIT", NULL},
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
static struct itemdef def_table[] = {
{"CHFN_RESTRICT", NULL},
{"CONSOLE_GROUPS", NULL},
{"CONSOLE", NULL},
{"CREATE_HOME", NULL},
{"DEFAULT_HOME", NULL},
{"ENCRYPT_METHOD", NULL},
{"ENV_PATH", NULL},
{"ENV_SUPATH", NULL},
{"ERASECHAR", NULL},
{"FAIL_DELAY", NULL},
{"FAKE_SHELL", NULL},
{"GID_MAX", NULL},
{"GID_MIN", NULL},
{"HUSHLOGIN_FILE", NULL},
{"KILLCHAR", NULL},
{"LOGIN_RETRIES", NULL},
{"LOGIN_TIMEOUT", NULL},
{"LOG_OK_LOGINS", NULL},
{"LOG_UNKFAIL_ENAB", NULL},
{"MAIL_DIR", NULL},
{"MAIL_FILE", NULL},
{"MAX_MEMBERS_PER_GROUP", NULL},
{"MD5_CRYPT_ENAB", NULL},
{"PASS_MAX_DAYS", NULL},
{"PASS_MIN_DAYS", NULL},
{"PASS_WARN_AGE", NULL},
#ifdef USE_SHA_CRYPT
{"SHA_CRYPT_MAX_ROUNDS", NULL},
{"SHA_CRYPT_MIN_ROUNDS", NULL},
#endif
{"SUB_GID_COUNT", NULL},
{"SUB_GID_MAX", NULL},
{"SUB_GID_MIN", NULL},
{"SUB_UID_COUNT", NULL},
{"SUB_UID_MAX", NULL},
{"SUB_UID_MIN", NULL},
{"SULOG_FILE", NULL},
{"SU_NAME", NULL},
{"SYS_GID_MAX", NULL},
{"SYS_GID_MIN", NULL},
{"SYS_UID_MAX", NULL},
{"SYS_UID_MIN", NULL},
{"TTYGROUP", NULL},
{"TTYPERM", NULL},
{"TTYTYPE_FILE", NULL},
{"UID_MAX", NULL},
{"UID_MIN", NULL},
{"UMASK", NULL},
{"USERDEL_CMD", NULL},
{"USERGROUPS_ENAB", NULL},
#ifndef USE_PAM
PAMDEFS
#endif
#ifdef USE_SYSLOG
{"SYSLOG_SG_ENAB", NULL},
{"SYSLOG_SU_ENAB", NULL},
#endif
#ifdef WITH_TCB
{"TCB_AUTH_GROUP", NULL},
{"TCB_SYMLINKS", NULL},
{"USE_TCB", NULL},
#endif
{"FORCE_SHADOW", NULL},
{NULL, NULL}
};
#define NUMKNOWNDEFS (sizeof(knowndef_table)/sizeof(knowndef_table[0]))
static struct itemdef knowndef_table[] = {
#ifdef USE_PAM
PAMDEFS
#endif
};
#ifndef LOGINDEFS
#define LOGINDEFS "/etc/login.defs"
#endif
static char def_fname[] = LOGINDEFS; /* login config defs file */
static bool def_loaded = false; /* are defs already loaded? */
/* local function prototypes */
static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *);
static void def_load (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.
*/
/*@observer@*/ /*@null@*/const char *getdef_str (const char *item)
{
struct itemdef *d;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
return ((NULL == d)? (const char *) NULL : d->value);
}
/*
* getdef_bool - get boolean value from table of definitions.
*
* Return TRUE if specified item is defined as "yes", else FALSE.
*/
bool getdef_bool (const char *item)
{
struct itemdef *d;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return false;
}
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;
long val;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
if ( (getlong (d->value, &val) == 0)
|| (val > INT_MAX)
|| (val < INT_MIN)) {
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return (int) val;
}
/*
* getdef_unum - get unsigned 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.
*/
unsigned int getdef_unum (const char *item, unsigned int dflt)
{
struct itemdef *d;
long val;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
if ( (getlong (d->value, &val) == 0)
|| (val < 0)
|| (val > INT_MAX)) {
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return (unsigned int) val;
}
/*
* 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;
long val;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
if (getlong (d->value, &val) == 0) {
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return val;
}
/*
* getdef_ulong - get unsigned long 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.
*/
unsigned long getdef_ulong (const char *item, unsigned long dflt)
{
struct itemdef *d;
unsigned long val;
if (!def_loaded) {
def_load ();
}
d = def_find (item);
if ((NULL == d) || (NULL == d->value)) {
return dflt;
}
if (getulong (d->value, &val) == 0) {
/* FIXME: we should have a getulong */
fprintf (stderr,
_("configuration error - cannot parse %s value: '%s'"),
item, d->value);
return dflt;
}
return val;
}
/*
* 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.
*/
d = def_find (name);
if (NULL == d) {
return -1;
}
/*
* Save off the value.
*/
cp = strdup (value);
if (NULL == cp) {
(void) fputs (_("Could not allocate space for config info.\n"),
stderr);
SYSLOG ((LOG_ERR, "could not allocate space for config info"));
return -1;
}
if (NULL != d->value) {
free (d->value);
}
d->value = cp;
return 0;
}
/*
* def_find - locate named item in table
*
* Search through a table of configurable items to locate the
* specified configuration option.
*/
static /*@observer@*/ /*@null@*/struct itemdef *def_find (const char *name)
{
struct itemdef *ptr;
/*
* Search into the table.
*/
for (ptr = def_table; NULL != ptr->name; ptr++) {
if (strcmp (ptr->name, name) == 0) {
return ptr;
}
}
/*
* Item was never found.
*/
for (ptr = knowndef_table; NULL != ptr->name; ptr++) {
if (strcmp (ptr->name, name) == 0) {
goto out;
}
}
fprintf (stderr,
_("configuration error - unknown item '%s' (notify administrator)\n"),
name);
SYSLOG ((LOG_CRIT, "unknown configuration item `%s'", name));
out:
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;
/*
* Set the initialized flag.
* (do it early to prevent recursion in putdef_str())
*/
def_loaded = true;
/*
* Open the configuration definitions file.
*/
fp = fopen (def_fname, "r");
if (NULL == fp) {
if (errno == ENOENT)
return;
int err = errno;
SYSLOG ((LOG_CRIT, "cannot open login definitions %s [%s]",
def_fname, strerror (err)));
exit (EXIT_FAILURE);
}
/*
* Go through all of the lines in the file.
*/
while (fgets (buf, (int) sizeof (buf), fp) != NULL) {
/*
* Trim trailing whitespace.
*/
for (i = (int) strlen (buf) - 1; i >= 0; --i) {
if (!isspace (buf[i])) {
break;
}
}
i++;
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.
*
* Ignore failures to load the login.defs file.
* The error was already reported to the user and to
* syslog. The tools will just use their default values.
*/
(void)putdef_str (name, value);
}
if (ferror (fp) != 0) {
int err = errno;
SYSLOG ((LOG_CRIT, "cannot read login definitions %s [%s]",
def_fname, strerror (err)));
exit (EXIT_FAILURE);
}
(void) fclose (fp);
}
#ifdef CKDEFS
int main (int argc, char **argv)
{
int i;
char *cp;
struct itemdef *d;
def_load ();
for (i = 0; i < NUMDEFS; ++i) {
d = def_find (def_table[i].name);
if (NULL == d) {
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++) {
cp = getdef_str (argv[1]);
if (NULL != cp) {
printf ("%s `%s'\n", argv[1], cp);
} else {
printf ("%s not found\n", argv[1]);
}
}
exit (EXIT_SUCCESS);
}
#endif
-47
View File
@@ -1,47 +0,0 @@
/*
* Copyright (c) 1991 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2002 - 2006, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _GETDEF_H
#define _GETDEF_H
/* getdef.c */
extern bool getdef_bool (const char *);
extern long getdef_long (const char *, long);
extern int getdef_num (const char *, int);
extern unsigned long getdef_ulong (const char *, unsigned long);
extern unsigned int getdef_unum (const char *, unsigned int);
extern /*@observer@*/ /*@null@*/const char *getdef_str (const char *);
extern int putdef_str (const char *, const char *);
/* default UMASK value if not specified in /etc/login.defs */
#define GETDEF_DEFAULT_UMASK 022
#endif /* _GETDEF_H */
-59
View File
@@ -1,59 +0,0 @@
/*
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <stdlib.h>
#include <errno.h>
#include "prototypes.h"
/*
* getlong - extract a long integer provided by the numstr string in *result
*
* It supports decimal, hexadecimal or octal representations.
*
* Returns 0 on failure, 1 on success.
*/
int getlong (const char *numstr, /*@out@*/long int *result)
{
long val;
char *endptr;
errno = 0;
val = strtol (numstr, &endptr, 0);
if (('\0' == *numstr) || ('\0' != *endptr) || (ERANGE == errno)) {
return 0;
}
*result = val;
return 1;
}
-62
View File
@@ -1,62 +0,0 @@
/*
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id: getlong.c 2763 2009-04-23 09:57:03Z nekral-guest $"
#include <stdlib.h>
#include <errno.h>
#include "prototypes.h"
/*
* getulong - extract an unsigned long integer provided by the numstr string in *result
*
* It supports decimal, hexadecimal or octal representations.
*
* Returns 0 on failure, 1 on success.
*/
int getulong (const char *numstr, /*@out@*/unsigned long int *result)
{
unsigned long int val;
char *endptr;
errno = 0;
val = strtoul (numstr, &endptr, 0);
if ( ('\0' == *numstr)
|| ('\0' != *endptr)
|| (ERANGE == errno)
) {
return 0;
}
*result = val;
return 1;
}
-463
View File
@@ -1,463 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <assert.h>
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
#include "getdef.h"
#include "groupio.h"
static /*@null@*/struct commonio_entry *merge_group_entries (
/*@null@*/ /*@returned@*/struct commonio_entry *gr1,
/*@null@*/struct commonio_entry *gr2);
static int split_groups (unsigned int max_members);
static int group_open_hook (void);
static /*@null@*/ /*@only@*/void *group_dup (const void *ent)
{
const struct group *gr = ent;
return __gr_dup (gr);
}
static void group_free (/*@out@*/ /*@only@*/void *ent)
{
struct group *gr = ent;
gr_free (gr);
}
static const char *group_getname (const void *ent)
{
const struct group *gr = ent;
return gr->gr_name;
}
static void *group_parse (const char *line)
{
return (void *) sgetgrent (line);
}
static int group_put (const void *ent, FILE * file)
{
const struct group *gr = ent;
if ( (NULL == gr)
|| (valid_field (gr->gr_name, ":\n") == -1)
|| (valid_field (gr->gr_passwd, ":\n") == -1)
|| (gr->gr_gid == (gid_t)-1)) {
return -1;
}
/* FIXME: fail also if gr->gr_mem == NULL ?*/
if (NULL != gr->gr_mem) {
size_t i;
for (i = 0; NULL != gr->gr_mem[i]; i++) {
if (valid_field (gr->gr_mem[i], ",:\n") == -1) {
return -1;
}
}
}
return (putgrent (gr, file) == -1) ? -1 : 0;
}
static int group_close_hook (void)
{
unsigned int max_members = getdef_unum("MAX_MEMBERS_PER_GROUP", 0);
if (0 == max_members) {
return 1;
}
return split_groups (max_members);
}
static struct commonio_ops group_ops = {
group_dup,
group_free,
group_getname,
group_parse,
group_put,
fgetsx,
fputsx,
group_open_hook,
group_close_hook
};
static /*@owned@*/struct commonio_db group_db = {
GROUP_FILE, /* filename */
&group_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
NULL, /* scontext */
#endif
0644, /* st_mode */
0, /* st_uid */
0, /* st_gid */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int gr_setdbname (const char *filename)
{
return commonio_setname (&group_db, filename);
}
/*@observer@*/const char *gr_dbname (void)
{
return group_db.filename;
}
int gr_lock (void)
{
return commonio_lock (&group_db);
}
int gr_open (int mode)
{
return commonio_open (&group_db, mode);
}
/*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name)
{
return commonio_locate (&group_db, name);
}
/*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid)
{
const struct group *grp;
gr_rewind ();
while ( ((grp = gr_next ()) != NULL)
&& (grp->gr_gid != gid)) {
}
return grp;
}
int gr_update (const struct group *gr)
{
return commonio_update (&group_db, (const void *) gr);
}
int gr_remove (const char *name)
{
return commonio_remove (&group_db, name);
}
int gr_rewind (void)
{
return commonio_rewind (&group_db);
}
/*@observer@*/ /*@null@*/const struct group *gr_next (void)
{
return commonio_next (&group_db);
}
int gr_close (void)
{
return commonio_close (&group_db);
}
int gr_unlock (void)
{
return commonio_unlock (&group_db);
}
void __gr_set_changed (void)
{
group_db.changed = true;
}
/*@dependent@*/ /*@null@*/struct commonio_entry *__gr_get_head (void)
{
return group_db.head;
}
/*@observer@*/const struct commonio_db *__gr_get_db (void)
{
return &group_db;
}
void __gr_del_entry (const struct commonio_entry *ent)
{
commonio_del_entry (&group_db, ent);
}
static int gr_cmp (const void *p1, const void *p2)
{
gid_t u1, u2;
if ((*(struct commonio_entry **) p1)->eptr == NULL) {
return 1;
}
if ((*(struct commonio_entry **) p2)->eptr == NULL) {
return -1;
}
u1 = ((struct group *) (*(struct commonio_entry **) p1)->eptr)->gr_gid;
u2 = ((struct group *) (*(struct commonio_entry **) p2)->eptr)->gr_gid;
if (u1 < u2) {
return -1;
} else if (u1 > u2) {
return 1;
} else {
return 0;
}
}
/* Sort entries by GID */
int gr_sort ()
{
return commonio_sort (&group_db, gr_cmp);
}
static int group_open_hook (void)
{
unsigned int max_members = getdef_unum("MAX_MEMBERS_PER_GROUP", 0);
struct commonio_entry *gr1, *gr2;
if (0 == max_members) {
return 1;
}
for (gr1 = group_db.head; NULL != gr1; gr1 = gr1->next) {
for (gr2 = gr1->next; NULL != gr2; gr2 = gr2->next) {
struct group *g1 = (struct group *)gr1->eptr;
struct group *g2 = (struct group *)gr2->eptr;
if (NULL != g1 &&
NULL != g2 &&
0 == strcmp (g1->gr_name, g2->gr_name) &&
0 == strcmp (g1->gr_passwd, g2->gr_passwd) &&
g1->gr_gid == g2->gr_gid) {
/* Both group entries refer to the same
* group. It is a split group. Merge the
* members. */
gr1 = merge_group_entries (gr1, gr2);
if (NULL == gr1)
return 0;
/* Unlink gr2 */
if (NULL != gr2->next) {
gr2->next->prev = gr2->prev;
}
/* gr2 does not start with head */
assert (NULL != gr2->prev);
gr2->prev->next = gr2->next;
}
}
assert (NULL != gr1);
}
return 1;
}
/*
* Merge the list of members of the two group entries.
*
* The commonio_entry arguments shall be group entries.
*
* You should not merge the members of two groups if they don't have the
* same name, password and gid.
*
* It merge the members of the second entry in the first one, and return
* the modified first entry on success, or NULL on failure (with errno
* set).
*/
static /*@null@*/struct commonio_entry *merge_group_entries (
/*@null@*/ /*@returned@*/struct commonio_entry *gr1,
/*@null@*/struct commonio_entry *gr2)
{
struct group *gptr1;
struct group *gptr2;
char **new_members;
size_t members = 0;
char *new_line;
size_t new_line_len, i;
if (NULL == gr2 || NULL == gr1) {
errno = EINVAL;
return NULL;
}
gptr1 = (struct group *)gr1->eptr;
gptr2 = (struct group *)gr2->eptr;
if (NULL == gptr2 || NULL == gptr1) {
errno = EINVAL;
return NULL;
}
/* Concatenate the 2 lines */
new_line_len = strlen (gr1->line) + strlen (gr2->line) +1;
new_line = (char *)malloc (new_line_len + 1);
if (NULL == new_line) {
errno = ENOMEM;
return NULL;
}
snprintf(new_line, new_line_len, "%s\n%s", gr1->line, gr2->line);
new_line[new_line_len] = '\0';
/* Concatenate the 2 list of members */
for (i=0; NULL != gptr1->gr_mem[i]; i++);
members += i;
for (i=0; NULL != gptr2->gr_mem[i]; i++) {
char **pmember = gptr1->gr_mem;
while (NULL != *pmember) {
if (0 == strcmp(*pmember, gptr2->gr_mem[i])) {
break;
}
pmember++;
}
if (NULL == *pmember) {
members++;
}
}
new_members = (char **)calloc ( (members+1), sizeof(char*) );
if (NULL == new_members) {
free (new_line);
errno = ENOMEM;
return NULL;
}
for (i=0; NULL != gptr1->gr_mem[i]; i++) {
new_members[i] = gptr1->gr_mem[i];
}
/* NULL termination enforced by above calloc */
members = i;
for (i=0; NULL != gptr2->gr_mem[i]; i++) {
char **pmember = new_members;
while (NULL != *pmember) {
if (0 == strcmp(*pmember, gptr2->gr_mem[i])) {
break;
}
pmember++;
}
if (NULL == *pmember) {
new_members[members] = gptr2->gr_mem[i];
members++;
new_members[members] = NULL;
}
}
gr1->line = new_line;
gptr1->gr_mem = new_members;
return gr1;
}
/*
* Scan the group database and split the groups which have more members
* than specified, if this is the result from a current change.
*
* Return 0 on failure (errno set) and 1 on success.
*/
static int split_groups (unsigned int max_members)
{
struct commonio_entry *gr;
for (gr = group_db.head; NULL != gr; gr = gr->next) {
struct group *gptr = (struct group *)gr->eptr;
struct commonio_entry *new;
struct group *new_gptr;
unsigned int members = 0;
unsigned int i;
/* Check if this group must be split */
if (!gr->changed) {
continue;
}
if (NULL == gptr) {
continue;
}
for (members = 0; NULL != gptr->gr_mem[members]; members++);
if (members <= max_members) {
continue;
}
new = (struct commonio_entry *) malloc (sizeof *new);
if (NULL == new) {
errno = ENOMEM;
return 0;
}
new->eptr = group_dup(gr->eptr);
if (NULL == new->eptr) {
free (new);
errno = ENOMEM;
return 0;
}
new_gptr = (struct group *)new->eptr;
new->line = NULL;
new->changed = true;
/* Enforce the maximum number of members on gptr */
for (i = max_members; NULL != gptr->gr_mem[i]; i++) {
free (gptr->gr_mem[i]);
gptr->gr_mem[i] = NULL;
}
/* Shift all the members */
/* The number of members in new_gptr will be check later */
for (i = 0; NULL != new_gptr->gr_mem[i + max_members]; i++) {
if (NULL != new_gptr->gr_mem[i]) {
free (new_gptr->gr_mem[i]);
}
new_gptr->gr_mem[i] = new_gptr->gr_mem[i + max_members];
new_gptr->gr_mem[i + max_members] = NULL;
}
for (; NULL != new_gptr->gr_mem[i]; i++) {
free (new_gptr->gr_mem[i]);
new_gptr->gr_mem[i] = NULL;
}
/* insert the new entry in the list */
new->prev = gr;
new->next = gr->next;
gr->next = new;
}
return 1;
}
-55
View File
@@ -1,55 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _GROUPIO_H
#define _GROUPIO_H
#include <sys/types.h>
#include <grp.h>
extern int gr_close (void);
extern /*@observer@*/ /*@null@*/const struct group *gr_locate (const char *name);
extern /*@observer@*/ /*@null@*/const struct group *gr_locate_gid (gid_t gid);
extern int gr_lock (void);
extern int gr_setdbname (const char *filename);
extern /*@observer@*/const char *gr_dbname (void);
extern /*@observer@*/ /*@null@*/const struct group *gr_next (void);
extern int gr_open (int mode);
extern int gr_remove (const char *name);
extern int gr_rewind (void);
extern int gr_unlock (void);
extern int gr_update (const struct group *gr);
extern int gr_sort (void);
#endif
-106
View File
@@ -1,106 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2013, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include "groupio.h"
/*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent)
{
struct group *gr;
int i;
gr = (struct group *) malloc (sizeof *gr);
if (NULL == gr) {
return NULL;
}
/* The libc might define other fields. They won't be copied. */
memset (gr, 0, sizeof *gr);
gr->gr_gid = grent->gr_gid;
/*@-mustfreeonly@*/
gr->gr_name = strdup (grent->gr_name);
/*@=mustfreeonly@*/
if (NULL == gr->gr_name) {
gr_free(gr);
return NULL;
}
/*@-mustfreeonly@*/
gr->gr_passwd = strdup (grent->gr_passwd);
/*@=mustfreeonly@*/
if (NULL == gr->gr_passwd) {
gr_free(gr);
return NULL;
}
for (i = 0; grent->gr_mem[i]; i++);
/*@-mustfreeonly@*/
gr->gr_mem = (char **) malloc ((i + 1) * sizeof (char *));
/*@=mustfreeonly@*/
if (NULL == gr->gr_mem) {
gr_free(gr);
return NULL;
}
for (i = 0; grent->gr_mem[i]; i++) {
gr->gr_mem[i] = strdup (grent->gr_mem[i]);
if (NULL == gr->gr_mem[i]) {
gr_free(gr);
return NULL;
}
}
gr->gr_mem[i] = NULL;
return gr;
}
void gr_free (/*@out@*/ /*@only@*/struct group *grent)
{
free (grent->gr_name);
if (NULL != grent->gr_passwd) {
memzero (grent->gr_passwd, strlen (grent->gr_passwd));
free (grent->gr_passwd);
}
if (NULL != grent->gr_mem) {
size_t i;
for (i = 0; NULL != grent->gr_mem[i]; i++) {
free (grent->gr_mem[i]);
}
free (grent->gr_mem);
}
free (grent);
}
-529
View File
@@ -1,529 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#if defined(SHADOWGRP) && !defined(HAVE_SHADOWGRP) /*{ */
#ident "$Id$"
#include <stdio.h>
#include "prototypes.h"
#include "defines.h"
static /*@null@*/FILE *shadow;
static /*@null@*//*@only@*/char **members = NULL;
static size_t nmembers = 0;
static /*@null@*//*@only@*/char **admins = NULL;
static size_t nadmins = 0;
static struct sgrp sgroup;
#define FIELDS 4
#ifdef USE_NIS
static bool nis_used;
static bool nis_ignore;
static enum { native, start, middle, native2 } nis_state;
static bool 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
/*
* bind_nis - bind to NIS server
*/
static int bind_nis (void)
{
if (yp_get_default_domain (&nis_domain))
return -1;
nis_bound = true;
return 0;
}
#endif
static /*@null@*/char **build_list (char *s, char **list[], size_t * nlist)
{
char **ptr = *list;
size_t nelem = *nlist, size;
while (s != NULL && *s != '\0') {
size = (nelem + 1) * sizeof (ptr);
ptr = realloc (*list, size);
if (NULL != ptr) {
ptr[nelem] = s;
nelem++;
*list = ptr;
*nlist = nelem;
s = strchr (s, ',');
if (NULL != s) {
*s = '\0';
s++;
}
}
}
size = (nelem + 1) * sizeof (ptr);
ptr = realloc (*list, size);
if (NULL != ptr) {
ptr[nelem] = NULL;
*list = ptr;
}
return ptr;
}
void setsgent (void)
{
#ifdef USE_NIS
nis_state = native;
#endif
if (NULL != shadow) {
rewind (shadow);
} else {
shadow = fopen (SGROUP_FILE, "r");
}
}
void endsgent (void)
{
if (NULL != shadow) {
(void) fclose (shadow);
}
shadow = (FILE *) 0;
}
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *string)
{
static char *sgrbuf = NULL;
static size_t sgrbuflen = 0;
char *fields[FIELDS];
char *cp;
int i;
size_t len = strlen (string) + 1;
if (len > sgrbuflen) {
char *buf = (char *) realloc (sgrbuf, sizeof (char) * len);
if (NULL == buf) {
return NULL;
}
sgrbuf = buf;
sgrbuflen = len;
}
strncpy (sgrbuf, string, len);
sgrbuf[len-1] = '\0';
cp = strrchr (sgrbuf, '\n');
if (NULL != cp) {
*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) && (NULL != cp); i++) {
fields[i] = cp;
cp = strchr (cp, ':');
if (NULL != cp) {
*cp++ = '\0';
}
}
/*
* If there was an extra field somehow, or perhaps not enough,
* the line is invalid.
*/
if ((NULL != cp) || (i != FIELDS)) {
#ifdef USE_NIS
if (!IS_NISCHAR (fields[0][0])) {
return 0;
} else {
nis_used = true;
}
#else
return 0;
#endif
}
sgroup.sg_name = fields[0];
sgroup.sg_passwd = fields[1];
if (0 != nadmins) {
nadmins = 0;
free (admins);
admins = NULL;
}
if (0 != nmembers) {
nmembers = 0;
free (members);
members = NULL;
}
sgroup.sg_adm = build_list (fields[2], &admins, &nadmins);
sgroup.sg_mem = build_list (fields[3], &members, &nmembers);
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.
*/
/*@observer@*//*@null@*/struct sgrp *fgetsgent (/*@null@*/FILE * fp)
{
static size_t buflen = 0;
static char *buf = NULL;
char *cp;
if (0 == buflen) {
buf = (char *) malloc (BUFSIZ);
if (NULL == buf) {
return NULL;
}
buflen = BUFSIZ;
}
if (NULL == fp) {
return NULL;
}
#ifdef USE_NIS
while (fgetsx (buf, (int) buflen, fp) == buf)
#else
if (fgetsx (buf, (int) buflen, fp) == buf)
#endif
{
while ( ((cp = strrchr (buf, '\n')) == NULL)
&& (feof (fp) == 0)) {
size_t len;
cp = (char *) realloc (buf, buflen*2);
if (NULL == cp) {
return NULL;
}
buf = cp;
buflen *= 2;
len = strlen (buf);
if (fgetsx (&buf[len],
(int) (buflen - len),
fp) != &buf[len]) {
return NULL;
}
}
cp = strrchr (buf, '\n');
if (NULL != cp) {
*cp = '\0';
}
#ifdef USE_NIS
if (nis_ignore && IS_NISCHAR (buf[0])) {
continue;
}
#endif
return (sgetsgent (buf));
}
return NULL;
}
/*
* getsgent - get a single shadow group entry
*/
/*@observer@*//*@null@*/struct sgrp *getsgent (void)
{
#ifdef USE_NIS
bool nis_1_group = false;
struct sgrp *val;
#endif
if (NULL == 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.
*/
val = fgetsgent (shadow);
if (NULL == val) {
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 ('\0' != val->sg_name[1]) {
nis_1_group = true;
} 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 && (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) {
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
*/
/*@observer@*//*@null@*/struct sgrp *getsgnam (const char *name)
{
struct sgrp *sgrp;
#ifdef USE_NIS
static char save_name[16];
int nis_disabled = 0;
#endif
setsgent ();
#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) {
cp = strchr (nis_val, '\n');
if (NULL != cp) {
*cp = '\0';
}
nis_state = middle;
sgrp = sgetsgent (nis_val);
if (NULL != sgrp) {
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 = true;
nis_disabled = true;
}
#endif
while ((sgrp = getsgent ()) != (struct sgrp *) 0) {
if (strcmp (name, sgrp->sg_name) == 0) {
break;
}
}
#ifdef USE_NIS
nis_ignore = false;
#endif
return sgrp;
}
/*
* 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 ((NULL == fp) || (NULL == sgrp)) {
return -1;
}
/* calculate the required buffer size */
size = strlen (sgrp->sg_name) + strlen (sgrp->sg_passwd) + 10;
for (i = 0; (NULL != sgrp->sg_adm) && (NULL != sgrp->sg_adm[i]); i++) {
size += strlen (sgrp->sg_adm[i]) + 1;
}
for (i = 0; (NULL != sgrp->sg_mem) && (NULL != sgrp->sg_mem[i]); i++) {
size += strlen (sgrp->sg_mem[i]) + 1;
}
buf = malloc (size);
if (NULL == 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; NULL != sgrp->sg_adm[i]; i++) {
if (i > 0) {
*cp++ = ',';
}
strcpy (cp, sgrp->sg_adm[i]);
cp += strlen (cp);
}
*cp = ':';
cp++;
/*
* Now do likewise with the group members.
*/
for (i = 0; NULL != sgrp->sg_mem[i]; i++) {
if (i > 0) {
*cp = ',';
cp++;
}
strcpy (cp, sgrp->sg_mem[i]);
cp += strlen (cp);
}
*cp = '\n';
cp++;
*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 */
-75
View File
@@ -1,75 +0,0 @@
/*
* Copyright (c) 1988 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*/
#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 administrator list */
char **sg_mem; /* group membership list */
};
/*
* Shadow group security file functions.
*/
#include <stdio.h> /* for FILE */
#if __STDC__
/*@observer@*//*@null@*/struct sgrp *getsgent (void);
/*@observer@*//*@null@*/struct sgrp *getsgnam (const char *);
/*@observer@*//*@null@*/struct sgrp *sgetsgent (const char *);
/*@observer@*//*@null@*/struct sgrp *fgetsgent (/*@null@*/FILE *);
void setsgent (void);
void endsgent (void);
int putsgent (const struct sgrp *, FILE *);
#else
/*@observer@*//*@null@*/struct sgrp *getsgent ();
/*@observer@*//*@null@*/struct sgrp *getsgnam ();
/*@observer@*//*@null@*/struct sgrp *sgetsgent ();
/*@observer@*//*@null@*/struct sgrp *fgetsgent ();
void setsgent ();
void endsgent ();
int putsgent ();
#endif
#define GSHADOW "/etc/gshadow"
#endif /* ifndef _H_GSHADOW */
-108
View File
@@ -1,108 +0,0 @@
/*
* Copyright (c) 1992 , Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ifndef HAVE_LCKPWDF
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include "pwio.h"
#include "shadowio.h"
/*
* 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
-57
View File
@@ -1,57 +0,0 @@
/* Author: Peter Vrabec <pvrabec@redhat.com> */
#include <config.h>
#ifdef USE_NSCD
#include <stdio.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "exitcodes.h"
#include "defines.h"
#include "prototypes.h"
#include "nscd.h"
#define MSG_NSCD_FLUSH_CACHE_FAILED "%s: Failed to flush the nscd cache.\n"
/*
* nscd_flush_cache - flush specified service buffer in nscd cache
*/
int nscd_flush_cache (const char *service)
{
int status, code;
const char *cmd = "/usr/sbin/nscd";
const char *spawnedArgs[] = {"nscd", "-i", service, NULL};
const char *spawnedEnv[] = {NULL};
if (run_command (cmd, spawnedArgs, spawnedEnv, &status) != 0) {
/* run_command writes its own more detailed message. */
(void) fprintf (stderr, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog);
return -1;
}
code = WEXITSTATUS (status);
if (!WIFEXITED (status)) {
(void) fprintf (stderr,
_("%s: nscd did not terminate normally (signal %d)\n"),
Prog, WTERMSIG (status));
return -1;
} else if (code == E_CMD_NOTFOUND) {
/* nscd is not installed, or it is installed but uses an
interpreter that is missing. Probably the former. */
return 0;
} else if (code == 1) {
/* nscd is installed, but it isn't active. */
return 0;
} else if (code != 0) {
(void) fprintf (stderr, _("%s: nscd exited with status %d\n"),
Prog, code);
(void) fprintf (stderr, _(MSG_NSCD_FLUSH_CACHE_FAILED), Prog);
return -1;
}
return 0;
}
#else /* USE_NSCD */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* USE_NSCD */
-13
View File
@@ -1,13 +0,0 @@
#ifndef _NSCD_H_
#define _NSCD_H_
/*
* nscd_flush_cache - flush specified service buffer in nscd cache
*/
#ifdef USE_NSCD
extern int nscd_flush_cache (const char *service);
#else
#define nscd_flush_cache(service) (0)
#endif
#endif
-58
View File
@@ -1,58 +0,0 @@
/*
* Copyright (c) 1999 , Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <security/pam_appl.h>
#ifdef HAVE_SECURITY_PAM_MISC_H
# include <security/pam_misc.h>
#endif
#ifdef HAVE_SECURITY_OPENPAM_H
# include <security/openpam.h>
#endif
static struct pam_conv conv = {
SHADOW_PAM_CONVERSATION,
NULL
};
/* compatibility with different versions of Linux-PAM */
#if !HAVE_DECL_PAM_ESTABLISH_CRED
#define PAM_ESTABLISH_CRED PAM_CRED_ESTABLISH
#endif
#if !HAVE_DECL_PAM_DELETE_CRED
#define PAM_DELETE_CRED PAM_CRED_DELETE
#endif
#if !HAVE_DECL_PAM_NEW_AUTHTOK_REQD
#define PAM_NEW_AUTHTOK_REQD PAM_AUTHTOKEN_REQD
#endif
#if !HAVE_DECL_PAM_DATA_SILENT
#define PAM_DATA_SILENT 0
#endif
-477
View File
@@ -1,477 +0,0 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "defines.h"
#include "prototypes.h"
#include "port.h"
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 (('\0' != *pattern) && (*pattern == *port)) {
pattern++;
port++;
}
if (('\0' == *pattern) && ('\0' == *port)) {
return 0;
}
if (('S' == orig[0]) && ('U' == orig[1]) && ('\0' == orig[2])) {
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 (NULL != 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 (NULL != ports) {
(void) 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 (NULL == ports) {
setportent ();
}
if (NULL == 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, (int) 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 (('\0' != *cp) && (':' != *cp) && (',' != *cp)) {
cp++;
}
if ('\0' == *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';
cp++;
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';
cp++;
port.pt_users[j] = cp;
j++;
}
}
port.pt_users[j] = 0;
} else {
port.pt_users = 0;
}
if (':' != *cp) {
goto again;
}
*cp = '\0';
cp++;
/*
* 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 ('\0' == *cp) {
port.pt_times = 0;
return &port;
}
port.pt_times = ptimes;
/*
* Get the next comma separated entry
*/
for (j = 0; ('\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;
('\0' != cp[i]) && ('\0' != 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 (0 == i) {
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; ('\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 = 0, i = 0;
('\0' != cp[i]) && isdigit (cp[i]);
i++) {
dtime = dtime * 10 + cp[i] - '0';
}
if ( ((',' != cp[i]) && ('\0' != 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 ()) != NULL) {
if ( (0 == port->pt_names)
|| (0 == port->pt_users)) {
continue;
}
for (i = 0; NULL != port->pt_names[i]; i++) {
if (portcmp (port->pt_names[i], tty) == 0) {
break;
}
}
if (port->pt_names[i] == 0) {
continue;
}
for (j = 0; NULL != 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.
*/
bool 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 plenty of ways to have an
* entry to match all users.
*/
pp = getttyuser (port, id);
if (NULL == pp) {
return true;
}
/*
* The entry is there, but has no time entries - don't
* ever let them login.
*/
if (0 == pp->pt_times) {
return false;
}
/*
* The current time is converted to HHMM format for
* comparison 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 comparison 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 true;
}
} else {
if ( (dtime >= pp->pt_times[i].t_start)
|| (dtime <= pp->pt_times[i].t_end)) {
return true;
}
}
}
/*
* No matching time entry was found, user shouldn't
* be let in right now.
*/
return false;
}
-83
View File
@@ -1,83 +0,0 @@
/*
* Copyright (c) 1989 - 1991, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* port.h - structure of /etc/porttime
*
* $Id$
*
* 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;
};
-437
View File
@@ -1,437 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
* Copyright (c) 2007 - 2010, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* prototypes.h
*
* prototypes of libmisc functions, and private lib functions.
*
* $Id$
*
*/
#ifndef _PROTOTYPES_H
#define _PROTOTYPES_H
#include <config.h>
#include <sys/stat.h>
#ifdef USE_UTMPX
#include <utmpx.h>
#else
#include <utmp.h>
#endif
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <shadow.h>
#include <lastlog.h>
#include "defines.h"
#include "commonio.h"
extern /*@observer@*/ const char *Prog;
/* addgrps.c */
#if defined (HAVE_SETGROUPS) && ! defined (USE_PAM)
extern int add_groups (const char *);
#endif
/* age.c */
extern void agecheck (/*@null@*/const struct spwd *);
extern int expire (const struct passwd *, /*@null@*/const struct spwd *);
/* isexpired.c */
extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *);
/* basename() renamed to Basename() to avoid libc name space confusion */
/* basename.c */
extern /*@observer@*/const char *Basename (const char *str);
/* chowndir.c */
extern int chown_tree (const char *root,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
/* chowntty.c */
extern void chown_tty (const struct passwd *);
/* cleanup.c */
typedef /*@null@*/void (*cleanup_function) (/*@null@*/void *arg);
void add_cleanup (/*@notnull@*/cleanup_function pcf, /*@null@*/void *arg);
void del_cleanup (/*@notnull@*/cleanup_function pcf);
void do_cleanups (void);
/* cleanup_group.c */
struct cleanup_info_mod {
char *audit_msg;
char *action;
/*@observer@*/const char *name;
};
void cleanup_report_add_group (void *group_name);
void cleanup_report_add_group_group (void *group_name);
#ifdef SHADOWGRP
void cleanup_report_add_group_gshadow (void *group_name);
#endif
void cleanup_report_del_group (void *group_name);
void cleanup_report_del_group_group (void *group_name);
#ifdef SHADOWGRP
void cleanup_report_del_group_gshadow (void *group_name);
#endif
void cleanup_report_mod_passwd (void *cleanup_info);
void cleanup_report_mod_group (void *cleanup_info);
void cleanup_report_mod_gshadow (void *cleanup_info);
void cleanup_unlock_group (/*@null@*/void *unused);
#ifdef SHADOWGRP
void cleanup_unlock_gshadow (/*@null@*/void *unused);
#endif
void cleanup_unlock_passwd (/*@null@*/void *unused);
/* console.c */
extern bool console (const char *);
/* copydir.c */
extern int copy_tree (const char *src_root, const char *dst_root,
bool copy_root,
bool reset_selinux,
uid_t old_uid, uid_t new_uid,
gid_t old_gid, gid_t new_gid);
/* encrypt.c */
extern /*@exposed@*//*@null@*/char *pw_encrypt (const char *, const char *);
/* entry.c */
extern void pw_entry (const char *, struct passwd *);
/* env.c */
extern void addenv (const char *, /*@null@*/const char *);
extern void initenv (void);
extern void set_env (int, char *const *);
extern void sanitize_env (void);
/* fields.c */
extern void change_field (char *, size_t, const char *);
extern int valid_field (const char *, const char *);
/* find_new_gid.c */
extern int find_new_gid (bool sys_group,
gid_t *gid,
/*@null@*/gid_t const *preferred_gid);
/* find_new_uid.c */
extern int find_new_uid (bool sys_user,
uid_t *uid,
/*@null@*/uid_t const *preferred_uid);
#ifdef ENABLE_SUBIDS
/* find_new_sub_gids.c */
extern int find_new_sub_gids (const char *owner,
gid_t *range_start, unsigned long *range_count);
/* find_new_sub_uids.c */
extern int find_new_sub_uids (const char *owner,
uid_t *range_start, unsigned long *range_count);
#endif /* ENABLE_SUBIDS */
/* get_gid.c */
extern int get_gid (const char *gidstr, gid_t *gid);
/* getgr_nam_gid.c */
extern /*@only@*//*@null@*/struct group *getgr_nam_gid (/*@null@*/const char *grname);
/* getlong.c */
extern int getlong (const char *numstr, /*@out@*/long int *result);
/* get_pid.c */
extern int get_pid (const char *pidstr, pid_t *pid);
/* getrange */
extern int getrange (char *range,
unsigned long *min, bool *has_min,
unsigned long *max, bool *has_max);
/* get_uid.c */
extern int get_uid (const char *uidstr, uid_t *uid);
/* getulong.c */
extern int getulong (const char *numstr, /*@out@*/unsigned long int *result);
/* fputsx.c */
extern /*@null@*/char *fgetsx (/*@returned@*/ /*@out@*/char *, int, FILE *);
extern int fputsx (const char *, FILE *);
/* groupio.c */
extern void __gr_del_entry (const struct commonio_entry *ent);
extern /*@observer@*/const struct commonio_db *__gr_get_db (void);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__gr_get_head (void);
extern void __gr_set_changed (void);
/* groupmem.c */
extern /*@null@*/ /*@only@*/struct group *__gr_dup (const struct group *grent);
extern void gr_free (/*@out@*/ /*@only@*/struct group *grent);
/* hushed.c */
extern bool hushed (const char *username);
/* audit_help.c */
#ifdef WITH_AUDIT
extern int audit_fd;
extern void audit_help_open (void);
/* Use AUDIT_NO_ID when a name is provided to audit_logger instead of an ID */
#define AUDIT_NO_ID ((unsigned int) -1)
typedef enum {
SHADOW_AUDIT_FAILURE = 0,
SHADOW_AUDIT_SUCCESS = 1} shadow_audit_result;
extern void audit_logger (int type, const char *pgname, const char *op,
const char *name, unsigned int id,
shadow_audit_result result);
void audit_logger_message (const char *message, shadow_audit_result result);
#endif
/* limits.c */
#ifndef USE_PAM
extern void setup_limits (const struct passwd *);
#endif
/* list.c */
extern /*@only@*/ /*@out@*/char **add_list (/*@returned@*/ /*@only@*/char **, const char *);
extern /*@only@*/ /*@out@*/char **del_list (/*@returned@*/ /*@only@*/char **, const char *);
extern /*@only@*/ /*@out@*/char **dup_list (char *const *);
extern bool is_on_list (char *const *list, const char *member);
extern /*@only@*/char **comma_to_list (const char *);
/* log.c */
extern void dolastlog (
struct lastlog *ll,
const struct passwd *pw,
/*@unique@*/const char *line,
/*@unique@*/const char *host);
/* login_nopam.c */
extern int login_access (const char *user, const char *from);
/* loginprompt.c */
extern void login_prompt (const char *, char *, int);
/* mail.c */
extern void mailcheck (void);
/* motd.c */
extern void motd (void);
/* myname.c */
extern /*@null@*//*@only@*/struct passwd *get_my_pwent (void);
/* pam_pass_non_interractive.c */
#ifdef USE_PAM
extern int do_pam_passwd_non_interractive (const char *pam_service,
const char *username,
const char* password);
#endif /* USE_PAM */
/* obscure.c */
#ifndef USE_PAM
extern bool obscure (const char *, const char *, const struct passwd *);
#endif
/* pam_pass.c */
#ifdef USE_PAM
extern void do_pam_passwd (const char *user, bool silent, bool change_expired);
#endif
/* port.c */
extern bool isttytime (const char *, const char *, time_t);
/* pwd2spwd.c */
#ifndef USE_PAM
extern struct spwd *pwd_to_spwd (const struct passwd *);
#endif
/* pwdcheck.c */
#ifndef USE_PAM
extern void passwd_check (const char *, const char *, const char *);
#endif
/* pwd_init.c */
extern void pwd_init (void);
/* pwio.c */
extern void __pw_del_entry (const struct commonio_entry *ent);
extern struct commonio_db *__pw_get_db (void);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__pw_get_head (void);
/* pwmem.c */
extern /*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent);
extern void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent);
/* remove_tree.c */
extern int remove_tree (const char *root, bool remove_root);
/* rlogin.c */
extern int do_rlogin (const char *remote_host, char *name, size_t namelen,
char *term, size_t termlen);
/* root_flag.c */
extern void process_root_flag (const char* short_opt, int argc, char **argv);
/* salt.c */
extern /*@observer@*/const char *crypt_make_salt (/*@null@*//*@observer@*/const char *meth, /*@null@*/void *arg);
/* selinux.c */
#ifdef WITH_SELINUX
extern int set_selinux_file_context (const char *dst_name);
extern int reset_selinux_file_context (void);
#endif
/* semanage.c */
#ifdef WITH_SELINUX
extern int set_seuser(const char *login_name, const char *seuser_name);
extern int del_seuser(const char *login_name);
#endif
/* setugid.c */
extern int setup_groups (const struct passwd *info);
extern int change_uid (const struct passwd *info);
#if (defined HAVE_INITGROUPS) && (! defined USE_PAM)
extern int setup_uid_gid (const struct passwd *info, bool is_console);
#else
extern int setup_uid_gid (const struct passwd *info);
#endif
/* setup.c */
extern void setup (struct passwd *);
/* setupenv.c */
extern void setup_env (struct passwd *);
/* sgetgrent.c */
extern struct group *sgetgrent (const char *buf);
/* sgetpwent.c */
extern struct passwd *sgetpwent (const char *buf);
/* sgetspent.c */
#ifndef HAVE_SGETSPENT
extern struct spwd *sgetspent (const char *string);
#endif
/* sgroupio.c */
extern void __sgr_del_entry (const struct commonio_entry *ent);
extern /*@null@*/ /*@only@*/struct sgrp *__sgr_dup (const struct sgrp *sgent);
extern void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent);
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__sgr_get_head (void);
extern void __sgr_set_changed (void);
/* shadowio.c */
extern /*@dependent@*/ /*@null@*/struct commonio_entry *__spw_get_head (void);
extern void __spw_del_entry (const struct commonio_entry *ent);
/* shadowmem.c */
extern /*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent);
extern void spw_free (/*@out@*/ /*@only@*/struct spwd *spent);
/* shell.c */
extern int shell (const char *file, /*@null@*/const char *arg, char *const envp[]);
/* spawn.c */
extern int run_command (const char *cmd, const char *argv[],
/*@null@*/const char *envp[], /*@out@*/int *status);
/* strtoday.c */
extern long strtoday (const char *);
/* suauth.c */
extern int check_su_auth (const char *actual_id,
const char *wanted_id,
bool su_to_root);
/* sulog.c */
extern void sulog (const char *tty,
bool success,
const char *oldname,
const char *name);
/* sub.c */
extern void subsystem (const struct passwd *);
/* ttytype.c */
extern void ttytype (const char *);
/* tz.c */
#ifndef USE_PAM
extern /*@observer@*/const char *tz (const char *);
#endif
/* ulimit.c */
extern int set_filesize_limit (int blocks);
/* user_busy.c */
extern int user_busy (const char *name, uid_t uid);
/* utmp.c */
extern /*@null@*/struct utmp *get_current_utmp (void);
extern struct utmp *prepare_utmp (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut);
extern int setutmp (struct utmp *ut);
#ifdef USE_UTMPX
extern struct utmpx *prepare_utmpx (const char *name,
const char *line,
const char *host,
/*@null@*/const struct utmp *ut);
extern int setutmpx (struct utmpx *utx);
#endif /* USE_UTMPX */
/* valid.c */
extern bool valid (const char *, const struct passwd *);
/* xmalloc.c */
extern /*@maynotreturn@*/ /*@only@*//*@out@*//*@notnull@*/char *xmalloc (size_t size)
/*@ensures MaxSet(result) == (size - 1); @*/;
extern /*@maynotreturn@*/ /*@only@*//*@notnull@*/char *xstrdup (const char *);
/* xgetpwnam.c */
extern /*@null@*/ /*@only@*/struct passwd *xgetpwnam (const char *);
/* xgetpwuid.c */
extern /*@null@*/ /*@only@*/struct passwd *xgetpwuid (uid_t);
/* xgetgrnam.c */
extern /*@null@*/ /*@only@*/struct group *xgetgrnam (const char *);
/* xgetgrgid.c */
extern /*@null@*/ /*@only@*/struct group *xgetgrgid (gid_t);
/* xgetspnam.c */
extern /*@null@*/ /*@only@*/struct spwd *xgetspnam(const char *);
/* yesno.c */
extern bool yes_or_no (bool read_only);
#endif /* _PROTOTYPES_H */
-234
View File
@@ -1,234 +0,0 @@
/*
* Copyright (c) 1992 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2003 - 2006, Tomasz Kłoczko
* Copyright (c) 2008 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ifndef USE_PAM
#ident "$Id$"
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include "prototypes.h"
#include "defines.h"
#include "pwauth.h"
#include "getdef.h"
#ifdef SKEY
#include <skey.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
bool wipe_clear_pass = true;
/*@null@*/char *clear_pass = NULL;
/*
* pw_auth - perform getpass/crypt authentication
*
* pw_auth gets the user's cleartext password and encrypts it
* using the salt in the encrypted password. The results are
* compared.
*/
int pw_auth (const char *cipher,
const char *user,
int reason,
/*@null@*/const char *input)
{
char prompt[1024];
char *clear = NULL;
const char *cp;
const char *encrypted;
int retval;
#ifdef SKEY
bool use_skey = false;
char challenge_info[40];
struct skey skey;
#endif
/*
* There are programs for adding and deleting authentication data.
*/
if ((PW_ADD == reason) || (PW_DELETE == reason)) {
return 0;
}
/*
* There are even programs for changing the user name ...
*/
if ((PW_CHANGE == reason) && (NULL != input)) {
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 ((PW_CHANGE == reason) && (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 ((NULL == cipher) || ('\0' == *cipher)) {
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.
*/
# ifdef SKEY_BSD_STYLE
/*
* Some BSD updates to the S/KEY API adds a fourth parameter; the
* sizeof of the challenge info buffer.
*/
# define skeychallenge(s,u,c) skeychallenge(s,u,c,sizeof(c))
# endif
if (skeychallenge (&skey, user, challenge_info) == 0) {
use_skey = true;
}
#endif
/*
* Prompt for the password as required. FTPD and REXECD both
* get the cleartext password for us.
*/
if ((PW_FTP != reason) && (PW_REXEC != reason) && (NULL == input)) {
cp = getdef_str ("LOGIN_STRING");
if (NULL == cp) {
cp = _(PROMPT);
}
#ifdef SKEY
if (use_skey) {
printf ("[%s]\n", challenge_info);
}
#endif
snprintf (prompt, sizeof prompt, cp, user);
clear = getpass (prompt);
if (NULL == 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.
*/
encrypted = pw_encrypt (input, cipher);
if (NULL != encrypted) {
retval = strcmp (encrypted, cipher);
} else {
retval = -1;
}
#ifdef SKEY
/*
* If (1) The password fails to match, and
* (2) The password is empty and
* (3) We are using OPIE or S/Key, then
* ...Re-prompt, with echo on.
* -- AR 8/22/1999
*/
if ((0 != retval) && ('\0' == input[0]) && use_skey) {
clear = getpass (prompt);
if (NULL == clear) {
static char c[1];
c[0] = '\0';
clear = c;
}
input = clear;
}
if ((0 != retval) && use_skey) {
int passcheck = -1;
if (skeyverify (&skey, input) == 0) {
passcheck = skey.n;
}
if (passcheck > 0) {
retval = 0;
}
}
#endif
/*
* 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 && (NULL != clear) && ('\0' != *clear)) {
strzero (clear);
}
return retval;
}
#else /* !USE_PAM */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !USE_PAM */
-66
View File
@@ -1,66 +0,0 @@
/*
* Copyright (c) 1992 - 1993, Julianne Frances Haugh
* Copyright (c) 1996 - 1997, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* $Id$
*/
#ifndef USE_PAM
int pw_auth (const char *cipher,
const char *user,
int flag,
/*@null@*/const char *input);
#endif /* !USE_PAM */
/*
* 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
-226
View File
@@ -1,226 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <pwd.h>
#include <stdio.h>
#include "commonio.h"
#include "pwio.h"
static /*@null@*/ /*@only@*/void *passwd_dup (const void *ent)
{
const struct passwd *pw = ent;
return __pw_dup (pw);
}
static void passwd_free (/*@out@*/ /*@only@*/void *ent)
{
struct passwd *pw = ent;
pw_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;
if ( (NULL == pw)
|| (valid_field (pw->pw_name, ":\n") == -1)
|| (valid_field (pw->pw_passwd, ":\n") == -1)
|| (pw->pw_uid == (uid_t)-1)
|| (pw->pw_gid == (gid_t)-1)
|| (valid_field (pw->pw_gecos, ":\n") == -1)
|| (valid_field (pw->pw_dir, ":\n") == -1)
|| (valid_field (pw->pw_shell, ":\n") == -1)) {
return -1;
}
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,
NULL, /* open_hook */
NULL /* close_hook */
};
static struct commonio_db passwd_db = {
PASSWD_FILE, /* filename */
&passwd_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
NULL, /* scontext */
#endif
0644, /* st_mode */
0, /* st_uid */
0, /* st_gid */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int pw_setdbname (const char *filename)
{
return commonio_setname (&passwd_db, filename);
}
/*@observer@*/const char *pw_dbname (void)
{
return passwd_db.filename;
}
int pw_lock (void)
{
return commonio_lock (&passwd_db);
}
int pw_open (int mode)
{
return commonio_open (&passwd_db, mode);
}
/*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name)
{
return commonio_locate (&passwd_db, name);
}
/*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid)
{
const struct passwd *pwd;
pw_rewind ();
while ( ((pwd = pw_next ()) != NULL)
&& (pwd->pw_uid != uid)) {
}
return pwd;
}
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);
}
/*@observer@*/ /*@null@*/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);
}
/*@null@*/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);
}
struct commonio_db *__pw_get_db (void)
{
return &passwd_db;
}
static int pw_cmp (const void *p1, const void *p2)
{
uid_t u1, u2;
if ((*(struct commonio_entry **) p1)->eptr == NULL)
return 1;
if ((*(struct commonio_entry **) p2)->eptr == NULL)
return -1;
u1 = ((struct passwd *) (*(struct commonio_entry **) p1)->eptr)->pw_uid;
u2 = ((struct passwd *) (*(struct commonio_entry **) p2)->eptr)->pw_uid;
if (u1 < u2)
return -1;
else if (u1 > u2)
return 1;
else
return 0;
}
/* Sort entries by UID */
int pw_sort ()
{
return commonio_sort (&passwd_db, pw_cmp);
}
-55
View File
@@ -1,55 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2005 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _PWIO_H
#define _PWIO_H
#include <sys/types.h>
#include <pwd.h>
extern int pw_close (void);
extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate (const char *name);
extern /*@observer@*/ /*@null@*/const struct passwd *pw_locate_uid (uid_t uid);
extern int pw_lock (void);
extern int pw_setdbname (const char *filename);
extern /*@observer@*/const char *pw_dbname (void);
extern /*@observer@*/ /*@null@*/const struct passwd *pw_next (void);
extern int pw_open (int mode);
extern int pw_remove (const char *name);
extern int pw_rewind (void);
extern int pw_unlock (void);
extern int pw_update (const struct passwd *pw);
extern int pw_sort (void);
#endif
-106
View File
@@ -1,106 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2007 - 2013, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <stdio.h>
#include "defines.h"
#include "prototypes.h"
#include "pwio.h"
/*@null@*/ /*@only@*/struct passwd *__pw_dup (const struct passwd *pwent)
{
struct passwd *pw;
pw = (struct passwd *) malloc (sizeof *pw);
if (NULL == pw) {
return NULL;
}
/* The libc might define other fields. They won't be copied. */
memset (pw, 0, sizeof *pw);
pw->pw_uid = pwent->pw_uid;
pw->pw_gid = pwent->pw_gid;
/*@-mustfreeonly@*/
pw->pw_name = strdup (pwent->pw_name);
/*@=mustfreeonly@*/
if (NULL == pw->pw_name) {
pw_free(pw);
return NULL;
}
/*@-mustfreeonly@*/
pw->pw_passwd = strdup (pwent->pw_passwd);
/*@=mustfreeonly@*/
if (NULL == pw->pw_passwd) {
pw_free(pw);
return NULL;
}
/*@-mustfreeonly@*/
pw->pw_gecos = strdup (pwent->pw_gecos);
/*@=mustfreeonly@*/
if (NULL == pw->pw_gecos) {
pw_free(pw);
return NULL;
}
/*@-mustfreeonly@*/
pw->pw_dir = strdup (pwent->pw_dir);
/*@=mustfreeonly@*/
if (NULL == pw->pw_dir) {
pw_free(pw);
return NULL;
}
/*@-mustfreeonly@*/
pw->pw_shell = strdup (pwent->pw_shell);
/*@=mustfreeonly@*/
if (NULL == pw->pw_shell) {
pw_free(pw);
return NULL;
}
return pw;
}
void pw_free (/*@out@*/ /*@only@*/struct passwd *pwent)
{
free (pwent->pw_name);
if (pwent->pw_passwd) {
memzero (pwent->pw_passwd, strlen (pwent->pw_passwd));
free (pwent->pw_passwd);
}
free (pwent->pw_gecos);
free (pwent->pw_dir);
free (pwent->pw_shell);
free (pwent);
}
-103
View File
@@ -1,103 +0,0 @@
/*
* Copyright (c) 2011 , Peter Vrabec <pvrabec@redhat.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ifdef WITH_SELINUX
#include "defines.h"
#include <selinux/selinux.h>
#include "prototypes.h"
static bool selinux_checked = false;
static bool selinux_enabled;
/*
* set_selinux_file_context - Set the security context before any file or
* directory creation.
*
* set_selinux_file_context () should be called before any creation
* of file, symlink, directory, ...
*
* Callers may have to Reset SELinux to create files with default
* contexts with reset_selinux_file_context
*/
int set_selinux_file_context (const char *dst_name)
{
/*@null@*/security_context_t scontext = NULL;
if (!selinux_checked) {
selinux_enabled = is_selinux_enabled () > 0;
selinux_checked = true;
}
if (selinux_enabled) {
/* Get the default security context for this file */
if (matchpathcon (dst_name, 0, &scontext) < 0) {
if (security_getenforce () != 0) {
return 1;
}
}
/* Set the security context for the next created file */
if (setfscreatecon (scontext) < 0) {
if (security_getenforce () != 0) {
return 1;
}
}
freecon (scontext);
}
return 0;
}
/*
* reset_selinux_file_context - Reset the security context to the default
* policy behavior
*
* reset_selinux_file_context () should be called after the context
* was changed with set_selinux_file_context ()
*/
int reset_selinux_file_context (void)
{
if (!selinux_checked) {
selinux_enabled = is_selinux_enabled () > 0;
selinux_checked = true;
}
if (selinux_enabled) {
if (setfscreatecon (NULL) != 0) {
return 1;
}
}
return 0;
}
#else /* !WITH_SELINUX */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !WITH_SELINUX */
-378
View File
@@ -1,378 +0,0 @@
/*
* Copyright (c) 2010 , Jakub Hrozek <jhrozek@redhat.com>
* Copyright (c) 2011 , Peter Vrabec <pvrabec@redhat.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ifdef WITH_SELINUX
#include "defines.h"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <stdarg.h>
#include <selinux/selinux.h>
#include <semanage/semanage.h>
#include "prototypes.h"
#ifndef DEFAULT_SERANGE
#define DEFAULT_SERANGE "s0"
#endif
static void semanage_error_callback (unused void *varg,
semanage_handle_t *handle,
const char *fmt, ...)
{
int ret;
char * message = NULL;
va_list ap;
va_start (ap, fmt);
ret = vasprintf (&message, fmt, ap);
va_end (ap);
if (ret < 0) {
/* ENOMEM */
return;
}
switch (semanage_msg_get_level (handle)) {
case SEMANAGE_MSG_ERR:
case SEMANAGE_MSG_WARN:
fprintf (stderr, _("[libsemanage]: %s\n"), message);
break;
case SEMANAGE_MSG_INFO:
/* nop */
break;
}
free (message);
}
static semanage_handle_t *semanage_init (void)
{
int ret;
semanage_handle_t *handle = NULL;
handle = semanage_handle_create ();
if (NULL == handle) {
fprintf (stderr,
_("Cannot create SELinux management handle\n"));
return NULL;
}
semanage_msg_set_callback (handle, semanage_error_callback, NULL);
ret = semanage_is_managed (handle);
if (ret != 1) {
fprintf (stderr, _("SELinux policy not managed\n"));
goto fail;
}
ret = semanage_access_check (handle);
if (ret < SEMANAGE_CAN_READ) {
fprintf (stderr, _("Cannot read SELinux policy store\n"));
goto fail;
}
ret = semanage_connect (handle);
if (ret != 0) {
fprintf (stderr,
_("Cannot establish SELinux management connection\n"));
goto fail;
}
ret = semanage_begin_transaction (handle);
if (ret != 0) {
fprintf (stderr, _("Cannot begin SELinux transaction\n"));
goto fail;
}
return handle;
fail:
semanage_handle_destroy (handle);
return NULL;
}
static int semanage_user_mod (semanage_handle_t *handle,
semanage_seuser_key_t *key,
const char *login_name,
const char *seuser_name)
{
int ret;
semanage_seuser_t *seuser = NULL;
semanage_seuser_query (handle, key, &seuser);
if (NULL == seuser) {
fprintf (stderr,
_("Could not query seuser for %s\n"), login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
if (ret != 0) {
fprintf (stderr,
_("Could not set serange for %s\n"), login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_set_sename (handle, seuser, seuser_name);
if (ret != 0) {
fprintf (stderr,
_("Could not set sename for %s\n"),
login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_modify_local (handle, key, seuser);
if (ret != 0) {
fprintf (stderr,
_("Could not modify login mapping for %s\n"),
login_name);
ret = 1;
goto done;
}
ret = 0;
done:
semanage_seuser_free (seuser);
return ret;
}
static int semanage_user_add (semanage_handle_t *handle,
semanage_seuser_key_t *key,
const char *login_name,
const char *seuser_name)
{
int ret;
semanage_seuser_t *seuser = NULL;
ret = semanage_seuser_create (handle, &seuser);
if (ret != 0) {
fprintf (stderr,
_("Cannot create SELinux login mapping for %s\n"),
login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_set_name (handle, seuser, login_name);
if (ret != 0) {
fprintf (stderr, _("Could not set name for %s\n"), login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_set_mlsrange (handle, seuser, DEFAULT_SERANGE);
if (ret != 0) {
fprintf (stderr,
_("Could not set serange for %s\n"),
login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_set_sename (handle, seuser, seuser_name);
if (ret != 0) {
fprintf (stderr,
_("Could not set SELinux user for %s\n"),
login_name);
ret = 1;
goto done;
}
ret = semanage_seuser_modify_local (handle, key, seuser);
if (ret != 0) {
fprintf (stderr,
_("Could not add login mapping for %s\n"),
login_name);
ret = 1;
goto done;
}
ret = 0;
done:
semanage_seuser_free (seuser);
return ret;
}
int set_seuser (const char *login_name, const char *seuser_name)
{
semanage_handle_t *handle = NULL;
semanage_seuser_key_t *key = NULL;
int ret;
int seuser_exists = 0;
if (NULL == seuser_name) {
/* don't care, just let system pick the defaults */
return 0;
}
handle = semanage_init ();
if (NULL == handle) {
fprintf (stderr, _("Cannot init SELinux management\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_key_create (handle, login_name, &key);
if (ret != 0) {
fprintf (stderr, _("Cannot create SELinux user key\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_exists (handle, key, &seuser_exists);
if (ret < 0) {
fprintf (stderr, _("Cannot verify the SELinux user\n"));
ret = 1;
goto done;
}
if (0 != seuser_exists) {
ret = semanage_user_mod (handle, key, login_name, seuser_name);
if (ret != 0) {
fprintf (stderr,
_("Cannot modify SELinux user mapping\n"));
ret = 1;
goto done;
}
} else {
ret = semanage_user_add (handle, key, login_name, seuser_name);
if (ret != 0) {
fprintf (stderr,
_("Cannot add SELinux user mapping\n"));
ret = 1;
goto done;
}
}
ret = semanage_commit (handle);
if (ret < 0) {
fprintf (stderr, _("Cannot commit SELinux transaction\n"));
ret = 1;
goto done;
}
ret = 0;
done:
semanage_seuser_key_free (key);
semanage_handle_destroy (handle);
return ret;
}
int del_seuser (const char *login_name)
{
semanage_handle_t *handle = NULL;
semanage_seuser_key_t *key = NULL;
int ret;
int exists = 0;
handle = semanage_init ();
if (NULL == handle) {
fprintf (stderr, _("Cannot init SELinux management\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_key_create (handle, login_name, &key);
if (ret != 0) {
fprintf (stderr, _("Cannot create SELinux user key\n"));
ret = 1;
goto done;
}
ret = semanage_seuser_exists (handle, key, &exists);
if (ret < 0) {
fprintf (stderr, _("Cannot verify the SELinux user\n"));
ret = 1;
goto done;
}
if (0 == exists) {
fprintf (stderr,
_("Login mapping for %s is not defined, OK if default mapping was used\n"),
login_name);
ret = 0; /* probably default mapping */
goto done;
}
ret = semanage_seuser_exists_local (handle, key, &exists);
if (ret < 0) {
fprintf (stderr, _("Cannot verify the SELinux user\n"));
ret = 1;
goto done;
}
if (0 == exists) {
fprintf (stderr,
_("Login mapping for %s is defined in policy, cannot be deleted\n"),
login_name);
ret = 0; /* Login mapping defined in policy can't be deleted */
goto done;
}
ret = semanage_seuser_del_local (handle, key);
if (ret != 0) {
fprintf (stderr,
_("Could not delete login mapping for %s"),
login_name);
ret = 1;
goto done;
}
ret = semanage_commit (handle);
if (ret < 0) {
fprintf (stderr, _("Cannot commit SELinux transaction\n"));
ret = 1;
goto done;
}
ret = 0;
done:
semanage_handle_destroy (handle);
return ret;
}
#else /* !WITH_SELINUX */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !WITH_SELINUX */
-154
View File
@@ -1,154 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <stdio.h>
#include <sys/types.h>
#include <grp.h>
#include "defines.h"
#include "prototypes.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 (('\0' != *s) && (',' != *s)) {
s++;
}
if ('\0' != *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);
cp = strrchr (grpbuf, '\n');
if (NULL != cp) {
*cp = '\0';
}
for (cp = grpbuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) {
grpfields[i] = cp;
cp = strchr (cp, ':');
if (NULL != cp) {
*cp = '\0';
cp++;
}
}
if (i < (NFIELDS - 1) || *grpfields[2] == '\0') {
return (struct group *) 0;
}
grent.gr_name = grpfields[0];
grent.gr_passwd = grpfields[1];
if (get_gid (grpfields[2], &grent.gr_gid) == 0) {
return (struct group *) 0;
}
grent.gr_mem = list (grpfields[3]);
if (NULL == grent.gr_mem) {
return (struct group *) 0; /* out of memory */
}
return &grent;
}
-122
View File
@@ -1,122 +0,0 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include <sys/types.h>
#include "defines.h"
#include <stdio.h>
#include <pwd.h>
#include "prototypes.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 *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) && (NULL != cp); i++) {
fields[i] = cp;
while (('\0' != *cp) && (':' != *cp)) {
cp++;
}
if ('\0' != *cp) {
*cp = '\0';
cp++;
} else {
cp = NULL;
}
}
/*
* There must be exactly NFIELDS colon separated fields or
* the entry is invalid. Also, the UID and GID must be non-blank.
*/
if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
return NULL;
/*
* 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 (get_uid (fields[2], &pwent.pw_uid) == 0) {
return NULL;
}
if (get_gid (fields[3], &pwent.pw_gid) == 0) {
return NULL;
}
pwent.pw_gecos = fields[4];
pwent.pw_dir = fields[5];
pwent.pw_shell = fields[6];
return &pwent;
}
-208
View File
@@ -1,208 +0,0 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#ifndef HAVE_SGETSPENT
#ident "$Id$"
#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);
cp = strrchr (spwbuf, '\n');
if (NULL != cp) {
*cp = '\0';
}
/*
* Tokenize the string into colon separated fields. Allow up to
* FIELDS different fields.
*/
for (cp = spwbuf, i = 0; ('\0' != *cp) && (i < FIELDS); i++) {
fields[i] = cp;
while (('\0' != *cp) && (':' != *cp)) {
cp++;
}
if ('\0' != *cp) {
*cp = '\0';
cp++;
}
}
if (i == (FIELDS - 1)) {
fields[i++] = cp;
}
if ( ((NULL != cp) && ('\0' != *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 (fields[2][0] == '\0') {
spwd.sp_lstchg = -1;
} else if ( (getlong (fields[2], &spwd.sp_lstchg) == 0)
|| (spwd.sp_lstchg < 0)) {
return 0;
}
/*
* Get the minimum period between password changes.
*/
if (fields[3][0] == '\0') {
spwd.sp_min = -1;
} else if ( (getlong (fields[3], &spwd.sp_min) == 0)
|| (spwd.sp_min < 0)) {
return 0;
}
/*
* Get the maximum number of days a password is valid.
*/
if (fields[4][0] == '\0') {
spwd.sp_max = -1;
} else if ( (getlong (fields[4], &spwd.sp_max) == 0)
|| (spwd.sp_max < 0)) {
return 0;
}
/*
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
* formatted file), initialize the other field members to -1.
*/
if (i == OFIELDS) {
spwd.sp_warn = -1;
spwd.sp_inact = -1;
spwd.sp_expire = -1;
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
return &spwd;
}
/*
* Get the number of days of password expiry warning.
*/
if (fields[5][0] == '\0') {
spwd.sp_warn = -1;
} else if ( (getlong (fields[5], &spwd.sp_warn) == 0)
|| (spwd.sp_warn < 0)) {
return 0;
}
/*
* Get the number of days of inactivity before an account is
* disabled.
*/
if (fields[6][0] == '\0') {
spwd.sp_inact = -1;
} else if ( (getlong (fields[6], &spwd.sp_inact) == 0)
|| (spwd.sp_inact < 0)) {
return 0;
}
/*
* Get the number of days after the epoch before the account is
* set to expire.
*/
if (fields[7][0] == '\0') {
spwd.sp_expire = -1;
} else if ( (getlong (fields[7], &spwd.sp_expire) == 0)
|| (spwd.sp_expire < 0)) {
return 0;
}
/*
* This field is reserved for future use. But it isn't supposed
* to have anything other than a valid integer in it.
*/
if (fields[8][0] == '\0') {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else if (getlong (fields[8], &spwd.sp_flag) == 0) {
/* FIXME: add a getulong function */
return 0;
}
return (&spwd);
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif
-327
View File
@@ -1,327 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2013, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ifdef SHADOWGRP
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include "commonio.h"
#include "sgroupio.h"
/*@null@*/ /*@only@*/struct sgrp *__sgr_dup (const struct sgrp *sgent)
{
struct sgrp *sg;
int i;
sg = (struct sgrp *) malloc (sizeof *sg);
if (NULL == sg) {
return NULL;
}
/* Do the same as the other _dup function, even if we know the
* structure. */
memset (sg, 0, sizeof *sg);
/*@-mustfreeonly@*/
sg->sg_name = strdup (sgent->sg_name);
/*@=mustfreeonly@*/
if (NULL == sg->sg_name) {
free (sg);
return NULL;
}
/*@-mustfreeonly@*/
sg->sg_passwd = strdup (sgent->sg_passwd);
/*@=mustfreeonly@*/
if (NULL == sg->sg_passwd) {
free (sg->sg_name);
free (sg);
return NULL;
}
for (i = 0; NULL != sgent->sg_adm[i]; i++);
/*@-mustfreeonly@*/
sg->sg_adm = (char **) malloc ((i + 1) * sizeof (char *));
/*@=mustfreeonly@*/
if (NULL == sg->sg_adm) {
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
}
for (i = 0; NULL != sgent->sg_adm[i]; i++) {
sg->sg_adm[i] = strdup (sgent->sg_adm[i]);
if (NULL == sg->sg_adm[i]) {
for (i = 0; NULL != sg->sg_adm[i]; i++) {
free (sg->sg_adm[i]);
}
free (sg->sg_adm);
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
}
}
sg->sg_adm[i] = NULL;
for (i = 0; NULL != sgent->sg_mem[i]; i++);
/*@-mustfreeonly@*/
sg->sg_mem = (char **) malloc ((i + 1) * sizeof (char *));
/*@=mustfreeonly@*/
if (NULL == sg->sg_mem) {
for (i = 0; NULL != sg->sg_adm[i]; i++) {
free (sg->sg_adm[i]);
}
free (sg->sg_adm);
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
}
for (i = 0; NULL != sgent->sg_mem[i]; i++) {
sg->sg_mem[i] = strdup (sgent->sg_mem[i]);
if (NULL == sg->sg_mem[i]) {
for (i = 0; NULL != sg->sg_mem[i]; i++) {
free (sg->sg_mem[i]);
}
free (sg->sg_mem);
for (i = 0; NULL != sg->sg_adm[i]; i++) {
free (sg->sg_adm[i]);
}
free (sg->sg_adm);
free (sg->sg_passwd);
free (sg->sg_name);
free (sg);
return NULL;
}
}
sg->sg_mem[i] = NULL;
return sg;
}
static /*@null@*/ /*@only@*/void *gshadow_dup (const void *ent)
{
const struct sgrp *sg = ent;
return __sgr_dup (sg);
}
static void gshadow_free (/*@out@*/ /*@only@*/void *ent)
{
struct sgrp *sg = ent;
sgr_free (sg);
}
void sgr_free (/*@out@*/ /*@only@*/struct sgrp *sgent)
{
size_t i;
free (sgent->sg_name);
if (NULL != sgent->sg_passwd) {
memzero (sgent->sg_passwd, strlen (sgent->sg_passwd));
free (sgent->sg_passwd);
}
for (i = 0; NULL != sgent->sg_adm[i]; i++) {
free (sgent->sg_adm[i]);
}
free (sgent->sg_adm);
for (i = 0; NULL != sgent->sg_mem[i]; i++) {
free (sgent->sg_mem[i]);
}
free (sgent->sg_mem);
free (sgent);
}
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;
if ( (NULL == sg)
|| (valid_field (sg->sg_name, ":\n") == -1)
|| (valid_field (sg->sg_passwd, ":\n") == -1)) {
return -1;
}
/* FIXME: fail also if sg->sg_adm == NULL ?*/
if (NULL != sg->sg_adm) {
size_t i;
for (i = 0; NULL != sg->sg_adm[i]; i++) {
if (valid_field (sg->sg_adm[i], ",:\n") == -1) {
return -1;
}
}
}
/* FIXME: fail also if sg->sg_mem == NULL ?*/
if (NULL != sg->sg_mem) {
size_t i;
for (i = 0; NULL != sg->sg_mem[i]; i++) {
if (valid_field (sg->sg_mem[i], ",:\n") == -1) {
return -1;
}
}
}
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,
NULL, /* open_hook */
NULL /* close_hook */
};
static struct commonio_db gshadow_db = {
SGROUP_FILE, /* filename */
&gshadow_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
NULL, /* scontext */
#endif
0400, /* st_mode */
0, /* st_uid */
0, /* st_gid */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int sgr_setdbname (const char *filename)
{
return commonio_setname (&gshadow_db, filename);
}
/*@observer@*/const char *sgr_dbname (void)
{
return gshadow_db.filename;
}
bool sgr_file_present (void)
{
if (getdef_bool ("FORCE_SHADOW"))
return true;
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);
}
/*@observer@*/ /*@null@*/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);
}
/*@null@*/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 = true;
}
/*@dependent@*/ /*@null@*/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);
}
/* Sort with respect to group ordering. */
int sgr_sort ()
{
return commonio_sort_wrt (&gshadow_db, __gr_get_db ());
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif
-52
View File
@@ -1,52 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _SGROUPIO_H
#define _SGROUPIO_H
extern int sgr_close (void);
extern bool sgr_file_present (void);
extern /*@observer@*/ /*@null@*/const struct sgrp *sgr_locate (const char *name);
extern int sgr_lock (void);
extern int sgr_setdbname (const char *filename);
extern /*@observer@*/const char *sgr_dbname (void);
extern /*@null@*/const struct sgrp *sgr_next (void);
extern int sgr_open (int mode);
extern int sgr_remove (const char *name);
extern int sgr_rewind (void);
extern int sgr_unlock (void);
extern int sgr_update (const struct sgrp *sg);
extern int sgr_sort (void);
#endif
-557
View File
@@ -1,557 +0,0 @@
/*
* Copyright (c) 1989 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 1998, Marek Michałkiewicz
* Copyright (c) 2003 - 2005, Tomasz Kłoczko
* Copyright (c) 2009 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
/* Newer versions of Linux libc already have shadow support. */
#ifndef HAVE_GETSPNAM
#ident "$Id$"
#include <sys/types.h>
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#ifdef USE_NIS
static bool nis_used;
static bool nis_ignore;
static enum { native, start, middle, native2 } nis_state;
static bool 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;
#define FIELDS 9
#define OFIELDS 5
#ifdef USE_NIS
/*
* __setspNIS - turn on or off NIS searches
*/
void __setspNIS (bool flag)
{
nis_ignore = !flag;
if (nis_ignore) {
nis_used = false;
}
}
/*
* bind_nis - bind to NIS server
*/
static int bind_nis (void)
{
if (yp_get_default_domain (&nis_domain)) {
return -1;
}
nis_bound = true;
return 0;
}
#endif
/*
* setspent - initialize access to shadow text and DBM files
*/
void setspent (void)
{
if (NULL != shadow) {
rewind (shadow);
}else {
shadow = fopen (SHADOW_FILE, "r");
}
#ifdef USE_NIS
nis_state = native;
#endif
}
/*
* endspent - terminate access to shadow text and DBM files
*/
void endspent (void)
{
if (NULL != shadow) {
(void) fclose (shadow);
}
shadow = (FILE *) 0;
}
/*
* my_sgetspent - convert string in shadow file format to (struct spwd *)
*/
static struct spwd *my_sgetspent (const char *string)
{
static char spwbuf[BUFSIZ];
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;
strcpy (spwbuf, string);
cp = strrchr (spwbuf, '\n');
if (NULL != cp)
*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';
}
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 = true;
}
#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 (fields[2][0] == '\0') {
spwd.sp_lstchg = -1;
} else {
if (getlong (fields[2], &spwd.sp_lstchg) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_lstchg = -1;
} else
#endif
return 0;
} else if (spwd.sp_lstchg < 0) {
return 0;
}
}
/*
* Get the minimum period between password changes.
*/
if (fields[3][0] == '\0') {
spwd.sp_min = -1;
} else {
if (getlong (fields[3], &spwd.sp_min) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_min = -1;
} else
#endif
{
return 0;
}
} else if (spwd.sp_min < 0) {
return 0;
}
}
/*
* Get the maximum number of days a password is valid.
*/
if (fields[4][0] == '\0') {
spwd.sp_max = -1;
} else {
if (getlong (fields[4], &spwd.sp_max) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_max = -1;
} else
#endif
return 0;
} else if (spwd.sp_max < 0) {
return 0;
}
}
/*
* If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
* formatted file), initialize the other field members to -1.
*/
if (i == OFIELDS) {
spwd.sp_warn = -1;
spwd.sp_inact = -1;
spwd.sp_expire = -1;
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
return &spwd;
}
/*
* Get the number of days of password expiry warning.
*/
if (fields[5][0] == '\0') {
spwd.sp_warn = -1;
} else {
if (getlong (fields[5], &spwd.sp_warn) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_warn = -1;
} else
#endif
{
return 0;
}
} else if (spwd.sp_warn < 0) {
return 0;
}
}
/*
* Get the number of days of inactivity before an account is
* disabled.
*/
if (fields[6][0] == '\0') {
spwd.sp_inact = -1;
} else {
if (getlong (fields[6], &spwd.sp_inact) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_inact = -1;
} else
#endif
{
return 0;
}
} else if (spwd.sp_inact < 0) {
return 0;
}
}
/*
* Get the number of days after the epoch before the account is
* set to expire.
*/
if (fields[7][0] == '\0') {
spwd.sp_expire = -1;
} else {
if (getlong (fields[7], &spwd.sp_expire) == 0) {
#ifdef USE_NIS
if (nis_used) {
spwd.sp_expire = -1;
} else
#endif
{
return 0;
}
} else if (spwd.sp_expire < 0) {
return 0;
}
}
/*
* This field is reserved for future use. But it isn't supposed
* to have anything other than a valid integer in it.
*/
if (fields[8][0] == '\0') {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else {
if (getlong (fields[8], &spwd.sp_flag) == 0) {
/* FIXME: add a getulong function */
#ifdef USE_NIS
if (nis_used) {
spwd.sp_flag = SHADOW_SP_FLAG_UNSET;
} else
#endif
{
return 0;
}
} else if (spwd.sp_flag < 0) {
return 0;
}
}
return (&spwd);
}
/*
* fgetspent - get an entry from a /etc/shadow formatted stream
*/
struct spwd *fgetspent (FILE * fp)
{
char buf[BUFSIZ];
char *cp;
if (NULL == fp) {
return (0);
}
#ifdef USE_NIS
while (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
#else
if (fgets (buf, (int) sizeof buf, fp) != (char *) 0)
#endif
{
cp = strchr (buf, '\n');
if (NULL != cp) {
*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 (NULL == 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.
*/
val = fgetspent (shadow);
if (NULL == val)
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) {
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 USE_NIS
char buf[BUFSIZ];
static char save_name[16];
bool nis_disabled = false;
#endif
setspent ();
#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) {
cp = strchr (nis_val, '\n');
if (NULL != cp) {
*cp = '\0';
}
nis_state = middle;
sp = my_sgetspent (nis_val);
if (NULL != sp) {
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 = true;
nis_disabled = true;
}
#endif
while ((sp = getspent ()) != (struct spwd *) 0) {
if (strcmp (name, sp->sp_namp) == 0) {
break;
}
}
#ifdef USE_NIS
if (nis_disabled) {
nis_ignore = false;
}
#endif
endspent ();
return (sp);
}
#else
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif
-266
View File
@@ -1,266 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2009, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <shadow.h>
#include <stdio.h>
#include "commonio.h"
#include "shadowio.h"
#ifdef WITH_TCB
#include <tcb.h>
#include "tcbfuncs.h"
#endif /* WITH_TCB */
static /*@null@*/ /*@only@*/void *shadow_dup (const void *ent)
{
const struct spwd *sp = ent;
return __spw_dup (sp);
}
static void shadow_free (/*@out@*//*@only@*/void *ent)
{
struct spwd *sp = ent;
spw_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;
if ( (NULL == sp)
|| (valid_field (sp->sp_namp, ":\n") == -1)
|| (valid_field (sp->sp_pwdp, ":\n") == -1)) {
return -1;
}
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,
NULL, /* open_hook */
NULL /* close_hook */
};
static struct commonio_db shadow_db = {
SHADOW_FILE, /* filename */
&shadow_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
NULL, /* scontext */
#endif /* WITH_SELINUX */
0400, /* st_mode */
0, /* st_uid */
0, /* st_gid */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int spw_setdbname (const char *filename)
{
return commonio_setname (&shadow_db, filename);
}
/*@observer@*/const char *spw_dbname (void)
{
return shadow_db.filename;
}
bool spw_file_present (void)
{
if (getdef_bool ("FORCE_SHADOW"))
return true;
return commonio_present (&shadow_db);
}
int spw_lock (void)
{
#ifdef WITH_TCB
int retval = 0;
if (!getdef_bool ("USE_TCB")) {
#endif /* WITH_TCB */
return commonio_lock (&shadow_db);
#ifdef WITH_TCB
}
if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
return 0;
}
if (lckpwdf_tcb (shadow_db.filename) == 0) {
shadow_db.locked = 1;
retval = 1;
}
if (shadowtcb_gain_priv () == SHADOWTCB_FAILURE) {
return 0;
}
return retval;
#endif /* WITH_TCB */
}
int spw_open (int mode)
{
int retval = 0;
#ifdef WITH_TCB
bool use_tcb = getdef_bool ("USE_TCB");
if (use_tcb && (shadowtcb_drop_priv () == SHADOWTCB_FAILURE)) {
return 0;
}
#endif /* WITH_TCB */
retval = commonio_open (&shadow_db, mode);
#ifdef WITH_TCB
if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) {
return 0;
}
#endif /* WITH_TCB */
return retval;
}
/*@observer@*/ /*@null@*/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);
}
/*@observer@*/ /*@null@*/const struct spwd *spw_next (void)
{
return commonio_next (&shadow_db);
}
int spw_close (void)
{
int retval = 0;
#ifdef WITH_TCB
bool use_tcb = getdef_bool ("USE_TCB");
if (use_tcb && (shadowtcb_drop_priv () == SHADOWTCB_FAILURE)) {
return 0;
}
#endif /* WITH_TCB */
retval = commonio_close (&shadow_db);
#ifdef WITH_TCB
if (use_tcb && (shadowtcb_gain_priv () == SHADOWTCB_FAILURE)) {
return 0;
}
#endif /* WITH_TCB */
return retval;
}
int spw_unlock (void)
{
#ifdef WITH_TCB
int retval = 0;
if (!getdef_bool ("USE_TCB")) {
#endif /* WITH_TCB */
return commonio_unlock (&shadow_db);
#ifdef WITH_TCB
}
if (shadowtcb_drop_priv () == SHADOWTCB_FAILURE) {
return 0;
}
if (ulckpwdf_tcb () == 0) {
shadow_db.locked = 0;
retval = 1;
}
if (shadowtcb_gain_priv () == SHADOWTCB_FAILURE) {
return 0;
}
return retval;
#endif /* WITH_TCB */
}
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);
}
/* Sort with respect to passwd ordering. */
int spw_sort ()
{
#ifdef WITH_TCB
if (getdef_bool ("USE_TCB")) {
return 0;
}
#endif /* WITH_TCB */
return commonio_sort_wrt (&shadow_db, __pw_get_db ());
}
-53
View File
@@ -1,53 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 - 2005, Tomasz Kłoczko
* Copyright (c) 2008 , Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* $Id$ */
#ifndef _SHADOWIO_H
#define _SHADOWIO_H
#include "defines.h"
extern int spw_close (void);
extern bool spw_file_present (void);
extern /*@observer@*/ /*@null@*/const struct spwd *spw_locate (const char *name);
extern int spw_lock (void);
extern int spw_setdbname (const char *filename);
extern /*@observer@*/const char *spw_dbname (void);
extern /*@observer@*/ /*@null@*/const struct spwd *spw_next (void);
extern int spw_open (int mode);
extern int spw_remove (const char *name);
extern int spw_rewind (void);
extern int spw_unlock (void);
extern int spw_update (const struct spwd *sp);
extern int spw_sort (void);
#endif
-89
View File
@@ -1,89 +0,0 @@
/*
* Copyright (c) 1990 - 1994, Julianne Frances Haugh
* Copyright (c) 1996 - 2000, Marek Michałkiewicz
* Copyright (c) 2001 , Michał Moskal
* Copyright (c) 2005 , Tomasz Kłoczko
* Copyright (c) 2007 - 2013, Nicolas François
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#ident "$Id$"
#include "prototypes.h"
#include "defines.h"
#include <shadow.h>
#include <stdio.h>
#include "shadowio.h"
/*@null@*/ /*@only@*/struct spwd *__spw_dup (const struct spwd *spent)
{
struct spwd *sp;
sp = (struct spwd *) malloc (sizeof *sp);
if (NULL == sp) {
return NULL;
}
/* The libc might define other fields. They won't be copied. */
memset (sp, 0, sizeof *sp);
sp->sp_lstchg = spent->sp_lstchg;
sp->sp_min = spent->sp_min;
sp->sp_max = spent->sp_max;
sp->sp_warn = spent->sp_warn;
sp->sp_inact = spent->sp_inact;
sp->sp_expire = spent->sp_expire;
sp->sp_flag = spent->sp_flag;
/*@-mustfreeonly@*/
sp->sp_namp = strdup (spent->sp_namp);
/*@=mustfreeonly@*/
if (NULL == sp->sp_namp) {
free(sp);
return NULL;
}
/*@-mustfreeonly@*/
sp->sp_pwdp = strdup (spent->sp_pwdp);
/*@=mustfreeonly@*/
if (NULL == sp->sp_pwdp) {
free(sp->sp_namp);
free(sp);
return NULL;
}
return sp;
}
void spw_free (/*@out@*/ /*@only@*/struct spwd *spent)
{
free (spent->sp_namp);
if (NULL != spent->sp_pwdp) {
memzero (spent->sp_pwdp, strlen (spent->sp_pwdp));
free (spent->sp_pwdp);
}
free (spent);
}
-82
View File
@@ -1,82 +0,0 @@
/*
* Copyright (c) 2011 , Jonathan Nieder
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the copyright holders or contributors may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include "exitcodes.h"
#include "prototypes.h"
int run_command (const char *cmd, const char *argv[],
/*@null@*/const char *envp[], /*@out@*/int *status)
{
pid_t pid, wpid;
if (NULL == envp) {
envp = (const char **)environ;
}
(void) fflush (stdout);
(void) fflush (stderr);
pid = fork ();
if (0 == pid) {
(void) execve (cmd, (char * const *) argv,
(char * const *) envp);
if (ENOENT == errno) {
exit (E_CMD_NOTFOUND);
}
fprintf (stderr, "%s: cannot execute %s: %s\n",
Prog, cmd, strerror (errno));
exit (E_CMD_NOEXEC);
} else if ((pid_t)-1 == pid) {
fprintf (stderr, "%s: cannot execute %s: %s\n",
Prog, cmd, strerror (errno));
return -1;
}
do {
wpid = waitpid (pid, status, 0);
} while ( ((pid_t)-1 == wpid && errno == EINTR)
|| (wpid != pid));
if ((pid_t)-1 == wpid) {
fprintf (stderr, "%s: waitpid (status: %d): %s\n",
Prog, *status, strerror (errno));
return -1;
}
return 0;
}
-701
View File
@@ -1,701 +0,0 @@
/*
* Copyright (c) 2012 - Eric Biederman
*/
#include <config.h>
#ifdef ENABLE_SUBIDS
#include "prototypes.h"
#include "defines.h"
#include <stdio.h>
#include "commonio.h"
#include "subordinateio.h"
#include <sys/types.h>
#include <pwd.h>
struct subordinate_range {
const char *owner;
unsigned long start;
unsigned long count;
};
#define NFIELDS 3
/*
* subordinate_dup: create a duplicate range
*
* @ent: a pointer to a subordinate_range struct
*
* Returns a pointer to a newly allocated duplicate subordinate_range struct
* or NULL on failure
*/
static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
{
const struct subordinate_range *rangeent = ent;
struct subordinate_range *range;
range = (struct subordinate_range *) malloc (sizeof *range);
if (NULL == range) {
return NULL;
}
range->owner = strdup (rangeent->owner);
if (NULL == range->owner) {
free(range);
return NULL;
}
range->start = rangeent->start;
range->count = rangeent->count;
return range;
}
/*
* subordinate_free: free a subordinate_range struct
*
* @ent: pointer to a subordinate_range struct to free.
*/
static void subordinate_free (/*@out@*/ /*@only@*/void *ent)
{
struct subordinate_range *rangeent = ent;
free ((void *)(rangeent->owner));
free (rangeent);
}
/*
* subordinate_parse:
*
* @line: a line to parse
*
* Returns a pointer to a subordinate_range struct representing the values
* in @line, or NULL on failure. Note that the returned value should not
* be freed by the caller.
*/
static void *subordinate_parse (const char *line)
{
static struct subordinate_range range;
static char rangebuf[1024];
int i;
char *cp;
char *fields[NFIELDS];
/*
* Copy the string to a temporary buffer so the substrings can
* be modified to be NULL terminated.
*/
if (strlen (line) >= sizeof rangebuf)
return NULL; /* fail if too long */
strcpy (rangebuf, line);
/*
* Save a pointer to the start of each colon separated
* field. The fields are converted into NUL terminated strings.
*/
for (cp = rangebuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) {
fields[i] = cp;
while (('\0' != *cp) && (':' != *cp)) {
cp++;
}
if ('\0' != *cp) {
*cp = '\0';
cp++;
} else {
cp = NULL;
}
}
/*
* There must be exactly NFIELDS colon separated fields or
* the entry is invalid. Also, fields must be non-blank.
*/
if (i != NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0')
return NULL;
range.owner = fields[0];
if (getulong (fields[1], &range.start) == 0)
return NULL;
if (getulong (fields[2], &range.count) == 0)
return NULL;
return &range;
}
/*
* subordinate_put: print a subordinate_range value to a file
*
* @ent: a pointer to a subordinate_range struct to print out.
* @file: file to which to print.
*
* Returns 0 on success, -1 on error.
*/
static int subordinate_put (const void *ent, FILE * file)
{
const struct subordinate_range *range = ent;
return fprintf(file, "%s:%lu:%lu\n",
range->owner,
range->start,
range->count) < 0 ? -1 : 0;
}
static struct commonio_ops subordinate_ops = {
subordinate_dup, /* dup */
subordinate_free, /* free */
NULL, /* getname */
subordinate_parse, /* parse */
subordinate_put, /* put */
fgets, /* fgets */
fputs, /* fputs */
NULL, /* open_hook */
NULL, /* close_hook */
};
static /*@observer@*/ /*@null*/const struct subordinate_range *subordinate_next(struct commonio_db *db)
{
return (const struct subordinate_range *)commonio_next (db);
}
/*
* range_exists: Check whether @owner owns any ranges
*
* @db: database to query
* @owner: owner being queried
*
* Returns true if @owner owns any subuid ranges, false otherwise.
*/
static const bool range_exists(struct commonio_db *db, const char *owner)
{
const struct subordinate_range *range;
commonio_rewind(db);
while ((range = commonio_next(db)) != NULL) {
if (0 == strcmp(range->owner, owner))
return true;
}
return false;
}
/*
* find_range: find a range which @owner is authorized to use which includes
* subuid @val.
*
* @db: database to query
* @owner: owning uid being queuried
* @val: subuid being searched for.
*
* Returns a range of subuids belonging to @owner and including the subuid
* @val, or NULL if no such range exists.
*/
static const struct subordinate_range *find_range(struct commonio_db *db,
const char *owner, unsigned long val)
{
const struct subordinate_range *range;
/*
* Search for exact username/group specification
*
* This is the original method - go fast through the db, doing only
* exact username/group string comparison. Therefore we leave it as-is
* for the time being, in order to keep it equally fast as it was
* before.
*/
commonio_rewind(db);
while ((range = commonio_next(db)) != NULL) {
unsigned long first = range->start;
unsigned long last = first + range->count - 1;
if (0 != strcmp(range->owner, owner))
continue;
if ((val >= first) && (val <= last))
return range;
}
/*
* We only do special handling for these two files
*/
if ((0 != strcmp(db->filename, "/etc/subuid")) && (0 != strcmp(db->filename, "/etc/subgid")))
return NULL;
/*
* Search loop above did not produce any result. Let's rerun it,
* but this time try to matcha actual UIDs. The first entry that
* matches is considered a success.
* (It may be specified as literal UID or as another username which
* has the same UID as the username we are looking for.)
*/
struct passwd *pwd;
uid_t owner_uid;
char owner_uid_string[33] = "";
/* Get UID of the username we are looking for */
pwd = getpwnam(owner);
if (NULL == pwd) {
/* Username not defined in /etc/passwd, or error occured during lookup */
return NULL;
}
owner_uid = pwd->pw_uid;
sprintf(owner_uid_string, "%lu", (unsigned long int)owner_uid);
commonio_rewind(db);
while ((range = commonio_next(db)) != NULL) {
unsigned long first = range->start;
unsigned long last = first + range->count - 1;
/* For performance reasons check range before using getpwnam() */
if ((val < first) || (val > last)) {
continue;
}
/*
* Range matches. Check if range owner is specified
* as numeric UID and if it matches.
*/
if (0 == strcmp(range->owner, owner_uid_string)) {
return range;
}
/*
* Ok, this range owner is not specified as numeric UID
* we are looking for. It may be specified as another
* UID or as a literal username.
*
* If specified as another UID, the call to getpwnam()
* will return NULL.
*
* If specified as literal username, we will get its
* UID and compare that to UID we are looking for.
*/
const struct passwd *range_owner_pwd;
range_owner_pwd = getpwnam(range->owner);
if (NULL == range_owner_pwd) {
continue;
}
if (owner_uid == range_owner_pwd->pw_uid) {
return range;
}
}
return NULL;
}
/*
* have_range: check whether @owner is authorized to use the range
* (@start .. @start+@count-1).
* @db: database to check
* @owner: owning uid being queried
* @start: start of range
* @count: number of uids in range
*
* Returns true if @owner is authorized to use the range, false otherwise.
*/
static bool have_range(struct commonio_db *db,
const char *owner, unsigned long start, unsigned long count)
{
const struct subordinate_range *range;
unsigned long end;
if (count == 0)
return false;
end = start + count - 1;
range = find_range (db, owner, start);
while (range) {
unsigned long last;
last = range->start + range->count - 1;
if (last >= (start + count - 1))
return true;
count = end - last;
start = last + 1;
range = find_range(db, owner, start);
}
return false;
}
/*
* subordinate_range_cmp: compare uid ranges
*
* @p1: pointer to a commonio_entry struct to compare
* @p2: pointer to second commonio_entry struct to compare
*
* Returns 0 if the entries are the same. Otherwise return -1
* if the range in p1 is lower than that in p2, or (if the ranges are
* equal) if the owning uid in p1 is lower than p2's. Return 1 if p1's
* range or owning uid is great than p2's.
*/
static int subordinate_range_cmp (const void *p1, const void *p2)
{
struct subordinate_range *range1, *range2;
if ((*(struct commonio_entry **) p1)->eptr == NULL)
return 1;
if ((*(struct commonio_entry **) p2)->eptr == NULL)
return -1;
range1 = ((struct subordinate_range *) (*(struct commonio_entry **) p1)->eptr);
range2 = ((struct subordinate_range *) (*(struct commonio_entry **) p2)->eptr);
if (range1->start < range2->start)
return -1;
else if (range1->start > range2->start)
return 1;
else if (range1->count < range2->count)
return -1;
else if (range1->count > range2->count)
return 1;
else
return strcmp(range1->owner, range2->owner);
}
/*
* find_free_range: find an unused consecutive sequence of ids to allocate
* to a user.
* @db: database to search
* @min: the first uid in the range to find
* @max: the highest uid to find
* @count: the number of uids needed
*
* Return the lowest new uid, or ULONG_MAX on failure.
*/
static unsigned long find_free_range(struct commonio_db *db,
unsigned long min, unsigned long max,
unsigned long count)
{
const struct subordinate_range *range;
unsigned long low, high;
/* When given invalid parameters fail */
if ((count == 0) || (max < min))
goto fail;
/* Sort by range then by owner */
commonio_sort (db, subordinate_range_cmp);
commonio_rewind(db);
low = min;
while ((range = commonio_next(db)) != NULL) {
unsigned long first = range->start;
unsigned long last = first + range->count - 1;
/* Find the top end of the hole before this range */
high = first;
/* Don't allocate IDs after max (included) */
if (high > max + 1) {
high = max + 1;
}
/* Is the hole before this range large enough? */
if ((high > low) && ((high - low) >= count))
return low;
/* Compute the low end of the next hole */
if (low < (last + 1))
low = last + 1;
if (low > max)
goto fail;
}
/* Is the remaining unclaimed area large enough? */
if (((max - low) + 1) >= count)
return low;
fail:
return ULONG_MAX;
}
/*
* add_range: add a subuid range to an owning uid's list of authorized
* subuids.
* @db: database to which to add
* @owner: uid which owns the subuid
* @start: the first uid in the owned range
* @count: the number of uids in the range
*
* Return 1 if the range is already present or on succcess. On error
* return 0 and set errno appropriately.
*/
static int add_range(struct commonio_db *db,
const char *owner, unsigned long start, unsigned long count)
{
struct subordinate_range range;
range.owner = owner;
range.start = start;
range.count = count;
/* See if the range is already present */
if (have_range(db, owner, start, count))
return 1;
/* Otherwise append the range */
return commonio_append(db, &range);
}
/*
* remove_range: remove a range of subuids from an owning uid's list
* of authorized subuids.
* @db: database to work on
* @owner: owning uid whose range is being removed
* @start: start of the range to be removed
* @count: number of uids in the range.
*
* Returns 0 on failure, 1 on success. Failure means that we needed to
* create a new range to represent the new limits, and failed doing so.
*/
static int remove_range (struct commonio_db *db,
const char *owner,
unsigned long start, unsigned long count)
{
struct commonio_entry *ent;
unsigned long end;
if (count == 0) {
return 1;
}
end = start + count - 1;
for (ent = db->head; NULL != ent; ent = ent->next) {
struct subordinate_range *range = ent->eptr;
unsigned long first;
unsigned long last;
/* Skip unparsed entries */
if (NULL == range) {
continue;
}
first = range->start;
last = first + range->count - 1;
/* Skip entries with a different owner */
if (0 != strcmp (range->owner, owner)) {
continue;
}
/* Skip entries outside of the range to remove */
if ((end < first) || (start > last)) {
continue;
}
if (start <= first) {
if (end >= last) {
/* to be removed: [start, end]
* range: [first, last] */
/* entry completely contained in the
* range to remove */
commonio_del_entry (db, ent);
} else {
/* to be removed: [start, end]
* range: [first, last] */
/* Remove only the start of the entry */
range->start = end + 1;
range->count = (last - range->start) + 1;
ent->changed = true;
db->changed = true;
}
} else {
if (end >= last) {
/* to be removed: [start, end]
* range: [first, last] */
/* Remove only the end of the entry */
range->count = start - range->start;
ent->changed = true;
db->changed = true;
} else {
/* to be removed: [start, end]
* range: [first, last] */
/* Remove the middle of the range
* This requires to create a new range */
struct subordinate_range tail;
tail.owner = range->owner;
tail.start = end + 1;
tail.count = (last - tail.start) + 1;
if (commonio_append (db, &tail) == 0) {
return 0;
}
range->count = start - range->start;
ent->changed = true;
db->changed = true;
}
}
}
return 1;
}
static struct commonio_db subordinate_uid_db = {
"/etc/subuid", /* filename */
&subordinate_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
NULL, /* scontext */
#endif
0644, /* st_mode */
0, /* st_uid */
0, /* st_gid */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int sub_uid_setdbname (const char *filename)
{
return commonio_setname (&subordinate_uid_db, filename);
}
/*@observer@*/const char *sub_uid_dbname (void)
{
return subordinate_uid_db.filename;
}
bool sub_uid_file_present (void)
{
return commonio_present (&subordinate_uid_db);
}
int sub_uid_lock (void)
{
return commonio_lock (&subordinate_uid_db);
}
int sub_uid_open (int mode)
{
return commonio_open (&subordinate_uid_db, mode);
}
bool sub_uid_assigned(const char *owner)
{
return range_exists (&subordinate_uid_db, owner);
}
bool have_sub_uids(const char *owner, uid_t start, unsigned long count)
{
return have_range (&subordinate_uid_db, owner, start, count);
}
int sub_uid_add (const char *owner, uid_t start, unsigned long count)
{
return add_range (&subordinate_uid_db, owner, start, count);
}
int sub_uid_remove (const char *owner, uid_t start, unsigned long count)
{
return remove_range (&subordinate_uid_db, owner, start, count);
}
int sub_uid_close (void)
{
return commonio_close (&subordinate_uid_db);
}
int sub_uid_unlock (void)
{
return commonio_unlock (&subordinate_uid_db);
}
uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count)
{
unsigned long start;
start = find_free_range (&subordinate_uid_db, min, max, count);
return start == ULONG_MAX ? (uid_t) -1 : start;
}
static struct commonio_db subordinate_gid_db = {
"/etc/subgid", /* filename */
&subordinate_ops, /* ops */
NULL, /* fp */
#ifdef WITH_SELINUX
NULL, /* scontext */
#endif
0644, /* st_mode */
0, /* st_uid */
0, /* st_gid */
NULL, /* head */
NULL, /* tail */
NULL, /* cursor */
false, /* changed */
false, /* isopen */
false, /* locked */
false /* readonly */
};
int sub_gid_setdbname (const char *filename)
{
return commonio_setname (&subordinate_gid_db, filename);
}
/*@observer@*/const char *sub_gid_dbname (void)
{
return subordinate_gid_db.filename;
}
bool sub_gid_file_present (void)
{
return commonio_present (&subordinate_gid_db);
}
int sub_gid_lock (void)
{
return commonio_lock (&subordinate_gid_db);
}
int sub_gid_open (int mode)
{
return commonio_open (&subordinate_gid_db, mode);
}
bool have_sub_gids(const char *owner, gid_t start, unsigned long count)
{
return have_range(&subordinate_gid_db, owner, start, count);
}
bool sub_gid_assigned(const char *owner)
{
return range_exists (&subordinate_gid_db, owner);
}
int sub_gid_add (const char *owner, gid_t start, unsigned long count)
{
return add_range (&subordinate_gid_db, owner, start, count);
}
int sub_gid_remove (const char *owner, gid_t start, unsigned long count)
{
return remove_range (&subordinate_gid_db, owner, start, count);
}
int sub_gid_close (void)
{
return commonio_close (&subordinate_gid_db);
}
int sub_gid_unlock (void)
{
return commonio_unlock (&subordinate_gid_db);
}
gid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count)
{
unsigned long start;
start = find_free_range (&subordinate_gid_db, min, max, count);
return start == ULONG_MAX ? (gid_t) -1 : start;
}
#else /* !ENABLE_SUBIDS */
extern int errno; /* warning: ANSI C forbids an empty source file */
#endif /* !ENABLE_SUBIDS */
-41
View File
@@ -1,41 +0,0 @@
/*
* Copyright (c) 2012- Eric W. Biederman
*/
#ifndef _SUBORDINATEIO_H
#define _SUBORDINATEIO_H
#include <config.h>
#ifdef ENABLE_SUBIDS
#include <sys/types.h>
extern int sub_uid_close(void);
extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count);
extern bool sub_uid_file_present (void);
extern bool sub_uid_assigned(const char *owner);
extern int sub_uid_lock (void);
extern int sub_uid_setdbname (const char *filename);
extern /*@observer@*/const char *sub_uid_dbname (void);
extern int sub_uid_open (int mode);
extern int sub_uid_unlock (void);
extern int sub_uid_add (const char *owner, uid_t start, unsigned long count);
extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count);
extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count);
extern int sub_gid_close(void);
extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count);
extern bool sub_gid_file_present (void);
extern bool sub_gid_assigned(const char *owner);
extern int sub_gid_lock (void);
extern int sub_gid_setdbname (const char *filename);
extern /*@observer@*/const char *sub_gid_dbname (void);
extern int sub_gid_open (int mode);
extern int sub_gid_unlock (void);
extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
#endif /* ENABLE_SUBIDS */
#endif
-613
View File
@@ -1,613 +0,0 @@
/*
* Copyright (c) 2001 Rafal Wojtczuk, Solar Designer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <tcb.h>
#include <unistd.h>
#include "config.h"
#include "defines.h"
#include "prototypes.h"
#include "getdef.h"
#include "shadowio.h"
#include "tcbfuncs.h"
#define SHADOWTCB_HASH_BY 1000
#define SHADOWTCB_LOCK_SUFFIX ".lock"
static /*@null@*//*@only@*/char *stored_tcb_user = NULL;
shadowtcb_status shadowtcb_drop_priv (void)
{
if (!getdef_bool ("USE_TCB")) {
return SHADOWTCB_SUCCESS;
}
if (NULL != stored_tcb_user) {
if (tcb_drop_priv (stored_tcb_user) == 0) {
return SHADOWTCB_SUCCESS;
}
}
return SHADOWTCB_FAILURE;
}
shadowtcb_status shadowtcb_gain_priv (void)
{
if (!getdef_bool ("USE_TCB")) {
return SHADOWTCB_SUCCESS;
}
return (tcb_gain_priv () == 0) ? SHADOWTCB_SUCCESS : SHADOWTCB_FAILURE;
}
/* In case something goes wrong, we return immediately, not polluting the
* code with free(). All errors are fatal, so the application is expected
* to exit soon.
*/
#define OUT_OF_MEMORY do { \
fprintf (stderr, _("%s: out of memory\n"), Prog); \
(void) fflush (stderr); \
} while (false)
/* Returns user's tcb directory path relative to TCB_DIR. */
static /*@null@*/ char *shadowtcb_path_rel (const char *name, uid_t uid)
{
char *ret;
if (!getdef_bool ("TCB_SYMLINKS") || uid < SHADOWTCB_HASH_BY) {
if (asprintf (&ret, "%s", name) == -1) {
OUT_OF_MEMORY;
return NULL;
}
} else if (uid < SHADOWTCB_HASH_BY * SHADOWTCB_HASH_BY) {
if (asprintf (&ret, ":%dK/%s",
uid / SHADOWTCB_HASH_BY, name) == -1) {
OUT_OF_MEMORY;
return NULL;
}
} else {
if (asprintf (&ret, ":%dM/:%dK/%s",
uid / (SHADOWTCB_HASH_BY * SHADOWTCB_HASH_BY),
(uid % (SHADOWTCB_HASH_BY * SHADOWTCB_HASH_BY)) / SHADOWTCB_HASH_BY,
name) == -1) {
OUT_OF_MEMORY;
return NULL;
}
}
return ret;
}
static /*@null@*/ char *shadowtcb_path_rel_existing (const char *name)
{
char *path, *rval;
struct stat st;
char link[8192];
ssize_t ret;
if (asprintf (&path, TCB_DIR "/%s", name) == -1) {
OUT_OF_MEMORY;
return NULL;
}
if (lstat (path, &st) != 0) {
fprintf (stderr,
_("%s: Cannot stat %s: %s\n"),
Prog, path, strerror (errno));
free (path);
return NULL;
}
if (S_ISDIR (st.st_mode)) {
free (path);
rval = strdup (name);
if (NULL == rval) {
OUT_OF_MEMORY;
return NULL;
}
return rval;
}
if (!S_ISLNK (st.st_mode)) {
fprintf (stderr,
_("%s: %s is neither a directory, nor a symlink.\n"),
Prog, path);
free (path);
return NULL;
}
ret = readlink (path, link, sizeof (link) - 1);
if (-1 == ret) {
fprintf (stderr,
_("%s: Cannot read symbolic link %s: %s\n"),
Prog, path, strerror (errno));
free (path);
return NULL;
}
free (path);
if ((size_t)ret >= sizeof(link) - 1) {
link[sizeof(link) - 1] = '\0';
fprintf (stderr,
_("%s: Suspiciously long symlink: %s\n"),
Prog, link);
return NULL;
}
link[(size_t)ret] = '\0';
rval = strdup (link);
if (NULL == rval) {
OUT_OF_MEMORY;
return NULL;
}
return rval;
}
static /*@null@*/ char *shadowtcb_path (const char *name, uid_t uid)
{
char *ret, *rel;
rel = shadowtcb_path_rel (name, uid);
if (NULL == rel) {
return NULL;
}
if (asprintf (&ret, TCB_DIR "/%s", rel) == -1) {
OUT_OF_MEMORY;
free (rel);
return NULL;
}
free (rel);
return ret;
}
static /*@null@*/ char *shadowtcb_path_existing (const char *name)
{
char *ret, *rel;
rel = shadowtcb_path_rel_existing (name);
if (NULL == rel) {
return NULL;
}
if (asprintf (&ret, TCB_DIR "/%s", rel) == -1) {
OUT_OF_MEMORY;
free (rel);
return NULL;
}
free (rel);
return ret;
}
static shadowtcb_status mkdir_leading (const char *name, uid_t uid)
{
char *ind, *dir, *ptr, *path = shadowtcb_path_rel (name, uid);
struct stat st;
if (NULL == path) {
return SHADOWTCB_FAILURE;
}
ptr = path;
if (stat (TCB_DIR, &st) != 0) {
fprintf (stderr,
_("%s: Cannot stat %s: %s\n"),
Prog, TCB_DIR, strerror (errno));
goto out_free_path;
}
while ((ind = strchr (ptr, '/'))) {
*ind = '\0';
if (asprintf (&dir, TCB_DIR "/%s", path) == -1) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if ((mkdir (dir, 0700) != 0) && (errno != EEXIST)) {
fprintf (stderr,
_("%s: Cannot create directory %s: %s\n"),
Prog, dir, strerror (errno));
goto out_free_dir;
}
if (chown (dir, 0, st.st_gid) != 0) {
fprintf (stderr,
_("%s: Cannot change owner of %s: %s\n"),
Prog, dir, strerror (errno));
goto out_free_dir;
}
if (chmod (dir, 0711) != 0) {
fprintf (stderr,
_("%s: Cannot change mode of %s: %s\n"),
Prog, dir, strerror (errno));
goto out_free_dir;
}
free (dir);
*ind = '/';
ptr = ind + 1;
}
free (path);
return SHADOWTCB_SUCCESS;
out_free_dir:
free (dir);
out_free_path:
free (path);
return SHADOWTCB_FAILURE;
}
static shadowtcb_status unlink_suffs (const char *user)
{
static char *suffs[] = { "+", "-", SHADOWTCB_LOCK_SUFFIX };
char *tmp;
int i;
for (i = 0; i < 3; i++) {
if (asprintf (&tmp, TCB_FMT "%s", user, suffs[i]) == -1) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if ((unlink (tmp) != 0) && (errno != ENOENT)) {
fprintf (stderr,
_("%s: unlink: %s: %s\n"),
Prog, tmp, strerror (errno));
free (tmp);
return SHADOWTCB_FAILURE;
}
free (tmp);
}
return SHADOWTCB_SUCCESS;
}
/* path should be a relative existing tcb directory */
static shadowtcb_status rmdir_leading (char *path)
{
char *ind, *dir;
shadowtcb_status ret = SHADOWTCB_SUCCESS;
while ((ind = strrchr (path, '/'))) {
*ind = '\0';
if (asprintf (&dir, TCB_DIR "/%s", path) == -1) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if (rmdir (dir) != 0) {
if (errno != ENOTEMPTY) {
fprintf (stderr,
_("%s: Cannot remove directory %s: %s\n"),
Prog, dir, strerror (errno));
ret = SHADOWTCB_FAILURE;
}
free (dir);
break;
}
free (dir);
}
return ret;
}
static shadowtcb_status move_dir (const char *user_newname, uid_t user_newid)
{
char *olddir = NULL, *newdir = NULL;
char *real_old_dir = NULL, *real_new_dir = NULL;
char *real_old_dir_rel = NULL, *real_new_dir_rel = NULL;
uid_t old_uid, the_newid;
struct stat oldmode;
shadowtcb_status ret = SHADOWTCB_FAILURE;
if (NULL == stored_tcb_user) {
return SHADOWTCB_FAILURE;
}
if (asprintf (&olddir, TCB_DIR "/%s", stored_tcb_user) == -1) {
goto out_free_nomem;
}
if (stat (olddir, &oldmode) != 0) {
fprintf (stderr,
_("%s: Cannot stat %s: %s\n"),
Prog, olddir, strerror (errno));
goto out_free;
}
old_uid = oldmode.st_uid;
the_newid = (user_newid == -1) ? old_uid : user_newid;
real_old_dir = shadowtcb_path_existing (stored_tcb_user);
if (NULL == real_old_dir) {
goto out_free;
}
real_new_dir = shadowtcb_path (user_newname, the_newid);
if (NULL == real_new_dir) {
goto out_free;
}
if (strcmp (real_old_dir, real_new_dir) == 0) {
ret = SHADOWTCB_SUCCESS;
goto out_free;
}
real_old_dir_rel = shadowtcb_path_rel_existing (stored_tcb_user);
if (NULL == real_old_dir_rel) {
goto out_free;
}
if (mkdir_leading (user_newname, the_newid) == SHADOWTCB_FAILURE) {
goto out_free;
}
if (rename (real_old_dir, real_new_dir) != 0) {
fprintf (stderr,
_("%s: Cannot rename %s to %s: %s\n"),
Prog, real_old_dir, real_new_dir, strerror (errno));
goto out_free;
}
if (rmdir_leading (real_old_dir_rel) == SHADOWTCB_FAILURE) {
goto out_free;
}
if ((unlink (olddir) != 0) && (errno != ENOENT)) {
fprintf (stderr,
_("%s: Cannot remove %s: %s\n"),
Prog, olddir, strerror (errno));
goto out_free;
}
if (asprintf (&newdir, TCB_DIR "/%s", user_newname) == -1) {
goto out_free_nomem;
}
real_new_dir_rel = shadowtcb_path_rel (user_newname, the_newid);
if (NULL == real_new_dir_rel) {
goto out_free;
}
if ( (strcmp (real_new_dir, newdir) != 0)
&& (symlink (real_new_dir_rel, newdir) != 0)) {
fprintf (stderr,
_("%s: Cannot create symbolic link %s: %s\n"),
Prog, real_new_dir_rel, strerror (errno));
goto out_free;
}
ret = SHADOWTCB_SUCCESS;
goto out_free;
out_free_nomem:
OUT_OF_MEMORY;
out_free:
free (olddir);
free (newdir);
free (real_old_dir);
free (real_new_dir);
free (real_old_dir_rel);
free (real_new_dir_rel);
return ret;
}
shadowtcb_status shadowtcb_set_user (const char* name)
{
char *buf;
shadowtcb_status retval;
if (!getdef_bool ("USE_TCB")) {
return SHADOWTCB_SUCCESS;
}
if (NULL != stored_tcb_user) {
free (stored_tcb_user);
}
stored_tcb_user = strdup (name);
if (NULL == stored_tcb_user) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if (asprintf (&buf, TCB_FMT, name) == -1) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
retval = (spw_setdbname (buf) != 0) ? SHADOWTCB_SUCCESS : SHADOWTCB_FAILURE;
free (buf);
return retval;
}
/* tcb directory must be empty before shadowtcb_remove is called. */
shadowtcb_status shadowtcb_remove (const char *name)
{
shadowtcb_status ret = SHADOWTCB_SUCCESS;
char *path = shadowtcb_path_existing (name);
char *rel = shadowtcb_path_rel_existing (name);
if ((NULL == path) || (NULL == rel) || (rmdir (path) != 0)) {
return SHADOWTCB_FAILURE;
}
if (rmdir_leading (rel) == SHADOWTCB_FAILURE) {
return SHADOWTCB_FAILURE;
}
free (path);
free (rel);
if (asprintf (&path, TCB_DIR "/%s", name) == -1) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if ((unlink (path) != 0) && (errno != ENOENT)) {
ret = SHADOWTCB_FAILURE;
}
free (path);
return ret;
}
shadowtcb_status shadowtcb_move (/*@NULL@*/const char *user_newname, uid_t user_newid)
{
struct stat dirmode, filemode;
char *tcbdir, *shadow;
shadowtcb_status ret = SHADOWTCB_FAILURE;
if (!getdef_bool ("USE_TCB")) {
return SHADOWTCB_SUCCESS;
}
if (NULL == stored_tcb_user) {
return SHADOWTCB_FAILURE;
}
if (NULL == user_newname) {
user_newname = stored_tcb_user;
}
if (move_dir (user_newname, user_newid) == SHADOWTCB_FAILURE) {
return SHADOWTCB_FAILURE;
}
if (-1 == user_newid) {
return SHADOWTCB_SUCCESS;
}
if ( (asprintf (&tcbdir, TCB_DIR "/%s", user_newname) == -1)
|| (asprintf (&shadow, TCB_FMT, user_newname) == -1)) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if (stat (tcbdir, &dirmode) != 0) {
fprintf (stderr,
_("%s: Cannot stat %s: %s\n"),
Prog, tcbdir, strerror (errno));
goto out_free;
}
if (chown (tcbdir, 0, 0) != 0) {
fprintf (stderr,
_("%s: Cannot change owners of %s: %s\n"),
Prog, tcbdir, strerror (errno));
goto out_free;
}
if (chmod (tcbdir, 0700) != 0) {
fprintf (stderr,
_("%s: Cannot change mode of %s: %s\n"),
Prog, tcbdir, strerror (errno));
goto out_free;
}
if (lstat (shadow, &filemode) != 0) {
if (errno != ENOENT) {
fprintf (stderr,
_("%s: Cannot lstat %s: %s\n"),
Prog, shadow, strerror (errno));
goto out_free;
}
fprintf (stderr,
_("%s: Warning, user %s has no tcb shadow file.\n"),
Prog, user_newname);
} else {
if (!S_ISREG (filemode.st_mode) ||
filemode.st_nlink != 1) {
fprintf (stderr,
_("%s: Emergency: %s's tcb shadow is not a "
"regular file with st_nlink=1.\n"
"The account is left locked.\n"),
Prog, user_newname);
goto out_free;
}
if (chown (shadow, user_newid, filemode.st_gid) != 0) {
fprintf (stderr,
_("%s: Cannot change owner of %s: %s\n"),
Prog, shadow, strerror (errno));
goto out_free;
}
if (chmod (shadow, filemode.st_mode & 07777) != 0) {
fprintf (stderr,
_("%s: Cannot change mode of %s: %s\n"),
Prog, shadow, strerror (errno));
goto out_free;
}
}
if (unlink_suffs (user_newname) == SHADOWTCB_FAILURE) {
goto out_free;
}
if (chown (tcbdir, user_newid, dirmode.st_gid) != 0) {
fprintf (stderr,
_("%s: Cannot change owner of %s: %s\n"),
Prog, tcbdir, strerror (errno));
goto out_free;
}
ret = SHADOWTCB_SUCCESS;
out_free:
free (tcbdir);
free (shadow);
return ret;
}
shadowtcb_status shadowtcb_create (const char *name, uid_t uid)
{
char *dir, *shadow;
struct stat tcbdir_stat;
gid_t shadowgid, authgid;
struct group *gr;
int fd;
shadowtcb_status ret = SHADOWTCB_FAILURE;
if (!getdef_bool ("USE_TCB")) {
return SHADOWTCB_SUCCESS;
}
if (stat (TCB_DIR, &tcbdir_stat) != 0) {
fprintf (stderr,
_("%s: Cannot stat %s: %s\n"),
Prog, TCB_DIR, strerror (errno));
return SHADOWTCB_FAILURE;
}
shadowgid = tcbdir_stat.st_gid;
authgid = shadowgid;
if (getdef_bool ("TCB_AUTH_GROUP")) {
gr = getgrnam ("auth");
if (NULL != gr) {
authgid = gr->gr_gid;
}
}
if ( (asprintf (&dir, TCB_DIR "/%s", name) == -1)
|| (asprintf (&shadow, TCB_FMT, name) == -1)) {
OUT_OF_MEMORY;
return SHADOWTCB_FAILURE;
}
if (mkdir (dir, 0700) != 0) {
fprintf (stderr,
_("%s: mkdir: %s: %s\n"),
Prog, dir, strerror (errno));
goto out_free;
}
fd = open (shadow, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (fd < 0) {
fprintf (stderr,
_("%s: Cannot open %s: %s\n"),
Prog, shadow, strerror (errno));
goto out_free;
}
close (fd);
if (chown (shadow, 0, authgid) != 0) {
fprintf (stderr,
_("%s: Cannot change owner of %s: %s\n"),
Prog, shadow, strerror (errno));
goto out_free;
}
if (chmod (shadow, (mode_t) ((authgid == shadowgid) ? 0600 : 0640)) != 0) {
fprintf (stderr,
_("%s: Cannot change mode of %s: %s\n"),
Prog, shadow, strerror (errno));
goto out_free;
}
if (chown (dir, 0, authgid) != 0) {
fprintf (stderr,
_("%s: Cannot change owner of %s: %s\n"),
Prog, dir, strerror (errno));
goto out_free;
}
if (chmod (dir, (mode_t) ((authgid == shadowgid) ? 02700 : 02710)) != 0) {
fprintf (stderr,
_("%s: Cannot change mode of %s: %s\n"),
Prog, dir, strerror (errno));
goto out_free;
}
if ( (shadowtcb_set_user (name) == SHADOWTCB_FAILURE)
|| (shadowtcb_move (NULL, uid) == SHADOWTCB_FAILURE)) {
goto out_free;
}
ret = SHADOWTCB_SUCCESS;
out_free:
free (dir);
free (shadow);
return ret;
}
-19
View File
@@ -1,19 +0,0 @@
#ifndef _TCBFUNCS_H
#define _TCBFUNCS_H
#include <sys/types.h>
typedef enum {
SHADOWTCB_FAILURE = 0,
SHADOWTCB_SUCCESS = 1
} shadowtcb_status;
extern shadowtcb_status shadowtcb_drop_priv (void);
extern shadowtcb_status shadowtcb_gain_priv (void);
extern shadowtcb_status shadowtcb_set_user (const char *name);
extern shadowtcb_status shadowtcb_remove (const char *name);
extern shadowtcb_status shadowtcb_move (/*@null@*/const char *user_newname,
uid_t user_newid);
extern shadowtcb_status shadowtcb_create (const char *name, uid_t uid);
#endif

Some files were not shown because too many files have changed in this diff Show More