Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4c944d236c | ||
|
|
46cc41933b | ||
|
|
388cb97893 | ||
|
|
81c4e06c3b | ||
|
|
4fcb8d510b | ||
|
|
2ff61e3c80 | ||
|
|
61472718df | ||
|
|
b63aced4b3 | ||
|
|
b532614a3b | ||
|
|
02f8995749 | ||
|
|
cb56b9d10e | ||
|
|
bdb2aa7202 | ||
|
|
7a3935ef98 | ||
|
|
9d0f797494 | ||
|
|
862809e6de | ||
|
|
0e71b4600c | ||
|
|
fcee2d4028 | ||
|
|
3ee8ec58bb | ||
|
|
d20c220441 | ||
|
|
451264e2b2 | ||
|
|
d2ea0055d4 | ||
|
|
d48226e507 | ||
|
|
1a19ece5ee | ||
|
|
a70f9f8694 | ||
|
|
02ea908972 |
-47
@@ -1,47 +0,0 @@
|
||||
*~
|
||||
lib*.a
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.gmo
|
||||
.deps
|
||||
.libs
|
||||
|
||||
*.patch
|
||||
*.rej
|
||||
*.orig
|
||||
|
||||
Makefile
|
||||
Makefile.in
|
||||
|
||||
/ABOUT-NLS
|
||||
/aclocal.m4
|
||||
/autom4te.cache
|
||||
/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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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 \
|
||||
"$@"
|
||||
-685
@@ -1,685 +0,0 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT
|
||||
AM_INIT_AUTOMAKE(shadow, 4.2)
|
||||
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_RUN_IFELSE([AC_LANG_SOURCE([
|
||||
#include <sys/types.h>
|
||||
int main(void) {
|
||||
uid_t u;
|
||||
gid_t g;
|
||||
return (sizeof u < 4) || (sizeof g < 4);
|
||||
}
|
||||
])], [id32bit="yes"], [id32bit="no"])
|
||||
|
||||
if test "x$id32bit" = "xyes"; 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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..."
|
||||
@@ -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='[1m' # start embolden
|
||||
E='[m' # 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.
|
||||
@@ -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;
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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.
Vendored
-16
@@ -1,16 +0,0 @@
|
||||
PKG=shadow
|
||||
SITE=ftp://pkg-shadow.alioth.debian.org/pub/pkg-shadow/
|
||||
|
||||
deb:: check_cheese
|
||||
|
||||
include /usr/share/quilt/quilt.debbuild.mk
|
||||
|
||||
check_cheese:
|
||||
@dpkg-parsechangelog | grep -q "\* The \".*\".* release\." || { \
|
||||
echo ""; \
|
||||
echo " ** **"; \
|
||||
echo " ** Warning: not a cheesy release! **"; \
|
||||
echo " ** **"; \
|
||||
echo ""; \
|
||||
exit 1; \
|
||||
}
|
||||
Vendored
-36
@@ -1,36 +0,0 @@
|
||||
shadow (1:4.0.15-5) unstable; urgency=low
|
||||
|
||||
* commands passed in argument to su must use su's -c option and must quote
|
||||
the command if it contains a space, as in:
|
||||
su - root -c "ls -l /"
|
||||
The following commands won't work anymore:
|
||||
su - root -c ls -l /
|
||||
su - root "ls -l /"
|
||||
su - root ls -l /
|
||||
|
||||
-- Christian Perrier <bubulle@debian.org> Sat, 8 Apr 2006 20:11:38 +0200
|
||||
|
||||
shadow (1:4.0.14-1) unstable; urgency=low
|
||||
|
||||
* passwd does not support the -f, -s, and -g options anymore. You should use
|
||||
the chfn, chsh and gpasswd utilities instead.
|
||||
* login now distributes the nologin utility, which can be used as a shell
|
||||
to politely refuse a login
|
||||
|
||||
-- Christian Perrier <bubulle@debian.org> Thu, 5 Jan 2006 08:47:44 +0100
|
||||
|
||||
shadow (1:4.0.12-1) unstable; urgency=low
|
||||
|
||||
CLOSE_SESSIONS and other variables are not used anymore in
|
||||
/etc/login/defs.
|
||||
As shadow utilities which use this file now warn about unknown
|
||||
entries there, administrators should remove such unknown entries.
|
||||
The supplied login.defs file does not include them anymore.
|
||||
|
||||
dpasswd is no more distributed by upstream. Login do not support
|
||||
dialup password anymore. Re-introducing this functionality in
|
||||
upstream is not trivial.
|
||||
|
||||
|
||||
-- Christian Perrier <bubulle@debian.org> Thu, 25 Aug 2005 08:38:47 +0200
|
||||
|
||||
Vendored
-62
@@ -1,62 +0,0 @@
|
||||
Read this file first for a brief overview of the new versions of login
|
||||
and passwd.
|
||||
|
||||
|
||||
---Shadow passwords
|
||||
|
||||
The command `shadowconfig on' will turn on shadow password support.
|
||||
`shadowconfig off' will turn it back off. If you turn on shadow
|
||||
password support, you'll gain the ability to set password ages and
|
||||
expirations with chage(1).
|
||||
|
||||
NOTE: If you use the nscd package, you may have problems with a
|
||||
slight delay in updating the password information. You may notice
|
||||
this during upgrades of certain packages that try to add a system
|
||||
user and then access the users information immediately afterwards.
|
||||
To avoid this, it is suggested that you stop the nscd daemon before
|
||||
upgrades, then restart it again.
|
||||
|
||||
---General configuration
|
||||
|
||||
Most of the configuration for the shadow utilities is in
|
||||
/etc/login.defs. See login.defs(5). The defaults are quite
|
||||
reasonable.
|
||||
|
||||
Also see the /etc/pam.d/* files for each program to configure the PAM
|
||||
support. PAM documentation is available in several formats in the
|
||||
libpam-doc package.
|
||||
|
||||
|
||||
---MD5 Encryption
|
||||
|
||||
This is enabled now using the /etc/pam.d/* files. Examples are given.
|
||||
|
||||
|
||||
---Adding users and groups
|
||||
|
||||
Though you may add users and groups with the SysV type commands,
|
||||
useradd and groupadd, I recommend you add them with Debian adduser
|
||||
version 3+. adduser gives you more configuration and conforms to the
|
||||
Debian UID and GID allocation.
|
||||
|
||||
Editing user and group parameters can be done with usermod and
|
||||
groupmod. Removing users and groups can be done with userdel and
|
||||
groupdel.
|
||||
|
||||
|
||||
--- Group administration
|
||||
|
||||
Local group allocation is much easier. With gpasswd(1) you can
|
||||
designate users to administer groups. They can then securely add or
|
||||
remove users from the group.
|
||||
|
||||
|
||||
--- What to read next?
|
||||
|
||||
Read the manpages, the other files in this directory, and the Shadow
|
||||
Password HOWTO (included in the doc-linux package). A large portion
|
||||
of these files deals with getting shadow installed. You can, of
|
||||
course, ignore those parts.
|
||||
|
||||
Also, the libpam-doc package will go a long way to allowing you to take
|
||||
full advantage of the PAM authentication scheme.
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
This package uses quilt to patch the upstream source.
|
||||
|
||||
You can find some info on how to generate the patched source, add a new
|
||||
modification, and remove an existing modification on:
|
||||
/usr/share/doc/quilt/README.source
|
||||
|
||||
================================================================================
|
||||
|
||||
To package a new upstream release, you can use the Makefile:
|
||||
svn://svn.debian.org/svn/pkg-shadow/debian/trunk/Makefile
|
||||
|
||||
================================================================================
|
||||
|
||||
A testsuite is also available. Instruction on how to run this testsuite
|
||||
are available on:
|
||||
svn://svn.debian.org/svn/pkg-shadow/debian/trunk/tests/README
|
||||
|
||||
Vendored
-19
@@ -1,19 +0,0 @@
|
||||
Things that should be done:
|
||||
* Verify the files left in debian/tmp
|
||||
+ e.g. /etc/default/adduser should be installed
|
||||
* Check the build system: rebuilding the package twoce in the same tree
|
||||
doubles the size of the diff.gz file
|
||||
|
||||
Other points (not related to the release of a syncronized shadow):
|
||||
* compare the source with the usages and man pages
|
||||
+ probably add a sentence to chsh/chfn's manpages about authentication
|
||||
required for ordinary users
|
||||
* do something (a tool) for the variables in login.defs
|
||||
In Debian, some tools are not compiled with the PAM support, so upstream
|
||||
getdef.c won't be OK.
|
||||
It should be nice to see in each man page the set of variables used.
|
||||
The Debian package can now compile (export DEB_BUILD_OPTIONS='nostrip debug')
|
||||
with the debugging informations. This may be used to extract the set of
|
||||
variables used in Debian/for each tools.
|
||||
* verify all the patches around (I've found patches for at least RedHat,
|
||||
OWL, LFS, Mandriva, Gentoo; are they already applied?)
|
||||
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
This described the usertags used by the team.
|
||||
|
||||
For usertags documentation, see
|
||||
http://lists.debian.org/debian-devel-announce/2005/09/msg00002.html
|
||||
|
||||
All bugs tagged by team members must be tagged with
|
||||
"user pkg-shadow-devel@lists.alioth.debian.org"
|
||||
|
||||
Tags list
|
||||
---------
|
||||
|
||||
toclose: This bug has been announced to be closed in case no more news
|
||||
or information is received from the bug submitter or someone
|
||||
else until the delay specified in the limits_YYYYMMDD tag
|
||||
|
||||
limits-YYYYMMDD: combine it with "toclose". Specifies the date after which
|
||||
bugs can be closed without other action in case no news
|
||||
is received
|
||||
|
||||
manpages-replace A bug reported angainst a manpages-xx package to indicate
|
||||
conflicting man pages. This tag can be used to tune the
|
||||
Replaces fields.
|
||||
|
||||
su-transition: This bug is related to the su transition (#276419)
|
||||
|
||||
Vendored
-3722
File diff suppressed because it is too large
Load Diff
Vendored
-1
@@ -1 +0,0 @@
|
||||
6
|
||||
Vendored
-45
@@ -1,45 +0,0 @@
|
||||
Source: shadow
|
||||
Section: admin
|
||||
Priority: required
|
||||
Maintainer: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
|
||||
Standards-Version: 3.9.5
|
||||
Uploaders: Christian Perrier <bubulle@debian.org>,
|
||||
Balint Reczey <balint@balintreczey.hu>
|
||||
Build-Depends: dh-autoreconf, gettext, libpam0g-dev, debhelper (>= 6.0.7~), quilt, dpkg-dev (>= 1.13.5), xsltproc, docbook-xsl, docbook-xml, libxml2-utils, cdbs, libselinux1-dev [linux-any], libsemanage1-dev [linux-any], gnome-doc-utils (>= 0.4.3), bison, libaudit-dev [linux-any]
|
||||
,hardening-wrapper
|
||||
Vcs-Git: git://anonscm.debian.org/git/pkg-shadow/shadow.git
|
||||
Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-shadow/shadow.git;a=summary
|
||||
Homepage: http://pkg-shadow.alioth.debian.org/
|
||||
|
||||
Package: passwd
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-modules, debianutils (>= 2.15.2)
|
||||
Replaces: manpages-tr (<<1.0.5), manpages-zh (<<1.5.1-1)
|
||||
Multi-Arch: foreign
|
||||
Description: change and administer password and group data
|
||||
This package includes passwd, chsh, chfn, and many other programs to
|
||||
maintain password and group data.
|
||||
.
|
||||
Shadow passwords are supported. See /usr/share/doc/passwd/README.Debian
|
||||
|
||||
Package: login
|
||||
Architecture: any
|
||||
Pre-Depends: ${shlibs:Depends}, ${misc:Depends}, libpam-runtime, libpam-modules (>= 1.1.8-1)
|
||||
Conflicts: gnunet (<< 0.7.0c-2), amavisd-new (<<2.3.3-8), python-4suite (<< 0.99cvs20060405-1), backupninja (<< 0.9.3-5), echolot (<< 2.1.8-4)
|
||||
Breaks: coreutils (<< 8.21~) [hurd-any], passwd (<< 1:4.1.5.1-2~) [hurd-any], hurd (<< 20140206~) [hurd-any]
|
||||
Replaces: manpages-de (<< 0.5-3), manpages-tr (<<1.0.5), manpages-zh (<<1.5.1-1), passwd (<< 1:4.1.5.1-2~) [hurd-any], coreutils (<< 8.21~) [hurd-any], hurd (<< 20140206~) [hurd-any]
|
||||
Essential: yes
|
||||
Description: system login tools
|
||||
These tools are required to be able to login and use your system. The
|
||||
login program invokes your user shell and enables command execution. The
|
||||
newgrp program is used to change your effective group ID (useful for
|
||||
workgroup type situations). The su program allows changing your effective
|
||||
user ID (useful being able to execute commands as another user).
|
||||
|
||||
Package: uidmap
|
||||
Priority: optional
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Architecture: any
|
||||
Description: programs to help use subuids
|
||||
These programs help unprivileged users to create uid and gid mappings in
|
||||
user namespaces.
|
||||
Vendored
-103
@@ -1,103 +0,0 @@
|
||||
This is Debian GNU/Linux's prepackaged version of the shadow utilities.
|
||||
|
||||
It was downloaded from: <ftp://ftp.pld.org.pl/software/shadow/>.
|
||||
As of May 2007, this site is no longer available.
|
||||
|
||||
Copyright:
|
||||
|
||||
Parts of this software are copyright 1988 - 1994, Julianne Frances Haugh.
|
||||
All rights reserved.
|
||||
|
||||
Parts of this software are copyright 1997 - 2001, Marek Michałkiewicz.
|
||||
All rights reserved.
|
||||
|
||||
Parts of this software are copyright 2001 - 2004, Andrzej Krzysztofowicz
|
||||
All rights reserved.
|
||||
|
||||
Parts of this software are copyright 2000 - 2007, 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. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
This source code is currently archived on ftp.uu.net in the
|
||||
comp.sources.misc portion of the USENET archives. You may also contact
|
||||
the author, Julianne F. Haugh, at jockgrrl@ix.netcom.com if you have
|
||||
any questions regarding this package.
|
||||
|
||||
THIS SOFTWARE IS BEING DISTRIBUTED AS-IS. THE AUTHORS DISCLAIM ALL
|
||||
LIABILITY FOR ANY CONSEQUENCES OF USE. THE USER IS SOLELY RESPONSIBLE
|
||||
FOR THE MAINTENANCE OF THIS SOFTWARE PACKAGE. THE AUTHORS ARE UNDER NO
|
||||
OBLIGATION TO PROVIDE MODIFICATIONS OR IMPROVEMENTS. THE USER IS
|
||||
ENCOURAGED TO TAKE ANY AND ALL STEPS NEEDED TO PROTECT AGAINST ACCIDENTAL
|
||||
LOSS OF INFORMATION OR MACHINE RESOURCES.
|
||||
|
||||
Special thanks are due to Chip Rosenthal for his fine testing efforts;
|
||||
to Steve Simmons for his work in porting this code to BSD; and to Bill
|
||||
Kennedy for his contributions of LaserJet printer time and energies.
|
||||
Also, thanks for Dennis L. Mumaugh for the initial shadow password
|
||||
information and to Tony Walton (olapw@olgb1.oliv.co.uk) for the System
|
||||
V Release 4 changes. Effort in porting to SunOS has been contributed
|
||||
by Dr. Michael Newberry (miken@cs.adfa.oz.au) and Micheal J. Miller, Jr.
|
||||
(mke@kaberd.rain.com). Effort in porting to AT&T UNIX System V Release
|
||||
4 has been provided by Andrew Herbert (andrew@werple.pub.uu.oz.au).
|
||||
Special thanks to Marek Michalkiewicz (marekm@i17linuxb.ists.pwr.wroc.pl)
|
||||
for taking over the Linux port of this software.
|
||||
|
||||
Source files: login_access.c, login_desrpc.c, login_krb.c are derived
|
||||
from the logdaemon-5.0 package, which is under the following license:
|
||||
|
||||
/************************************************************************
|
||||
* Copyright 1995 by Wietse Venema. All rights reserved. Individual files
|
||||
* may be covered by other copyrights (as noted in the file itself.)
|
||||
*
|
||||
* This material was originally written and compiled by Wietse Venema at
|
||||
* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
|
||||
* 1992, 1993, 1994 and 1995.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that this entire copyright notice is duplicated in all such
|
||||
* copies.
|
||||
*
|
||||
* This software is provided "as is" and without any expressed or implied
|
||||
* warranties, including, without limitation, the implied warranties of
|
||||
* merchantibility and fitness for any particular purpose.
|
||||
************************************************************************/
|
||||
|
||||
Some parts substantially in src/su.c derived from an ancestor of
|
||||
su for GNU. Run a shell with substitute user and group IDs.
|
||||
Copyright (C) 1992-2003 Free Software Foundation, Inc.
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
On Debian GNU/Linux systems, the complete text of the GNU General Public
|
||||
License can be found in '/usr/share/common-licenses/GPL-2'
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
.so man8/cppw.8
|
||||
Vendored
-27
@@ -1,27 +0,0 @@
|
||||
.TH CPPW 8 "7 Apr 2005"
|
||||
.SH NAME
|
||||
cppw, cpgr \- copy with locking the given file to the password or group file
|
||||
.SH SYNOPSIS
|
||||
\fBcppw\fR [\fB\-h\fR] [\fB\-s\fR] password_file
|
||||
.br
|
||||
\fBcpgr\fR [\fB\-h\fR] [\fB\-s\fR] group_file
|
||||
|
||||
.SH DESCRIPTION
|
||||
.BR cppw " and " cpgr
|
||||
will copy, with locking, the given file to
|
||||
.IR /etc/passwd " and " /etc/group ", respectively."
|
||||
With the \fB\-s\fR flag, they will copy the shadow versions of those files,
|
||||
.IR /etc/shadow " and " /etc/gshadow ", respectively."
|
||||
|
||||
With the \fB\-h\fR flag, the commands display a short help message and exit
|
||||
silently.
|
||||
.SH "SEE ALSO"
|
||||
.BR vipw (8),
|
||||
.BR vigr (8),
|
||||
.BR group (5),
|
||||
.BR passwd (5),
|
||||
.BR shadow (5),
|
||||
.BR gshadow (5)
|
||||
.SH AUTHOR
|
||||
\fBcppw\fR and \fBcpgr\fR were written by Stephen Frost, based on
|
||||
\fBvipw\fR and \fBvigr\fR written by Guy Maor.
|
||||
Vendored
-94
@@ -1,94 +0,0 @@
|
||||
Build-Depends:
|
||||
==============
|
||||
* autoconf
|
||||
* automake1.9
|
||||
works with 1.7 or 1.9 (at least)
|
||||
* libtool
|
||||
* gettext
|
||||
POT, PO, GMO regenerated?
|
||||
* libpam0g-dev
|
||||
OK
|
||||
* debhelper (>= 4.1.16)
|
||||
* po-debconf
|
||||
OK
|
||||
* quilt
|
||||
patch system
|
||||
* dpkg-dev (>= 1.13.5)
|
||||
* xsltproc
|
||||
used to generate the manpages
|
||||
* docbook-xsl
|
||||
needed for /usr/share/xml/docbook/stylesheet/nwalsh/manpages/docbook.xsl
|
||||
* docbook-xml
|
||||
manpages/docbook.xsl includes html/docbook.xsl
|
||||
(But it is not strictly needed. The generated manpages are identical.
|
||||
Without it, a warning is generated.)
|
||||
Needed by JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN], [DocBook XML DTD V4.1.2], [], enable_man=no)
|
||||
* libxml2-utils
|
||||
needed by the JH_CHECK_XML_CATALOG macros
|
||||
* cdbs
|
||||
used in debian/rules
|
||||
* libselinux1-dev [!hurd-i386 !kfreebsd-i386 !kfreebsd-amd64]
|
||||
* gnome-doc-utils (>= 0.4.3-1)
|
||||
xml2po, 0.4.3-1 needed for the -l switch.
|
||||
|
||||
passwd Depends:
|
||||
===============
|
||||
* ${shlibs:Depends}
|
||||
OK
|
||||
* ${loginpam}
|
||||
- hurd
|
||||
login
|
||||
libpam-modules (>= 0.72-5)
|
||||
- other archs
|
||||
+ login (>= 970502-1)
|
||||
login is needed because some passwd utils need /etc/login.defs
|
||||
login is Essential, so this is just to enforce the version
|
||||
+ libpam-modules (>= 0.72-5)
|
||||
* debianutils (>= 2.15.2)
|
||||
After 1:4.0.12-6, {add,remove}-shell are distributed in debianutils (2.15)
|
||||
/etc/shell was forgotten and introduced in debianutils in 2.15.2
|
||||
|
||||
passwd Conflicts:
|
||||
=================
|
||||
|
||||
passwd Replaces:
|
||||
================
|
||||
Some of the passwd man pages are also distributed in some manpages* packages.
|
||||
Look at the debian/02/run test to optimize these dependencies.
|
||||
NOTE: Not all maintainers have been notified.
|
||||
* manpages-de (<< 0.4-9), manpages-fi (<< 0.2-4), manpages-fr (<<1.64.0-1), manpages-hu (<< 20010119-5), manpages-it (<< 0.3.4-3), manpages-ja (<< 0.5.0.0.20050915-1), manpages-ko (<< 20050219-2), manpages-es (<< 1.55-4), manpages-es-extra (<< 0.8a-15), manpages-ru (<< 0.98-3)
|
||||
All those packages have been updated during sarge->etch. So these Replaces
|
||||
should be removed after lenny release
|
||||
* manpages-tr, manpages-zh
|
||||
Those packages are still in etch, so the Replaces should be kept even
|
||||
after lenny release
|
||||
|
||||
login Pre-Depends:
|
||||
==================
|
||||
* ${shlibs:Depends}
|
||||
* libpam-runtime (>= 0.76-14)
|
||||
sarge contained 0.76-22
|
||||
|
||||
Why Pre-Depends? (because it's an essential package?)
|
||||
|
||||
login Depends:
|
||||
==============
|
||||
* libpam-modules (>= 0.72-5)
|
||||
libpam-modules is needed.
|
||||
potato contained 0.72-9
|
||||
|
||||
login Conflicts:
|
||||
================
|
||||
|
||||
login Replaces:
|
||||
===============
|
||||
* Some of the login man pages are also distributed in some manpages* packages.
|
||||
Look at the debian/02/run test to optimize these dependencies.
|
||||
NOTE: Not all maintainers have been notified.
|
||||
- manpages-fi, manpages-fr (<<1.64.0-1), manpages-hu, manpages-it, manpages-ko, manpages-ja (<< 0.5.0.0.20050915-1), manpages-de (<< 0.4-10), manpages-es-extra (<<0.8a-15)
|
||||
Those are packages that have been updated during sarge->etch. These
|
||||
Replaces should be removed after lenny
|
||||
- manpages-tr, manpages-zh
|
||||
Those packages are still in etch, so the Replaces should be kept even
|
||||
after lenny release
|
||||
|
||||
Vendored
-340
@@ -1,340 +0,0 @@
|
||||
#
|
||||
# /etc/login.defs - Configuration control definitions for the login package.
|
||||
#
|
||||
# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH.
|
||||
# If unspecified, some arbitrary (and possibly incorrect) value will
|
||||
# be assumed. All other items are optional - if not specified then
|
||||
# the described action or option will be inhibited.
|
||||
#
|
||||
# Comment lines (lines beginning with "#") and blank lines are ignored.
|
||||
#
|
||||
# Modified for Linux. --marekm
|
||||
|
||||
# REQUIRED for useradd/userdel/usermod
|
||||
# Directory where mailboxes reside, _or_ name of file, relative to the
|
||||
# home directory. If you _do_ define MAIL_DIR and MAIL_FILE,
|
||||
# MAIL_DIR takes precedence.
|
||||
#
|
||||
# Essentially:
|
||||
# - MAIL_DIR defines the location of users mail spool files
|
||||
# (for mbox use) by appending the username to MAIL_DIR as defined
|
||||
# below.
|
||||
# - MAIL_FILE defines the location of the users mail spool files as the
|
||||
# fully-qualified filename obtained by prepending the user home
|
||||
# directory before $MAIL_FILE
|
||||
#
|
||||
# NOTE: This is no more used for setting up users MAIL environment variable
|
||||
# which is, starting from shadow 4.0.12-1 in Debian, entirely the
|
||||
# job of the pam_mail PAM modules
|
||||
# See default PAM configuration files provided for
|
||||
# login, su, etc.
|
||||
#
|
||||
# This is a temporary situation: setting these variables will soon
|
||||
# move to /etc/default/useradd and the variables will then be
|
||||
# no more supported
|
||||
MAIL_DIR /var/mail
|
||||
#MAIL_FILE .mail
|
||||
|
||||
#
|
||||
# Enable logging and display of /var/log/faillog login failure info.
|
||||
# This option conflicts with the pam_tally PAM module.
|
||||
#
|
||||
FAILLOG_ENAB yes
|
||||
|
||||
#
|
||||
# Enable display of unknown usernames when login failures are recorded.
|
||||
#
|
||||
# WARNING: Unknown usernames may become world readable.
|
||||
# See #290803 and #298773 for details about how this could become a security
|
||||
# concern
|
||||
LOG_UNKFAIL_ENAB no
|
||||
|
||||
#
|
||||
# Enable logging of successful logins
|
||||
#
|
||||
LOG_OK_LOGINS no
|
||||
|
||||
#
|
||||
# Enable "syslog" logging of su activity - in addition to sulog file logging.
|
||||
# SYSLOG_SG_ENAB does the same for newgrp and sg.
|
||||
#
|
||||
SYSLOG_SU_ENAB yes
|
||||
SYSLOG_SG_ENAB yes
|
||||
|
||||
#
|
||||
# If defined, all su activity is logged to this file.
|
||||
#
|
||||
#SULOG_FILE /var/log/sulog
|
||||
|
||||
#
|
||||
# If defined, file which maps tty line to TERM environment parameter.
|
||||
# Each line of the file is in a format something like "vt100 tty01".
|
||||
#
|
||||
#TTYTYPE_FILE /etc/ttytype
|
||||
|
||||
#
|
||||
# If defined, login failures will be logged here in a utmp format
|
||||
# last, when invoked as lastb, will read /var/log/btmp, so...
|
||||
#
|
||||
FTMP_FILE /var/log/btmp
|
||||
|
||||
#
|
||||
# If defined, the command name to display when running "su -". For
|
||||
# example, if this is defined as "su" then a "ps" will display the
|
||||
# command is "-su". If not defined, then "ps" would display the
|
||||
# name of the shell actually being run, e.g. something like "-sh".
|
||||
#
|
||||
SU_NAME su
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
#
|
||||
# *REQUIRED* The default PATH settings, for superuser and normal users.
|
||||
#
|
||||
# (they are minimal, add the rest in the shell startup files)
|
||||
ENV_SUPATH PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
ENV_PATH PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
|
||||
|
||||
#
|
||||
# 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" program which is "setgid" to a special group
|
||||
# which owns the terminals, define TTYGROUP to the group number and
|
||||
# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign
|
||||
# TTYPERM to either 622 or 600.
|
||||
#
|
||||
# In Debian /usr/bin/bsd-write or similar programs are setgid tty
|
||||
# However, the default and recommended value for TTYPERM is still 0600
|
||||
# to not allow anyone to write to anyone else console or terminal
|
||||
|
||||
# Users can still allow other people to write them by issuing
|
||||
# the "mesg y" command.
|
||||
|
||||
TTYGROUP tty
|
||||
TTYPERM 0600
|
||||
|
||||
#
|
||||
# Login configuration initializations:
|
||||
#
|
||||
# ERASECHAR Terminal ERASE character ('\010' = backspace).
|
||||
# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
|
||||
# UMASK Default "umask" value.
|
||||
#
|
||||
# The ERASECHAR and KILLCHAR are used only on System V machines.
|
||||
#
|
||||
# UMASK is the default umask value for pam_umask and is used by
|
||||
# useradd and newusers to set the mode of the new home directories.
|
||||
# 022 is the "historical" value in Debian for UMASK
|
||||
# 027, or even 077, could be considered better for privacy
|
||||
# There is no One True Answer here : each sysadmin must make up his/her
|
||||
# mind.
|
||||
#
|
||||
# If USERGROUPS_ENAB is set to "yes", that will modify this UMASK default value
|
||||
# for private user groups, i. e. the uid is the same as gid, and username is
|
||||
# the same as the primary group name: for these, the user permissions will be
|
||||
# used as group permissions, e. g. 022 will become 002.
|
||||
#
|
||||
# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
|
||||
#
|
||||
ERASECHAR 0177
|
||||
KILLCHAR 025
|
||||
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_WARN_AGE Number of days warning given before a password expires.
|
||||
#
|
||||
PASS_MAX_DAYS 99999
|
||||
PASS_MIN_DAYS 0
|
||||
PASS_WARN_AGE 7
|
||||
|
||||
#
|
||||
# Min/max values for automatic uid selection in useradd
|
||||
#
|
||||
UID_MIN 1000
|
||||
UID_MAX 60000
|
||||
# System accounts
|
||||
#SYS_UID_MIN 100
|
||||
#SYS_UID_MAX 999
|
||||
|
||||
#
|
||||
# Min/max values for automatic gid selection in groupadd
|
||||
#
|
||||
GID_MIN 1000
|
||||
GID_MAX 60000
|
||||
# System accounts
|
||||
#SYS_GID_MIN 100
|
||||
#SYS_GID_MAX 999
|
||||
|
||||
#
|
||||
# Max number of login retries if password is bad. This will most likely be
|
||||
# overriden by PAM, since the default pam_unix module has it's own built
|
||||
# in of 3 retries. However, this is a safe fallback in case you are using
|
||||
# an authentication module that does not enforce PAM_MAXTRIES.
|
||||
#
|
||||
LOGIN_RETRIES 5
|
||||
|
||||
#
|
||||
# Max time in seconds for login
|
||||
#
|
||||
LOGIN_TIMEOUT 60
|
||||
|
||||
#
|
||||
# Which fields may be changed by regular users using chfn - 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
|
||||
|
||||
#
|
||||
# Should login be allowed if we can't cd to the home directory?
|
||||
# Default in no.
|
||||
#
|
||||
DEFAULT_HOME yes
|
||||
|
||||
#
|
||||
# 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
|
||||
|
||||
#
|
||||
# If set to yes, userdel will remove the user´s group if it contains no
|
||||
# more members, and useradd will create by default a group with the name
|
||||
# of the user.
|
||||
#
|
||||
# Other former uses of this variable such as setting the umask when
|
||||
# user==primary group are not used in PAM environments, such as Debian
|
||||
#
|
||||
USERGROUPS_ENAB yes
|
||||
|
||||
#
|
||||
# Instead of the real user shell, the program specified by this parameter
|
||||
# will be launched, although its visible name (argv[0]) will be the shell's.
|
||||
# The program may do whatever it wants (logging, additional authentification,
|
||||
# banner, ...) before running the actual shell.
|
||||
#
|
||||
# FAKE_SHELL /bin/fakeshell
|
||||
|
||||
#
|
||||
# If defined, either full pathname of a file containing device names or
|
||||
# a ":" delimited list of device names. Root logins will be allowed only
|
||||
# upon these devices.
|
||||
#
|
||||
# This variable is used by login and su.
|
||||
#
|
||||
#CONSOLE /etc/consoles
|
||||
#CONSOLE console:tty01:tty02:tty03:tty04
|
||||
|
||||
#
|
||||
# List of groups to add to the user's supplementary group set
|
||||
# when logging in on 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 on the console.
|
||||
# How to do it is left as an exercise for the reader...
|
||||
#
|
||||
# This variable is used by login and su.
|
||||
#
|
||||
#CONSOLE_GROUPS floppy:audio:cdrom
|
||||
|
||||
#
|
||||
# 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".
|
||||
#
|
||||
# This variable is deprecated. You should use ENCRYPT_METHOD.
|
||||
#
|
||||
#MD5_CRYPT_ENAB no
|
||||
|
||||
#
|
||||
# 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: It is recommended to use a value consistent with
|
||||
# the PAM modules configuration.
|
||||
#
|
||||
ENCRYPT_METHOD SHA512
|
||||
|
||||
#
|
||||
# Only used 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 forcing the password.
|
||||
# But note also that it more CPU resources will be needed to authenticate
|
||||
# users.
|
||||
#
|
||||
# If not specified, the libc will choose the default number of rounds (5000).
|
||||
# The values must be inside 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
|
||||
|
||||
################# OBSOLETED BY PAM ##############
|
||||
# #
|
||||
# These options are now handled by PAM. Please #
|
||||
# edit the appropriate file in /etc/pam.d/ to #
|
||||
# enable the equivelants of them.
|
||||
#
|
||||
###############
|
||||
|
||||
#MOTD_FILE
|
||||
#DIALUPS_CHECK_ENAB
|
||||
#LASTLOG_ENAB
|
||||
#MAIL_CHECK_ENAB
|
||||
#OBSCURE_CHECKS_ENAB
|
||||
#PORTTIME_CHECKS_ENAB
|
||||
#SU_WHEEL_ONLY
|
||||
#CRACKLIB_DICTPATH
|
||||
#PASS_CHANGE_TRIES
|
||||
#PASS_ALWAYS_WARN
|
||||
#ENVIRON_FILE
|
||||
#NOLOGINS_FILE
|
||||
#ISSUE_FILE
|
||||
#PASS_MIN_LEN
|
||||
#PASS_MAX_LEN
|
||||
#ULIMIT
|
||||
#ENV_HZ
|
||||
#CHFN_AUTH
|
||||
#CHSH_AUTH
|
||||
#FAIL_DELAY
|
||||
|
||||
################# OBSOLETED #######################
|
||||
# #
|
||||
# These options are no more handled by shadow. #
|
||||
# #
|
||||
# Shadow utilities will display a warning if they #
|
||||
# still appear. #
|
||||
# #
|
||||
###################################################
|
||||
|
||||
# CLOSE_SESSIONS
|
||||
# LOGIN_STRING
|
||||
# NO_PASSWORD_CONSOLE
|
||||
# QMAIL_DIR
|
||||
|
||||
|
||||
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
usr/share/lintian/overrides
|
||||
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
usr/share/locale/*/LC_MESSAGES/shadow.mo
|
||||
usr/share/man/*/man1/login.1
|
||||
usr/share/man/*/man1/newgrp.1
|
||||
usr/share/man/*/man1/sg.1
|
||||
usr/share/man/*/man1/su.1
|
||||
usr/share/man/*/man5/faillog.5
|
||||
usr/share/man/*/man5/login.defs.5
|
||||
usr/share/man/*/man8/faillog.8
|
||||
usr/share/man/*/man8/lastlog.8
|
||||
usr/share/man/*/man8/nologin.8
|
||||
usr/share/man/man1/login.1
|
||||
usr/share/man/man1/newgrp.1
|
||||
usr/share/man/man1/sg.1
|
||||
usr/share/man/man1/su.1
|
||||
usr/share/man/man5/faillog.5
|
||||
usr/share/man/man5/login.defs.5
|
||||
usr/share/man/man8/faillog.8
|
||||
usr/share/man/man8/lastlog.8
|
||||
usr/share/man/man8/nologin.8
|
||||
usr/sbin/nologin
|
||||
usr/bin/faillog
|
||||
usr/bin/lastlog
|
||||
usr/bin/newgrp
|
||||
bin/login
|
||||
bin/su
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
usr/bin/newgrp usr/bin/sg
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
login: setuid-binary usr/bin/newgrp 4755 root/root
|
||||
login: setuid-binary bin/su 4755 root/root
|
||||
login: possible-missing-colon-in-closes l667:closes bug 336321
|
||||
Vendored
-111
@@ -1,111 +0,0 @@
|
||||
#
|
||||
# The PAM configuration file for the Shadow `login' service
|
||||
#
|
||||
|
||||
# Enforce a minimal delay in case of failure (in microseconds).
|
||||
# (Replaces the `FAIL_DELAY' setting from login.defs)
|
||||
# Note that other modules may require another minimal delay. (for example,
|
||||
# to disable any delay, you should add the nodelay option to pam_unix)
|
||||
auth optional pam_faildelay.so delay=3000000
|
||||
|
||||
# Outputs an issue file prior to each login prompt (Replaces the
|
||||
# ISSUE_FILE option from login.defs). Uncomment for use
|
||||
# auth required pam_issue.so issue=/etc/issue
|
||||
|
||||
# Disallows root logins except on tty's listed in /etc/securetty
|
||||
# (Replaces the `CONSOLE' setting from login.defs)
|
||||
#
|
||||
# With the default control of this module:
|
||||
# [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die]
|
||||
# root will not be prompted for a password on insecure lines.
|
||||
# if an invalid username is entered, a password is prompted (but login
|
||||
# will eventually be rejected)
|
||||
#
|
||||
# You can change it to a "requisite" module if you think root may mis-type
|
||||
# her login and should not be prompted for a password in that case. But
|
||||
# this will leave the system as vulnerable to user enumeration attacks.
|
||||
#
|
||||
# You can change it to a "required" module if you think it permits to
|
||||
# guess valid user names of your system (invalid user names are considered
|
||||
# as possibly being root on insecure lines), but root passwords may be
|
||||
# communicated over insecure lines.
|
||||
auth [success=ok new_authtok_reqd=ok ignore=ignore user_unknown=bad default=die] pam_securetty.so
|
||||
|
||||
# Disallows other than root logins when /etc/nologin exists
|
||||
# (Replaces the `NOLOGINS_FILE' option from login.defs)
|
||||
auth requisite pam_nologin.so
|
||||
|
||||
# SELinux needs to be the first session rule. This ensures that any
|
||||
# lingering context has been cleared. Without out this it is possible
|
||||
# that a module could execute code in the wrong domain.
|
||||
# When the module is present, "required" would be sufficient (When SELinux
|
||||
# is disabled, this returns success.)
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so close
|
||||
|
||||
# This module parses environment configuration file(s)
|
||||
# and also allows you to use an extended config
|
||||
# file /etc/security/pam_env.conf.
|
||||
#
|
||||
# parsing /etc/environment needs "readenv=1"
|
||||
session required pam_env.so readenv=1
|
||||
# locale variables are also kept into /etc/default/locale in etch
|
||||
# reading this file *in addition to /etc/environment* does not hurt
|
||||
session required pam_env.so readenv=1 envfile=/etc/default/locale
|
||||
|
||||
# Standard Un*x authentication.
|
||||
@include common-auth
|
||||
|
||||
# This allows certain extra groups to be granted to a user
|
||||
# based on things like time of day, tty, service, and user.
|
||||
# Please edit /etc/security/group.conf to fit your needs
|
||||
# (Replaces the `CONSOLE_GROUPS' option in login.defs)
|
||||
auth optional pam_group.so
|
||||
|
||||
# Uncomment and edit /etc/security/time.conf if you need to set
|
||||
# time restrainst on logins.
|
||||
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
|
||||
# as well as /etc/porttime)
|
||||
# account requisite pam_time.so
|
||||
|
||||
# Uncomment and edit /etc/security/access.conf if you need to
|
||||
# set access limits.
|
||||
# (Replaces /etc/login.access file)
|
||||
# account required pam_access.so
|
||||
|
||||
# Sets up user limits according to /etc/security/limits.conf
|
||||
# (Replaces the use of /etc/limits in old login)
|
||||
session required pam_limits.so
|
||||
|
||||
# Prints the last login info upon succesful login
|
||||
# (Replaces the `LASTLOG_ENAB' option from login.defs)
|
||||
session optional pam_lastlog.so
|
||||
|
||||
# Prints the message of the day upon succesful login.
|
||||
# (Replaces the `MOTD_FILE' option in login.defs)
|
||||
session optional pam_exec.so type=open_session stdout /bin/uname -snrvm
|
||||
session optional pam_motd.so
|
||||
|
||||
# Prints the status of the user's mailbox upon succesful login
|
||||
# (Replaces the `MAIL_CHECK_ENAB' option from login.defs).
|
||||
#
|
||||
# This also defines the MAIL environment variable
|
||||
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
|
||||
# in /etc/login.defs to make sure that removing a user
|
||||
# also removes the user's mail spool file.
|
||||
# See comments in /etc/login.defs
|
||||
session optional pam_mail.so standard
|
||||
|
||||
# Sets the loginuid process attribute
|
||||
session required pam_loginuid.so
|
||||
|
||||
# Standard Un*x account and session
|
||||
@include common-account
|
||||
@include common-session
|
||||
@include common-password
|
||||
|
||||
# SELinux needs to intervene at login time to ensure that the process
|
||||
# starts in the proper default security context. Only sessions which are
|
||||
# intended to run in the user's context should be run after this.
|
||||
session [success=ok ignore=ignore module_unknown=ignore default=bad] pam_selinux.so open
|
||||
# When the module is present, "required" would be sufficient (When SELinux
|
||||
# is disabled, this returns success.)
|
||||
Vendored
-44
@@ -1,44 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
if test "$1" = configure
|
||||
then
|
||||
if test -f /etc/init.d/logoutd
|
||||
then
|
||||
if test "$(md5sum /etc/init.d/logoutd)" = "9080f92783dd53f6f2108e698c06bd53 /etc/init.d/logoutd"
|
||||
then
|
||||
echo "removing logoutd cruft"
|
||||
rm /etc/init.d/logoutd
|
||||
update-rc.d logoutd remove
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm -f /etc/pam.d/login.pre-upgrade 2>/dev/null
|
||||
|
||||
if [ "$1" = "configure" ] && [ "$2" = "" ]
|
||||
then
|
||||
# Install faillog during initial installs only
|
||||
if [ ! -f /var/log/faillog ] ; then
|
||||
touch /var/log/faillog
|
||||
chown root:root /var/log/faillog
|
||||
chmod 644 /var/log/faillog
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create subuid/subgid if missing
|
||||
if [ ! -e /etc/subuid ]; then
|
||||
touch /etc/subuid
|
||||
chown root:root /etc/subuid
|
||||
chmod 644 /etc/subuid
|
||||
fi
|
||||
|
||||
if [ ! -e /etc/subgid ]; then
|
||||
touch /etc/subgid
|
||||
chown root:root /etc/subgid
|
||||
chmod 644 /etc/subgid
|
||||
fi
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
Vendored
-52
@@ -1,52 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <new-preinst> `install'
|
||||
# * <new-preinst> `install' <old-version>
|
||||
# * <new-preinst> `upgrade' <old-version>
|
||||
# * <old-preinst> `abort-upgrade' <new-version>
|
||||
#
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
remove_md5() {
|
||||
if md5sum $1 2>/dev/null |grep -q $2; then
|
||||
cp $1 $1.pre-upgrade
|
||||
sed -e '/^[^#][ \t]*assword[ \t]*required[ \t]*pam_unix.so/ s/ md5$//' $1 >$1.post-upgrade \
|
||||
&& mv $1.post-upgrade $1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
install|upgrade)
|
||||
if [ "x$2" != "x" ] ; then
|
||||
if dpkg --compare-versions $2 lt 1:4.0.3 ; then
|
||||
remove_md5 /etc/pam.d/login 5e61c3334e25625fe1fa4d79cf9123ff
|
||||
fi
|
||||
fi
|
||||
|
||||
;;
|
||||
|
||||
abort-upgrade)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "preinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
Vendored
-61
@@ -1,61 +0,0 @@
|
||||
#
|
||||
# The PAM configuration file for the Shadow `su' service
|
||||
#
|
||||
|
||||
# This allows root to su without passwords (normal operation)
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# Uncomment this to force users to be a member of group root
|
||||
# before they can use `su'. You can also add "group=foo"
|
||||
# to the end of this line if you want to use a group other
|
||||
# than the default "root" (but this may have side effect of
|
||||
# denying "root" user, unless she's a member of "foo" or explicitly
|
||||
# permitted earlier by e.g. "sufficient pam_rootok.so").
|
||||
# (Replaces the `SU_WHEEL_ONLY' option from login.defs)
|
||||
# auth required pam_wheel.so
|
||||
|
||||
# Uncomment this if you want wheel members to be able to
|
||||
# su without a password.
|
||||
# auth sufficient pam_wheel.so trust
|
||||
|
||||
# Uncomment this if you want members of a specific group to not
|
||||
# be allowed to use su at all.
|
||||
# auth required pam_wheel.so deny group=nosu
|
||||
|
||||
# Uncomment and edit /etc/security/time.conf if you need to set
|
||||
# time restrainst on su usage.
|
||||
# (Replaces the `PORTTIME_CHECKS_ENAB' option from login.defs
|
||||
# as well as /etc/porttime)
|
||||
# account requisite pam_time.so
|
||||
|
||||
# This module parses environment configuration file(s)
|
||||
# and also allows you to use an extended config
|
||||
# file /etc/security/pam_env.conf.
|
||||
#
|
||||
# parsing /etc/environment needs "readenv=1"
|
||||
session required pam_env.so readenv=1
|
||||
# locale variables are also kept into /etc/default/locale in etch
|
||||
# reading this file *in addition to /etc/environment* does not hurt
|
||||
session required pam_env.so readenv=1 envfile=/etc/default/locale
|
||||
|
||||
# Defines the MAIL environment variable
|
||||
# However, userdel also needs MAIL_DIR and MAIL_FILE variables
|
||||
# in /etc/login.defs to make sure that removing a user
|
||||
# also removes the user's mail spool file.
|
||||
# See comments in /etc/login.defs
|
||||
#
|
||||
# "nopen" stands to avoid reporting new mail when su'ing to another user
|
||||
session optional pam_mail.so nopen
|
||||
|
||||
# Sets up user limits according to /etc/security/limits.conf
|
||||
# (Replaces the use of /etc/limits in old login)
|
||||
session required pam_limits.so
|
||||
|
||||
# The standard Unix authentication modules, used with
|
||||
# NIS (man nsswitch) as well as normal /etc/passwd and
|
||||
# /etc/shadow entries.
|
||||
@include common-auth
|
||||
@include common-account
|
||||
@include common-session
|
||||
|
||||
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'chage' service
|
||||
#
|
||||
|
||||
# This allows root to change password aging being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
Vendored
-16
@@ -1,16 +0,0 @@
|
||||
#
|
||||
# The PAM configuration file for the Shadow `chfn' service
|
||||
#
|
||||
|
||||
# This allows root to change user infomation without being
|
||||
# prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# The standard Unix authentication modules, used with
|
||||
# NIS (man nsswitch) as well as normal /etc/passwd and
|
||||
# /etc/shadow entries.
|
||||
@include common-auth
|
||||
@include common-account
|
||||
@include common-session
|
||||
|
||||
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'chpasswd' service
|
||||
#
|
||||
|
||||
@include common-password
|
||||
|
||||
Vendored
-20
@@ -1,20 +0,0 @@
|
||||
#
|
||||
# The PAM configuration file for the Shadow `chsh' service
|
||||
#
|
||||
|
||||
# This will not allow a user to change their shell unless
|
||||
# their current one is listed in /etc/shells. This keeps
|
||||
# accounts with special shells from changing them.
|
||||
auth required pam_shells.so
|
||||
|
||||
# This allows root to change user shell without being
|
||||
# prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# The standard Unix authentication modules, used with
|
||||
# NIS (man nsswitch) as well as normal /etc/passwd and
|
||||
# /etc/shadow entries.
|
||||
@include common-auth
|
||||
@include common-account
|
||||
@include common-session
|
||||
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /var/backups || exit 0
|
||||
|
||||
for FILE in passwd group shadow gshadow; do
|
||||
test -f /etc/$FILE || continue
|
||||
cmp -s $FILE.bak /etc/$FILE && continue
|
||||
cp -p /etc/$FILE $FILE.bak && chmod 600 $FILE.bak
|
||||
done
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
usr/share/lintian/overrides
|
||||
etc/default
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
debian/passwd.expire.cron
|
||||
Vendored
-57
@@ -1,57 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# passwd.expire.cron: sample expiry notification script for use as a cronjob
|
||||
#
|
||||
# Copyright 1999 by Ben Collins <bcollins@debian.org>, complete rights granted
|
||||
# for use, distribution, modification, etc.
|
||||
#
|
||||
# Usage:
|
||||
# edit the listed options, including the actual email, then rename to
|
||||
# /etc/cron.daily/passwd
|
||||
#
|
||||
# If your users don't have a valid login shell (ie. they are ftp or mail
|
||||
# users only), they will need some other way to change their password
|
||||
# (telnet will work since login will handle password aging, or a poppasswd
|
||||
# program, if they are mail users).
|
||||
|
||||
# <CONFIG> #
|
||||
|
||||
# should be same as /etc/adduser.conf
|
||||
$LOW_UID=1000;
|
||||
$HIGH_UID=29999;
|
||||
|
||||
# this let's the MTA handle the domain,
|
||||
# set it manually if you want. Make sure
|
||||
# you also add the @ like "\@domain.com"
|
||||
$MAIL_DOM="";
|
||||
|
||||
# </CONFIG> #
|
||||
|
||||
# Set the current day reference
|
||||
$curdays = int(time() / (60 * 60 * 24));
|
||||
|
||||
# Now go through the list
|
||||
|
||||
open(SH, "< /etc/shadow");
|
||||
while (<SH>) {
|
||||
@shent = split(':', $_);
|
||||
@userent = getpwnam($shent[0]);
|
||||
if ($userent[2] >= $LOW_UID && $userent[2] <= $HIGH_UID) {
|
||||
if ($curdays > $shent[2] + $shent[4] - $shent[5] &&
|
||||
$shent[4] != -1 && $shent[4] != 0 &&
|
||||
$shent[5] != -1 && $shent[5] != 0) {
|
||||
$daysleft = ($shent[2] + $shent[4]) - $curdays;
|
||||
if ($daysleft == 1) { $days = "day"; } else {$days = "days"; }
|
||||
if ($daysleft < 0) { next; }
|
||||
open (MAIL, "| mail -s '[WARNING] account will expire in $daysleft $days' $shent[0]${MAIL_DOM}");
|
||||
print MAIL <<EOF;
|
||||
Your account will expire in $daysleft $days. Please change your password before
|
||||
then or your account will expire
|
||||
EOF
|
||||
close (MAIL);
|
||||
# This makes sure we also get a list of almost expired users
|
||||
print "$shent[0]'s account will expire in $daysleft days\n";
|
||||
}
|
||||
}
|
||||
@userent = getpwent();
|
||||
}
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'groupadd' service
|
||||
#
|
||||
|
||||
# This allows root to add groups without being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'groupdel' service
|
||||
#
|
||||
|
||||
# This allows root to remove groups without being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'groupmod' service
|
||||
#
|
||||
|
||||
# This allows root to modify groups without being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
Vendored
-78
@@ -1,78 +0,0 @@
|
||||
usr/bin/chage
|
||||
usr/bin/chfn
|
||||
usr/bin/chsh
|
||||
usr/bin/expiry
|
||||
usr/bin/gpasswd
|
||||
usr/bin/passwd
|
||||
usr/sbin/chpasswd
|
||||
usr/sbin/chgpasswd
|
||||
usr/sbin/cppw
|
||||
usr/sbin/groupadd
|
||||
usr/sbin/groupdel
|
||||
usr/sbin/groupmod
|
||||
usr/sbin/grpck
|
||||
usr/sbin/grpconv
|
||||
usr/sbin/grpunconv
|
||||
usr/sbin/newusers
|
||||
usr/sbin/pwck
|
||||
usr/sbin/pwconv
|
||||
usr/sbin/pwunconv
|
||||
usr/sbin/useradd
|
||||
usr/sbin/userdel
|
||||
usr/sbin/usermod
|
||||
usr/sbin/vipw
|
||||
usr/share/man/*/man1/chage.1
|
||||
usr/share/man/*/man1/chfn.1
|
||||
usr/share/man/*/man1/chsh.1
|
||||
usr/share/man/*/man1/expiry.1
|
||||
usr/share/man/*/man1/gpasswd.1
|
||||
usr/share/man/*/man1/passwd.1
|
||||
usr/share/man/*/man5/passwd.5
|
||||
usr/share/man/*/man5/shadow.5
|
||||
usr/share/man/*/man5/gshadow.5
|
||||
usr/share/man/*/man8/chpasswd.8
|
||||
usr/share/man/*/man8/groupadd.8
|
||||
usr/share/man/*/man8/groupdel.8
|
||||
usr/share/man/*/man8/groupmod.8
|
||||
usr/share/man/*/man8/grpck.8
|
||||
usr/share/man/*/man8/grpconv.8
|
||||
usr/share/man/*/man8/grpunconv.8
|
||||
usr/share/man/*/man8/newusers.8
|
||||
usr/share/man/*/man8/pwck.8
|
||||
usr/share/man/*/man8/pwconv.8
|
||||
usr/share/man/*/man8/pwunconv.8
|
||||
usr/share/man/*/man8/useradd.8
|
||||
usr/share/man/*/man8/userdel.8
|
||||
usr/share/man/*/man8/usermod.8
|
||||
usr/share/man/*/man8/vigr.8
|
||||
usr/share/man/*/man8/vipw.8
|
||||
usr/share/man/man1/chage.1
|
||||
usr/share/man/man1/chfn.1
|
||||
usr/share/man/man1/chsh.1
|
||||
usr/share/man/man1/expiry.1
|
||||
usr/share/man/man1/gpasswd.1
|
||||
usr/share/man/man1/passwd.1
|
||||
usr/share/man/man5/passwd.5
|
||||
usr/share/man/man5/shadow.5
|
||||
usr/share/man/man5/gshadow.5
|
||||
usr/share/man/man5/subuid.5
|
||||
usr/share/man/man5/subgid.5
|
||||
usr/share/man/man5/subgid.5
|
||||
usr/share/man/man5/subuid.5
|
||||
usr/share/man/man8/chgpasswd.8
|
||||
usr/share/man/man8/chpasswd.8
|
||||
usr/share/man/man8/groupadd.8
|
||||
usr/share/man/man8/groupdel.8
|
||||
usr/share/man/man8/groupmod.8
|
||||
usr/share/man/man8/grpck.8
|
||||
usr/share/man/man8/grpconv.8
|
||||
usr/share/man/man8/grpunconv.8
|
||||
usr/share/man/man8/newusers.8
|
||||
usr/share/man/man8/pwck.8
|
||||
usr/share/man/man8/pwconv.8
|
||||
usr/share/man/man8/pwunconv.8
|
||||
usr/share/man/man8/useradd.8
|
||||
usr/share/man/man8/userdel.8
|
||||
usr/share/man/man8/usermod.8
|
||||
usr/share/man/man8/vigr.8
|
||||
usr/share/man/man8/vipw.8
|
||||
Vendored
-2
@@ -1,2 +0,0 @@
|
||||
usr/sbin/vipw usr/sbin/vigr
|
||||
usr/sbin/cppw usr/sbin/cpgr
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
passwd: setgid-binary usr/bin/chage 2755 root/shadow
|
||||
passwd: setuid-binary usr/bin/chfn 4755 root/root
|
||||
passwd: setuid-binary usr/bin/chsh 4755 root/root
|
||||
passwd: setgid-binary usr/bin/expiry 2755 root/shadow
|
||||
passwd: setuid-binary usr/bin/gpasswd 4755 root/root
|
||||
passwd: setuid-binary usr/bin/passwd 4755 root/root
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'newusers' service
|
||||
#
|
||||
|
||||
@include common-password
|
||||
|
||||
Vendored
-6
@@ -1,6 +0,0 @@
|
||||
#
|
||||
# The PAM configuration file for the Shadow `passwd' service
|
||||
#
|
||||
|
||||
@include common-password
|
||||
|
||||
Vendored
-44
@@ -1,44 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
case "$1" in
|
||||
configure)
|
||||
# Fix permissions on various log files from old versions of the debian
|
||||
# installer, some unrelated to passwd but we decided to put the fix
|
||||
# here since there was no better place. This can safely be removed
|
||||
# after etch is released.
|
||||
if dpkg --compare-versions "$2" lt "1:4.0.14-9"; then
|
||||
for log in /var/log/base-config* \
|
||||
$(find /var/log/debian-installer/ /var/log/installer/ -type f 2>/dev/null ); do
|
||||
if [ -e "$log" ]; then
|
||||
chmod 600 "$log"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -f /etc/pam.d/passwd.pre-upgrade 2>/dev/null
|
||||
if ! getent group shadow | grep -q '^shadow:[^:]*:42'
|
||||
then
|
||||
groupadd -g 42 shadow || (
|
||||
cat <<EOF
|
||||
Group ID 42 has been allocated for the shadow group. You have either
|
||||
used 42 yourself or created a shadow group with a different ID.
|
||||
Please correct this problem and reconfigure with ``dpkg --configure passwd''.
|
||||
|
||||
Note that both user and group IDs in the range 0-99 are globally
|
||||
allocated by the Debian project and must be the same on every Debian
|
||||
system.
|
||||
EOF
|
||||
exit 1
|
||||
)
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Run shadowconfig only on new installs
|
||||
[ -z "$2" ] && shadowconfig on
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
Vendored
-51
@@ -1,51 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
#
|
||||
# see: dh_installdeb(1)
|
||||
|
||||
set -e
|
||||
|
||||
# summary of how this script can be called:
|
||||
# * <new-preinst> `install'
|
||||
# * <new-preinst> `install' <old-version>
|
||||
# * <new-preinst> `upgrade' <old-version>
|
||||
# * <old-preinst> `abort-upgrade' <new-version>
|
||||
#
|
||||
# for details, see http://www.debian.org/doc/debian-policy/ or
|
||||
# the debian-policy package
|
||||
|
||||
remove_md5() {
|
||||
if md5sum $1 2>/dev/null |grep -q $2; then
|
||||
cp $1 $1.pre-upgrade
|
||||
sed -e '/^[^#]*[ \t]*password[ \t]*required[ \t]*pam_unix.so/ s/ md5$//' $1 >$1.post-upgrade \
|
||||
&& mv $1.post-upgrade $1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
install|upgrade)
|
||||
if [ "x$2" != "x" ] ; then
|
||||
if dpkg --compare-versions $2 lt 1:4.0.3 ; then
|
||||
remove_md5 /etc/pam.d/passwd 23a5d1465bbc1e39ca6e0c32f22a75c9
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
|
||||
abort-upgrade)
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "preinst called with unknown argument \`$1'" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# dh_installdeb will replace this with shell code automatically
|
||||
# generated by other debhelper scripts.
|
||||
|
||||
#DEBHELPER#
|
||||
|
||||
exit 0
|
||||
|
||||
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'useradd' service
|
||||
#
|
||||
|
||||
# This allows root to add users without being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'userdel' service
|
||||
#
|
||||
|
||||
# This allows root to remove users without being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
# The PAM configuration file for the Shadow 'groupdel' service
|
||||
#
|
||||
|
||||
# This allows root to remove groups without being prompted for a password
|
||||
auth sufficient pam_rootok.so
|
||||
|
||||
# checks for account validity
|
||||
account required pam_permit.so
|
||||
-55
@@ -1,55 +0,0 @@
|
||||
Goal: Log login failures to the btmp file
|
||||
|
||||
Notes:
|
||||
* I'm not sure login should add an entry in the FTMP file when PAM is used.
|
||||
(but nothing in /etc/login.defs indicates that the failure is not logged)
|
||||
|
||||
Index: git/src/login.c
|
||||
===================================================================
|
||||
--- git.orig/src/login.c
|
||||
+++ git/src/login.c
|
||||
@@ -831,6 +831,24 @@
|
||||
(void) puts ("");
|
||||
(void) puts (_("Login incorrect"));
|
||||
|
||||
+ if (getdef_str("FTMP_FILE") != NULL) {
|
||||
+#ifdef USE_UTMPX
|
||||
+ struct utmpx *failent =
|
||||
+ prepare_utmpx (failent_user,
|
||||
+ tty,
|
||||
+ /* FIXME: or fromhost? */hostname,
|
||||
+ utent);
|
||||
+#else /* !USE_UTMPX */
|
||||
+ struct utmp *failent =
|
||||
+ prepare_utmp (failent_user,
|
||||
+ tty,
|
||||
+ hostname,
|
||||
+ utent);
|
||||
+#endif /* !USE_UTMPX */
|
||||
+ failtmp (failent_user, failent);
|
||||
+ free (failent);
|
||||
+ }
|
||||
+
|
||||
if (failcount >= retries) {
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"TOO MANY LOGIN TRIES (%u)%s FOR '%s'",
|
||||
Index: git/lib/getdef.c
|
||||
===================================================================
|
||||
--- git.orig/lib/getdef.c
|
||||
+++ git/lib/getdef.c
|
||||
@@ -62,6 +62,7 @@
|
||||
{"ERASECHAR", NULL},
|
||||
{"FAIL_DELAY", NULL},
|
||||
{"FAKE_SHELL", NULL},
|
||||
+ {"FTMP_FILE", NULL},
|
||||
{"GID_MAX", NULL},
|
||||
{"GID_MIN", NULL},
|
||||
{"HUSHLOGIN_FILE", NULL},
|
||||
@@ -109,7 +110,6 @@
|
||||
{"ENVIRON_FILE", NULL},
|
||||
{"ENV_TZ", NULL},
|
||||
{"FAILLOG_ENAB", NULL},
|
||||
- {"FTMP_FILE", NULL},
|
||||
{"ISSUE_FILE", NULL},
|
||||
{"LASTLOG_ENAB", NULL},
|
||||
{"LOGIN_STRING", NULL},
|
||||
Vendored
-93
@@ -1,93 +0,0 @@
|
||||
=== modified file 'etc/login.defs'
|
||||
Index: git/etc/login.defs
|
||||
===================================================================
|
||||
--- git.orig/etc/login.defs
|
||||
+++ git/etc/login.defs
|
||||
@@ -229,7 +229,7 @@
|
||||
# Extra per user uids
|
||||
SUB_UID_MIN 100000
|
||||
SUB_UID_MAX 600100000
|
||||
-SUB_UID_COUNT 10000
|
||||
+SUB_UID_COUNT 65536
|
||||
|
||||
#
|
||||
# Min/max values for automatic gid selection in groupadd(8)
|
||||
@@ -242,7 +242,7 @@
|
||||
# Extra per user group ids
|
||||
SUB_GID_MIN 100000
|
||||
SUB_GID_MAX 600100000
|
||||
-SUB_GID_COUNT 10000
|
||||
+SUB_GID_COUNT 65536
|
||||
|
||||
#
|
||||
# Max number of login(1) retries if password is bad
|
||||
Index: git/src/newusers.c
|
||||
===================================================================
|
||||
--- git.orig/src/newusers.c
|
||||
+++ git/src/newusers.c
|
||||
@@ -988,8 +988,8 @@
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
#ifdef ENABLE_SUBIDS
|
||||
- is_sub_uid = sub_uid_file_present ();
|
||||
- is_sub_gid = sub_gid_file_present ();
|
||||
+ is_sub_uid = sub_uid_file_present () && !rflg;
|
||||
+ is_sub_gid = sub_gid_file_present () && !rflg;
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
open_files ();
|
||||
Index: git/src/useradd.c
|
||||
===================================================================
|
||||
--- git.orig/src/useradd.c
|
||||
+++ git/src/useradd.c
|
||||
@@ -1994,6 +1994,10 @@
|
||||
#endif /* USE_PAM */
|
||||
#endif /* ACCT_TOOLS_SETUID */
|
||||
|
||||
+ /* Needed for userns check */
|
||||
+ uid_t uid_min = (uid_t) getdef_ulong ("UID_MIN", 1000UL);
|
||||
+ uid_t uid_max = (uid_t) getdef_ulong ("UID_MAX", 60000UL);
|
||||
+
|
||||
/*
|
||||
* Get my name so that I can use it to report errors.
|
||||
*/
|
||||
@@ -2023,8 +2027,10 @@
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
#ifdef ENABLE_SUBIDS
|
||||
- is_sub_uid = sub_uid_file_present ();
|
||||
- is_sub_gid = sub_gid_file_present ();
|
||||
+ is_sub_uid = sub_uid_file_present () && !rflg &&
|
||||
+ (!user_id || (user_id <= uid_max && user_id >= uid_min));
|
||||
+ is_sub_gid = sub_gid_file_present () && !rflg &&
|
||||
+ (!user_id || (user_id <= uid_max && user_id >= uid_min));
|
||||
#endif /* ENABLE_SUBIDS */
|
||||
|
||||
get_defaults ();
|
||||
|
||||
Index: git/libmisc/find_new_sub_uids.c
|
||||
===================================================================
|
||||
--- git.orig/libmisc/find_new_sub_uids.c
|
||||
+++ git/libmisc/find_new_sub_uids.c
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
min = getdef_ulong ("SUB_UID_MIN", 100000UL);
|
||||
max = getdef_ulong ("SUB_UID_MAX", 600100000UL);
|
||||
- count = getdef_ulong ("SUB_UID_COUNT", 10000);
|
||||
+ count = getdef_ulong ("SUB_UID_COUNT", 65536);
|
||||
|
||||
if (min > max || count >= max || (min + count - 1) > max) {
|
||||
(void) fprintf (stderr,
|
||||
Index: git/libmisc/find_new_sub_gids.c
|
||||
===================================================================
|
||||
--- git.orig/libmisc/find_new_sub_gids.c
|
||||
+++ git/libmisc/find_new_sub_gids.c
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
min = getdef_ulong ("SUB_GID_MIN", 100000UL);
|
||||
max = getdef_ulong ("SUB_GID_MAX", 600100000UL);
|
||||
- count = getdef_ulong ("SUB_GID_COUNT", 10000);
|
||||
+ count = getdef_ulong ("SUB_GID_COUNT", 65536);
|
||||
|
||||
if (min > max || count >= max || (min + count - 1) > max) {
|
||||
(void) fprintf (stderr,
|
||||
-2687
File diff suppressed because it is too large
Load Diff
-38
@@ -1,38 +0,0 @@
|
||||
Description: Fix user_busy to not leave subuid open in case of error.
|
||||
Author: William Grant <wgrant@ubuntu.com>
|
||||
Bug: https://bugs.launchpad.net/ubuntu/vivid/+source/shadow/+bug/1436937
|
||||
|
||||
Index: shadow-4.2/libmisc/user_busy.c
|
||||
===================================================================
|
||||
--- shadow-4.2.orig/libmisc/user_busy.c
|
||||
+++ shadow-4.2/libmisc/user_busy.c
|
||||
@@ -175,6 +175,9 @@ static int user_busy_processes (const ch
|
||||
if (stat ("/", &sbroot) != 0) {
|
||||
perror ("stat (\"/\")");
|
||||
(void) closedir (proc);
|
||||
+#ifdef ENABLE_SUBIDS
|
||||
+ sub_uid_close();
|
||||
+#endif /* ENABLE_SUBIDS */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -212,6 +215,9 @@ static int user_busy_processes (const ch
|
||||
|
||||
if (check_status (name, tmp_d_name, uid) != 0) {
|
||||
(void) closedir (proc);
|
||||
+#ifdef ENABLE_SUBIDS
|
||||
+ sub_uid_close();
|
||||
+#endif /* ENABLE_SUBIDS */
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently used by process %d\n"),
|
||||
Prog, name, pid);
|
||||
@@ -232,6 +238,9 @@ static int user_busy_processes (const ch
|
||||
}
|
||||
if (check_status (name, task_path+6, uid) != 0) {
|
||||
(void) closedir (proc);
|
||||
+#ifdef ENABLE_SUBIDS
|
||||
+ sub_uid_close();
|
||||
+#endif /* ENABLE_SUBIDS */
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently used by process %d\n"),
|
||||
Prog, name, pid);
|
||||
@@ -1,59 +0,0 @@
|
||||
From 08fd4b69e84364677a10e519ccb25b71710ee686 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
Date: Thu, 23 Feb 2017 09:47:29 -0600
|
||||
Subject: [PATCH] su: properly clear child PID
|
||||
|
||||
If su is compiled with PAM support, it is possible for any local user
|
||||
to send SIGKILL to other processes with root privileges. There are
|
||||
only two conditions. First, the user must be able to perform su with
|
||||
a successful login. This does NOT have to be the root user, even using
|
||||
su with the same id is enough, e.g. "su $(whoami)". Second, SIGKILL
|
||||
can only be sent to processes which were executed after the su process.
|
||||
It is not possible to send SIGKILL to processes which were already
|
||||
running. I consider this as a security vulnerability, because I was
|
||||
able to write a proof of concept which unlocked a screen saver of
|
||||
another user this way.
|
||||
---
|
||||
src/su.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/src/su.c
|
||||
+++ b/src/su.c
|
||||
@@ -363,20 +363,35 @@ static void prepare_pam_close_session (v
|
||||
/* wake child when resumed */
|
||||
kill (pid, SIGCONT);
|
||||
stop = false;
|
||||
+ } else {
|
||||
+ pid_child = 0;
|
||||
}
|
||||
} while (!stop);
|
||||
}
|
||||
|
||||
- if (0 != caught) {
|
||||
+ if (0 != caught && 0 != pid_child) {
|
||||
(void) fputs ("\n", stderr);
|
||||
(void) fputs (_("Session terminated, terminating shell..."),
|
||||
stderr);
|
||||
(void) kill (-pid_child, caught);
|
||||
|
||||
(void) signal (SIGALRM, kill_child);
|
||||
+ (void) signal (SIGCHLD, catch_signals);
|
||||
(void) alarm (2);
|
||||
|
||||
- (void) wait (&status);
|
||||
+ sigemptyset (&ourset);
|
||||
+ if ((sigaddset (&ourset, SIGALRM) != 0)
|
||||
+ || (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0)) {
|
||||
+ fprintf (stderr, _("%s: signal masking malfunction\n"), Prog);
|
||||
+ kill_child (0);
|
||||
+ } else {
|
||||
+ while (0 == waitpid (pid_child, &status, WNOHANG)) {
|
||||
+ sigsuspend (&ourset);
|
||||
+ }
|
||||
+ pid_child = 0;
|
||||
+ (void) sigprocmask (SIG_UNBLOCK, &ourset, NULL);
|
||||
+ }
|
||||
+
|
||||
(void) fputs (_(" ...terminated.\n"), stderr);
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
From 1d5a926cc2d6078d23a96222b1ef3e558724dad1 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Krahmer <krahmer@suse.com>
|
||||
Date: Wed, 3 Aug 2016 11:51:07 -0500
|
||||
Subject: [PATCH] Simplify getulong
|
||||
|
||||
Use strtoul to read an unsigned long, rather than reading
|
||||
a signed long long and casting it.
|
||||
|
||||
https://bugzilla.suse.com/show_bug.cgi?id=979282
|
||||
---
|
||||
lib/getulong.c | 9 +++------
|
||||
1 file changed, 3 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/lib/getulong.c b/lib/getulong.c
|
||||
index 61579ca..08d2c1a 100644
|
||||
--- a/lib/getulong.c
|
||||
+++ b/lib/getulong.c
|
||||
@@ -44,22 +44,19 @@
|
||||
*/
|
||||
int getulong (const char *numstr, /*@out@*/unsigned long int *result)
|
||||
{
|
||||
- long long int val;
|
||||
+ unsigned long int val;
|
||||
char *endptr;
|
||||
|
||||
errno = 0;
|
||||
- val = strtoll (numstr, &endptr, 0);
|
||||
+ val = strtoul (numstr, &endptr, 0);
|
||||
if ( ('\0' == *numstr)
|
||||
|| ('\0' != *endptr)
|
||||
|| (ERANGE == errno)
|
||||
- /*@+ignoresigns@*/
|
||||
- || (val != (unsigned long int)val)
|
||||
- /*@=ignoresigns@*/
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
- *result = (unsigned long int)val;
|
||||
+ *result = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
From 7d82f203eeec881c584b2fa06539b39e82985d97 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
Date: Sun, 14 May 2017 17:58:10 +0200
|
||||
Subject: [PATCH] Reset pid_child only if waitpid was successful.
|
||||
|
||||
Do not reset the pid_child to 0 if the child process is still
|
||||
running. This else-condition can be reached with pid being -1,
|
||||
therefore explicitly test this condition.
|
||||
|
||||
This is a regression fix for CVE-2017-2616. If su receives a
|
||||
signal like SIGTERM, it is not propagated to the child.
|
||||
|
||||
Reported-by: Radu Duta <raduduta@gmail.com>
|
||||
Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
|
||||
---
|
||||
src/su.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/src/su.c
|
||||
+++ b/src/su.c
|
||||
@@ -363,7 +363,7 @@ static void prepare_pam_close_session (v
|
||||
/* wake child when resumed */
|
||||
kill (pid, SIGCONT);
|
||||
stop = false;
|
||||
- } else {
|
||||
+ } else if ( (pid_t)-1 != pid) {
|
||||
pid_child = 0;
|
||||
}
|
||||
} while (!stop);
|
||||
Vendored
-282
@@ -1,282 +0,0 @@
|
||||
#! /bin/sh /usr/share/dpatch/dpatch-run
|
||||
## 401_cppw_src.dpatch by Nicolas FRANCOIS <nicolas.francois@centraliens.net>
|
||||
##
|
||||
## All lines beginning with `## DP:' are a description of the patch.
|
||||
## DP: Add cppw / cpgr
|
||||
|
||||
@DPATCH@
|
||||
Index: git/src/cppw.c
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/src/cppw.c
|
||||
@@ -0,0 +1,238 @@
|
||||
+/*
|
||||
+ cppw, cpgr copy with locking given file over the password or group file
|
||||
+ with -s will copy with locking given file over shadow or gshadow file
|
||||
+
|
||||
+ Copyright (C) 1999 Stephen Frost <sfrost@snowman.net>
|
||||
+
|
||||
+ Based on vipw, vigr by:
|
||||
+ Copyright (C) 1997 Guy Maor <maor@ece.utexas.edu>
|
||||
+
|
||||
+ 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 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program is distributed in the hope that it will be useful, but
|
||||
+ WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program; if not, write to the Free Software
|
||||
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
+
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+#include "defines.h"
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <unistd.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <signal.h>
|
||||
+#include <utime.h>
|
||||
+#include "exitcodes.h"
|
||||
+#include "prototypes.h"
|
||||
+#include "pwio.h"
|
||||
+#include "shadowio.h"
|
||||
+#include "groupio.h"
|
||||
+#include "sgroupio.h"
|
||||
+
|
||||
+
|
||||
+const char *Prog;
|
||||
+
|
||||
+const char *filename, *filenewname;
|
||||
+static bool filelocked = false;
|
||||
+static int (*unlock) (void);
|
||||
+
|
||||
+/* local function prototypes */
|
||||
+static int create_copy (FILE *fp, const char *dest, struct stat *sb);
|
||||
+static void cppwexit (const char *msg, int syserr, int ret);
|
||||
+static void cppwcopy (const char *file,
|
||||
+ const char *in_file,
|
||||
+ int (*file_lock) (void),
|
||||
+ int (*file_unlock) (void));
|
||||
+
|
||||
+static int create_copy (FILE *fp, const char *dest, struct stat *sb)
|
||||
+{
|
||||
+ struct utimbuf ub;
|
||||
+ FILE *bkfp;
|
||||
+ int c;
|
||||
+ mode_t mask;
|
||||
+
|
||||
+ mask = umask (077);
|
||||
+ bkfp = fopen (dest, "w");
|
||||
+ (void) umask (mask);
|
||||
+ if (NULL == bkfp) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ rewind (fp);
|
||||
+ while ((c = getc (fp)) != EOF) {
|
||||
+ if (putc (c, bkfp) == EOF) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if ( (c != EOF)
|
||||
+ || (fflush (bkfp) != 0)) {
|
||||
+ (void) fclose (bkfp);
|
||||
+ (void) unlink (dest);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if ( (fsync (fileno (bkfp)) != 0)
|
||||
+ || (fclose (bkfp) != 0)) {
|
||||
+ (void) unlink (dest);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ ub.actime = sb->st_atime;
|
||||
+ ub.modtime = sb->st_mtime;
|
||||
+ if ( (utime (dest, &ub) != 0)
|
||||
+ || (chmod (dest, sb->st_mode) != 0)
|
||||
+ || (chown (dest, sb->st_uid, sb->st_gid) != 0)) {
|
||||
+ (void) unlink (dest);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void cppwexit (const char *msg, int syserr, int ret)
|
||||
+{
|
||||
+ int err = errno;
|
||||
+ if (filelocked) {
|
||||
+ (*unlock) ();
|
||||
+ }
|
||||
+ if (NULL != msg) {
|
||||
+ fprintf (stderr, "%s: %s", Prog, msg);
|
||||
+ if (0 != syserr) {
|
||||
+ fprintf (stderr, ": %s", strerror (err));
|
||||
+ }
|
||||
+ (void) fputs ("\n", stderr);
|
||||
+ }
|
||||
+ if (NULL != filename) {
|
||||
+ fprintf (stderr, _("%s: %s is unchanged\n"), Prog, filename);
|
||||
+ } else {
|
||||
+ fprintf (stderr, _("%s: no changes\n"), Prog);
|
||||
+ }
|
||||
+
|
||||
+ exit (ret);
|
||||
+}
|
||||
+
|
||||
+static void cppwcopy (const char *file,
|
||||
+ const char *in_file,
|
||||
+ int (*file_lock) (void),
|
||||
+ int (*file_unlock) (void))
|
||||
+{
|
||||
+ struct stat st1;
|
||||
+ FILE *f;
|
||||
+ char filenew[1024];
|
||||
+
|
||||
+ snprintf (filenew, sizeof filenew, "%s.new", file);
|
||||
+ unlock = file_unlock;
|
||||
+ filename = file;
|
||||
+ filenewname = filenew;
|
||||
+
|
||||
+ if (access (file, F_OK) != 0) {
|
||||
+ cppwexit (file, 1, 1);
|
||||
+ }
|
||||
+ if (file_lock () == 0) {
|
||||
+ cppwexit (_("Couldn't lock file"), 0, 5);
|
||||
+ }
|
||||
+ filelocked = true;
|
||||
+
|
||||
+ /* file to copy has same owners, perm */
|
||||
+ if (stat (file, &st1) != 0) {
|
||||
+ cppwexit (file, 1, 1);
|
||||
+ }
|
||||
+ f = fopen (in_file, "r");
|
||||
+ if (NULL == f) {
|
||||
+ cppwexit (in_file, 1, 1);
|
||||
+ }
|
||||
+ if (create_copy (f, filenew, &st1) != 0) {
|
||||
+ cppwexit (_("Couldn't make copy"), errno, 1);
|
||||
+ }
|
||||
+
|
||||
+ /* XXX - here we should check filenew for errors; if there are any,
|
||||
+ * fail w/ an appropriate error code and let the user manually fix
|
||||
+ * it. Use pwck or grpck to do the check. - Stephen (Shamelessly
|
||||
+ * stolen from '--marekm's comment) */
|
||||
+
|
||||
+ if (rename (filenew, file) != 0) {
|
||||
+ fprintf (stderr, _("%s: can't copy %s: %s)\n"),
|
||||
+ Prog, filenew, strerror (errno));
|
||||
+ cppwexit (NULL,0,1);
|
||||
+ }
|
||||
+
|
||||
+ (*file_unlock) ();
|
||||
+}
|
||||
+
|
||||
+int main (int argc, char **argv)
|
||||
+{
|
||||
+ int flag;
|
||||
+ bool cpshadow = false;
|
||||
+ char *in_file;
|
||||
+ int e = E_USAGE;
|
||||
+ bool do_cppw = true;
|
||||
+
|
||||
+ (void) setlocale (LC_ALL, "");
|
||||
+ (void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
+ (void) textdomain (PACKAGE);
|
||||
+
|
||||
+ Prog = Basename (argv[0]);
|
||||
+ if (strcmp (Prog, "cpgr") == 0) {
|
||||
+ do_cppw = false;
|
||||
+ }
|
||||
+
|
||||
+ while ((flag = getopt (argc, argv, "ghps")) != EOF) {
|
||||
+ switch (flag) {
|
||||
+ case 'p':
|
||||
+ do_cppw = true;
|
||||
+ break;
|
||||
+ case 'g':
|
||||
+ do_cppw = false;
|
||||
+ break;
|
||||
+ case 's':
|
||||
+ cpshadow = true;
|
||||
+ break;
|
||||
+ case 'h':
|
||||
+ e = E_SUCCESS;
|
||||
+ /*pass through*/
|
||||
+ default:
|
||||
+ (void) fputs (_("Usage:\n\
|
||||
+`cppw <file>' copys over /etc/passwd `cppw -s <file>' copys over /etc/shadow\n\
|
||||
+`cpgr <file>' copys over /etc/group `cpgr -s <file>' copys over /etc/gshadow\n\
|
||||
+"), (E_SUCCESS != e) ? stderr : stdout);
|
||||
+ exit (e);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (argc != optind + 1) {
|
||||
+ cppwexit (_("wrong number of arguments, -h for usage"),0,1);
|
||||
+ }
|
||||
+
|
||||
+ in_file = argv[optind];
|
||||
+
|
||||
+ if (do_cppw) {
|
||||
+ if (cpshadow) {
|
||||
+ cppwcopy (SHADOW_FILE, in_file, spw_lock, spw_unlock);
|
||||
+ } else {
|
||||
+ cppwcopy (PASSWD_FILE, in_file, pw_lock, pw_unlock);
|
||||
+ }
|
||||
+ } else {
|
||||
+#ifdef SHADOWGRP
|
||||
+ if (cpshadow) {
|
||||
+ cppwcopy (SGROUP_FILE, in_file, sgr_lock, sgr_unlock);
|
||||
+ } else
|
||||
+#endif /* SHADOWGRP */
|
||||
+ {
|
||||
+ cppwcopy (GROUP_FILE, in_file, gr_lock, gr_unlock);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
Index: git/src/Makefile.am
|
||||
===================================================================
|
||||
--- git.orig/src/Makefile.am
|
||||
+++ git/src/Makefile.am
|
||||
@@ -29,6 +29,7 @@
|
||||
ubin_PROGRAMS += newgidmap newuidmap
|
||||
endif
|
||||
usbin_PROGRAMS = \
|
||||
+ cppw \
|
||||
chgpasswd \
|
||||
chpasswd \
|
||||
groupadd \
|
||||
@@ -87,6 +88,7 @@
|
||||
chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
|
||||
chsh_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
|
||||
chpasswd_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT)
|
||||
+cppw_LDADD = $(LDADD) $(LIBSELINUX)
|
||||
gpasswd_LDADD = $(LDADD) $(LIBAUDIT) $(LIBSELINUX) $(LIBCRYPT)
|
||||
groupadd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
||||
groupdel_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
|
||||
Index: git/po/POTFILES.in
|
||||
===================================================================
|
||||
--- git.orig/po/POTFILES.in
|
||||
+++ git/po/POTFILES.in
|
||||
@@ -85,6 +85,7 @@
|
||||
src/chgpasswd.c
|
||||
src/chpasswd.c
|
||||
src/chsh.c
|
||||
+src/cppw.c
|
||||
src/expiry.c
|
||||
src/faillog.c
|
||||
src/gpasswd.c
|
||||
Vendored
-64
@@ -1,64 +0,0 @@
|
||||
Goal: Add selinux support to cppw
|
||||
|
||||
Fix:
|
||||
|
||||
Status wrt upstream: cppw is not available upstream.
|
||||
The patch was made based on the
|
||||
302_vim_selinux_support patch. It needs to be
|
||||
reviewed by an SE-Linux aware person.
|
||||
|
||||
Depends on 401_cppw_src.dpatch
|
||||
|
||||
Index: git/src/cppw.c
|
||||
===================================================================
|
||||
--- git.orig/src/cppw.c
|
||||
+++ git/src/cppw.c
|
||||
@@ -34,6 +34,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <utime.h>
|
||||
+#ifdef WITH_SELINUX
|
||||
+#include <selinux/selinux.h>
|
||||
+#endif /* WITH_SELINUX */
|
||||
#include "exitcodes.h"
|
||||
#include "prototypes.h"
|
||||
#include "pwio.h"
|
||||
@@ -139,6 +142,22 @@
|
||||
if (access (file, F_OK) != 0) {
|
||||
cppwexit (file, 1, 1);
|
||||
}
|
||||
+#ifdef WITH_SELINUX
|
||||
+ /* if SE Linux is enabled then set the context of all new files
|
||||
+ * to be the context of the file we are editing */
|
||||
+ if (is_selinux_enabled () > 0) {
|
||||
+ security_context_t passwd_context=NULL;
|
||||
+ int ret = 0;
|
||||
+ if (getfilecon (file, &passwd_context) < 0) {
|
||||
+ cppwexit (_("Couldn't get file context"), errno, 1);
|
||||
+ }
|
||||
+ ret = setfscreatecon (passwd_context);
|
||||
+ freecon (passwd_context);
|
||||
+ if (0 != ret) {
|
||||
+ cppwexit (_("setfscreatecon () failed"), errno, 1);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* WITH_SELINUX */
|
||||
if (file_lock () == 0) {
|
||||
cppwexit (_("Couldn't lock file"), 0, 5);
|
||||
}
|
||||
@@ -167,6 +186,15 @@
|
||||
cppwexit (NULL,0,1);
|
||||
}
|
||||
|
||||
+#ifdef WITH_SELINUX
|
||||
+ /* unset the fscreatecon */
|
||||
+ if (is_selinux_enabled () > 0) {
|
||||
+ if (setfscreatecon (NULL)) {
|
||||
+ cppwexit (_("setfscreatecon() failed"), errno, 1);
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* WITH_SELINUX */
|
||||
+
|
||||
(*file_unlock) ();
|
||||
}
|
||||
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
Goal: Re-enable logging and displaying failures on login when login is
|
||||
compiled with PAM and when FAILLOG_ENAB is set to yes. And create the
|
||||
faillog file if it does not exist on postinst (as on Woody).
|
||||
Depends: 008_login_more_LOG_UNKFAIL_ENAB
|
||||
Fixes: #192849
|
||||
|
||||
Note: It could be removed if pam_tally could report the number of failures
|
||||
preceding a successful login.
|
||||
|
||||
Index: git/src/login.c
|
||||
===================================================================
|
||||
--- git.orig/src/login.c
|
||||
+++ git/src/login.c
|
||||
@@ -131,9 +131,9 @@
|
||||
const char *host,
|
||||
/*@null@*/const struct utmp *utent);
|
||||
|
||||
-#ifndef USE_PAM
|
||||
static struct faillog faillog;
|
||||
|
||||
+#ifndef USE_PAM
|
||||
static void bad_time_notify (void);
|
||||
static void check_nologin (bool login_to_root);
|
||||
#else
|
||||
@@ -791,6 +791,9 @@
|
||||
SYSLOG ((LOG_NOTICE,
|
||||
"TOO MANY LOGIN TRIES (%u)%s FOR '%s'",
|
||||
failcount, fromhost, failent_user));
|
||||
+ if ((NULL != pwd) && getdef_bool("FAILLOG_ENAB")) {
|
||||
+ failure (pwd->pw_uid, tty, &faillog);
|
||||
+ }
|
||||
fprintf (stderr,
|
||||
_("Maximum number of tries exceeded (%u)\n"),
|
||||
failcount);
|
||||
@@ -808,6 +811,14 @@
|
||||
pam_strerror (pamh, retcode)));
|
||||
failed = true;
|
||||
}
|
||||
+ if ( (NULL != pwd)
|
||||
+ && getdef_bool("FAILLOG_ENAB")
|
||||
+ && ! failcheck (pwd->pw_uid, &faillog, failed)) {
|
||||
+ SYSLOG((LOG_CRIT,
|
||||
+ "exceeded failure limit for `%s' %s",
|
||||
+ failent_user, fromhost));
|
||||
+ failed = 1;
|
||||
+ }
|
||||
|
||||
if (!failed) {
|
||||
break;
|
||||
@@ -831,6 +842,10 @@
|
||||
(void) puts ("");
|
||||
(void) puts (_("Login incorrect"));
|
||||
|
||||
+ if ((NULL != pwd) && getdef_bool("FAILLOG_ENAB")) {
|
||||
+ failure (pwd->pw_uid, tty, &faillog);
|
||||
+ }
|
||||
+
|
||||
if (getdef_str("FTMP_FILE") != NULL) {
|
||||
#ifdef USE_UTMPX
|
||||
struct utmpx *failent =
|
||||
@@ -1285,6 +1300,7 @@
|
||||
*/
|
||||
#ifndef USE_PAM
|
||||
motd (); /* print the message of the day */
|
||||
+#endif
|
||||
if ( getdef_bool ("FAILLOG_ENAB")
|
||||
&& (0 != faillog.fail_cnt)) {
|
||||
failprint (&faillog);
|
||||
@@ -1297,6 +1313,7 @@
|
||||
username, (int) faillog.fail_cnt));
|
||||
}
|
||||
}
|
||||
+#ifndef USE_PAM
|
||||
if ( getdef_bool ("LASTLOG_ENAB")
|
||||
&& (ll.ll_time != 0)) {
|
||||
time_t ll_time = ll.ll_time;
|
||||
Index: git/lib/getdef.c
|
||||
===================================================================
|
||||
--- git.orig/lib/getdef.c
|
||||
+++ git/lib/getdef.c
|
||||
@@ -61,6 +61,7 @@
|
||||
{"ENV_SUPATH", NULL},
|
||||
{"ERASECHAR", NULL},
|
||||
{"FAIL_DELAY", NULL},
|
||||
+ {"FAILLOG_ENAB", NULL},
|
||||
{"FAKE_SHELL", NULL},
|
||||
{"FTMP_FILE", NULL},
|
||||
{"GID_MAX", NULL},
|
||||
@@ -109,7 +110,6 @@
|
||||
{"ENV_HZ", NULL},
|
||||
{"ENVIRON_FILE", NULL},
|
||||
{"ENV_TZ", NULL},
|
||||
- {"FAILLOG_ENAB", NULL},
|
||||
{"ISSUE_FILE", NULL},
|
||||
{"LASTLOG_ENAB", NULL},
|
||||
{"LOGIN_STRING", NULL},
|
||||
-109
@@ -1,109 +0,0 @@
|
||||
Goal: Do not hardcode pam_fail_delay and let pam_unix do its
|
||||
job to set a delay...or not
|
||||
|
||||
Fixes: #87648
|
||||
|
||||
Status wrt upstream: Forwarded but not applied yet
|
||||
|
||||
Note: If removed, FAIL_DELAY must be re-added to /etc/login.defs
|
||||
|
||||
Index: git/src/login.c
|
||||
===================================================================
|
||||
--- git.orig/src/login.c
|
||||
+++ git/src/login.c
|
||||
@@ -525,7 +525,6 @@
|
||||
#if defined(HAVE_STRFTIME) && !defined(USE_PAM)
|
||||
char ptime[80];
|
||||
#endif
|
||||
- unsigned int delay;
|
||||
unsigned int retries;
|
||||
bool subroot = false;
|
||||
#ifndef USE_PAM
|
||||
@@ -545,6 +544,7 @@
|
||||
pid_t child;
|
||||
char *pam_user = NULL;
|
||||
#else
|
||||
+ unsigned int delay;
|
||||
struct spwd *spwd = NULL;
|
||||
#endif
|
||||
/*
|
||||
@@ -705,7 +705,6 @@
|
||||
}
|
||||
|
||||
environ = newenvp; /* make new environment active */
|
||||
- delay = getdef_unum ("FAIL_DELAY", 1);
|
||||
retries = getdef_unum ("LOGIN_RETRIES", RETRIES);
|
||||
|
||||
#ifdef USE_PAM
|
||||
@@ -721,8 +720,7 @@
|
||||
|
||||
/*
|
||||
* hostname & tty are either set to NULL or their correct values,
|
||||
- * depending on how much we know. We also set PAM's fail delay to
|
||||
- * ours.
|
||||
+ * depending on how much we know.
|
||||
*
|
||||
* PAM_RHOST and PAM_TTY are used for authentication, only use
|
||||
* information coming from login or from the caller (e.g. no utmp)
|
||||
@@ -731,10 +729,6 @@
|
||||
PAM_FAIL_CHECK;
|
||||
retcode = pam_set_item (pamh, PAM_TTY, tty);
|
||||
PAM_FAIL_CHECK;
|
||||
-#ifdef HAS_PAM_FAIL_DELAY
|
||||
- retcode = pam_fail_delay (pamh, 1000000 * delay);
|
||||
- PAM_FAIL_CHECK;
|
||||
-#endif
|
||||
/* if fflg, then the user has already been authenticated */
|
||||
if (!fflg) {
|
||||
unsigned int failcount = 0;
|
||||
@@ -775,12 +769,6 @@
|
||||
bool failed = false;
|
||||
|
||||
failcount++;
|
||||
-#ifdef HAS_PAM_FAIL_DELAY
|
||||
- if (delay > 0) {
|
||||
- retcode = pam_fail_delay(pamh, 1000000*delay);
|
||||
- PAM_FAIL_CHECK;
|
||||
- }
|
||||
-#endif
|
||||
|
||||
retcode = pam_authenticate (pamh, 0);
|
||||
|
||||
@@ -1103,14 +1091,17 @@
|
||||
free (username);
|
||||
username = NULL;
|
||||
|
||||
+#ifndef USE_PAM
|
||||
/*
|
||||
* Wait a while (a la SVR4 /usr/bin/login) before attempting
|
||||
* to login the user again. If the earlier alarm occurs
|
||||
* before the sleep() below completes, login will exit.
|
||||
*/
|
||||
+ delay = getdef_unum ("FAIL_DELAY", 1);
|
||||
if (delay > 0) {
|
||||
(void) sleep (delay);
|
||||
}
|
||||
+#endif
|
||||
|
||||
(void) puts (_("Login incorrect"));
|
||||
|
||||
Index: git/lib/getdef.c
|
||||
===================================================================
|
||||
--- git.orig/lib/getdef.c
|
||||
+++ git/lib/getdef.c
|
||||
@@ -60,7 +60,6 @@
|
||||
{"ENV_PATH", NULL},
|
||||
{"ENV_SUPATH", NULL},
|
||||
{"ERASECHAR", NULL},
|
||||
- {"FAIL_DELAY", NULL},
|
||||
{"FAILLOG_ENAB", NULL},
|
||||
{"FAKE_SHELL", NULL},
|
||||
{"FTMP_FILE", NULL},
|
||||
@@ -110,6 +109,7 @@
|
||||
{"ENV_HZ", NULL},
|
||||
{"ENVIRON_FILE", NULL},
|
||||
{"ENV_TZ", NULL},
|
||||
+ {"FAIL_DELAY", NULL},
|
||||
{"ISSUE_FILE", NULL},
|
||||
{"LASTLOG_ENAB", NULL},
|
||||
{"LOGIN_STRING", NULL},
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
Goal: save the [g]shadow files with the 'shadow' group and mode 0440
|
||||
|
||||
Fixes: #166793
|
||||
|
||||
Index: git/lib/commonio.c
|
||||
===================================================================
|
||||
--- git.orig/lib/commonio.c
|
||||
+++ git/lib/commonio.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
+#include <grp.h>
|
||||
#include "nscd.h"
|
||||
#ifdef WITH_TCB
|
||||
#include <tcb.h>
|
||||
@@ -966,13 +967,20 @@
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
+ struct group *grp;
|
||||
/*
|
||||
* Default permissions for new [g]shadow files.
|
||||
* (passwd and group always exist...)
|
||||
*/
|
||||
- sb.st_mode = 0400;
|
||||
+ sb.st_mode = 0440;
|
||||
sb.st_uid = 0;
|
||||
- sb.st_gid = 0;
|
||||
+ /*
|
||||
+ * Try to retrieve the shadow's GID, and fall back to GID 0.
|
||||
+ */
|
||||
+ if ((grp = getgrnam("shadow")) != NULL)
|
||||
+ sb.st_gid = grp->gr_gid;
|
||||
+ else
|
||||
+ sb.st_gid = 0;
|
||||
}
|
||||
|
||||
snprintf (buf, sizeof buf, "%s+", db->filename);
|
||||
Vendored
-201
@@ -1,201 +0,0 @@
|
||||
Goal: Document the shadowconfig utility
|
||||
|
||||
Status wrt upstream: The shadowconfig utility is debian specific.
|
||||
Its man page also (but it used to be distributed)
|
||||
|
||||
Index: git/man/shadowconfig.8
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/man/shadowconfig.8
|
||||
@@ -0,0 +1,41 @@
|
||||
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
|
||||
+.de Sh \" Subsection
|
||||
+.br
|
||||
+.if t .Sp
|
||||
+.ne 5
|
||||
+.PP
|
||||
+\fB\\$1\fR
|
||||
+.PP
|
||||
+..
|
||||
+.de Sp \" Vertical space (when we can't use .PP)
|
||||
+.if t .sp .5v
|
||||
+.if n .sp
|
||||
+..
|
||||
+.de Ip \" List item
|
||||
+.br
|
||||
+.ie \\n(.$>=3 .ne \\$3
|
||||
+.el .ne 3
|
||||
+.IP "\\$1" \\$2
|
||||
+..
|
||||
+.TH "SHADOWCONFIG" 8 "19 Apr 1997" "" ""
|
||||
+.SH NAME
|
||||
+shadowconfig \- toggle shadow passwords on and off
|
||||
+.SH "SYNOPSIS"
|
||||
+.ad l
|
||||
+.hy 0
|
||||
+.HP 13
|
||||
+\fBshadowconfig\fR \fB\fIon\fR\fR | \fB\fIoff\fR\fR
|
||||
+.ad
|
||||
+.hy
|
||||
+
|
||||
+.SH "DESCRIPTION"
|
||||
+
|
||||
+.PP
|
||||
+\fBshadowconfig\fR on will turn shadow passwords on; \fIshadowconfig off\fR will turn shadow passwords off\&. \fBshadowconfig\fR will print an error message and exit with a nonzero code if it finds anything awry\&. If that happens, you should correct the error and run it again\&. Turning shadow passwords on when they are already on, or off when they are already off, is harmless\&.
|
||||
+
|
||||
+.PP
|
||||
+Read \fI/usr/share/doc/passwd/README\&.Debian\fR for a brief introduction to shadow passwords and related features\&.
|
||||
+
|
||||
+.PP
|
||||
+Note that turning shadow passwords off and on again will lose all password aging information\&.
|
||||
+
|
||||
Index: git/man/shadowconfig.8.xml
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/man/shadowconfig.8.xml
|
||||
@@ -0,0 +1,52 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
|
||||
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
|
||||
+<refentry id='shadowconfig.8'>
|
||||
+ <!-- $Id: shadowconfig.8.xml,v 1.6 2005/06/15 12:39:27 kloczek Exp $ -->
|
||||
+ <refentryinfo>
|
||||
+ <date>19 Apr 1997</date>
|
||||
+ </refentryinfo>
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>shadowconfig</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum>
|
||||
+ <refmiscinfo class='date'>19 Apr 1997</refmiscinfo>
|
||||
+ <refmiscinfo class='source'>Debian GNU/Linux</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+ <refnamediv id='name'>
|
||||
+ <refname>shadowconfig</refname>
|
||||
+ <refpurpose>toggle shadow passwords on and off</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsynopsisdiv id='synopsis'>
|
||||
+ <cmdsynopsis>
|
||||
+ <command>shadowconfig</command>
|
||||
+ <group choice='plain'>
|
||||
+ <arg choice='plain'><replaceable>on</replaceable></arg>
|
||||
+ <arg choice='plain'><replaceable>off</replaceable></arg>
|
||||
+ </group>
|
||||
+ </cmdsynopsis>
|
||||
+ </refsynopsisdiv>
|
||||
+
|
||||
+ <refsect1 id='description'>
|
||||
+ <title>DESCRIPTION</title>
|
||||
+ <para><command>shadowconfig</command> on will turn shadow passwords on;
|
||||
+ <emphasis remap='B'>shadowconfig off</emphasis> will turn shadow
|
||||
+ passwords off. <command>shadowconfig</command> will print an error
|
||||
+ message and exit with a nonzero code if it finds anything awry. If
|
||||
+ that happens, you should correct the error and run it again. Turning
|
||||
+ shadow passwords on when they are already on, or off when they are
|
||||
+ already off, is harmless.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ Read <filename>/usr/share/doc/passwd/README.Debian</filename> for a
|
||||
+ brief introduction
|
||||
+ to shadow passwords and related features.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>Note that turning shadow passwords off and on again will lose all
|
||||
+ password
|
||||
+ aging information.
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+</refentry>
|
||||
Index: git/man/fr/shadowconfig.8
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/man/fr/shadowconfig.8
|
||||
@@ -0,0 +1,26 @@
|
||||
+.\" This file was generated with po4a. Translate the source file.
|
||||
+.\"
|
||||
+.\"$Id: shadowconfig.8,v 1.4 2001/08/23 23:10:48 kloczek Exp $
|
||||
+.TH SHADOWCONFIG 8 "19 avril 1997" "Debian GNU/Linux"
|
||||
+.SH NOM
|
||||
+shadowconfig \- active ou désactive les mots de passe cachés
|
||||
+.SH SYNOPSIS
|
||||
+\fBshadowconfig\fP \fIon\fP | \fIoff\fP
|
||||
+.SH DESCRIPTION
|
||||
+.PP
|
||||
+\fBshadowconfig on\fP active les mots de passe cachés («\ shadow passwords\ »)\ ; \fBshadowconfig off\fP les désactive. \fBShadowconfig\fP affiche un message
|
||||
+d'erreur et quitte avec une valeur de retour non nulle s'il rencontre
|
||||
+quelque chose d'inattendu. Dans ce cas, vous devrez corriger l'erreur avant
|
||||
+de recommencer.
|
||||
+
|
||||
+Activer les mots de passe cachés lorsqu'ils sont déjà activés, ou les
|
||||
+désactiver lorsqu'ils ne sont pas actifs est sans effet.
|
||||
+
|
||||
+Lisez \fI/usr/share/doc/passwd/README.Debian\fP pour une brève introduction aux
|
||||
+mots de passe cachés et à leurs fonctionnalités.
|
||||
+
|
||||
+Notez que désactiver puis réactiver les mots de passe cachés aura pour
|
||||
+conséquence la perte des informations d'âge sur les mots de passe.
|
||||
+.SH TRADUCTION
|
||||
+Nicolas FRANÇOIS, 2004.
|
||||
+Veuillez signaler toute erreur à <\fIdebian\-l10\-french@lists.debian.org\fR>.
|
||||
Index: git/man/ja/shadowconfig.8
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/man/ja/shadowconfig.8
|
||||
@@ -0,0 +1,25 @@
|
||||
+.\" all right reserved,
|
||||
+.\" Translated Tue Oct 30 11:59:11 JST 2001
|
||||
+.\" by Maki KURODA <mkuroda@aisys-jp.com>
|
||||
+.\"
|
||||
+.TH SHADOWCONFIG 8 "19 Apr 1997" "Debian GNU/Linux"
|
||||
+.SH 名前
|
||||
+shadowconfig \- shadow パスワードの設定をオン及びオフに切替える
|
||||
+.SH 書式
|
||||
+.B "shadowconfig"
|
||||
+.IR on " | " off
|
||||
+.SH 説明
|
||||
+.PP
|
||||
+.B shadowconfig on
|
||||
+は shadow パスワードを有効にする。
|
||||
+.B shadowconfig off
|
||||
+は shadow パスワードを無効にする。
|
||||
+.B shadowconfig
|
||||
+は何らかの間違いがあると、エラーメッセージを表示し、
|
||||
+ゼロではない返り値を返す。
|
||||
+もしそのようなことが起こった場合、エラーを修正し、再度実行しなければならない。
|
||||
+shadow パスワードの設定がすでにオンの場合にオンに設定したり、
|
||||
+すでにオフの場合にオフに設定しても、何の影響もない。
|
||||
+
|
||||
+.I /usr/share/doc/passwd/README.debian.gz
|
||||
+には shadow パスワードとそれに関する特徴の簡単な紹介が書かれている。
|
||||
Index: git/man/pl/shadowconfig.8
|
||||
===================================================================
|
||||
--- /dev/null
|
||||
+++ git/man/pl/shadowconfig.8
|
||||
@@ -0,0 +1,27 @@
|
||||
+.\" $Id: shadowconfig.8,v 1.3 2001/08/23 23:10:51 kloczek Exp $
|
||||
+.\" {PTM/WK/1999-09-14}
|
||||
+.TH SHADOWCONFIG 8 "19 kwietnia 1997" "Debian GNU/Linux"
|
||||
+.SH NAZWA
|
||||
+shadowconfig - przełącza ochronę haseł i grup przez pliki shadow
|
||||
+.SH SKŁADNIA
|
||||
+.B "shadowconfig"
|
||||
+.IR on " | " off
|
||||
+.SH OPIS
|
||||
+.PP
|
||||
+.B shadowconfig on
|
||||
+włącza ochronę haseł i grup przez dodatkowe, przesłaniane pliki (shadow);
|
||||
+.B shadowconfig off
|
||||
+wyłącza dodatkowe pliki haseł i grup.
|
||||
+.B shadowconfig
|
||||
+wyświetla komunikat o błędzie i kończy pracę z niezerowym kodem jeśli
|
||||
+znajdzie coś nieprawidłowego. W takim wypadku powinieneś poprawić błąd
|
||||
+.\" if it finds anything awry.
|
||||
+i uruchomić program ponownie.
|
||||
+
|
||||
+Włączenie ochrony haseł, gdy jest ona już włączona lub jej wyłączenie,
|
||||
+gdy jest wyłączona jest nieszkodliwe.
|
||||
+
|
||||
+Przeczytaj
|
||||
+.IR /usr/share/doc/passwd/README.debian.gz ,
|
||||
+gdzie znajdziesz krótkie wprowadzenie do ochrony haseł z użyciem dodatkowych
|
||||
+plików haseł przesłanianych (shadow passwords) i związanych tematów.
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
Goal: Recommend using adduser and deluser.
|
||||
|
||||
Fixes: #406046
|
||||
|
||||
Status wrt upstream: Debian specific patch.
|
||||
|
||||
Index: git/man/useradd.8.xml
|
||||
===================================================================
|
||||
--- git.orig/man/useradd.8.xml
|
||||
+++ git/man/useradd.8.xml
|
||||
@@ -105,6 +105,12 @@
|
||||
<refsect1 id='description'>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
+ <command>useradd</command> is a low level utility for adding
|
||||
+ users. On Debian, administrators should usually use
|
||||
+ <citerefentry><refentrytitle>adduser</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum></citerefentry> instead.
|
||||
+ </para>
|
||||
+ <para>
|
||||
When invoked without the <option>-D</option> option, the
|
||||
<command>useradd</command> command creates a new user account using
|
||||
the values specified on the command line plus the default values from
|
||||
Index: git/man/userdel.8.xml
|
||||
===================================================================
|
||||
--- git.orig/man/userdel.8.xml
|
||||
+++ git/man/userdel.8.xml
|
||||
@@ -83,6 +83,12 @@
|
||||
<refsect1 id='description'>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
+ <command>userdel</command> is a low level utility for removing
|
||||
+ users. On Debian, administrators should usually use
|
||||
+ <citerefentry><refentrytitle>deluser</refentrytitle>
|
||||
+ <manvolnum>8</manvolnum></citerefentry> instead.
|
||||
+ </para>
|
||||
+ <para>
|
||||
The <command>userdel</command> command modifies the system account
|
||||
files, deleting all entries that refer to the user name <emphasis
|
||||
remap='I'>LOGIN</emphasis>. The named user must exist.
|
||||
Vendored
-106
@@ -1,106 +0,0 @@
|
||||
Goal: Relaxed usernames/groupnames checking patch.
|
||||
|
||||
Status wrt upstream: Debian specific. Not to be used upstream
|
||||
|
||||
Details:
|
||||
Allows any non-empty user/grounames that don't contain ':', ',' or '\n'
|
||||
characters and don't start with '-', '+', or '~'. This patch is more
|
||||
restrictive than original Karl's version. closes: #264879
|
||||
Also closes: #377844
|
||||
|
||||
Comments from Karl Ramm (shadow 1:4.0.3-9, 20 Aug 2003 02:06:50 -0400):
|
||||
|
||||
I can't come up with a good justification as to why characters other
|
||||
than ':'s and '\0's should be disallowed in group and usernames (other
|
||||
than '-' as the leading character). Thus, the maintenance tools don't
|
||||
anymore. closes: #79682, #166798, #171179
|
||||
|
||||
Index: git/libmisc/chkname.c
|
||||
===================================================================
|
||||
--- git.orig/libmisc/chkname.c
|
||||
+++ git/libmisc/chkname.c
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
static bool is_valid_name (const char *name)
|
||||
{
|
||||
+#if 0
|
||||
/*
|
||||
* User/group names must match [a-z_][a-z0-9_-]*[$]
|
||||
*/
|
||||
@@ -66,6 +67,26 @@
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
+ /*
|
||||
+ * POSIX indicate that usernames are composed of characters from the
|
||||
+ * portable filename character set [A-Za-z0-9._-], and that the hyphen
|
||||
+ * should not be used as the first character of a portable user name.
|
||||
+ *
|
||||
+ * Allow more relaxed user/group names in Debian -- ^[^-~+:,\s][^:,\s]*$
|
||||
+ */
|
||||
+ if ( ('\0' == *name)
|
||||
+ || ('-' == *name)
|
||||
+ || ('~' == *name)
|
||||
+ || ('+' == *name)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ do {
|
||||
+ if ((':' == *name) || (',' == *name) || isspace(*name)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ name++;
|
||||
+ } while ('\0' != *name);
|
||||
|
||||
return true;
|
||||
}
|
||||
Index: git/man/useradd.8.xml
|
||||
===================================================================
|
||||
--- git.orig/man/useradd.8.xml
|
||||
+++ git/man/useradd.8.xml
|
||||
@@ -633,12 +633,20 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
- Usernames must start with a lower case letter or an underscore,
|
||||
+ It is usually recommended to only use usernames that begin with a lower case letter or an underscore,
|
||||
followed by lower case letters, digits, underscores, or dashes.
|
||||
They can end with a dollar sign.
|
||||
In regular expression terms: [a-z_][a-z0-9_-]*[$]?
|
||||
</para>
|
||||
<para>
|
||||
+ On Debian, the only constraints are that usernames must neither start
|
||||
+ with a dash ('-') nor plus ('+') nor tilde ('~') nor contain a
|
||||
+ colon (':'), a comma (','), or a whitespace (space: ' ',
|
||||
+ end of line: '\n', tabulation: '\t', etc.). Note that using a slash
|
||||
+ ('/') may break the default algorithm for the definition of the
|
||||
+ user's home directory.
|
||||
+ </para>
|
||||
+ <para>
|
||||
Usernames may only be up to 32 characters long.
|
||||
</para>
|
||||
</refsect1>
|
||||
Index: git/man/groupadd.8.xml
|
||||
===================================================================
|
||||
--- git.orig/man/groupadd.8.xml
|
||||
+++ git/man/groupadd.8.xml
|
||||
@@ -256,12 +256,18 @@
|
||||
<refsect1 id='caveats'>
|
||||
<title>CAVEATS</title>
|
||||
<para>
|
||||
- Groupnames must start with a lower case letter or an underscore,
|
||||
+ It is usually recommended to only use groupnames that begin with a lower case letter or an underscore,
|
||||
followed by lower case letters, digits, underscores, or dashes.
|
||||
They can end with a dollar sign.
|
||||
In regular expression terms: [a-z_][a-z0-9_-]*[$]?
|
||||
</para>
|
||||
<para>
|
||||
+ On Debian, the only constraints are that groupnames must neither start
|
||||
+ with a dash ('-') nor plus ('+') nor tilde ('~') nor contain a
|
||||
+ colon (':'), a comma (','), or a whitespace (space:' ',
|
||||
+ end of line: '\n', tabulation: '\t', etc.).
|
||||
+ </para>
|
||||
+ <para>
|
||||
Groupnames may only be up to &GROUP_NAME_MAX_LENGTH; characters long.
|
||||
</para>
|
||||
<para>
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
Index: git/src/Makefile.am
|
||||
===================================================================
|
||||
--- git.orig/src/Makefile.am
|
||||
+++ git/src/Makefile.am
|
||||
@@ -23,7 +23,6 @@
|
||||
# $prefix/bin and $prefix/sbin, no install-data hacks...)
|
||||
|
||||
bin_PROGRAMS = groups login su
|
||||
-sbin_PROGRAMS = nologin
|
||||
ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
|
||||
if ENABLE_SUBIDS
|
||||
ubin_PROGRAMS += newgidmap newuidmap
|
||||
@@ -41,6 +40,7 @@
|
||||
grpunconv \
|
||||
logoutd \
|
||||
newusers \
|
||||
+ nologin \
|
||||
pwck \
|
||||
pwconv \
|
||||
pwunconv \
|
||||
@@ -1,48 +0,0 @@
|
||||
Goal: Concatenate the non-su arguments and provide them to the shell with
|
||||
the -c option
|
||||
Fixes: #317264
|
||||
see also #276419
|
||||
|
||||
Status wrt upstream: This is a Debian specific patch.
|
||||
|
||||
Note: the fix of the man page is still missing.
|
||||
(to be taken from the trunk)
|
||||
|
||||
--- a/src/su.c
|
||||
+++ b/src/su.c
|
||||
@@ -1167,6 +1167,35 @@
|
||||
argv[0] = "-c";
|
||||
argv[1] = command;
|
||||
}
|
||||
+ /* On Debian, the arguments are concatenated and the
|
||||
+ * resulting string is always given to the shell with its
|
||||
+ * -c option.
|
||||
+ */
|
||||
+ {
|
||||
+ char **parg;
|
||||
+ unsigned int cmd_len = 0;
|
||||
+ char *cmd = NULL;
|
||||
+ if (strcmp(argv[0], "-c") != 0) {
|
||||
+ argv--;
|
||||
+ argv[0] = "-c";
|
||||
+ }
|
||||
+ /* Now argv[0] is always -c, and other arguments
|
||||
+ * can be concatenated
|
||||
+ */
|
||||
+ cmd_len = 1; /* finale '\0' */
|
||||
+ for (parg = &argv[1]; *parg; parg++) {
|
||||
+ cmd_len += strlen (*parg) + 1;
|
||||
+ }
|
||||
+ cmd = (char *) xmalloc (sizeof (char) * cmd_len);
|
||||
+ cmd[0] = '\0';
|
||||
+ for (parg = &argv[1]; *parg; parg++) {
|
||||
+ strcat (cmd, " ");
|
||||
+ strcat (cmd, *parg);
|
||||
+ }
|
||||
+ cmd[cmd_len - 1] = '\0';
|
||||
+ argv[1] = &cmd[1]; /* do not take first space */
|
||||
+ argv[2] = NULL;
|
||||
+ }
|
||||
/*
|
||||
* Use the shell and create an argv
|
||||
* with the rest of the command line included.
|
||||
@@ -1,50 +0,0 @@
|
||||
Goal: Do not concatenate the additional arguments, and support an
|
||||
environment variable to revert to the old Debian's su behavior.
|
||||
|
||||
This patch needs the su_arguments_are_concatenated patch.
|
||||
|
||||
This patch, and su_arguments_are_concatenated should be dropped after
|
||||
Etch.
|
||||
|
||||
Status wrt upstream: This patch is Debian specific.
|
||||
|
||||
--- a/src/su.c
|
||||
+++ b/src/su.c
|
||||
@@ -104,6 +104,19 @@
|
||||
/* If nonzero, change some environment vars to indicate the user su'd to. */
|
||||
static bool change_environment = true;
|
||||
|
||||
+/*
|
||||
+ * If nonzero, keep the old Debian behavior:
|
||||
+ * * concatenate all the arguments and provide them to the -c option of
|
||||
+ * the shell
|
||||
+ * * If there are some additional arguments, but no -c, add a -c
|
||||
+ * argument anyway
|
||||
+ * Drawbacks:
|
||||
+ * * you can't provide options to the shell (other than -c)
|
||||
+ * * you can't rely on the argument count
|
||||
+ * See http://bugs.debian.org/276419
|
||||
+ */
|
||||
+static int old_debian_behavior;
|
||||
+
|
||||
#ifdef USE_PAM
|
||||
static pam_handle_t *pamh = NULL;
|
||||
static int caught = 0;
|
||||
@@ -964,6 +977,8 @@
|
||||
int ret;
|
||||
#endif /* USE_PAM */
|
||||
|
||||
+ old_debian_behavior = (getenv("SU_NO_SHELL_ARGS") != NULL);
|
||||
+
|
||||
(void) setlocale (LC_ALL, "");
|
||||
(void) bindtextdomain (PACKAGE, LOCALEDIR);
|
||||
(void) textdomain (PACKAGE);
|
||||
@@ -1171,7 +1186,7 @@
|
||||
* resulting string is always given to the shell with its
|
||||
* -c option.
|
||||
*/
|
||||
- {
|
||||
+ if (old_debian_behavior) {
|
||||
char **parg;
|
||||
unsigned int cmd_len = 0;
|
||||
char *cmd = NULL;
|
||||
Vendored
-47
@@ -1,47 +0,0 @@
|
||||
Goal: accepts the -O flag for backward compatibility. (was used by adduser?)
|
||||
|
||||
Note: useradd.8 needs to be regenerated.
|
||||
|
||||
Status wrt upstream: not included as this is just specific
|
||||
backward compatibility for Debian
|
||||
|
||||
Index: git/man/useradd.8.xml
|
||||
===================================================================
|
||||
--- git.orig/man/useradd.8.xml
|
||||
+++ git/man/useradd.8.xml
|
||||
@@ -329,6 +329,11 @@
|
||||
databases are resetted to avoid reusing the entry from a previously
|
||||
deleted user.
|
||||
</para>
|
||||
+ <para>
|
||||
+ For the compatibility with previous Debian's
|
||||
+ <command>useradd</command>, the <option>-O</option> option is
|
||||
+ also supported.
|
||||
+ </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
Index: git/src/useradd.c
|
||||
===================================================================
|
||||
--- git.orig/src/useradd.c
|
||||
+++ git/src/useradd.c
|
||||
@@ -1056,9 +1056,9 @@
|
||||
};
|
||||
while ((c = getopt_long (argc, argv,
|
||||
#ifdef WITH_SELINUX
|
||||
- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:s:u:UZ:",
|
||||
+ "b:c:d:De:f:g:G:hk:O:K:lmMNop:rR:s:u:UZ:",
|
||||
#else /* !WITH_SELINUX */
|
||||
- "b:c:d:De:f:g:G:hk:K:lmMNop:rR:s:u:U",
|
||||
+ "b:c:d:De:f:g:G:hk:O:K:lmMNop:rR:s:u:U",
|
||||
#endif /* !WITH_SELINUX */
|
||||
long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
@@ -1181,6 +1181,7 @@
|
||||
kflg = true;
|
||||
break;
|
||||
case 'K':
|
||||
+ case 'O': /* compatibility with previous Debian useradd */
|
||||
/*
|
||||
* override login.defs defaults (-K name=value)
|
||||
* example: -K UID_MIN=100 -K UID_MAX=499
|
||||
-81
@@ -1,81 +0,0 @@
|
||||
--- a/debian/passwd.install
|
||||
+++ b/debian/passwd.install
|
||||
@@ -9,6 +9,7 @@
|
||||
usr/sbin/cppw
|
||||
usr/sbin/groupadd
|
||||
usr/sbin/groupdel
|
||||
+usr/sbin/groupmems
|
||||
usr/sbin/groupmod
|
||||
usr/sbin/grpck
|
||||
usr/sbin/grpconv
|
||||
@@ -33,6 +34,7 @@
|
||||
usr/share/man/*/man8/chpasswd.8
|
||||
usr/share/man/*/man8/groupadd.8
|
||||
usr/share/man/*/man8/groupdel.8
|
||||
+usr/share/man/*/man8/groupmems.8
|
||||
usr/share/man/*/man8/groupmod.8
|
||||
usr/share/man/*/man8/grpck.8
|
||||
usr/share/man/*/man8/grpconv.8
|
||||
@@ -59,6 +61,7 @@
|
||||
usr/share/man/man8/chpasswd.8
|
||||
usr/share/man/man8/groupadd.8
|
||||
usr/share/man/man8/groupdel.8
|
||||
+usr/share/man/man8/groupmems.8
|
||||
usr/share/man/man8/groupmod.8
|
||||
usr/share/man/man8/grpck.8
|
||||
usr/share/man/man8/grpconv.8
|
||||
--- a/debian/passwd.postinst
|
||||
+++ b/debian/passwd.postinst
|
||||
@@ -31,6 +31,24 @@
|
||||
exit 1
|
||||
)
|
||||
fi
|
||||
+ if ! getent group groupmems | grep -q '^groupmems:[^:]*:99'
|
||||
+ then
|
||||
+ groupadd -g 99 groupmems || (
|
||||
+ cat <<EOF
|
||||
+************************ TESTSUITE *****************************
|
||||
+Group ID 99 has been allocated for the groupmems group. You have either
|
||||
+used 99 yourself or created a groupmems group with a different ID.
|
||||
+Please correct this problem and reconfigure with ``dpkg --configure passwd''.
|
||||
+
|
||||
+Note that both user and group IDs in the range 0-99 are globally
|
||||
+allocated by the Debian project and must be the same on every Debian
|
||||
+system.
|
||||
+EOF
|
||||
+ exit 1
|
||||
+ )
|
||||
+# FIXME
|
||||
+ chgrp groupmems /usr/sbin/groupmems
|
||||
+ fi
|
||||
;;
|
||||
esac
|
||||
|
||||
--- a/debian/rules
|
||||
+++ b/debian/rules
|
||||
@@ -60,6 +60,7 @@
|
||||
dh_installpam -p passwd --name=chsh
|
||||
dh_installpam -p passwd --name=chpasswd
|
||||
dh_installpam -p passwd --name=newusers
|
||||
+ dh_installpam -p passwd --name=groupmems
|
||||
ifeq ($(DEB_HOST_ARCH_OS),hurd)
|
||||
# login is not built on The Hurd, but some utilities of passwd depends on
|
||||
# /etc/login.defs.
|
||||
@@ -87,3 +88,6 @@
|
||||
chgrp shadow debian/passwd/usr/bin/expiry
|
||||
chmod g+s debian/passwd/usr/bin/chage
|
||||
chmod g+s debian/passwd/usr/bin/expiry
|
||||
+ chgrp groupmems debian/passwd/usr/sbin/groupmems
|
||||
+ chmod u+s debian/passwd/usr/sbin/groupmems
|
||||
+ chmod o-x debian/passwd/usr/sbin/groupmems
|
||||
--- /dev/null
|
||||
+++ b/debian/passwd.groupmems.pam
|
||||
@@ -0,0 +1,8 @@
|
||||
+# The PAM configuration file for the Shadow 'groupmod' service
|
||||
+#
|
||||
+
|
||||
+# This allows root to modify groups without being prompted for a password
|
||||
+auth sufficient pam_rootok.so
|
||||
+
|
||||
+@include common-auth
|
||||
+@include common-account
|
||||
Vendored
-76
@@ -1,76 +0,0 @@
|
||||
--- a/lib/Makefile.am
|
||||
+++ b/lib/Makefile.am
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
AUTOMAKE_OPTIONS = 1.0 foreign
|
||||
|
||||
+CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
+
|
||||
DEFS =
|
||||
|
||||
noinst_LTLIBRARIES = libshadow.la
|
||||
--- a/libmisc/Makefile.am
|
||||
+++ b/libmisc/Makefile.am
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
EXTRA_DIST = .indent.pro xgetXXbyYY.c
|
||||
|
||||
+CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
+
|
||||
INCLUDES = -I$(top_srcdir)/lib
|
||||
|
||||
noinst_LIBRARIES = libmisc.a
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -7,6 +7,8 @@
|
||||
suidperms = 4755
|
||||
sgidperms = 2755
|
||||
|
||||
+CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
+
|
||||
INCLUDES = \
|
||||
-I${top_srcdir}/lib \
|
||||
-I$(top_srcdir)/libmisc
|
||||
--- a/debian/rules
|
||||
+++ b/debian/rules
|
||||
@@ -40,6 +40,12 @@
|
||||
endif
|
||||
export CFLAGS
|
||||
|
||||
+clean:: clean_gcov
|
||||
+
|
||||
+clean_gcov:
|
||||
+ find . -name "*.gcda" -delete
|
||||
+ find . -name "*.gcno" -delete
|
||||
+
|
||||
# Add extras to the install process:
|
||||
binary-install/login::
|
||||
dh_installpam -p login
|
||||
--- a/lib/defines.h
|
||||
+++ b/lib/defines.h
|
||||
@@ -174,23 +174,9 @@
|
||||
trust the formatted time received from the unix domain (or worse,
|
||||
UDP) socket. -MM */
|
||||
/* Avoid translated PAM error messages: Set LC_ALL to "C".
|
||||
+ * This is disabled for coverage testing
|
||||
* --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)
|
||||
+#define SYSLOG(x) syslog x
|
||||
#else /* !ENABLE_NLS */
|
||||
#define SYSLOG(x) syslog x
|
||||
#endif /* !ENABLE_NLS */
|
||||
Vendored
-37
@@ -1,37 +0,0 @@
|
||||
From 954e3d2e7113e9ac06632aee3c69b8d818cc8952 Mon Sep 17 00:00:00 2001
|
||||
From: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
Date: Fri, 31 Mar 2017 16:25:06 +0200
|
||||
Subject: [PATCH] Fix buffer overflow if NULL line is present in db.
|
||||
|
||||
If ptr->line == NULL for an entry, the first cycle will exit,
|
||||
but the second one will happily write past entries buffer.
|
||||
We actually do not want to exit the first cycle prematurely
|
||||
on ptr->line == NULL.
|
||||
Signed-off-by: Tomas Mraz <tmraz@fedoraproject.org>
|
||||
---
|
||||
lib/commonio.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/lib/commonio.c
|
||||
+++ b/lib/commonio.c
|
||||
@@ -755,16 +755,16 @@
|
||||
for (ptr = db->head;
|
||||
(NULL != ptr)
|
||||
#if KEEP_NIS_AT_END
|
||||
- && (NULL != ptr->line)
|
||||
- && ( ('+' != ptr->line[0])
|
||||
- && ('-' != ptr->line[0]))
|
||||
+ && ((NULL == ptr->line)
|
||||
+ || (('+' != ptr->line[0])
|
||||
+ && ('-' != ptr->line[0])))
|
||||
#endif
|
||||
;
|
||||
ptr = ptr->next) {
|
||||
n++;
|
||||
}
|
||||
#if KEEP_NIS_AT_END
|
||||
- if ((NULL != ptr) && (NULL != ptr->line)) {
|
||||
+ if (NULL != ptr) {
|
||||
nis = ptr;
|
||||
}
|
||||
#endif
|
||||
Vendored
-174
@@ -1,174 +0,0 @@
|
||||
From fb28c99b8a66ff2605c5cb96abc0a4d975f92de0 Mon Sep 17 00:00:00 2001
|
||||
From: Aleksa Sarai <asarai@suse.de>
|
||||
Date: Thu, 15 Feb 2018 23:49:40 +1100
|
||||
Subject: [PATCH] newgidmap: enforce setgroups=deny if self-mapping a group
|
||||
|
||||
This is necessary to match the kernel-side policy of "self-mapping in a
|
||||
user namespace is fine, but you cannot drop groups" -- a policy that was
|
||||
created in order to stop user namespaces from allowing trivial privilege
|
||||
escalation by dropping supplementary groups that were "blacklisted" from
|
||||
certain paths.
|
||||
|
||||
This is the simplest fix for the underlying issue, and effectively makes
|
||||
it so that unless a user has a valid mapping set in /etc/subgid (which
|
||||
only administrators can modify) -- and they are currently trying to use
|
||||
that mapping -- then /proc/$pid/setgroups will be set to deny. This
|
||||
workaround is only partial, because ideally it should be possible to set
|
||||
an "allow_setgroups" or "deny_setgroups" flag in /etc/subgid to allow
|
||||
administrators to further restrict newgidmap(1).
|
||||
|
||||
We also don't write anything in the "allow" case because "allow" is the
|
||||
default, and users may have already written "deny" even if they
|
||||
technically are allowed to use setgroups. And we don't write anything if
|
||||
the setgroups policy is already "deny".
|
||||
|
||||
Ref: https://bugs.launchpad.net/ubuntu/+source/shadow/+bug/1729357
|
||||
Fixes: CVE-2018-7169
|
||||
Reported-by: Craig Furman <craig.furman89@gmail.com>
|
||||
Signed-off-by: Aleksa Sarai <asarai@suse.de>
|
||||
--- a/src/newgidmap.c
|
||||
+++ b/src/newgidmap.c
|
||||
@@ -46,32 +46,37 @@
|
||||
*/
|
||||
const char *Prog;
|
||||
|
||||
-static bool verify_range(struct passwd *pw, struct map_range *range)
|
||||
+
|
||||
+static bool verify_range(struct passwd *pw, struct map_range *range, bool *allow_setgroups)
|
||||
{
|
||||
/* An empty range is invalid */
|
||||
if (range->count == 0)
|
||||
return false;
|
||||
|
||||
- /* Test /etc/subgid */
|
||||
- if (have_sub_gids(pw->pw_name, range->lower, range->count))
|
||||
+ /* Test /etc/subgid. If the mapping is valid then we allow setgroups. */
|
||||
+ if (have_sub_gids(pw->pw_name, range->lower, range->count)) {
|
||||
+ *allow_setgroups = true;
|
||||
return true;
|
||||
+ }
|
||||
|
||||
- /* Allow a process to map it's own gid */
|
||||
- if ((range->count == 1) && (pw->pw_gid == range->lower))
|
||||
+ /* Allow a process to map its own gid. */
|
||||
+ if ((range->count == 1) && (pw->pw_gid == range->lower)) {
|
||||
+ /* noop -- if setgroups is enabled already we won't disable it. */
|
||||
return true;
|
||||
|
||||
+ }
|
||||
return false;
|
||||
}
|
||||
|
||||
static void verify_ranges(struct passwd *pw, int ranges,
|
||||
- struct map_range *mappings)
|
||||
+ struct map_range *mappings, bool *allow_setgroups)
|
||||
{
|
||||
struct map_range *mapping;
|
||||
int idx;
|
||||
|
||||
mapping = mappings;
|
||||
for (idx = 0; idx < ranges; idx++, mapping++) {
|
||||
- if (!verify_range(pw, mapping)) {
|
||||
+ if (!verify_range(pw, mapping, allow_setgroups)) {
|
||||
fprintf(stderr, _( "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"),
|
||||
Prog,
|
||||
mapping->upper,
|
||||
@@ -89,6 +94,70 @@
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
+void write_setgroups(int proc_dir_fd, bool allow_setgroups)
|
||||
+{
|
||||
+ int setgroups_fd;
|
||||
+ char *policy, policy_buffer[4096];
|
||||
+
|
||||
+ /*
|
||||
+ * Default is "deny", and any "allow" will out-rank a "deny". We don't
|
||||
+ * forcefully write an "allow" here because the process we are writing
|
||||
+ * mappings for may have already set themselves to "deny" (and "allow"
|
||||
+ * is the default anyway). So allow_setgroups == true is a noop.
|
||||
+ */
|
||||
+ policy = "deny\n";
|
||||
+ if (allow_setgroups)
|
||||
+ return;
|
||||
+
|
||||
+ setgroups_fd = openat(proc_dir_fd, "setgroups", O_RDWR|O_CLOEXEC);
|
||||
+ if (setgroups_fd < 0) {
|
||||
+ /*
|
||||
+ * If it's an ENOENT then we are on too old a kernel for the setgroups
|
||||
+ * code to exist. Emit a warning and bail on this.
|
||||
+ */
|
||||
+ if (ENOENT == errno) {
|
||||
+ fprintf(stderr, _("%s: kernel doesn't support setgroups restrictions\n"), Prog);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ fprintf(stderr, _("%s: couldn't open process setgroups: %s\n"),
|
||||
+ Prog,
|
||||
+ strerror(errno));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Check whether the policy is already what we want. /proc/self/setgroups
|
||||
+ * is write-once, so attempting to write after it's already written to will
|
||||
+ * fail.
|
||||
+ */
|
||||
+ if (read(setgroups_fd, policy_buffer, sizeof(policy_buffer)) < 0) {
|
||||
+ fprintf(stderr, _("%s: failed to read setgroups: %s\n"),
|
||||
+ Prog,
|
||||
+ strerror(errno));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ if (!strncmp(policy_buffer, policy, strlen(policy)))
|
||||
+ goto out;
|
||||
+
|
||||
+ /* Write the policy. */
|
||||
+ if (lseek(setgroups_fd, 0, SEEK_SET) < 0) {
|
||||
+ fprintf(stderr, _("%s: failed to seek setgroups: %s\n"),
|
||||
+ Prog,
|
||||
+ strerror(errno));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+ if (dprintf(setgroups_fd, "%s", policy) < 0) {
|
||||
+ fprintf(stderr, _("%s: failed to setgroups %s policy: %s\n"),
|
||||
+ Prog,
|
||||
+ policy,
|
||||
+ strerror(errno));
|
||||
+ exit(EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ close(setgroups_fd);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* newgidmap - Set the gid_map for the specified process
|
||||
*/
|
||||
@@ -103,6 +172,7 @@
|
||||
struct stat st;
|
||||
struct passwd *pw;
|
||||
int written;
|
||||
+ bool allow_setgroups = false;
|
||||
|
||||
Prog = Basename (argv[0]);
|
||||
|
||||
@@ -144,7 +214,7 @@
|
||||
(unsigned long) getuid ()));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
-
|
||||
+
|
||||
/* Get the effective uid and effective gid of the target process */
|
||||
if (fstat(proc_dir_fd, &st) < 0) {
|
||||
fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
|
||||
@@ -174,8 +244,9 @@
|
||||
if (!mappings)
|
||||
usage();
|
||||
|
||||
- verify_ranges(pw, ranges, mappings);
|
||||
+ verify_ranges(pw, ranges, mappings, &allow_setgroups);
|
||||
|
||||
+ write_setgroups(proc_dir_fd, allow_setgroups);
|
||||
write_mapping(proc_dir_fd, ranges, mappings, "gid_map");
|
||||
sub_gid_close();
|
||||
|
||||
Vendored
-71
@@ -1,71 +0,0 @@
|
||||
Small intro to the system for numbering the patches here...
|
||||
|
||||
-The 0xx series of patches are patches isolated from the latest
|
||||
version of the shadow Debian package not using quilt in order to
|
||||
separate upstream from Debian-specific stuff.
|
||||
|
||||
NO MORE PATCHES SHOULD BE ADDED IN THESE SERIES
|
||||
|
||||
-The 1xx series are l10n patches to upstream 4.0.18.1. As upstream has
|
||||
adopted Debian translations, it is very likely that these patches
|
||||
will become useless when we will have synced with upstream
|
||||
|
||||
-The 2xx series are patches for manual pages translations to upstream
|
||||
4.0.18.1.
|
||||
|
||||
-The 3xx series are patches which have been temporarily applied to
|
||||
Debian's shadow while we *know* they have been applied upstream as well
|
||||
These patches should NOT be kept when we will sync with upstream
|
||||
|
||||
-The 4xx series are patches which have been applied to Debian's shadow
|
||||
and have NOT been accepted and/or applied upstream. These patches MUST be kept
|
||||
even after resynced with upstream
|
||||
|
||||
-The 5xx series are patches which are applied to Debian's shadow
|
||||
and will never be proposed upstream because they're too specific
|
||||
This list SHOULD BE AS SHORT AS POSSIBLE
|
||||
|
||||
In short, while we are working towards synchronisation with upstream,
|
||||
our goal is to make 0xx patches disappear by moving them either to 3xx
|
||||
series (things already implemented upstream) or to 4xx series
|
||||
(Debian-specific patches).
|
||||
|
||||
|
||||
Short HOWTO for quilt
|
||||
=====================
|
||||
|
||||
The quilt system can be assimilated to a Pile Of Patches management system.
|
||||
Patches live in debian/patches, the working directory is "."
|
||||
|
||||
The basic commands are (abbreviation accepted):
|
||||
quilt push (asks to apply the next patch in the pile)
|
||||
quilt pop (removes the current patch and go up in the pile)
|
||||
quilt refresh (take the current changes in tree onto the patch)
|
||||
|
||||
When a file is changed by a patch, quilt saves it somewhere under .pc on
|
||||
application. This is how it can refresh it afterward (comparing the version
|
||||
in .pc and the one you currently have in your working dir).
|
||||
|
||||
There are three common pitfalls with quilt:
|
||||
- doing "quilt pop" without doing "quilt refresh". The version of current
|
||||
dir is replaced with the version of the .pc dir. Your changes are lost.
|
||||
Quilt wont let you do so, but you can force it with '-f' if you're fool.
|
||||
- editing a file with is not in the patch yet. Quilt didn't do any previous
|
||||
backup.
|
||||
Use "quilt add" to add files to patches.
|
||||
Set $EDITOR and use "quilt edit" to edit a file, and add it onto the
|
||||
patch if needed.
|
||||
- If you update your working directory, patches may not revert cleanly.
|
||||
It is thus recommended to use "quilt pop -a" before updating with
|
||||
"svn up".
|
||||
If you forget (and run into trouble), you may want to remove the whole
|
||||
shadow-?.?.? directory. If you use the makefile which is in the upper
|
||||
directory (trunk/), shadow-?.?.?/debian/patches is a link to
|
||||
debian/patches, so this dirctory does not contain any valuable info.
|
||||
|
||||
The documentation is quite well done, I think. "quilt -h" will list you the
|
||||
commands. "quilt <cmd> -h" will give you some hints about it. "man quilt" is
|
||||
a reference documentation. /usr/share/doc/quilt/quilt.pdf.gz is a complete
|
||||
manual, with tutorial.
|
||||
|
||||
|
||||
Vendored
-42
@@ -1,42 +0,0 @@
|
||||
# These patches are only for the testsuite:
|
||||
#900_testsuite_groupmems
|
||||
#901_testsuite_gcov
|
||||
|
||||
503_shadowconfig.8
|
||||
008_login_log_failure_in_FTMP
|
||||
301-CVE-2017-2616-su-properly-clear-child-PID.patch
|
||||
302-CVE-2016-6252-fix-integer-overflow.patch
|
||||
303-Reset-pid_child-only-if-waitpid-was-successful.patch
|
||||
429_login_FAILLOG_ENAB
|
||||
401_cppw_src.dpatch
|
||||
# 402 should be merged in 401, but should be reviewed by SE Linux experts first
|
||||
402_cppw_selinux
|
||||
506_relaxed_usernames
|
||||
542_useradd-O_option
|
||||
501_commonio_group_shadow
|
||||
463_login_delay_obeys_to_PAM
|
||||
523_su_arguments_are_concatenated
|
||||
523_su_arguments_are_no_more_concatenated_by_default
|
||||
508_nologin_in_usr_sbin
|
||||
505_useradd_recommend_adduser
|
||||
#userns/01_userns_doc
|
||||
#userns/02_userns_doc_login.defs
|
||||
#userns/03_userns_implement_commonio_append
|
||||
#userns/04_userns_add_backend_support
|
||||
#userns/05_userns_implemend_find_new_sub_xids
|
||||
#userns/06_userns_userdel
|
||||
#userns/07_userns_useradd
|
||||
#userns/08_userns_detect_busy_subids
|
||||
#userns/09_userns_usermod
|
||||
#userns/10_userns_newusers
|
||||
#userns/11_userns_newxidmap
|
||||
#userns/12_userns_selinuxlibs
|
||||
#userns/13_subordinate_parse_static_buf
|
||||
#userns/14_fix_getopt
|
||||
#userns/manpagetypo
|
||||
#userns/16_add-argument-sanity-checking.patch
|
||||
1000_configure_userns
|
||||
1010_vietnamese_translation
|
||||
1020_fix_user_busy_errors
|
||||
CVE-2017-12424.patch
|
||||
CVE-2018-7169.patch
|
||||
Vendored
-334
@@ -1,334 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:14:18 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id DAC33C80F4; Tue, 22 Jan 2013 09:14:18 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 274ACC80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:14:14 +0000 (UTC)
|
||||
Received: from out01.mta.xmission.com ([166.70.13.231])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZuB-0006Xm-N5; Tue, 22 Jan 2013 02:12:31 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out01.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZuA-0005NR-BQ; Tue, 22 Jan 2013 02:12:30 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZu7-0004Pj-Ec; Tue, 22 Jan 2013 02:12:30 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:12:23 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <877gn5shs8.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX18YouPWtKNAX3LovSW2+p/ONbuCHMFEQpM=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 01/11] Documentation for /etc/subuid and /etc/subgid
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2071
|
||||
Status: RO
|
||||
Content-Length: 9835
|
||||
Lines: 286
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
man/Makefile.am | 4 ++
|
||||
man/subgid.5.xml | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
man/subuid.5.xml | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 244 insertions(+), 0 deletions(-)
|
||||
create mode 100644 man/subgid.5.xml
|
||||
create mode 100644 man/subuid.5.xml
|
||||
|
||||
Index: shadow/man/Makefile.am
|
||||
===================================================================
|
||||
--- shadow.orig/man/Makefile.am 2013-02-01 15:26:14.428082026 -0600
|
||||
+++ shadow/man/Makefile.am 2013-02-01 15:27:37.000000000 -0600
|
||||
@@ -43,6 +43,8 @@
|
||||
man5/shadow.5 \
|
||||
man1/su.1 \
|
||||
man5/suauth.5 \
|
||||
+ man5/subgid.5 \
|
||||
+ man5/subuid.5 \
|
||||
man8/useradd.8 \
|
||||
man8/userdel.8 \
|
||||
man8/usermod.8 \
|
||||
@@ -94,6 +96,8 @@
|
||||
sg.1.xml \
|
||||
su.1.xml \
|
||||
suauth.5.xml \
|
||||
+ subgid.5.xml \
|
||||
+ subuid.5.xml \
|
||||
useradd.8.xml \
|
||||
userdel.8.xml \
|
||||
usermod.8.xml \
|
||||
Index: shadow/man/subgid.5.xml
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/man/subgid.5.xml 2013-02-01 15:26:14.424082026 -0600
|
||||
@@ -0,0 +1,120 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<!--
|
||||
+ Copyright (c) 2013 Eric W. Biederman
|
||||
+ 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.
|
||||
+-->
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
|
||||
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
+<!-- SHADOW-CONFIG-HERE -->
|
||||
+]>
|
||||
+<refentry id='subgid.5'>
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>subgid</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ <refmiscinfo class="sectdesc">File Formats and Conversions</refmiscinfo>
|
||||
+ <refmiscinfo class="source">shadow-utils</refmiscinfo>
|
||||
+ <refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+ <refnamediv id='name'>
|
||||
+ <refname>subgid</refname>
|
||||
+ <refpurpose>the subordinate gid file</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsect1 id='description'>
|
||||
+ <title>DESCRIPTION</title>
|
||||
+ <para>
|
||||
+ Each line in <filename>/etc/subgid</filename> contains
|
||||
+ a user id and a range of suboridinate user ids that user
|
||||
+ is allowed to use.
|
||||
+
|
||||
+ This is specified with three fields delimited by colons
|
||||
+ (<quote>:</quote>).
|
||||
+ These fields are:
|
||||
+ </para>
|
||||
+ <itemizedlist mark='bullet'>
|
||||
+ <listitem>
|
||||
+ <para>login name</para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>numerical subordinate user ID</para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>numerical subordinate user ID count</para>
|
||||
+ </listitem>
|
||||
+ </itemizedlist>
|
||||
+
|
||||
+ <para>
|
||||
+ This file specifies the group IDs to be that each user may use
|
||||
+ with the <command>newgidmap</command> command that ordinary users can use to
|
||||
+ configure gid mapping in a user namespace.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ Multiple ranges may be specified per user ID.
|
||||
+ </para>
|
||||
+
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='files'>
|
||||
+ <title>FILES</title>
|
||||
+ <variablelist>
|
||||
+ <varlistentry>
|
||||
+ <term><filename>/etc/subgid</filename></term>
|
||||
+ <listitem>
|
||||
+ <para>Per user subordinate group IDs.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><filename>/etc/subgid-</filename></term>
|
||||
+ <listitem>
|
||||
+ <para>Backup file for /etc/subgid.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='see_also'>
|
||||
+ <title>SEE ALSO</title>
|
||||
+ <para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>subuid</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>logindefs</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>newuidmap</refentrytitle><manvolnum>1</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>newgidmap</refentrytitle><manvolnum>1</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>usermod</refentrytitle><manvolnum>8</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+</refentry>
|
||||
Index: shadow/man/subuid.5.xml
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/man/subuid.5.xml 2013-02-01 15:26:14.424082026 -0600
|
||||
@@ -0,0 +1,120 @@
|
||||
+<?xml version="1.0" encoding="UTF-8"?>
|
||||
+<!--
|
||||
+ Copyright (c) 2013 Eric W. Biederman
|
||||
+ 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.
|
||||
+-->
|
||||
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
|
||||
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
|
||||
+<!-- SHADOW-CONFIG-HERE -->
|
||||
+]>
|
||||
+<refentry id='subuid.5'>
|
||||
+ <refmeta>
|
||||
+ <refentrytitle>subuid</refentrytitle>
|
||||
+ <manvolnum>5</manvolnum>
|
||||
+ <refmiscinfo class="sectdesc">File Formats and Conversions</refmiscinfo>
|
||||
+ <refmiscinfo class="source">shadow-utils</refmiscinfo>
|
||||
+ <refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
|
||||
+ </refmeta>
|
||||
+ <refnamediv id='name'>
|
||||
+ <refname>subuid</refname>
|
||||
+ <refpurpose>the subordinate uid file</refpurpose>
|
||||
+ </refnamediv>
|
||||
+
|
||||
+ <refsect1 id='description'>
|
||||
+ <title>DESCRIPTION</title>
|
||||
+ <para>
|
||||
+ Each line in <filename>/etc/subuid</filename> contains
|
||||
+ a user id and a range of suboridinate user ids that user
|
||||
+ is allowed to use.
|
||||
+
|
||||
+ This is specified with three fields delimited by colons
|
||||
+ (<quote>:</quote>).
|
||||
+ These fields are:
|
||||
+ </para>
|
||||
+ <itemizedlist mark='bullet'>
|
||||
+ <listitem>
|
||||
+ <para>login name</para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>numerical subordinate user ID</para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>numerical subordinate user ID count</para>
|
||||
+ </listitem>
|
||||
+ </itemizedlist>
|
||||
+
|
||||
+ <para>
|
||||
+ This file specifies the user IDs to be that each user may use
|
||||
+ with the <command>newuidmap</command> command that ordinary users can use to
|
||||
+ configure uid mapping in a user namespace.
|
||||
+ </para>
|
||||
+
|
||||
+ <para>
|
||||
+ Multiple ranges may be specified per user ID.
|
||||
+ </para>
|
||||
+
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='files'>
|
||||
+ <title>FILES</title>
|
||||
+ <variablelist>
|
||||
+ <varlistentry>
|
||||
+ <term><filename>/etc/subuid</filename></term>
|
||||
+ <listitem>
|
||||
+ <para>Per user subordinate user IDs.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><filename>/etc/subuid-</filename></term>
|
||||
+ <listitem>
|
||||
+ <para>Backup file for /etc/subuid.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ </variablelist>
|
||||
+ </refsect1>
|
||||
+
|
||||
+ <refsect1 id='see_also'>
|
||||
+ <title>SEE ALSO</title>
|
||||
+ <para>
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>subgid</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>logindefs</refentrytitle><manvolnum>5</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>newuidmap</refentrytitle><manvolnum>1</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>newgidmap</refentrytitle><manvolnum>1</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ <citerefentry>
|
||||
+ <refentrytitle>usermod</refentrytitle><manvolnum>8</manvolnum>
|
||||
+ </citerefentry>,
|
||||
+ </para>
|
||||
+ </refsect1>
|
||||
+</refentry>
|
||||
-218
@@ -1,218 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:14:55 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id 140DBC80F4; Tue, 22 Jan 2013 09:14:55 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 5D815C80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:14:50 +0000 (UTC)
|
||||
Received: from out03.mta.xmission.com ([166.70.13.233])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZum-0006il-0f; Tue, 22 Jan 2013 02:13:08 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out03.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZul-0004GF-Id; Tue, 22 Jan 2013 02:13:07 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZuf-0004T0-MS; Tue, 22 Jan 2013 02:13:07 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:12:58 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <871uddshr9.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX19iYyOCEx6dl2v1Ya/KIGpixG5+3MVA1bY=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 02/11] login.defs.5: Document the new variables in login.defs
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2072
|
||||
Status: RO
|
||||
Content-Length: 7615
|
||||
Lines: 170
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
man/Makefile.am | 2 +
|
||||
man/login.defs.5.xml | 8 ++++++
|
||||
man/login.defs.d/SUB_GID_COUNT.xml | 46 ++++++++++++++++++++++++++++++++++++
|
||||
man/login.defs.d/SUB_UID_COUNT.xml | 46 ++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 102 insertions(+), 0 deletions(-)
|
||||
create mode 100644 man/login.defs.d/SUB_GID_COUNT.xml
|
||||
create mode 100644 man/login.defs.d/SUB_UID_COUNT.xml
|
||||
|
||||
Index: shadow/man/Makefile.am
|
||||
===================================================================
|
||||
--- shadow.orig/man/Makefile.am 2013-02-01 15:27:51.048080390 -0600
|
||||
+++ shadow/man/Makefile.am 2013-02-01 15:27:51.040080390 -0600
|
||||
@@ -163,6 +163,8 @@
|
||||
USERDEL_CMD.xml \
|
||||
USERGROUPS_ENAB.xml \
|
||||
USE_TCB.xml \
|
||||
+ SUB_GID_COUNT.xml \
|
||||
+ SUB_UID_COUNT.xml \
|
||||
SYS_GID_MAX.xml \
|
||||
SYS_UID_MAX.xml
|
||||
|
||||
Index: shadow/man/login.defs.5.xml
|
||||
===================================================================
|
||||
--- shadow.orig/man/login.defs.5.xml 2013-02-01 15:27:51.048080390 -0600
|
||||
+++ shadow/man/login.defs.5.xml 2013-02-01 15:27:51.044080390 -0600
|
||||
@@ -78,6 +78,8 @@
|
||||
<!ENTITY SULOG_FILE SYSTEM "login.defs.d/SULOG_FILE.xml">
|
||||
<!ENTITY SU_NAME SYSTEM "login.defs.d/SU_NAME.xml">
|
||||
<!ENTITY SU_WHEEL_ONLY SYSTEM "login.defs.d/SU_WHEEL_ONLY.xml">
|
||||
+<!ENTITY SUB_GID_COUNT SYSTEM "login.defs.d/SUB_GID_COUNT.xml">
|
||||
+<!ENTITY SUB_UID_COUNT SYSTEM "login.defs.d/SUB_UID_COUNT.xml">
|
||||
<!ENTITY SYS_GID_MAX SYSTEM "login.defs.d/SYS_GID_MAX.xml">
|
||||
<!ENTITY SYSLOG_SG_ENAB SYSTEM "login.defs.d/SYSLOG_SG_ENAB.xml">
|
||||
<!ENTITY SYSLOG_SU_ENAB SYSTEM "login.defs.d/SYSLOG_SU_ENAB.xml">
|
||||
@@ -216,6 +218,8 @@
|
||||
&SULOG_FILE;
|
||||
&SU_NAME;
|
||||
&SU_WHEEL_ONLY;
|
||||
+ &SUB_GID_COUNT; <!-- documents also SUB_GID_MIN SUB_GID_MAX -->
|
||||
+ &SUB_UID_COUNT; <!-- documents also SUB_UID_MIN SUB_UID_MAX -->
|
||||
&SYS_GID_MAX; <!-- documents also SYS_GID_MIN -->
|
||||
&SYS_UID_MAX; <!-- documents also SYS_UID_MIN -->
|
||||
&SYSLOG_SG_ENAB;
|
||||
@@ -393,6 +397,8 @@
|
||||
PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
|
||||
<phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
|
||||
SHA_CRYPT_MIN_ROUNDS</phrase>
|
||||
+ SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
|
||||
+ SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
|
||||
SYS_GID_MAX SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN
|
||||
UMASK
|
||||
</para>
|
||||
@@ -470,6 +476,8 @@
|
||||
GID_MAX GID_MIN
|
||||
MAIL_DIR MAX_MEMBERS_PER_GROUP
|
||||
PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
|
||||
+ SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
|
||||
+ SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
|
||||
SYS_GID_MAX SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN
|
||||
UMASK
|
||||
<phrase condition="tcb">TCB_AUTH_GROUP TCB_SYMLINK USE_TCB</phrase>
|
||||
Index: shadow/man/login.defs.d/SUB_GID_COUNT.xml
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/man/login.defs.d/SUB_GID_COUNT.xml 2013-02-01 15:27:51.044080390 -0600
|
||||
@@ -0,0 +1,46 @@
|
||||
+<!--
|
||||
+ Copyright (c) 2013, Eric W. Biederman
|
||||
+ 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.
|
||||
+-->
|
||||
+<varlistentry>
|
||||
+ <term><option>SUB_GID_MIN</option> (number)</term>
|
||||
+ <term><option>SUB_GID_MAX</option> (number)</term>
|
||||
+ <term><option>SUB_GID_COUNT</option> (number)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The commands <command>useradd</command> and <command>newusers</command>
|
||||
+ allocate <option>SUB_GID_COUNT</option> unused group IDs from the range
|
||||
+ <option>SUB_GID_MIN</option> to <option>SUB_GID_MAX</option> for each
|
||||
+ new user.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ The default values for <option>SUB_GID_MAN</option>,
|
||||
+ <option>SUB_GID_MIN</option>, <option>SUB_GID_COUNT</option>
|
||||
+ are respectively 100000, 600100000 and 10000.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+</varlistentry>
|
||||
Index: shadow/man/login.defs.d/SUB_UID_COUNT.xml
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/man/login.defs.d/SUB_UID_COUNT.xml 2013-02-01 15:27:51.044080390 -0600
|
||||
@@ -0,0 +1,46 @@
|
||||
+<!--
|
||||
+ Copyright (c) 2013, Eric W. Biederman
|
||||
+ 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.
|
||||
+-->
|
||||
+<varlistentry>
|
||||
+ <term><option>SUB_UID_MIN</option> (number)</term>
|
||||
+ <term><option>SUB_UID_MAX</option> (number)</term>
|
||||
+ <term><option>SUB_UID_COUNT</option> (number)</term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ The commands <command>useradd</command> and <command>newusers</command>
|
||||
+ allocate <option>SUB_UID_COUNT</option> unused user IDs from the range
|
||||
+ <option>SUB_UID_MIN</option> to <option>SUB_UID_MAX</option> for each
|
||||
+ new user.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ The default values for <option>SUB_GID_MAN</option>,
|
||||
+ <option>SUB_GID_MIN</option>, <option>SUB_GID_COUNT</option>
|
||||
+ are respectively 100000, 600100000 and 10000.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+</varlistentry>
|
||||
@@ -1,110 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:15:19 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id CAFA8C80F6; Tue, 22 Jan 2013 09:15:19 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 43FAEC80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:15:15 +0000 (UTC)
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZvA-0006sA-Pq; Tue, 22 Jan 2013 02:13:32 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZv8-0004VI-Fi; Tue, 22 Jan 2013 02:13:32 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:13:26 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <87vcapr361.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1++0A/mQBimfZkeNedO095IfnCYGQfIolI=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 03/11] Implement commonio_append.
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2073
|
||||
Status: RO
|
||||
Content-Length: 1874
|
||||
Lines: 65
|
||||
|
||||
|
||||
To support files that do not have a simple unique key implement
|
||||
commonio_append to allow new entries to be added.
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
lib/commonio.c | 30 ++++++++++++++++++++++++++++++
|
||||
lib/commonio.h | 1 +
|
||||
2 files changed, 31 insertions(+), 0 deletions(-)
|
||||
|
||||
Index: shadow/lib/commonio.c
|
||||
===================================================================
|
||||
--- shadow.orig/lib/commonio.c 2013-02-01 15:27:51.376080384 -0600
|
||||
+++ shadow/lib/commonio.c 2013-02-01 15:27:51.368080384 -0600
|
||||
@@ -1121,6 +1121,36 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
+int commonio_append (struct commonio_db *db, const void *eptr)
|
||||
+{
|
||||
+ struct commonio_entry *p;
|
||||
+ void *nentry;
|
||||
+
|
||||
+ if (!db->isopen || db->readonly) {
|
||||
+ errno = EINVAL;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ nentry = db->ops->dup (eptr);
|
||||
+ if (NULL == nentry) {
|
||||
+ errno = ENOMEM;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ /* new entry */
|
||||
+ p = (struct commonio_entry *) malloc (sizeof *p);
|
||||
+ if (NULL == p) {
|
||||
+ db->ops->free (nentry);
|
||||
+ errno = ENOMEM;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ p->eptr = nentry;
|
||||
+ p->line = NULL;
|
||||
+ p->changed = true;
|
||||
+ add_one_entry (db, p);
|
||||
+
|
||||
+ db->changed = true;
|
||||
+ return 1;
|
||||
+}
|
||||
|
||||
void commonio_del_entry (struct commonio_db *db, const struct commonio_entry *p)
|
||||
{
|
||||
Index: shadow/lib/commonio.h
|
||||
===================================================================
|
||||
--- shadow.orig/lib/commonio.h 2013-02-01 15:27:51.376080384 -0600
|
||||
+++ shadow/lib/commonio.h 2013-02-01 15:27:51.368080384 -0600
|
||||
@@ -146,6 +146,7 @@
|
||||
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 *);
|
||||
+extern int commonio_append (struct commonio_db *, const void *);
|
||||
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 *);
|
||||
-685
@@ -1,685 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:16:29 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id AF9A9C80F4; Tue, 22 Jan 2013 09:16:29 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id EDF70C80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:16:24 +0000 (UTC)
|
||||
Received: from out01.mta.xmission.com ([166.70.13.231])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZwI-0007HS-Mn; Tue, 22 Jan 2013 02:14:42 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out01.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZwI-0005wP-8E; Tue, 22 Jan 2013 02:14:42 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZwE-0004bA-Mv; Tue, 22 Jan 2013 02:14:42 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:14:35 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <87liblr344.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1/3QOlmT6VsAuzQbs/RJ/nb1IrpO++QYVA=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 04/11] Add backend support for suboridnate uids and gids
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2074
|
||||
Status: RO
|
||||
X-Status: A
|
||||
Content-Length: 15967
|
||||
Lines: 636
|
||||
|
||||
|
||||
These files list the set of subordinate uids and gids that users are allowed
|
||||
to use. The expect use case is with the user namespace but other uses are
|
||||
allowed.
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
etc/login.defs | 8 +
|
||||
lib/Makefile.am | 2 +
|
||||
lib/getdef.c | 6 +
|
||||
lib/subordinateio.c | 512 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
lib/subordinateio.h | 38 ++++
|
||||
5 files changed, 566 insertions(+), 0 deletions(-)
|
||||
create mode 100644 lib/subordinateio.c
|
||||
create mode 100644 lib/subordinateio.h
|
||||
|
||||
Index: shadow/etc/login.defs
|
||||
===================================================================
|
||||
--- shadow.orig/etc/login.defs 2013-02-01 15:27:51.684080379 -0600
|
||||
+++ shadow/etc/login.defs 2013-02-01 15:27:51.676080379 -0600
|
||||
@@ -226,6 +226,10 @@
|
||||
# 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 10000
|
||||
|
||||
#
|
||||
# Min/max values for automatic gid selection in groupadd
|
||||
@@ -235,6 +239,10 @@
|
||||
# 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 10000
|
||||
|
||||
#
|
||||
# Max number of login retries if password is bad
|
||||
Index: shadow/lib/Makefile.am
|
||||
===================================================================
|
||||
--- shadow.orig/lib/Makefile.am 2013-02-01 15:27:51.684080379 -0600
|
||||
+++ shadow/lib/Makefile.am 2013-02-01 15:27:51.676080379 -0600
|
||||
@@ -39,6 +39,8 @@
|
||||
pwio.c \
|
||||
pwio.h \
|
||||
pwmem.c \
|
||||
+ subordinateio.h \
|
||||
+ subordinateio.c \
|
||||
selinux.c \
|
||||
semanage.c \
|
||||
sgetgrent.c \
|
||||
Index: shadow/lib/getdef.c
|
||||
===================================================================
|
||||
--- shadow.orig/lib/getdef.c 2013-02-01 15:27:51.684080379 -0600
|
||||
+++ shadow/lib/getdef.c 2013-02-01 15:27:51.680080379 -0600
|
||||
@@ -82,6 +82,12 @@
|
||||
{"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},
|
||||
Index: shadow/lib/subordinateio.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/lib/subordinateio.c 2013-02-01 15:27:51.680080379 -0600
|
||||
@@ -0,0 +1,512 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2012 - Eric Biederman
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+#include "prototypes.h"
|
||||
+#include "defines.h"
|
||||
+#include <stdio.h>
|
||||
+#include "commonio.h"
|
||||
+#include "subordinateio.h"
|
||||
+
|
||||
+struct subordinate_range {
|
||||
+ const char *owner;
|
||||
+ unsigned long start;
|
||||
+ unsigned long count;
|
||||
+};
|
||||
+
|
||||
+#define NFIELDS 3
|
||||
+
|
||||
+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;
|
||||
+}
|
||||
+
|
||||
+static void subordinate_free (/*@out@*/ /*@only@*/void *ent)
|
||||
+{
|
||||
+ struct subordinate_range *rangeent = ent;
|
||||
+
|
||||
+ free ((void *)(rangeent->owner));
|
||||
+ free (rangeent);
|
||||
+}
|
||||
+
|
||||
+static void *subordinate_parse (const char *line)
|
||||
+{
|
||||
+ static struct subordinate_range range;
|
||||
+ 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 ⦥
|
||||
+}
|
||||
+
|
||||
+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)
|
||||
+{
|
||||
+ commonio_next (db);
|
||||
+}
|
||||
+
|
||||
+static bool is_range_free(struct commonio_db *db, unsigned long start,
|
||||
+ unsigned long count)
|
||||
+{
|
||||
+ const struct subordinate_range *range;
|
||||
+ unsigned long end = start + count - 1;
|
||||
+
|
||||
+ commonio_rewind(db);
|
||||
+ while ((range = commonio_next(db)) != NULL) {
|
||||
+ unsigned long first = range->start;
|
||||
+ unsigned long last = first + range->count - 1;
|
||||
+
|
||||
+ if ((end >= first) && (start <= last))
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+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) {
|
||||
+ unsigned long first = range->start;
|
||||
+ unsigned long last = first + range->count - 1;
|
||||
+
|
||||
+ if (0 == strcmp(range->owner, owner))
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static const struct subordinate_range *find_range(struct commonio_db *db,
|
||||
+ const char *owner, unsigned long val)
|
||||
+{
|
||||
+ const struct subordinate_range *range;
|
||||
+ commonio_rewind(db);
|
||||
+ while ((range = commonio_next(db)) != NULL) {
|
||||
+ unsigned long first = range->start;
|
||||
+ unsigned long last = first + range->count - 1;
|
||||
+
|
||||
+ if (0 != strcmp(range->owner, owner))
|
||||
+ continue;
|
||||
+
|
||||
+ if ((val >= first) && (val <= last))
|
||||
+ return range;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+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;
|
||||
+}
|
||||
+
|
||||
+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);
|
||||
+}
|
||||
+
|
||||
+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 than 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;
|
||||
+ if (high > max)
|
||||
+ high = max;
|
||||
+
|
||||
+ /* Is the hole before this range large enough? */
|
||||
+ if ((high > low) && (((high - low) + 1) >= 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;
|
||||
+}
|
||||
+
|
||||
+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;
|
||||
+
|
||||
+ /* Oterwise append the range */
|
||||
+ return commonio_append(db, &range);
|
||||
+}
|
||||
+
|
||||
+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; ent; ent = ent->next) {
|
||||
+ struct subordinate_range *range = ent->eptr;
|
||||
+ unsigned long first;
|
||||
+ unsigned long last;
|
||||
+
|
||||
+ /* Skip unparsed entries */
|
||||
+ if (!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;
|
||||
+
|
||||
+ /* Is entry completely contained in the range to remove? */
|
||||
+ if ((start <= first) && (end >= last)) {
|
||||
+ commonio_del_entry (db, ent);
|
||||
+ }
|
||||
+ /* Is just the start of the entry removed? */
|
||||
+ else if ((start <= first) && (end < last)) {
|
||||
+ range->start = end + 1;
|
||||
+ range->count = (last - range->start) + 1;
|
||||
+
|
||||
+ ent->changed = true;
|
||||
+ }
|
||||
+ /* Is just the end of the entry removed? */
|
||||
+ else if ((start > first) && (end >= last)) {
|
||||
+ range->count = (start - range->start) + 1;
|
||||
+
|
||||
+ ent->changed = true;
|
||||
+ }
|
||||
+ /* The middle of the range is removed */
|
||||
+ else {
|
||||
+ struct subordinate_range tail;
|
||||
+ tail.owner = range->owner;
|
||||
+ tail.start = end + 1;
|
||||
+ tail.count = (last - tail.start) + 1;
|
||||
+
|
||||
+ if (!commonio_append(db, &tail))
|
||||
+ return 0;
|
||||
+
|
||||
+ range->count = (start - range->start) + 1;
|
||||
+
|
||||
+ ent->changed = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static struct commonio_db subordinate_uid_db = {
|
||||
+ "/etc/subuid", /* filename */
|
||||
+ &subordinate_ops, /* ops */
|
||||
+ NULL, /* fp */
|
||||
+#ifdef WITH_SELINUX
|
||||
+ NULL, /* scontext */
|
||||
+#endif
|
||||
+ NULL, /* head */
|
||||
+ NULL, /* tail */
|
||||
+ NULL, /* cursor */
|
||||
+ false, /* changed */
|
||||
+ false, /* isopen */
|
||||
+ false, /* locked */
|
||||
+ false /* readonly */
|
||||
+};
|
||||
+
|
||||
+int sub_uid_setdbname (const char *filename)
|
||||
+{
|
||||
+ return commonio_setname (&subordinate_uid_db, filename);
|
||||
+}
|
||||
+
|
||||
+/*@observer@*/const char *sub_uid_dbname (void)
|
||||
+{
|
||||
+ return subordinate_uid_db.filename;
|
||||
+}
|
||||
+
|
||||
+bool sub_uid_file_present (void)
|
||||
+{
|
||||
+ return commonio_present (&subordinate_uid_db);
|
||||
+}
|
||||
+
|
||||
+int sub_uid_lock (void)
|
||||
+{
|
||||
+ return commonio_lock (&subordinate_uid_db);
|
||||
+}
|
||||
+
|
||||
+int sub_uid_open (int mode)
|
||||
+{
|
||||
+ return commonio_open (&subordinate_uid_db, mode);
|
||||
+}
|
||||
+
|
||||
+bool is_sub_uid_range_free(uid_t start, unsigned long count)
|
||||
+{
|
||||
+ return is_range_free (&subordinate_uid_db, start, count);
|
||||
+}
|
||||
+
|
||||
+bool sub_uid_assigned(const char *owner)
|
||||
+{
|
||||
+ return range_exists (&subordinate_uid_db, owner);
|
||||
+}
|
||||
+
|
||||
+bool have_sub_uids(const char *owner, uid_t start, unsigned long count)
|
||||
+{
|
||||
+ return have_range (&subordinate_uid_db, owner, start, count);
|
||||
+}
|
||||
+
|
||||
+int sub_uid_add (const char *owner, uid_t start, unsigned long count)
|
||||
+{
|
||||
+ return add_range (&subordinate_uid_db, owner, start, count);
|
||||
+}
|
||||
+
|
||||
+int sub_uid_remove (const char *owner, uid_t start, unsigned long count)
|
||||
+{
|
||||
+ return remove_range (&subordinate_uid_db, owner, start, count);
|
||||
+}
|
||||
+
|
||||
+int sub_uid_close (void)
|
||||
+{
|
||||
+ return commonio_close (&subordinate_uid_db);
|
||||
+}
|
||||
+
|
||||
+int sub_uid_unlock (void)
|
||||
+{
|
||||
+ return commonio_unlock (&subordinate_uid_db);
|
||||
+}
|
||||
+
|
||||
+uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count)
|
||||
+{
|
||||
+ unsigned long start;
|
||||
+ start = find_free_range (&subordinate_uid_db, min, max, count);
|
||||
+ return start == ULONG_MAX ? (uid_t) -1 : start;
|
||||
+}
|
||||
+
|
||||
+static struct commonio_db subordinate_gid_db = {
|
||||
+ "/etc/subgid", /* filename */
|
||||
+ &subordinate_ops, /* ops */
|
||||
+ NULL, /* fp */
|
||||
+#ifdef WITH_SELINUX
|
||||
+ NULL, /* scontext */
|
||||
+#endif
|
||||
+ NULL, /* head */
|
||||
+ NULL, /* tail */
|
||||
+ NULL, /* cursor */
|
||||
+ false, /* changed */
|
||||
+ false, /* isopen */
|
||||
+ false, /* locked */
|
||||
+ false /* readonly */
|
||||
+};
|
||||
+
|
||||
+int sub_gid_setdbname (const char *filename)
|
||||
+{
|
||||
+ return commonio_setname (&subordinate_gid_db, filename);
|
||||
+}
|
||||
+
|
||||
+/*@observer@*/const char *sub_gid_dbname (void)
|
||||
+{
|
||||
+ return subordinate_gid_db.filename;
|
||||
+}
|
||||
+
|
||||
+bool sub_gid_file_present (void)
|
||||
+{
|
||||
+ return commonio_present (&subordinate_gid_db);
|
||||
+}
|
||||
+
|
||||
+int sub_gid_lock (void)
|
||||
+{
|
||||
+ return commonio_lock (&subordinate_gid_db);
|
||||
+}
|
||||
+
|
||||
+int sub_gid_open (int mode)
|
||||
+{
|
||||
+ return commonio_open (&subordinate_gid_db, mode);
|
||||
+}
|
||||
+
|
||||
+bool is_sub_gid_range_free(gid_t start, unsigned long count)
|
||||
+{
|
||||
+ return is_range_free (&subordinate_gid_db, start, count);
|
||||
+}
|
||||
+
|
||||
+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;
|
||||
+}
|
||||
Index: shadow/lib/subordinateio.h
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/lib/subordinateio.h 2013-02-01 15:27:51.680080379 -0600
|
||||
@@ -0,0 +1,38 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2012- Eric W. Biederman
|
||||
+ */
|
||||
+
|
||||
+#ifndef _SUBORDINATEIO_H
|
||||
+#define _SUBORDINATEIO_H
|
||||
+
|
||||
+#include <sys/types.h>
|
||||
+
|
||||
+extern int sub_uid_close(void);
|
||||
+extern bool is_sub_uid_range_free(uid_t start, unsigned long count);
|
||||
+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 is_sub_gid_range_free(gid_t start, unsigned long count);
|
||||
+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
|
||||
@@ -1,283 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:17:02 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id 480ABC80F4; Tue, 22 Jan 2013 09:17:02 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 90ACFC80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:16:57 +0000 (UTC)
|
||||
Received: from out01.mta.xmission.com ([166.70.13.231])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZwp-0007cg-9X; Tue, 22 Jan 2013 02:15:15 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out01.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZwo-0006DN-OT; Tue, 22 Jan 2013 02:15:14 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZwj-0004g0-9e; Tue, 22 Jan 2013 02:15:14 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:15:05 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <87fw1tr33a.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX19KHX5xUOkaLY5iIEqDVLxZKDTByyA0Xk8=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 05/11] Implement find_new_sub_uids find_new_sub_gids
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2075
|
||||
Status: RO
|
||||
Content-Length: 8108
|
||||
Lines: 235
|
||||
|
||||
|
||||
Functions for finding new subordinate uid and gids ranges for use
|
||||
with useradd.
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
lib/prototypes.h | 9 ++++
|
||||
libmisc/Makefile.am | 2 +
|
||||
libmisc/find_new_sub_gids.c | 87 +++++++++++++++++++++++++++++++++++++++++++
|
||||
libmisc/find_new_sub_uids.c | 87 +++++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 185 insertions(+), 0 deletions(-)
|
||||
create mode 100644 libmisc/find_new_sub_gids.c
|
||||
create mode 100644 libmisc/find_new_sub_uids.c
|
||||
|
||||
Index: shadow/lib/prototypes.h
|
||||
===================================================================
|
||||
--- shadow.orig/lib/prototypes.h 2013-02-01 15:27:52.044080373 -0600
|
||||
+++ shadow/lib/prototypes.h 2013-02-01 15:27:52.040080373 -0600
|
||||
@@ -149,6 +149,15 @@
|
||||
uid_t *uid,
|
||||
/*@null@*/uid_t const *preferred_uid);
|
||||
|
||||
+/* 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);
|
||||
+
|
||||
+
|
||||
/* get_gid.c */
|
||||
extern int get_gid (const char *gidstr, gid_t *gid);
|
||||
|
||||
Index: shadow/libmisc/Makefile.am
|
||||
===================================================================
|
||||
--- shadow.orig/libmisc/Makefile.am 2013-02-01 15:27:52.044080373 -0600
|
||||
+++ shadow/libmisc/Makefile.am 2013-02-01 15:27:52.040080373 -0600
|
||||
@@ -25,6 +25,8 @@
|
||||
failure.h \
|
||||
find_new_gid.c \
|
||||
find_new_uid.c \
|
||||
+ find_new_sub_gids.c \
|
||||
+ find_new_sub_uids.c \
|
||||
getdate.h \
|
||||
getdate.y \
|
||||
getgr_nam_gid.c \
|
||||
Index: shadow/libmisc/find_new_sub_gids.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/libmisc/find_new_sub_gids.c 2013-02-01 15:27:52.040080373 -0600
|
||||
@@ -0,0 +1,87 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2012 Eric Biederman
|
||||
+ *
|
||||
+ * 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 <assert.h>
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "prototypes.h"
|
||||
+#include "subordinateio.h"
|
||||
+#include "getdef.h"
|
||||
+
|
||||
+/*
|
||||
+ * find_new_sub_gids - Find a new unused range of GIDs.
|
||||
+ *
|
||||
+ * If successful, find_new_sub_gids provides a range of unused
|
||||
+ * user IDs in the [SUB_GID_MIN:SUB_GID_MAX] range.
|
||||
+ *
|
||||
+ * Return 0 on success, -1 if no unused GIDs are available.
|
||||
+ */
|
||||
+int find_new_sub_gids (const char *owner,
|
||||
+ gid_t *range_start, unsigned long *range_count)
|
||||
+{
|
||||
+ unsigned long min, max;
|
||||
+ unsigned long count;
|
||||
+ gid_t start;
|
||||
+
|
||||
+ assert (range_start != NULL);
|
||||
+ assert (range_count != NULL);
|
||||
+
|
||||
+ min = getdef_ulong ("SUB_GID_MIN", 100000UL);
|
||||
+ max = getdef_ulong ("SUB_GID_MAX", 600100000UL);
|
||||
+ count = getdef_ulong ("SUB_GID_COUNT", 10000);
|
||||
+
|
||||
+ /* Is there a preferred range that works? */
|
||||
+ if ((*range_count != 0) &&
|
||||
+ (*range_start >= min) &&
|
||||
+ (((*range_start) + (*range_count) - 1) <= max) &&
|
||||
+ is_sub_gid_range_free(*range_start, *range_count)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (max < (min + count)) {
|
||||
+ (void) fprintf (stderr,
|
||||
+ _("%s: Invalid configuration: SUB_GID_MIN (%lu), SUB_GID_MAX (%lu)\n"),
|
||||
+ Prog, min, max);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ start = sub_gid_find_free_range(min, max, count);
|
||||
+ if (start == (gid_t)-1) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: Can't get unique secondary GID range\n"),
|
||||
+ Prog);
|
||||
+ SYSLOG ((LOG_WARN, "no more available secondary GIDs on the system"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ *range_start = start;
|
||||
+ *range_count = count;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
Index: shadow/libmisc/find_new_sub_uids.c
|
||||
===================================================================
|
||||
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
|
||||
+++ shadow/libmisc/find_new_sub_uids.c 2013-02-01 15:27:52.040080373 -0600
|
||||
@@ -0,0 +1,87 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2012 Eric Biederman
|
||||
+ *
|
||||
+ * 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 <assert.h>
|
||||
+#include <stdio.h>
|
||||
+#include <errno.h>
|
||||
+
|
||||
+#include "prototypes.h"
|
||||
+#include "subordinateio.h"
|
||||
+#include "getdef.h"
|
||||
+
|
||||
+/*
|
||||
+ * find_new_sub_uids - Find a new unused range of UIDs.
|
||||
+ *
|
||||
+ * If successful, find_new_sub_uids provides a range of unused
|
||||
+ * user IDs in the [SUB_UID_MIN:SUB_UID_MAX] range.
|
||||
+ *
|
||||
+ * Return 0 on success, -1 if no unused UIDs are available.
|
||||
+ */
|
||||
+int find_new_sub_uids (const char *owner,
|
||||
+ uid_t *range_start, unsigned long *range_count)
|
||||
+{
|
||||
+ unsigned long min, max;
|
||||
+ unsigned long count;
|
||||
+ uid_t start;
|
||||
+
|
||||
+ assert (range_start != NULL);
|
||||
+ assert (range_count != NULL);
|
||||
+
|
||||
+ min = getdef_ulong ("SUB_UID_MIN", 100000UL);
|
||||
+ max = getdef_ulong ("SUB_UID_MAX", 600100000UL);
|
||||
+ count = getdef_ulong ("SUB_UID_COUNT", 10000);
|
||||
+
|
||||
+ /* Is there a preferred range that works? */
|
||||
+ if ((*range_count != 0) &&
|
||||
+ (*range_start >= min) &&
|
||||
+ (((*range_start) + (*range_count) - 1) <= max) &&
|
||||
+ is_sub_uid_range_free(*range_start, *range_count)) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (max < (min + count)) {
|
||||
+ (void) fprintf (stderr,
|
||||
+ _("%s: Invalid configuration: SUB_UID_MIN (%lu), SUB_UID_MAX (%lu)\n"),
|
||||
+ Prog, min, max);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ start = sub_uid_find_free_range(min, max, count);
|
||||
+ if (start == (uid_t)-1) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: Can't get unique secondary UID range\n"),
|
||||
+ Prog);
|
||||
+ SYSLOG ((LOG_WARN, "no more available secondary UIDs on the system"));
|
||||
+ return -1;
|
||||
+ }
|
||||
+ *range_start = start;
|
||||
+ *range_count = count;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
-236
@@ -1,236 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:18:47 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id F2E6AC80F6; Tue, 22 Jan 2013 09:18:46 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 996B1C80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:18:42 +0000 (UTC)
|
||||
Received: from out03.mta.xmission.com ([166.70.13.233])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZyW-0008Bi-3X; Tue, 22 Jan 2013 02:17:00 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out03.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZyU-0005NA-Qm; Tue, 22 Jan 2013 02:16:59 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZyQ-0004qs-T1; Tue, 22 Jan 2013 02:16:58 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:16:51 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <878v7lr30c.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1/1l7dElNy9uNLAXx8eC28OMs/pxPM8NEo=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 06/11] userdel: Add support for removing subordinate user and group ids.
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2076
|
||||
Status: O
|
||||
Content-Length: 5573
|
||||
Lines: 186
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
src/userdel.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 115 insertions(+), 0 deletions(-)
|
||||
|
||||
Index: shadow/src/userdel.c
|
||||
===================================================================
|
||||
--- shadow.orig/src/userdel.c 2013-02-01 15:27:52.380080367 -0600
|
||||
+++ shadow/src/userdel.c 2013-02-01 15:27:52.372080367 -0600
|
||||
@@ -65,6 +65,7 @@
|
||||
#endif /* WITH_TCB */
|
||||
/*@-exitarg@*/
|
||||
#include "exitcodes.h"
|
||||
+#include "subordinateio.h"
|
||||
|
||||
/*
|
||||
* exit status values
|
||||
@@ -75,6 +76,8 @@
|
||||
#define E_GRP_UPDATE 10 /* can't update group file */
|
||||
#define E_HOMEDIR 12 /* can't remove home directory */
|
||||
#define E_SE_UPDATE 14 /* can't update SELinux user mapping */
|
||||
+#define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */
|
||||
+#define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
@@ -96,9 +99,13 @@
|
||||
static bool is_shadow_grp;
|
||||
static bool sgr_locked = false;
|
||||
#endif /* SHADOWGRP */
|
||||
+static bool is_sub_uid;
|
||||
+static bool is_sub_gid;
|
||||
static bool pw_locked = false;
|
||||
static bool gr_locked = false;
|
||||
static bool spw_locked = false;
|
||||
+static bool sub_uid_locked = false;
|
||||
+static bool sub_gid_locked = false;
|
||||
|
||||
/* local function prototypes */
|
||||
static void usage (int status);
|
||||
@@ -437,6 +444,34 @@
|
||||
sgr_locked = false;
|
||||
}
|
||||
#endif /* SHADOWGRP */
|
||||
+
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_close () == 0) {
|
||||
+ fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ()));
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_uid_locked = false;
|
||||
+ }
|
||||
+
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_close () == 0) {
|
||||
+ fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ()));
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_gid_locked = false;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -474,6 +509,20 @@
|
||||
}
|
||||
}
|
||||
#endif /* SHADOWGRP */
|
||||
+ if (sub_uid_locked) {
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
+ if (sub_gid_locked) {
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_DEL_USER, Prog,
|
||||
@@ -595,6 +644,58 @@
|
||||
}
|
||||
}
|
||||
#endif /* SHADOWGRP */
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_lock () == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_DEL_USER, Prog,
|
||||
+ "locking subordinate user file",
|
||||
+ user_name, (unsigned int) user_id,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif /* WITH_AUDIT */
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ sub_uid_locked = true;
|
||||
+ if (sub_uid_open (O_RDWR) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"), Prog, sub_uid_dbname ());
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_DEL_USER, Prog,
|
||||
+ "opening subordinate user file",
|
||||
+ user_name, (unsigned int) user_id,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif /* WITH_AUDIT */
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_lock () == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_DEL_USER, Prog,
|
||||
+ "locking subordinate group file",
|
||||
+ user_name, (unsigned int) user_id,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif /* WITH_AUDIT */
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ sub_gid_locked = true;
|
||||
+ if (sub_gid_open (O_RDWR) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"), Prog, sub_gid_dbname ());
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_DEL_USER, Prog,
|
||||
+ "opening subordinate group file",
|
||||
+ user_name, (unsigned int) user_id,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif /* WITH_AUDIT */
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -619,6 +720,18 @@
|
||||
Prog, user_name, spw_dbname ());
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
+ if (is_sub_uid && sub_uid_remove(user_name, 0, ULONG_MAX) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot remove entry %lu from %s\n"),
|
||||
+ Prog, (unsigned long)user_id, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ if (is_sub_gid && sub_gid_remove(user_name, 0, ULONG_MAX) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot remove entry %lu from %s\n"),
|
||||
+ Prog, (unsigned long)user_id, sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_DEL_USER, Prog,
|
||||
"deleting user entries",
|
||||
@@ -966,6 +1079,8 @@
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif /* SHADOWGRP */
|
||||
+ is_sub_uid = sub_uid_file_present ();
|
||||
+ is_sub_gid = sub_gid_file_present ();
|
||||
|
||||
/*
|
||||
* Start with a quick check to see if the user exists.
|
||||
-285
@@ -1,285 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:19:29 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id 61652C80DB; Tue, 22 Jan 2013 09:19:29 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id E0ABBC80F4
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:19:23 +0000 (UTC)
|
||||
Received: from out03.mta.xmission.com ([166.70.13.233])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZzB-0008QG-Kq; Tue, 22 Jan 2013 02:17:41 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out03.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZz7-0005Ui-1H; Tue, 22 Jan 2013 02:17:37 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZz4-0004tF-BP; Tue, 22 Jan 2013 02:17:36 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:17:30 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <8738xtr2z9.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1/Jm5H2PcjgcLXEyKh9YL3DVs2WZBJhDB8=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 07/11] useradd: Add support for subordinate user identifiers
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2077
|
||||
Status: RO
|
||||
Content-Length: 6886
|
||||
Lines: 235
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
src/useradd.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 files changed, 140 insertions(+), 1 deletions(-)
|
||||
|
||||
Index: shadow/src/useradd.c
|
||||
===================================================================
|
||||
--- shadow.orig/src/useradd.c 2013-02-01 15:27:52.668080362 -0600
|
||||
+++ shadow/src/useradd.c 2013-02-01 15:27:52.660080362 -0600
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
#include "shadowio.h"
|
||||
+#include "subordinateio.h"
|
||||
#ifdef WITH_TCB
|
||||
#include "tcbfuncs.h"
|
||||
#endif
|
||||
@@ -121,12 +122,20 @@
|
||||
static bool is_shadow_grp;
|
||||
static bool sgr_locked = false;
|
||||
#endif
|
||||
+static bool is_sub_uid = false;
|
||||
+static bool is_sub_gid = false;
|
||||
static bool pw_locked = false;
|
||||
static bool gr_locked = false;
|
||||
static bool spw_locked = false;
|
||||
+static bool sub_uid_locked = false;
|
||||
+static bool sub_gid_locked = false;
|
||||
static char **user_groups; /* NULL-terminated list */
|
||||
static long sys_ngroups;
|
||||
static bool do_grp_update = false; /* group files need to be updated */
|
||||
+static uid_t sub_uid_start; /* New subordinate uid range */
|
||||
+static unsigned long sub_uid_count;
|
||||
+static gid_t sub_gid_start; /* New subordinate gid range */
|
||||
+static unsigned long sub_gid_count;
|
||||
|
||||
static bool
|
||||
bflg = false, /* new default root of home directory */
|
||||
@@ -168,6 +177,8 @@
|
||||
#define E_GRP_UPDATE 10 /* can't update group file */
|
||||
#define E_HOMEDIR 12 /* can't create home directory */
|
||||
#define E_SE_UPDATE 14 /* can't update SELinux user mapping */
|
||||
+#define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */
|
||||
+#define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */
|
||||
|
||||
#define DGROUP "GROUP="
|
||||
#define DHOME "HOME="
|
||||
@@ -268,6 +279,32 @@
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+ if (sub_uid_locked) {
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_ADD_USER, Prog,
|
||||
+ "unlocking subodinate user file",
|
||||
+ user_name, AUDIT_NO_ID,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
+ if (sub_gid_locked) {
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_ADD_USER, Prog,
|
||||
+ "unlocking subodinate group file",
|
||||
+ user_name, AUDIT_NO_ID,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, Prog,
|
||||
@@ -1379,6 +1416,18 @@
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+ if (is_sub_uid && (sub_uid_close () == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ()));
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ if (is_sub_gid && (sub_gid_close () == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ()));
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
if (is_shadow_pwd) {
|
||||
if (spw_unlock () == 0) {
|
||||
fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
|
||||
@@ -1433,6 +1482,34 @@
|
||||
sgr_locked = false;
|
||||
}
|
||||
#endif
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_ADD_USER, Prog,
|
||||
+ "unlocking subordinate user file",
|
||||
+ user_name, AUDIT_NO_ID,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_uid_locked = false;
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+#ifdef WITH_AUDIT
|
||||
+ audit_logger (AUDIT_ADD_USER, Prog,
|
||||
+ "unlocking subordinate group file",
|
||||
+ user_name, AUDIT_NO_ID,
|
||||
+ SHADOW_AUDIT_FAILURE);
|
||||
+#endif
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_gid_locked = false;
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1487,6 +1564,36 @@
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_lock () == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ sub_uid_locked = true;
|
||||
+ if (sub_uid_open (O_RDWR) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_lock () == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ sub_gid_locked = true;
|
||||
+ if (sub_gid_open (O_RDWR) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
static void open_shadow (void)
|
||||
@@ -1733,13 +1840,27 @@
|
||||
#endif
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
+ if (is_sub_uid &&
|
||||
+ (sub_uid_add(user_name, sub_uid_start, sub_uid_count) == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to prepare the new %s entry\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ if (is_sub_gid &&
|
||||
+ (sub_gid_add(user_name, sub_gid_start, sub_gid_count) == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to prepare the new %s entry\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_ADD_USER, Prog,
|
||||
"adding user",
|
||||
user_name, (unsigned int) user_id,
|
||||
SHADOW_AUDIT_SUCCESS);
|
||||
#endif
|
||||
-
|
||||
/*
|
||||
* Do any group file updates for this user.
|
||||
*/
|
||||
@@ -1885,6 +2006,8 @@
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
+ is_sub_uid = sub_uid_file_present ();
|
||||
+ is_sub_gid = sub_gid_file_present ();
|
||||
|
||||
get_defaults ();
|
||||
|
||||
@@ -2035,6 +2158,22 @@
|
||||
grp_add ();
|
||||
}
|
||||
|
||||
+ if (is_sub_uid) {
|
||||
+ if (find_new_sub_uids(user_name, &sub_uid_start, &sub_uid_count) < 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: can't find subordinate user range\n"),
|
||||
+ Prog);
|
||||
+ fail_exit(E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (find_new_sub_gids(user_name, &sub_gid_start, &sub_gid_count) < 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: can't find subordinate group range\n"),
|
||||
+ Prog);
|
||||
+ fail_exit(E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
usr_update ();
|
||||
|
||||
if (mflg) {
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:19:49 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id E0EA3C80F4; Tue, 22 Jan 2013 09:19:49 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-2.2 required=8.0 tests=BAD_ENC_HEADER,BAYES_00,
|
||||
RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 1A2C7C80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:19:46 +0000 (UTC)
|
||||
Received: from out03.mta.xmission.com ([166.70.13.233])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZzX-00006D-G7; Tue, 22 Jan 2013 02:18:03 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out03.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZzV-0005Zh-Qq; Tue, 22 Jan 2013 02:18:02 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZzN-0004ul-H6; Tue, 22 Jan 2013 02:18:01 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:17:50 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <87y5flpoe9.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1/ZWJZMWIVV2ekPIrRQjHLl4Oh/kdyWJUw=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 08/11] Add support for detecting busy subordinate user ids
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2078
|
||||
Status: RO
|
||||
Content-Length: 2655
|
||||
Lines: 83
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
libmisc/user_busy.c | 18 +++++++++++++-----
|
||||
1 files changed, 13 insertions(+), 5 deletions(-)
|
||||
|
||||
Index: shadow/libmisc/user_busy.c
|
||||
===================================================================
|
||||
--- shadow.orig/libmisc/user_busy.c 2013-02-01 15:27:52.952080357 -0600
|
||||
+++ shadow/libmisc/user_busy.c 2013-02-01 15:27:52.948080357 -0600
|
||||
@@ -38,11 +38,13 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
+#include <fcntl.h>
|
||||
#include "defines.h"
|
||||
#include "prototypes.h"
|
||||
+#include "subordinateio.h"
|
||||
|
||||
#ifdef __linux__
|
||||
-static int check_status (const char *sname, uid_t uid);
|
||||
+static int check_status (const char *name, const char *sname, uid_t uid);
|
||||
static int user_busy_processes (const char *name, uid_t uid);
|
||||
#else /* !__linux__ */
|
||||
static int user_busy_utmp (const char *name);
|
||||
@@ -102,7 +104,7 @@
|
||||
#endif /* !__linux__ */
|
||||
|
||||
#ifdef __linux__
|
||||
-static int check_status (const char *sname, uid_t uid)
|
||||
+static int check_status (const char *name, const char *sname, uid_t uid)
|
||||
{
|
||||
/* 40: /proc/xxxxxxxxxx/task/xxxxxxxxxx/status + \0 */
|
||||
char status[40];
|
||||
@@ -125,7 +127,10 @@
|
||||
&ruid, &euid, &suid) == 3) {
|
||||
if ( (ruid == (unsigned long) uid)
|
||||
|| (euid == (unsigned long) uid)
|
||||
- || (suid == (unsigned long) uid)) {
|
||||
+ || (suid == (unsigned long) uid)
|
||||
+ || have_sub_uids(name, ruid, 1)
|
||||
+ || have_sub_uids(name, euid, 1)
|
||||
+ || have_sub_uids(name, suid, 1)) {
|
||||
(void) fclose (sfile);
|
||||
return 1;
|
||||
}
|
||||
@@ -153,6 +158,8 @@
|
||||
struct stat sbroot;
|
||||
struct stat sbroot_process;
|
||||
|
||||
+ sub_uid_open (O_RDONLY);
|
||||
+
|
||||
proc = opendir ("/proc");
|
||||
if (proc == NULL) {
|
||||
perror ("opendir /proc");
|
||||
@@ -196,7 +203,7 @@
|
||||
continue;
|
||||
}
|
||||
|
||||
- if (check_status (tmp_d_name, uid) != 0) {
|
||||
+ if (check_status (name, tmp_d_name, uid) != 0) {
|
||||
(void) closedir (proc);
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently used by process %d\n"),
|
||||
@@ -216,7 +223,7 @@
|
||||
if (tid == pid) {
|
||||
continue;
|
||||
}
|
||||
- if (check_status (task_path+6, uid) != 0) {
|
||||
+ if (check_status (name, task_path+6, uid) != 0) {
|
||||
(void) closedir (proc);
|
||||
fprintf (stderr,
|
||||
_("%s: user %s is currently used by process %d\n"),
|
||||
@@ -231,6 +238,7 @@
|
||||
}
|
||||
|
||||
(void) closedir (proc);
|
||||
+ sub_uid_close();
|
||||
return 0;
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
-536
@@ -1,536 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:20:27 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id 8625BC80F4; Tue, 22 Jan 2013 09:20:27 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=0.1 required=8.0 tests=BAD_ENC_HEADER,BAYES_00
|
||||
autolearn=no version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id 69CACC80D1
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:20:23 +0000 (UTC)
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1Txa08-0000JL-Uo; Tue, 22 Jan 2013 02:18:41 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1TxZzw-0004wm-8g; Tue, 22 Jan 2013 02:18:40 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:18:24 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <87sj5tpodb.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1/EkNiL4owL54HOscHbdbK8RucFTofOBo8=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 09/11] usermod: Add support for subordinate uids and gids.
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2079
|
||||
Status: O
|
||||
Content-Length: 15455
|
||||
Lines: 491
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
man/usermod.8.xml | 80 +++++++++++++++++
|
||||
src/usermod.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 332 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: shadow/man/usermod.8.xml
|
||||
===================================================================
|
||||
--- shadow.orig/man/usermod.8.xml 2013-02-01 15:27:53.240080352 -0600
|
||||
+++ shadow/man/usermod.8.xml 2013-02-01 15:27:53.232080353 -0600
|
||||
@@ -391,6 +391,86 @@
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
+ <option>-v</option>, <option>--add-sub-uids</option>
|
||||
+ <replaceable>FIRST</replaceable>-<replaceable>LAST</replaceable>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Add a range of subordinate uids to the users account.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ This option may be specified multiple times to add multiple ranges to a users account.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ No checks will be performed with regard to
|
||||
+ <option>SUB_UID_MIN</option>, <option>SUB_UID_MAX</option>, or
|
||||
+ <option>SUB_UID_COUNT</option> from /etc/login.defs.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>-V</option>, <option>--del-sub-uids</option>
|
||||
+ <replaceable>FIRST</replaceable>-<replaceable>LAST</replaceable>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Remove a range of subordinate uids from the users account.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ This option may be specified multiple times to remove multiple ranges to a users account.
|
||||
+ When both <option>--del-sub-uids</option> and <option>--add-sub-uids</option> are specified
|
||||
+ remove of all subordinate uid ranges happens before any subordinate uid ranges are added.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ No checks will be performed with regard to
|
||||
+ <option>SUB_UID_MIN</option>, <option>SUB_UID_MAX</option>, or
|
||||
+ <option>SUB_UID_COUNT</option> from /etc/login.defs.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>-w</option>, <option>--add-sub-gids</option>
|
||||
+ <replaceable>FIRST</replaceable>-<replaceable>LAST</replaceable>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Add a range of subordinate gids to the users account.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ This option may be specified multiple times to add multiple ranges to a users account.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ No checks will be performed with regard to
|
||||
+ <option>SUB_GID_MIN</option>, <option>SUB_GID_MAX</option>, or
|
||||
+ <option>SUB_GID_COUNT</option> from /etc/login.defs.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
+ <option>-W</option>, <option>--del-sub-gids</option>
|
||||
+ <replaceable>FIRST</replaceable>-<replaceable>LAST</replaceable>
|
||||
+ </term>
|
||||
+ <listitem>
|
||||
+ <para>
|
||||
+ Remove a range of subordinate gids from the users account.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ This option may be specified multiple times to remove multiple ranges to a users account.
|
||||
+ When both <option>--del-sub-gids</option> and <option>--add-sub-gids</option> are specified
|
||||
+ remove of all subordinate gid ranges happens before any subordinate gid ranges are added.
|
||||
+ </para>
|
||||
+ <para>
|
||||
+ No checks will be performed with regard to
|
||||
+ <option>SUB_GID_MIN</option>, <option>SUB_GID_MAX</option>, or
|
||||
+ <option>SUB_GID_COUNT</option> from /etc/login.defs.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term>
|
||||
<option>-Z</option>, <option>--selinux-user</option>
|
||||
<replaceable>SEUSER</replaceable>
|
||||
</term>
|
||||
Index: shadow/src/usermod.c
|
||||
===================================================================
|
||||
--- shadow.orig/src/usermod.c 2013-02-01 15:27:53.240080352 -0600
|
||||
+++ shadow/src/usermod.c 2013-02-01 15:27:53.236080353 -0600
|
||||
@@ -63,6 +63,7 @@
|
||||
#include "sgroupio.h"
|
||||
#endif
|
||||
#include "shadowio.h"
|
||||
+#include "subordinateio.h"
|
||||
#ifdef WITH_TCB
|
||||
#include "tcbfuncs.h"
|
||||
#endif
|
||||
@@ -86,6 +87,8 @@
|
||||
/* #define E_NOSPACE 11 insufficient space to move home dir */
|
||||
#define E_HOMEDIR 12 /* unable to complete home dir move */
|
||||
#define E_SE_UPDATE 13 /* can't update SELinux user mapping */
|
||||
+#define E_SUB_UID_UPDATE 16 /* can't update the subordinate uid file */
|
||||
+#define E_SUB_GID_UPDATE 18 /* can't update the subordinate gid file */
|
||||
#define VALID(s) (strcspn (s, ":\n") == strlen (s))
|
||||
/*
|
||||
* Global variables
|
||||
@@ -133,7 +136,11 @@
|
||||
Zflg = false, /* new selinux user */
|
||||
#endif
|
||||
uflg = false, /* specify new user ID */
|
||||
- Uflg = false; /* unlock the password */
|
||||
+ Uflg = false, /* unlock the password */
|
||||
+ vflg = false, /* add subordinate uids */
|
||||
+ Vflg = false, /* delete subordinate uids */
|
||||
+ wflg = false, /* add subordinate gids */
|
||||
+ Wflg = false; /* delete subordinate gids */
|
||||
|
||||
static bool is_shadow_pwd;
|
||||
|
||||
@@ -141,12 +148,17 @@
|
||||
static bool is_shadow_grp;
|
||||
#endif
|
||||
|
||||
+static bool is_sub_uid = false;
|
||||
+static bool is_sub_gid = false;
|
||||
+
|
||||
static bool pw_locked = false;
|
||||
static bool spw_locked = false;
|
||||
static bool gr_locked = false;
|
||||
#ifdef SHADOWGRP
|
||||
static bool sgr_locked = false;
|
||||
#endif
|
||||
+static bool sub_uid_locked = false;
|
||||
+static bool sub_gid_locked = false;
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
@@ -302,6 +314,69 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct ulong_range
|
||||
+{
|
||||
+ unsigned long first;
|
||||
+ unsigned long last;
|
||||
+};
|
||||
+
|
||||
+static struct ulong_range getulong_range(const char *str)
|
||||
+{
|
||||
+ struct ulong_range result = { .first = ULONG_MAX, .last = 0 };
|
||||
+ unsigned long long first, last;
|
||||
+ char *pos;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ first = strtoll(str, &pos, 10);
|
||||
+ if (('\0' == *str) || ('-' != *pos ) || (ERANGE == errno) ||
|
||||
+ (first != (unsigned long int)first))
|
||||
+ goto out;
|
||||
+
|
||||
+ errno = 0;
|
||||
+ last = strtoul(pos + 1, &pos, 10);
|
||||
+ if (('\0' != *pos ) || (ERANGE == errno) ||
|
||||
+ (last != (unsigned long int)last))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (first > last)
|
||||
+ goto out;
|
||||
+
|
||||
+ result.first = (unsigned long int)first;
|
||||
+ result.last = (unsigned long int)last;
|
||||
+out:
|
||||
+ return result;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+struct ulong_range_list_entry {
|
||||
+ struct ulong_range_list_entry *next;
|
||||
+ struct ulong_range range;
|
||||
+};
|
||||
+
|
||||
+static struct ulong_range_list_entry *add_sub_uids = NULL, *del_sub_uids = NULL;
|
||||
+static struct ulong_range_list_entry *add_sub_gids = NULL, *del_sub_gids = NULL;
|
||||
+
|
||||
+static int prepend_range(const char *str, struct ulong_range_list_entry **head)
|
||||
+{
|
||||
+ struct ulong_range range;
|
||||
+ struct ulong_range_list_entry *entry;
|
||||
+ range = getulong_range(str);
|
||||
+ if (range.first > range.last)
|
||||
+ return 0;
|
||||
+
|
||||
+ entry = malloc(sizeof(*entry));
|
||||
+ if (!entry) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to allocate memory: %s\n"),
|
||||
+ Prog, strerror (errno));
|
||||
+ return 0;
|
||||
+ }
|
||||
+ entry->next = *head;
|
||||
+ entry->range = range;
|
||||
+ *head = entry;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* usage - display usage message and exit
|
||||
*/
|
||||
@@ -334,6 +409,10 @@
|
||||
(void) fputs (_(" -s, --shell SHELL new login shell for the user account\n"), usageout);
|
||||
(void) fputs (_(" -u, --uid UID new UID for the user account\n"), usageout);
|
||||
(void) fputs (_(" -U, --unlock unlock the user account\n"), usageout);
|
||||
+ (void) fputs (_(" -v, --add-subuids FIRST-LAST add range of subordinate uids\n"), usageout);
|
||||
+ (void) fputs (_(" -V, --del-subuids FIRST-LAST remvoe range of subordinate uids\n"), usageout);
|
||||
+ (void) fputs (_(" -w, --add-subgids FIRST-LAST add range of subordinate gids\n"), usageout);
|
||||
+ (void) fputs (_(" -W, --del-subgids FIRST-LAST remvoe range of subordinate gids\n"), usageout);
|
||||
#ifdef WITH_SELINUX
|
||||
(void) fputs (_(" -Z, --selinux-user SEUSER new SELinux user mapping for the user account\n"), usageout);
|
||||
#endif /* WITH_SELINUX */
|
||||
@@ -590,6 +669,20 @@
|
||||
/* continue */
|
||||
}
|
||||
}
|
||||
+ if (sub_uid_locked) {
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
+ if (sub_gid_locked) {
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog,
|
||||
@@ -889,6 +982,10 @@
|
||||
{"shell", required_argument, NULL, 's'},
|
||||
{"uid", required_argument, NULL, 'u'},
|
||||
{"unlock", no_argument, NULL, 'U'},
|
||||
+ {"add-subuids", required_argument, NULL, 'v'},
|
||||
+ {"del-subuids", required_argument, NULL, 'V'},
|
||||
+ {"add-subgids", required_argument, NULL, 'w'},
|
||||
+ {"del-subgids", required_argument, NULL, 'W'},
|
||||
#ifdef WITH_SELINUX
|
||||
{"selinux-user", required_argument, NULL, 'Z'},
|
||||
#endif /* WITH_SELINUX */
|
||||
@@ -1018,6 +1115,41 @@
|
||||
case 'U':
|
||||
Uflg = true;
|
||||
break;
|
||||
+ case 'v':
|
||||
+ if (prepend_range (optarg, &add_sub_uids) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: invalid subordinate uid range '%s'\n"),
|
||||
+ Prog, optarg);
|
||||
+ exit(E_BAD_ARG);
|
||||
+ }
|
||||
+ vflg = true;
|
||||
+ break;
|
||||
+ case 'V':
|
||||
+ if (prepend_range (optarg, &del_sub_uids) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: invalid subordinate uid range '%s'\n"),
|
||||
+ Prog, optarg);
|
||||
+ exit(E_BAD_ARG);
|
||||
+ }
|
||||
+ Vflg = true;
|
||||
+ break;
|
||||
+ case 'w':
|
||||
+ if (prepend_range (optarg, &add_sub_gids) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: invalid subordinate gid range '%s'\n"),
|
||||
+ Prog, optarg);
|
||||
+ exit(E_BAD_ARG);
|
||||
+ }
|
||||
+ wflg = true;
|
||||
+ case 'W':
|
||||
+ if (prepend_range (optarg, &del_sub_gids) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: invalid subordinate gid range '%s'\n"),
|
||||
+ Prog, optarg);
|
||||
+ exit(E_BAD_ARG);
|
||||
+ }
|
||||
+ Wflg = true;
|
||||
+ break;
|
||||
#ifdef WITH_SELINUX
|
||||
case 'Z':
|
||||
if (is_selinux_enabled () > 0) {
|
||||
@@ -1170,6 +1302,7 @@
|
||||
|
||||
if (!(Uflg || uflg || sflg || pflg || mflg || Lflg ||
|
||||
lflg || Gflg || gflg || fflg || eflg || dflg || cflg
|
||||
+ || vflg || Vflg || wflg || Wflg
|
||||
#ifdef WITH_SELINUX
|
||||
|| Zflg
|
||||
#endif /* WITH_SELINUX */
|
||||
@@ -1200,6 +1333,7 @@
|
||||
Prog, (unsigned long) user_newid);
|
||||
exit (E_UID_IN_USE);
|
||||
}
|
||||
+
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1248,6 +1382,10 @@
|
||||
sgr_dbname ()));
|
||||
fail_exit (E_GRP_UPDATE);
|
||||
}
|
||||
+ }
|
||||
+#endif
|
||||
+#ifdef SHADOWGRP
|
||||
+ if (is_shadow_grp) {
|
||||
if (sgr_unlock () == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to unlock %s\n"),
|
||||
@@ -1296,6 +1434,33 @@
|
||||
sgr_locked = false;
|
||||
#endif
|
||||
|
||||
+ if (vflg || Vflg) {
|
||||
+ if (!is_sub_uid || (sub_uid_close () == 0)) {
|
||||
+ fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ()));
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ if (!is_sub_uid || (sub_uid_unlock () == 0)) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_uid_locked = false;
|
||||
+ }
|
||||
+ if (wflg || Wflg) {
|
||||
+ if (!is_sub_gid || (sub_gid_close () == 0)) {
|
||||
+ fprintf (stderr, _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ()));
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ if (!is_sub_gid || (sub_gid_unlock () == 0)) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_gid_locked = false;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Close the DBM and/or flat files
|
||||
*/
|
||||
@@ -1375,6 +1540,36 @@
|
||||
}
|
||||
#endif
|
||||
}
|
||||
+ if (vflg || Vflg) {
|
||||
+ if (!is_sub_uid || (sub_uid_lock () == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ sub_uid_locked = true;
|
||||
+ if (!is_sub_uid || (sub_uid_open (O_RDWR) == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ if (wflg || Wflg) {
|
||||
+ if (!is_sub_gid || (sub_gid_lock () == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ sub_gid_locked = true;
|
||||
+ if (!is_sub_gid || (sub_gid_open (O_RDWR) == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1476,6 +1671,58 @@
|
||||
fail_exit (E_PW_UPDATE);
|
||||
}
|
||||
}
|
||||
+ if (Vflg) {
|
||||
+ struct ulong_range_list_entry *ptr;
|
||||
+ for (ptr = del_sub_uids; ptr != NULL; ptr = ptr->next) {
|
||||
+ unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
+ if (sub_uid_remove(user_name, ptr->range.first, count) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to remove uid range %lu-%lu from '%s'\n"),
|
||||
+ Prog, ptr->range.first, ptr->range.last,
|
||||
+ sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (vflg) {
|
||||
+ struct ulong_range_list_entry *ptr;
|
||||
+ for (ptr = add_sub_uids; ptr != NULL; ptr = ptr->next) {
|
||||
+ unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
+ if (sub_uid_add(user_name, ptr->range.first, count) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to add uid range %lu-%lu from '%s'\n"),
|
||||
+ Prog, ptr->range.first, ptr->range.last,
|
||||
+ sub_uid_dbname ());
|
||||
+ fail_exit (E_SUB_UID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (Wflg) {
|
||||
+ struct ulong_range_list_entry *ptr;
|
||||
+ for (ptr = del_sub_gids; ptr != NULL; ptr = ptr->next) {
|
||||
+ unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
+ if (sub_gid_remove(user_name, ptr->range.first, count) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to remove gid range %lu-%lu from '%s'\n"),
|
||||
+ Prog, ptr->range.first, ptr->range.last,
|
||||
+ sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (wflg) {
|
||||
+ struct ulong_range_list_entry *ptr;
|
||||
+ for (ptr = add_sub_gids; ptr != NULL; ptr = ptr->next) {
|
||||
+ unsigned long count = ptr->range.last - ptr->range.first + 1;
|
||||
+ if (sub_gid_add(user_name, ptr->range.first, count) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to add gid range %lu-%lu from '%s'\n"),
|
||||
+ Prog, ptr->range.first, ptr->range.last,
|
||||
+ sub_gid_dbname ());
|
||||
+ fail_exit (E_SUB_GID_UPDATE);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1811,6 +2058,8 @@
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
+ is_sub_uid = sub_uid_file_present ();
|
||||
+ is_sub_gid = sub_gid_file_present ();
|
||||
|
||||
process_flags (argc, argv);
|
||||
|
||||
@@ -1818,7 +2067,7 @@
|
||||
* The home directory, the username and the user's UID should not
|
||||
* be changed while the user is logged in.
|
||||
*/
|
||||
- if ( (uflg || lflg || dflg)
|
||||
+ if ( (uflg || lflg || dflg || Vflg || Wflg)
|
||||
&& (user_busy (user_name, user_id) != 0)) {
|
||||
exit (E_USER_BUSY);
|
||||
}
|
||||
@@ -1871,7 +2120,7 @@
|
||||
*/
|
||||
open_files ();
|
||||
if ( cflg || dflg || eflg || fflg || gflg || Lflg || lflg || pflg
|
||||
- || sflg || uflg || Uflg) {
|
||||
+ || sflg || uflg || Uflg || vflg || Vflg || wflg || Wflg) {
|
||||
usr_update ();
|
||||
}
|
||||
if (Gflg || lflg) {
|
||||
-256
@@ -1,256 +0,0 @@
|
||||
From ebiederm@xmission.com Tue Jan 22 09:21:21 2013
|
||||
Return-Path: <ebiederm@xmission.com>
|
||||
X-Original-To: serge@hallyn.com
|
||||
Delivered-To: serge@hallyn.com
|
||||
Received: by mail.hallyn.com (Postfix, from userid 5001)
|
||||
id ADE59C80F5; Tue, 22 Jan 2013 09:21:21 +0000 (UTC)
|
||||
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
|
||||
X-Spam-Level:
|
||||
X-Spam-Status: No, score=-2.2 required=8.0 tests=BAD_ENC_HEADER,BAYES_00,
|
||||
RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1
|
||||
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
|
||||
(using TLSv1 with cipher AES256-SHA (256/256 bits))
|
||||
(No client certificate requested)
|
||||
by mail.hallyn.com (Postfix) with ESMTPS id D56AEC80DB
|
||||
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:21:17 +0000 (UTC)
|
||||
Received: from out03.mta.xmission.com ([166.70.13.233])
|
||||
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1Txa11-0000bo-MQ; Tue, 22 Jan 2013 02:19:35 -0700
|
||||
Received: from in02.mta.xmission.com ([166.70.13.52])
|
||||
by out03.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1Txa11-0005wx-1p; Tue, 22 Jan 2013 02:19:35 -0700
|
||||
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
|
||||
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
|
||||
(Exim 4.76)
|
||||
(envelope-from <ebiederm@xmission.com>)
|
||||
id 1Txa0y-000519-2O; Tue, 22 Jan 2013 02:19:34 -0700
|
||||
From: ebiederm@xmission.com (Eric W. Biederman)
|
||||
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
|
||||
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
|
||||
References: <87d2wxshu0.fsf@xmission.com>
|
||||
Date: Tue, 22 Jan 2013 01:19:28 -0800
|
||||
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
|
||||
"Tue, 22 Jan 2013 01:11:19 -0800")
|
||||
Message-ID: <87k3r5pobj.fsf@xmission.com>
|
||||
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain
|
||||
X-XM-AID: U2FsdGVkX1+qhualZ5pxk+DVqanIJA7JrJwlPXicL8c=
|
||||
X-SA-Exim-Connect-IP: 98.207.153.68
|
||||
X-SA-Exim-Mail-From: ebiederm@xmission.com
|
||||
Subject: [PATCH 10/11] newusers: Add support for assiging subordinate uids and gids.
|
||||
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
|
||||
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
|
||||
X-UID: 2080
|
||||
Status: O
|
||||
Content-Length: 5597
|
||||
Lines: 206
|
||||
|
||||
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
src/newusers.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 124 insertions(+), 0 deletions(-)
|
||||
|
||||
Index: shadow/src/newusers.c
|
||||
===================================================================
|
||||
--- shadow.orig/src/newusers.c 2013-02-01 15:27:53.548080347 -0600
|
||||
+++ shadow/src/newusers.c 2013-02-01 15:27:53.540080347 -0600
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "pwio.h"
|
||||
#include "sgroupio.h"
|
||||
#include "shadowio.h"
|
||||
+#include "subordinateio.h"
|
||||
#include "chkname.h"
|
||||
|
||||
/*
|
||||
@@ -82,6 +83,8 @@
|
||||
#endif /* USE_SHA_CRYPT */
|
||||
#endif /* !USE_PAM */
|
||||
|
||||
+static bool is_sub_uid = false;
|
||||
+static bool is_sub_gid = false;
|
||||
static bool is_shadow;
|
||||
#ifdef SHADOWGRP
|
||||
static bool is_shadow_grp;
|
||||
@@ -90,6 +93,8 @@
|
||||
static bool pw_locked = false;
|
||||
static bool gr_locked = false;
|
||||
static bool spw_locked = false;
|
||||
+static bool sub_uid_locked = false;
|
||||
+static bool sub_gid_locked = false;
|
||||
|
||||
/* local function prototypes */
|
||||
static void usage (int status);
|
||||
@@ -178,6 +183,20 @@
|
||||
}
|
||||
}
|
||||
#endif
|
||||
+ if (sub_uid_locked) {
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
+ if (sub_gid_locked) {
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ }
|
||||
|
||||
exit (code);
|
||||
}
|
||||
@@ -732,6 +751,24 @@
|
||||
sgr_locked = true;
|
||||
}
|
||||
#endif
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_lock () == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ sub_uid_locked = true;
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_lock () == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot lock %s; try again later.\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+ fail_exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ sub_gid_locked = true;
|
||||
+ }
|
||||
|
||||
if (pw_open (O_RDWR) == 0) {
|
||||
fprintf (stderr, _("%s: cannot open %s\n"), Prog, pw_dbname ());
|
||||
@@ -751,6 +788,22 @@
|
||||
fail_exit (EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_open (O_RDWR) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ fail_exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_open (O_RDWR) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: cannot open %s\n"),
|
||||
+ Prog, sub_gid_dbname ());
|
||||
+ fail_exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -795,6 +848,19 @@
|
||||
SYSLOG ((LOG_ERR, "failure while writing changes to %s", gr_dbname ()));
|
||||
fail_exit (EXIT_FAILURE);
|
||||
}
|
||||
+ if (is_sub_uid && (sub_uid_close () == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failure while writing changes to %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_uid_dbname ()));
|
||||
+ fail_exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+ if (is_sub_gid && (sub_gid_close () == 0)) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failure while writing changes to %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failure while writing changes to %s", sub_gid_dbname ()));
|
||||
+ fail_exit (EXIT_FAILURE);
|
||||
+ }
|
||||
+
|
||||
if (gr_unlock () == 0) {
|
||||
fprintf (stderr,
|
||||
_("%s: failed to unlock %s\n"),
|
||||
@@ -823,6 +889,22 @@
|
||||
sgr_locked = false;
|
||||
}
|
||||
#endif
|
||||
+ if (is_sub_uid) {
|
||||
+ if (sub_uid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_uid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_uid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_uid_locked = false;
|
||||
+ }
|
||||
+ if (is_sub_gid) {
|
||||
+ if (sub_gid_unlock () == 0) {
|
||||
+ fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, sub_gid_dbname ());
|
||||
+ SYSLOG ((LOG_ERR, "failed to unlock %s", sub_gid_dbname ()));
|
||||
+ /* continue */
|
||||
+ }
|
||||
+ sub_gid_locked = false;
|
||||
+ }
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
@@ -864,6 +946,8 @@
|
||||
#ifdef SHADOWGRP
|
||||
is_shadow_grp = sgr_file_present ();
|
||||
#endif
|
||||
+ is_sub_uid = sub_uid_file_present ();
|
||||
+ is_sub_gid = sub_gid_file_present ();
|
||||
|
||||
open_files ();
|
||||
|
||||
@@ -1044,6 +1128,46 @@
|
||||
errors++;
|
||||
continue;
|
||||
}
|
||||
+
|
||||
+ /*
|
||||
+ * Add subordinate uids if the user does not have them.
|
||||
+ */
|
||||
+ if (is_sub_uid && !sub_uid_assigned(fields[0])) {
|
||||
+ uid_t sub_uid_start = 0;
|
||||
+ unsigned long sub_uid_count = 0;
|
||||
+ if (find_new_sub_uids(fields[0], &sub_uid_start, &sub_uid_count) == 0) {
|
||||
+ if (sub_uid_add(fields[0], sub_uid_start, sub_uid_count) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to prepare new %s entry\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ }
|
||||
+ } else {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: can't find subordinate user range\n"),
|
||||
+ Prog);
|
||||
+ errors++;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Add subordinate gids if the user does not have them.
|
||||
+ */
|
||||
+ if (is_sub_gid && !sub_gid_assigned(fields[0])) {
|
||||
+ gid_t sub_gid_start = 0;
|
||||
+ unsigned long sub_gid_count = 0;
|
||||
+ if (find_new_sub_gids(fields[0], &sub_gid_start, &sub_gid_count) == 0) {
|
||||
+ if (sub_gid_add(fields[0], sub_gid_start, sub_gid_count) == 0) {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: failed to prepare new %s entry\n"),
|
||||
+ Prog, sub_uid_dbname ());
|
||||
+ }
|
||||
+ } else {
|
||||
+ fprintf (stderr,
|
||||
+ _("%s: can't find subordinate group range\n"),
|
||||
+ Prog);
|
||||
+ errors++;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
/*
|
||||
-1004
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user