summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-04 01:44:12 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-04 01:44:12 +0000
commit26bc67b9754d2e60823ff18b754088a116376590 (patch)
tree838ae4c946825675e61684c3ce3237f4a910c289
parent3c3162293c84b19f2ee25ffdafc103bcb99bcf75 (diff)
downloadshadow-26bc67b9754d2e60823ff18b754088a116376590.tar.gz
Refreshed patches
-rw-r--r--debian/patches/0001-503_shadowconfig.8.patch220
-rw-r--r--debian/patches/0002-428_grpck_add_prune_option.patch30
-rw-r--r--debian/patches/0003-008_login_log_failure_in_FTMP.patch61
-rw-r--r--debian/patches/0004-429_login_FAILLOG_ENAB.patch98
-rw-r--r--debian/patches/0005-401_cppw_src.dpatch.patch294
-rw-r--r--debian/patches/0006-402_cppw_selinux.patch69
-rw-r--r--debian/patches/0007-506_relaxed_usernames.patch113
-rw-r--r--debian/patches/0008-542_useradd-O_option.patch53
-rw-r--r--debian/patches/0009-501_commonio_group_shadow.patch44
-rw-r--r--debian/patches/0010-463_login_delay_obeys_to_PAM.patch114
-rw-r--r--debian/patches/0011-523_su_arguments_are_concatenated.patch52
-rw-r--r--debian/patches/0012-523_su_arguments_are_no_more_concatenated_by_default.patch56
-rw-r--r--debian/patches/0013-508_nologin_in_usr_sbin.patch28
-rw-r--r--debian/patches/0014-505_useradd_recommend_adduser.patch46
-rw-r--r--debian/patches/0015-utmp.c.patch56
-rw-r--r--debian/patches/0016-getspnam_r.patch75
-rw-r--r--debian/patches/0017-environ.patch36
-rw-r--r--debian/patches/0018-putgrent.patch60
-rw-r--r--debian/patches/0019-putpwent-segfault.patch22
19 files changed, 1527 insertions, 0 deletions
diff --git a/debian/patches/0001-503_shadowconfig.8.patch b/debian/patches/0001-503_shadowconfig.8.patch
new file mode 100644
index 0000000..ed296de
--- /dev/null
+++ b/debian/patches/0001-503_shadowconfig.8.patch
@@ -0,0 +1,220 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:47 +0000
+Subject: 503_shadowconfig.8
+
+Status wrt upstream: The shadowconfig utility is debian specific.
+ Its man page also (but it used to be distributed)
+---
+ man/fr/shadowconfig.8 | 26 ++++++++++++++++++++++++
+ man/ja/shadowconfig.8 | 25 +++++++++++++++++++++++
+ man/pl/shadowconfig.8 | 27 +++++++++++++++++++++++++
+ man/shadowconfig.8 | 41 ++++++++++++++++++++++++++++++++++++++
+ man/shadowconfig.8.xml | 52 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 171 insertions(+)
+ create mode 100644 man/fr/shadowconfig.8
+ create mode 100644 man/ja/shadowconfig.8
+ create mode 100644 man/pl/shadowconfig.8
+ create mode 100644 man/shadowconfig.8
+ create mode 100644 man/shadowconfig.8.xml
+
+diff --git a/man/fr/shadowconfig.8 b/man/fr/shadowconfig.8
+new file mode 100644
+index 0000000..784da70
+--- /dev/null
++++ b/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>.
+diff --git a/man/ja/shadowconfig.8 b/man/ja/shadowconfig.8
+new file mode 100644
+index 0000000..a75c6f7
+--- /dev/null
++++ b/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 パスワードとそれに関する特徴の簡単な紹介が書かれている。
+diff --git a/man/pl/shadowconfig.8 b/man/pl/shadowconfig.8
+new file mode 100644
+index 0000000..2016c9f
+--- /dev/null
++++ b/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.
+diff --git a/man/shadowconfig.8 b/man/shadowconfig.8
+new file mode 100644
+index 0000000..c0ee0af
+--- /dev/null
++++ b/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\&.
++
+diff --git a/man/shadowconfig.8.xml b/man/shadowconfig.8.xml
+new file mode 100644
+index 0000000..b4080ea
+--- /dev/null
++++ b/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>
diff --git a/debian/patches/0002-428_grpck_add_prune_option.patch b/debian/patches/0002-428_grpck_add_prune_option.patch
new file mode 100644
index 0000000..1dbe071
--- /dev/null
+++ b/debian/patches/0002-428_grpck_add_prune_option.patch
@@ -0,0 +1,30 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:47 +0000
+Subject: 428_grpck_add_prune_option
+
+Status wrt upstream: It could certainly be submitted to upstream.
+---
+ src/grpck.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/grpck.c b/src/grpck.c
+index 1846c4d..17cef2c 100644
+--- a/src/grpck.c
++++ b/src/grpck.c
+@@ -81,6 +81,7 @@ static bool gr_locked = false;
+ /* Options */
+ static bool read_only = false;
+ static bool sort_mode = false;
++static bool prune = false;
+
+ /* local function prototypes */
+ static void fail_exit (int status);
+@@ -203,7 +204,7 @@ static void process_flags (int argc, char **argv)
+ /*
+ * Parse the command line arguments
+ */
+- while ((c = getopt_long (argc, argv, "hqrR:s",
++ while ((c = getopt_long (argc, argv, "hqprR:s",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'h':
diff --git a/debian/patches/0003-008_login_log_failure_in_FTMP.patch b/debian/patches/0003-008_login_log_failure_in_FTMP.patch
new file mode 100644
index 0000000..ace8fae
--- /dev/null
+++ b/debian/patches/0003-008_login_log_failure_in_FTMP.patch
@@ -0,0 +1,61 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:47 +0000
+Subject: 008_login_log_failure_in_FTMP
+
+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)
+---
+ lib/getdef.c | 2 +-
+ src/login.c | 18 ++++++++++++++++++
+ 2 files changed, 19 insertions(+), 1 deletion(-)
+
+diff --git a/lib/getdef.c b/lib/getdef.c
+index ac08163..3673e84 100644
+--- a/lib/getdef.c
++++ b/lib/getdef.c
+@@ -62,6 +62,7 @@ static struct itemdef def_table[] = {
+ {"ERASECHAR", NULL},
+ {"FAIL_DELAY", NULL},
+ {"FAKE_SHELL", NULL},
++ {"FTMP_FILE", NULL},
+ {"GID_MAX", NULL},
+ {"GID_MIN", NULL},
+ {"HUSHLOGIN_FILE", NULL},
+@@ -103,7 +104,6 @@ static struct itemdef def_table[] = {
+ {"ENVIRON_FILE", NULL},
+ {"ENV_TZ", NULL},
+ {"FAILLOG_ENAB", NULL},
+- {"FTMP_FILE", NULL},
+ {"ISSUE_FILE", NULL},
+ {"LASTLOG_ENAB", NULL},
+ {"LOGIN_STRING", NULL},
+diff --git a/src/login.c b/src/login.c
+index fe628de..2d13b0f 100644
+--- a/src/login.c
++++ b/src/login.c
+@@ -835,6 +835,24 @@ int main (int argc, char **argv)
+ (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'",
diff --git a/debian/patches/0004-429_login_FAILLOG_ENAB.patch b/debian/patches/0004-429_login_FAILLOG_ENAB.patch
new file mode 100644
index 0000000..31543a6
--- /dev/null
+++ b/debian/patches/0004-429_login_FAILLOG_ENAB.patch
@@ -0,0 +1,98 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:47 +0000
+Subject: 429_login_FAILLOG_ENAB
+
+Note: It could be removed if pam_tally could report the number of failures
+ preceding a successful login.
+---
+ lib/getdef.c | 2 +-
+ src/login.c | 19 ++++++++++++++++++-
+ 2 files changed, 19 insertions(+), 2 deletions(-)
+
+diff --git a/lib/getdef.c b/lib/getdef.c
+index 3673e84..b42795b 100644
+--- a/lib/getdef.c
++++ b/lib/getdef.c
+@@ -61,6 +61,7 @@ static struct itemdef def_table[] = {
+ {"ENV_SUPATH", NULL},
+ {"ERASECHAR", NULL},
+ {"FAIL_DELAY", NULL},
++ {"FAILLOG_ENAB", NULL},
+ {"FAKE_SHELL", NULL},
+ {"FTMP_FILE", NULL},
+ {"GID_MAX", NULL},
+@@ -103,7 +104,6 @@ static struct itemdef def_table[] = {
+ {"ENV_HZ", NULL},
+ {"ENVIRON_FILE", NULL},
+ {"ENV_TZ", NULL},
+- {"FAILLOG_ENAB", NULL},
+ {"ISSUE_FILE", NULL},
+ {"LASTLOG_ENAB", NULL},
+ {"LOGIN_STRING", NULL},
+diff --git a/src/login.c b/src/login.c
+index 2d13b0f..5792c5e 100644
+--- a/src/login.c
++++ b/src/login.c
+@@ -133,9 +133,9 @@ static void update_utmp (const char *user,
+ /*@null@*/const struct utmp *utent);
+ #endif /* ! USE_PAM */
+
+-#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
+@@ -795,6 +795,9 @@ int main (int argc, char **argv)
+ 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);
+@@ -812,6 +815,14 @@ int main (int argc, char **argv)
+ 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;
+@@ -835,6 +846,10 @@ int main (int argc, char **argv)
+ (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 =
+@@ -1291,6 +1306,7 @@ int main (int argc, char **argv)
+ */
+ #ifndef USE_PAM
+ motd (); /* print the message of the day */
++#endif
+ if ( getdef_bool ("FAILLOG_ENAB")
+ && (0 != faillog.fail_cnt)) {
+ failprint (&faillog);
+@@ -1303,6 +1319,7 @@ int main (int argc, char **argv)
+ username, (int) faillog.fail_cnt));
+ }
+ }
++#ifndef USE_PAM
+ if ( getdef_bool ("LASTLOG_ENAB")
+ && (ll.ll_time != 0)) {
+ time_t ll_time = ll.ll_time;
diff --git a/debian/patches/0005-401_cppw_src.dpatch.patch b/debian/patches/0005-401_cppw_src.dpatch.patch
new file mode 100644
index 0000000..865e1b7
--- /dev/null
+++ b/debian/patches/0005-401_cppw_src.dpatch.patch
@@ -0,0 +1,294 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 401_cppw_src.dpatch
+
+#! /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@
+---
+ po/POTFILES.in | 1 +
+ src/Makefile.am | 2 +
+ src/cppw.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 241 insertions(+)
+ create mode 100644 src/cppw.c
+
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index 1758f49..ee1a486 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -85,6 +85,7 @@ src/chfn.c
+ src/chgpasswd.c
+ src/chpasswd.c
+ src/chsh.c
++src/cppw.c
+ src/expiry.c
+ src/faillog.c
+ src/gpasswd.c
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 88cae99..6a1e46b 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -26,6 +26,7 @@ bin_PROGRAMS = groups login su
+ sbin_PROGRAMS = nologin
+ ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
+ usbin_PROGRAMS = \
++ cppw \
+ chgpasswd \
+ chpasswd \
+ groupadd \
+@@ -82,6 +83,7 @@ chfn_LDADD = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $
+ 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)
+diff --git a/src/cppw.c b/src/cppw.c
+new file mode 100644
+index 0000000..beb4c36
+--- /dev/null
++++ b/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;
++}
++
diff --git a/debian/patches/0006-402_cppw_selinux.patch b/debian/patches/0006-402_cppw_selinux.patch
new file mode 100644
index 0000000..d258b0d
--- /dev/null
+++ b/debian/patches/0006-402_cppw_selinux.patch
@@ -0,0 +1,69 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 402_cppw_selinux
+
+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
+---
+ src/cppw.c | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/src/cppw.c b/src/cppw.c
+index beb4c36..2cbbbc0 100644
+--- a/src/cppw.c
++++ b/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 @@ static void cppwcopy (const char *file,
+ 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 @@ static void cppwcopy (const char *file,
+ 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) ();
+ }
+
diff --git a/debian/patches/0007-506_relaxed_usernames.patch b/debian/patches/0007-506_relaxed_usernames.patch
new file mode 100644
index 0000000..adfd922
--- /dev/null
+++ b/debian/patches/0007-506_relaxed_usernames.patch
@@ -0,0 +1,113 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 506_relaxed_usernames
+
+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
+---
+ libmisc/chkname.c | 21 +++++++++++++++++++++
+ man/groupadd.8.xml | 8 +++++++-
+ man/useradd.8.xml | 10 +++++++++-
+ 3 files changed, 37 insertions(+), 2 deletions(-)
+
+diff --git a/libmisc/chkname.c b/libmisc/chkname.c
+index 42111ae..f3799ac 100644
+--- a/libmisc/chkname.c
++++ b/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 @@ static bool is_valid_name (const char *name)
+ 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;
+ }
+diff --git a/man/groupadd.8.xml b/man/groupadd.8.xml
+index da2ebf3..eae7324 100644
+--- a/man/groupadd.8.xml
++++ b/man/groupadd.8.xml
+@@ -240,12 +240,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>
+diff --git a/man/useradd.8.xml b/man/useradd.8.xml
+index ee4b4e5..0ae6303 100644
+--- a/man/useradd.8.xml
++++ b/man/useradd.8.xml
+@@ -635,12 +635,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>
diff --git a/debian/patches/0008-542_useradd-O_option.patch b/debian/patches/0008-542_useradd-O_option.patch
new file mode 100644
index 0000000..1b35765
--- /dev/null
+++ b/debian/patches/0008-542_useradd-O_option.patch
@@ -0,0 +1,53 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 542_useradd-O_option
+
+Note: useradd.8 needs to be regenerated.
+
+Status wrt upstream: not included as this is just specific
+ backward compatibility for Debian
+---
+ man/useradd.8.xml | 5 +++++
+ src/useradd.c | 5 +++--
+ 2 files changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/man/useradd.8.xml b/man/useradd.8.xml
+index 0ae6303..3ee0e38 100644
+--- a/man/useradd.8.xml
++++ b/man/useradd.8.xml
+@@ -321,6 +321,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>
+diff --git a/src/useradd.c b/src/useradd.c
+index 4fdb29c..c240ef3 100644
+--- a/src/useradd.c
++++ b/src/useradd.c
+@@ -1011,9 +1011,9 @@ static void process_flags (int argc, char **argv)
+ };
+ 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) {
+@@ -1136,6 +1136,7 @@ static void process_flags (int argc, char **argv)
+ 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
diff --git a/debian/patches/0009-501_commonio_group_shadow.patch b/debian/patches/0009-501_commonio_group_shadow.patch
new file mode 100644
index 0000000..5150b52
--- /dev/null
+++ b/debian/patches/0009-501_commonio_group_shadow.patch
@@ -0,0 +1,44 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 501_commonio_group_shadow
+
+Fixes: #166793
+---
+ lib/commonio.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/lib/commonio.c b/lib/commonio.c
+index 60bcd83..3cde698 100644
+--- a/lib/commonio.c
++++ b/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 @@ int commonio_close (struct commonio_db *db)
+ 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);
diff --git a/debian/patches/0010-463_login_delay_obeys_to_PAM.patch b/debian/patches/0010-463_login_delay_obeys_to_PAM.patch
new file mode 100644
index 0000000..8c00f19
--- /dev/null
+++ b/debian/patches/0010-463_login_delay_obeys_to_PAM.patch
@@ -0,0 +1,114 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 463_login_delay_obeys_to_PAM
+
+Fixes: #87648
+
+Status wrt upstream: Forwarded but not applied yet
+
+Note: If removed, FAIL_DELAY must be re-added to /etc/login.defs
+---
+ lib/getdef.c | 2 +-
+ src/login.c | 19 +++++--------------
+ 2 files changed, 6 insertions(+), 15 deletions(-)
+
+diff --git a/lib/getdef.c b/lib/getdef.c
+index b42795b..038f7a2 100644
+--- a/lib/getdef.c
++++ b/lib/getdef.c
+@@ -60,7 +60,6 @@ static struct itemdef def_table[] = {
+ {"ENV_PATH", NULL},
+ {"ENV_SUPATH", NULL},
+ {"ERASECHAR", NULL},
+- {"FAIL_DELAY", NULL},
+ {"FAILLOG_ENAB", NULL},
+ {"FAKE_SHELL", NULL},
+ {"FTMP_FILE", NULL},
+@@ -104,6 +103,7 @@ static struct itemdef def_table[] = {
+ {"ENV_HZ", NULL},
+ {"ENVIRON_FILE", NULL},
+ {"ENV_TZ", NULL},
++ {"FAIL_DELAY", NULL},
+ {"ISSUE_FILE", NULL},
+ {"LASTLOG_ENAB", NULL},
+ {"LOGIN_STRING", NULL},
+diff --git a/src/login.c b/src/login.c
+index 5792c5e..260bf6d 100644
+--- a/src/login.c
++++ b/src/login.c
+@@ -529,7 +529,6 @@ int main (int argc, char **argv)
+ #if defined(HAVE_STRFTIME) && !defined(USE_PAM)
+ char ptime[80];
+ #endif
+- unsigned int delay;
+ unsigned int retries;
+ bool subroot = false;
+ #ifndef USE_PAM
+@@ -549,6 +548,7 @@ int main (int argc, char **argv)
+ pid_t child;
+ char *pam_user = NULL;
+ #else
++ unsigned int delay;
+ struct spwd *spwd = NULL;
+ #endif
+ /*
+@@ -709,7 +709,6 @@ int main (int argc, char **argv)
+ }
+
+ environ = newenvp; /* make new environment active */
+- delay = getdef_unum ("FAIL_DELAY", 1);
+ retries = getdef_unum ("LOGIN_RETRIES", RETRIES);
+
+ #ifdef USE_PAM
+@@ -725,8 +724,7 @@ int main (int argc, char **argv)
+
+ /*
+ * 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)
+@@ -735,10 +733,6 @@ int main (int argc, char **argv)
+ 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;
+@@ -779,12 +773,6 @@ int main (int argc, char **argv)
+ 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);
+
+@@ -1107,14 +1095,17 @@ int main (int argc, char **argv)
+ 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"));
+
diff --git a/debian/patches/0011-523_su_arguments_are_concatenated.patch b/debian/patches/0011-523_su_arguments_are_concatenated.patch
new file mode 100644
index 0000000..698c029
--- /dev/null
+++ b/debian/patches/0011-523_su_arguments_are_concatenated.patch
@@ -0,0 +1,52 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 523_su_arguments_are_concatenated
+
+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)
+---
+ src/su.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/src/su.c b/src/su.c
+index d719011..9f751fe 100644
+--- a/src/su.c
++++ b/src/su.c
+@@ -1150,6 +1150,35 @@ int main (int argc, char **argv)
+ 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.
diff --git a/debian/patches/0012-523_su_arguments_are_no_more_concatenated_by_default.patch b/debian/patches/0012-523_su_arguments_are_no_more_concatenated_by_default.patch
new file mode 100644
index 0000000..8edfa8a
--- /dev/null
+++ b/debian/patches/0012-523_su_arguments_are_no_more_concatenated_by_default.patch
@@ -0,0 +1,56 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 523_su_arguments_are_no_more_concatenated_by_default
+
+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.
+---
+ src/su.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+diff --git a/src/su.c b/src/su.c
+index 9f751fe..7405e24 100644
+--- a/src/su.c
++++ b/src/su.c
+@@ -104,6 +104,19 @@ static char caller_name[BUFSIZ];
+ /* 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;
+@@ -950,6 +963,8 @@ int main (int argc, char **argv)
+ 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);
+@@ -1154,7 +1169,7 @@ int main (int argc, char **argv)
+ * 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;
diff --git a/debian/patches/0013-508_nologin_in_usr_sbin.patch b/debian/patches/0013-508_nologin_in_usr_sbin.patch
new file mode 100644
index 0000000..897d62d
--- /dev/null
+++ b/debian/patches/0013-508_nologin_in_usr_sbin.patch
@@ -0,0 +1,28 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 508_nologin_in_usr_sbin
+
+---
+ src/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 6a1e46b..3cabcb2 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -23,7 +23,6 @@ INCLUDES = \
+ # $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
+ usbin_PROGRAMS = \
+ cppw \
+@@ -38,6 +37,7 @@ usbin_PROGRAMS = \
+ grpunconv \
+ logoutd \
+ newusers \
++ nologin \
+ pwck \
+ pwconv \
+ pwunconv \
diff --git a/debian/patches/0014-505_useradd_recommend_adduser.patch b/debian/patches/0014-505_useradd_recommend_adduser.patch
new file mode 100644
index 0000000..4521dff
--- /dev/null
+++ b/debian/patches/0014-505_useradd_recommend_adduser.patch
@@ -0,0 +1,46 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: 505_useradd_recommend_adduser
+
+Fixes: #406046
+
+Status wrt upstream: Debian specific patch.
+---
+ man/useradd.8.xml | 6 ++++++
+ man/userdel.8.xml | 6 ++++++
+ 2 files changed, 12 insertions(+)
+
+diff --git a/man/useradd.8.xml b/man/useradd.8.xml
+index 3ee0e38..3cdeefe 100644
+--- a/man/useradd.8.xml
++++ b/man/useradd.8.xml
+@@ -84,6 +84,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
+diff --git a/man/userdel.8.xml b/man/userdel.8.xml
+index 56218a1..51843d0 100644
+--- a/man/userdel.8.xml
++++ b/man/userdel.8.xml
+@@ -64,6 +64,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.
diff --git a/debian/patches/0015-utmp.c.patch b/debian/patches/0015-utmp.c.patch
new file mode 100644
index 0000000..70e2a23
--- /dev/null
+++ b/debian/patches/0015-utmp.c.patch
@@ -0,0 +1,56 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:48 +0000
+Subject: utmp.c
+
+===================================================================
+---
+ libmisc/utmp.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/libmisc/utmp.c b/libmisc/utmp.c
+index 437c3d5..8bb70ce 100644
+--- a/libmisc/utmp.c
++++ b/libmisc/utmp.c
+@@ -32,15 +32,19 @@
+
+ #include <config.h>
+
+-#include "defines.h"
+-#include "prototypes.h"
+-
+-#include <utmp.h>
+
+ #ifdef USE_UTMPX
+ #include <utmpx.h>
++#define utmp utmpx
++#define updwtmp updwtmpx
++#define pututline pututxline
++#else
++#include <utmp.h>
+ #endif
+
++#include "defines.h"
++#include "prototypes.h"
++
+ #include <assert.h>
+ #include <netdb.h>
+ #include <stdio.h>
+@@ -281,6 +285,10 @@ static void updwtmpx (const char *filename, const struct utmpx *utx)
+ /* ut_exit is only for DEAD_PROCESS */
+ utent->ut_session = getsid (0);
+ if (gettimeofday (&tv, NULL) == 0) {
++#ifdef USE_UTMPX
++ utent->ut_tv.tv_sec = tv.tv_sec;
++ utent->ut_tv.tv_usec = tv.tv_usec;
++#else
+ #ifdef HAVE_STRUCT_UTMP_UT_TIME
+ utent->ut_time = tv.tv_sec;
+ #endif /* HAVE_STRUCT_UTMP_UT_TIME */
+@@ -291,6 +299,7 @@ static void updwtmpx (const char *filename, const struct utmpx *utx)
+ utent->ut_tv.tv_sec = tv.tv_sec;
+ utent->ut_tv.tv_usec = tv.tv_usec;
+ #endif /* HAVE_STRUCT_UTMP_UT_TV */
++#endif
+ }
+
+ return utent;
diff --git a/debian/patches/0016-getspnam_r.patch b/debian/patches/0016-getspnam_r.patch
new file mode 100644
index 0000000..36c29da
--- /dev/null
+++ b/debian/patches/0016-getspnam_r.patch
@@ -0,0 +1,75 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:49 +0000
+Subject: getspnam_r
+
+===================================================================
+---
+ configure.in | 19 +++++++++++++++++++
+ libmisc/xgetXXbyYY.c | 6 ++++++
+ libmisc/xgetspnam.c | 4 ++++
+ 3 files changed, 29 insertions(+)
+
+diff --git a/configure.in b/configure.in
+index c7ef3bf..b85b571 100644
+--- a/configure.in
++++ b/configure.in
+@@ -45,6 +45,25 @@ AC_CHECK_FUNCS(l64a fchmod fchown fsync futimes getgroups gethostname getspnam \
+ getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getaddrinfo)
+ AC_SYS_LARGEFILE
+
++AC_MSG_CHECKING(if getspnam_r take 5 arguments)
++AC_TRY_COMPILE(
++ [
++#include <sys/types.h>
++#include <shadow.h>
++ ],
++ [
++struct spwd *pw;
++struct spwd pwbuf;
++char pwdata[512];
++(void) getspnam_r("bin", &pwbuf, pwdata, sizeof(pwdata), &pw);
++ ],
++ [AC_MSG_RESULT(yes)
++ AC_DEFINE(GETSPNAM_R_5ARG, 1,
++ [Define if your getspnam_r()
++ functions take 5 arguments])],
++ [AC_MSG_RESULT(no)]
++)
++
+ dnl Checks for typedefs, structures, and compiler characteristics.
+ AC_C_CONST
+ AC_TYPE_UID_T
+diff --git a/libmisc/xgetXXbyYY.c b/libmisc/xgetXXbyYY.c
+index 1b0b001..23d74ee 100644
+--- a/libmisc/xgetXXbyYY.c
++++ b/libmisc/xgetXXbyYY.c
+@@ -89,9 +89,15 @@
+ exit (13);
+ }
+ errno = 0;
++#ifndef __use_4_args
+ status = REENTRANT_NAME(ARG_NAME, result, buffer,
+ length, &resbuf);
+ if ((0 == status) && (resbuf == result)) {
++#else
++ resbuf = REENTRANT_NAME(ARG_NAME, result, buffer,
++ length);
++ if (resbuf == result) {
++#endif
+ /* Build a result structure that can be freed by
+ * the shadow *_free functions. */
+ LOOKUP_TYPE *ret_result = DUP_FUNCTION(result);
+diff --git a/libmisc/xgetspnam.c b/libmisc/xgetspnam.c
+index 287e97f..b8df928 100644
+--- a/libmisc/xgetspnam.c
++++ b/libmisc/xgetspnam.c
+@@ -60,5 +60,9 @@
+ #define DUP_FUNCTION __spw_dup
+ #define HAVE_FUNCTION_R (defined HAVE_GETSPNAM_R)
+
++#ifndef GETSPNAM_R_5ARG
++#define __use_4_args
++#endif
++
+ #include "xgetXXbyYY.c"
+
diff --git a/debian/patches/0017-environ.patch b/debian/patches/0017-environ.patch
new file mode 100644
index 0000000..b4cd428
--- /dev/null
+++ b/debian/patches/0017-environ.patch
@@ -0,0 +1,36 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:49 +0000
+Subject: environ
+
+===================================================================
+---
+ lib/spawn.c | 2 ++
+ src/su.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/lib/spawn.c b/lib/spawn.c
+index da98401..dd52399 100644
+--- a/lib/spawn.c
++++ b/lib/spawn.c
+@@ -38,6 +38,8 @@
+ #include "exitcodes.h"
+ #include "prototypes.h"
+
++extern char **environ;
++
+ int run_command (const char *cmd, const char *argv[],
+ /*@null@*/const char *envp[], /*@out@*/int *status)
+ {
+diff --git a/src/su.c b/src/su.c
+index 7405e24..7239ba9 100644
+--- a/src/su.c
++++ b/src/su.c
+@@ -78,6 +78,8 @@
+ /*@-exitarg@*/
+ #include "exitcodes.h"
+
++extern char **environ;
++
+ /*
+ * Global variables
+ */
diff --git a/debian/patches/0018-putgrent.patch b/debian/patches/0018-putgrent.patch
new file mode 100644
index 0000000..41852a6
--- /dev/null
+++ b/debian/patches/0018-putgrent.patch
@@ -0,0 +1,60 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:49 +0000
+Subject: putgrent
+
+===================================================================
+---
+ lib/groupio.c | 40 ++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 40 insertions(+)
+
+diff --git a/lib/groupio.c b/lib/groupio.c
+index 4644496..3302d37 100644
+--- a/lib/groupio.c
++++ b/lib/groupio.c
+@@ -44,6 +44,46 @@
+ #include "getdef.h"
+ #include "groupio.h"
+
++#ifndef HAVE_PUTGRENT
++#define _nn(x) x ? x : ""
++int putgrent (const struct group *gr, FILE *fp)
++{
++ int rc;
++ int i;
++
++ if ((NULL == gr) || (NULL == fp)) {
++ errno = EINVAL;
++ return -1;
++ }
++
++ flockfile(fp);
++ if (gr->gr_name[0] == '+' || gr->gr_name[0] == '-') {
++ rc = fprintf(fp, "%s:%s::", gr->gr_name, _nn(gr->gr_passwd));
++ } else {
++ rc = fprintf(fp, "%s:%s:%lu:", gr->gr_name, _nn(gr->gr_passwd), (unsigned long int) gr->gr_gid);
++ }
++
++ if (rc < 0) {
++ funlockfile(fp);
++ return -1;
++ }
++
++ if (NULL != gr->gr_mem) {
++ for (i = 0; gr->gr_mem[i] != NULL; ++i) {
++ if (0 > fprintf(fp, i == 0 ? "%s" : ",%s", gr->gr_mem[i])) {
++ funlockfile(fp);
++ return -1;
++ }
++ }
++ }
++
++ putc_unlocked('\n', fp);
++ funlockfile(fp);
++ return 0;
++}
++#undef _nn
++#endif /* HAVE_PUTGRENT */
++
+ static /*@null@*/struct commonio_entry *merge_group_entries (
+ /*@null@*/ /*@returned@*/struct commonio_entry *gr1,
+ /*@null@*/struct commonio_entry *gr2);
diff --git a/debian/patches/0019-putpwent-segfault.patch b/debian/patches/0019-putpwent-segfault.patch
new file mode 100644
index 0000000..093a762
--- /dev/null
+++ b/debian/patches/0019-putpwent-segfault.patch
@@ -0,0 +1,22 @@
+From: Shadow package maintainers <pkg-shadow-devel@lists.alioth.debian.org>
+Date: Mon, 4 Jun 2012 01:37:49 +0000
+Subject: putpwent-segfault
+
+===================================================================
+---
+ lib/pwmem.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/pwmem.c b/lib/pwmem.c
+index e23a6dc..af0162e 100644
+--- a/lib/pwmem.c
++++ b/lib/pwmem.c
+@@ -44,7 +44,7 @@
+ {
+ struct passwd *pw;
+
+- pw = (struct passwd *) malloc (sizeof *pw);
++ pw = (struct passwd *) calloc (1, sizeof *pw);
+ if (NULL == pw) {
+ return NULL;
+ }