[Pkg-shadow-devel] Ubuntu (new upstream) shadow 1:4.1.5.1-1.1ubuntu1

Ubuntu Merge-o-Matic mom at ubuntu.com
Fri May 2 23:38:39 UTC 2014


This e-mail has been sent due to an upload to Ubuntu of a new upstream
version which still contains Ubuntu changes.  It contains the difference
between the Ubuntu version and the equivalent base version in Debian, note
that this difference may include the upstream changes.
-------------- next part --------------
Format: 1.8
Date: Fri, 02 May 2014 15:17:15 -0400
Source: shadow
Binary: passwd login uidmap
Architecture: source
Version: 1:4.1.5.1-1.1ubuntu1
Distribution: utopic
Urgency: medium
Maintainer: Ubuntu Developers <ubuntu-devel-discuss at lists.ubuntu.com>
Changed-By: Stéphane Graber <stgraber at ubuntu.com>
Description: 
 login      - system login tools
 passwd     - change and administer password and group data
 uidmap     - programs to help use subuids
Closes: 583971 713979 724434 737805
Launchpad-Bugs-Fixed: 523896 1169558
Changes: 
 shadow (1:4.1.5.1-1.1ubuntu1) utopic; urgency=medium
 .
   * Merge from Debian unstable.  Remaining changes:
      - debian/passwd.upstart: Add an upstrat job to clear locks on
        [shadow-]passwd/group. (LP: #523896).
      - Allow LXC devices (lxc/console, lxc/tty[1234]) that we'll start using
        in LXC with Precise.
      - debian/login.defs:
        + Update documentation of USERGROUPS_ENAB: with pam_umask, the UPG
          handling does not only apply to "former (pre-PAM) uses".
        + Update documentation of UMASK: Explain that USERGROUPS_ENAB
          will modify this default for UPGs. (Closes: #583971)
      - debian/{source_shadow.py,rules}: Add apport hook
      - debian/patches/495_stdout-encrypted-password: chpasswd can report
        password hashes on stdout (Debian bug 505640).
      - Install upstart job by-hand, instead of using dh_installinit to avoid
        dependency on upstart-job.
      - Pass noupdate to pam_motd call for /run/motd.dynamic, to avoid running
        /etc/update-motd.d/* scripts twice (LP: #1169558).
      - debian/patches/496_su_kill_process_group: Kill the child process group,
        rather than just the immediate child; this is needed now that su no
        longer starts a controlling terminal when not running an interactive
        shell (closes: #713979).
      - Add uidmap package based on upstream patches that introduce
        newuidmap/newgidmap as well as /etc/subuid and /etc/subgid. Additional
        updates on those to widen the default allocation to 65536 uids and gids
        and only assign ranges to non-system users.
 .
 shadow (1:4.1.5.1-1.1) unstable; urgency=medium
 .
   * Non-maintainer upload.
 .
   [ Eric Dorland ]
   * Switch to automake1.11. (Closes: #724434)
 .
   [ Samuel Thibault ]
   * Enable the login package on hurd-any, but without /bin/login, still provided
     by the hurd package. Closes: #737805.
Checksums-Sha1: 
 e3cf1f09034705b6bf73d503f10d51a1f7702939 2361 shadow_4.1.5.1-1.1ubuntu1.dsc
 34b8575e5914bbd328ebd632866e08ba318905e1 112476 shadow_4.1.5.1-1.1ubuntu1.diff.gz
Checksums-Sha256: 
 2c88020959ab16c5ca8417482bc5877d95293eef02c7bf3673c6f86bea19d1e6 2361 shadow_4.1.5.1-1.1ubuntu1.dsc
 fdd8424efc548b7a1a9fa5beb1f45d832c4d80271925120fd9f730aaa33847bd 112476 shadow_4.1.5.1-1.1ubuntu1.diff.gz
Files: 
 77d156a21f988f9d51014e2c78db3ea5 2361 admin required shadow_4.1.5.1-1.1ubuntu1.dsc
 fed98d294e293d1df49127ed40b3afc8 112476 admin required shadow_4.1.5.1-1.1ubuntu1.diff.gz
Original-Maintainer: Shadow package maintainers <pkg-shadow-devel at lists.alioth.debian.org>
-------------- next part --------------
diff -pruN 1:4.1.5.1-1.1/debian/changelog 1:4.1.5.1-1.1ubuntu1/debian/changelog
--- 1:4.1.5.1-1.1/debian/changelog	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/changelog	2014-05-02 23:36:42.000000000 +0000
@@ -1,3 +1,33 @@
+shadow (1:4.1.5.1-1.1ubuntu1) utopic; urgency=medium
+
+  * Merge from Debian unstable.  Remaining changes:
+     - debian/passwd.upstart: Add an upstrat job to clear locks on
+       [shadow-]passwd/group. (LP: #523896).
+     - Allow LXC devices (lxc/console, lxc/tty[1234]) that we'll start using
+       in LXC with Precise.
+     - debian/login.defs:
+       + Update documentation of USERGROUPS_ENAB: with pam_umask, the UPG
+         handling does not only apply to "former (pre-PAM) uses".
+       + Update documentation of UMASK: Explain that USERGROUPS_ENAB
+         will modify this default for UPGs. (Closes: #583971)
+     - debian/{source_shadow.py,rules}: Add apport hook
+     - debian/patches/495_stdout-encrypted-password: chpasswd can report
+       password hashes on stdout (Debian bug 505640).
+     - Install upstart job by-hand, instead of using dh_installinit to avoid
+       dependency on upstart-job.
+     - Pass noupdate to pam_motd call for /run/motd.dynamic, to avoid running
+       /etc/update-motd.d/* scripts twice (LP: #1169558).
+     - debian/patches/496_su_kill_process_group: Kill the child process group,
+       rather than just the immediate child; this is needed now that su no
+       longer starts a controlling terminal when not running an interactive
+       shell (closes: #713979).
+     - Add uidmap package based on upstream patches that introduce
+       newuidmap/newgidmap as well as /etc/subuid and /etc/subgid. Additional
+       updates on those to widen the default allocation to 65536 uids and gids
+       and only assign ranges to non-system users.
+
+ -- Stéphane Graber <stgraber at ubuntu.com>  Fri, 02 May 2014 15:17:15 -0400
+
 shadow (1:4.1.5.1-1.1) unstable; urgency=medium
 
   * Non-maintainer upload.
@@ -11,6 +41,103 @@ shadow (1:4.1.5.1-1.1) unstable; urgency
 
  -- Samuel Thibault <sthibault at debian.org>  Sun, 16 Mar 2014 20:58:24 +0100
 
+shadow (1:4.1.5.1-1ubuntu9) trusty; urgency=medium
+
+  * Set our subuid and subgid range to 65536 uids by default.
+  * Patch newusers to not add subuids and subgids to system users.
+  * Patch useradd to not add subuids and subgids to system users and to
+    regular users who don't fit between uid_min and uid_max.
+    (This is needed due to adduser not passing --system...)
+
+ -- Stéphane Graber <stgraber at ubuntu.com>  Sun, 16 Feb 2014 19:33:48 -0500
+
+shadow (1:4.1.5.1-1ubuntu8) trusty; urgency=medium
+
+  * Fix postinst to create subuid and subgid when missing as those won't
+    get created by usermod or any of the other tools.
+
+ -- Stéphane Graber <stgraber at ubuntu.com>  Fri, 17 Jan 2014 16:15:13 -0500
+
+shadow (1:4.1.5.1-1ubuntu7) trusty; urgency=medium
+
+  * Don't ship subuid/subgid as conffiles as that'll just cause problems
+    on upgrades. Instead simply touch them if they're not already present.
+
+ -- Stéphane Graber <stgraber at ubuntu.com>  Sun, 12 Jan 2014 12:59:46 -0500
+
+shadow (1:4.1.5.1-1ubuntu6) saucy; urgency=low
+
+  * debian/patches/496_su_kill_process_group: Kill the child process group,
+    rather than just the immediate child; this is needed now that su no
+    longer starts a controlling terminal when not running an interactive
+    shell (closes: #713979).
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Fri, 26 Jul 2013 16:55:52 +0100
+
+shadow (1:4.1.5.1-1ubuntu5) saucy; urgency=low
+
+  [ Serge Hallyn ]
+  * debian/patches/userns: patches from Eric Biederman to enable use of
+    subuids, plus some bugfix patches on top of them. (LP: #1192864)
+  * passwd.install: add new manpages
+  * debian/control, debian/uidmap.install: create new uidmap package
+    containing the new setuid-root binaries newuidmap and newgidmap 
+  * debian/subuid, debian/rules: install a default /etc/subuid and /etc/subgid
+  * debian/patches/userns/16_add-argument-sanity-checking.patch: address
+    three sanity checking concerns brought up by sarnold at
+    http://lists.alioth.debian.org/pipermail/pkg-shadow-devel/2013-June/ \
+    009752.html.
+
+ -- Dmitrijs Ledkovs <dmitrij.ledkov at ubuntu.com>  Fri, 28 Jun 2013 11:31:51 +0100
+
+shadow (1:4.1.5.1-1ubuntu4) raring; urgency=low
+
+  * Pass noupdate to pam_motd call for /run/motd.dynamic, to avoid running
+    /etc/update-motd.d/* scripts twice (LP: #1169558).
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Thu, 18 Apr 2013 01:01:45 +0100
+
+shadow (1:4.1.5.1-1ubuntu3) raring; urgency=low
+
+  * Install upstart job by-hand, instead of using dh_installinit to avoid
+    dependency on upstart-job.
+
+ -- Dmitrijs Ledkovs <dmitrij.ledkov at ubuntu.com>  Mon, 18 Mar 2013 03:23:31 +0000
+
+shadow (1:4.1.5.1-1ubuntu2) raring; urgency=low
+
+  * Revert build-dependency from gettext:any to gettext, now that gettext is
+    Multi-Arch: foreign.
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Thu, 29 Nov 2012 15:27:11 +0000
+
+shadow (1:4.1.5.1-1ubuntu1) raring; urgency=low
+
+  * The "Yorkshire Blue" release.
+  * Merge from Debian unstable.  Remaining changes:  
+     - debian/passwd.upstart: Add an upstrat job to clear locks on
+       [shadow-]passwd/group. (LP: #523896).
+     - Build-depend on gettext:any for cross-building support.
+     - Allow LXC devices (lxc/console, lxc/tty[1234]) that we'll start using
+       in LXC with Precise.
+     - debian/login.defs:
+       + Update documentation of USERGROUPS_ENAB: with pam_umask, the UPG
+         handling does not only apply to "former (pre-PAM) uses".
+       + Update documentation of UMASK: Explain that USERGROUPS_ENAB will modify
+         this default for UPGs. (Closes: #583971)
+     - debian/{source_shadow.py,rules}: Add apport hook
+     - debian/patches/495_stdout-encrypted-password: chpasswd can report
+       password hashes on stdout (Debian bug 505640).
+
+  * Dropped changes, merged in Debian:
+     - Fix case of ttyAMA0-3 devices and move them near the ttyAM0-15 ones;
+       Debian #544184; fixes console on Vexpress boards (e.g. in QEMU).
+     - use SHA512 by default for password crypt routine.
+     - debian/rules: fix FTBFS from newer libtools
+     - Mark passwd Multi-Arch: foreign.
+  
+ -- Dmitrijs Ledkovs <dmitrij.ledkov at ubuntu.com>  Tue, 23 Oct 2012 09:59:19 +0100
+
 shadow (1:4.1.5.1-1) unstable; urgency=low
 
   * The "Gruyère" release.
@@ -154,6 +281,68 @@ shadow (1:4.1.5-1) unstable; urgency=low
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Sun, 12 Feb 2012 22:27:03 +0100
 
+shadow (1:4.1.4.2+svn3283-3ubuntu7) quantal; urgency=low
+
+  * debian/passwd.upstart: Add an upstrat job to clear locks on
+    [shadow-]passwd/group. (LP: #523896).
+
+ -- Dmitrijs Ledkovs <dmitrij.ledkov at ubuntu.com>  Fri, 31 Aug 2012 13:00:33 +0100
+
+shadow (1:4.1.4.2+svn3283-3ubuntu6) quantal; urgency=low
+
+  * debian/source_shadow.py: Fix compatibility with python3. Thanks Edward
+    Donovan! (LP: #1013171)
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Mon, 18 Jun 2012 15:09:54 +0200
+
+shadow (1:4.1.4.2+svn3283-3ubuntu5) precise; urgency=low
+
+  * Build-depend on gettext:any for cross-building support.
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Mon, 09 Apr 2012 00:28:03 +0100
+
+shadow (1:4.1.4.2+svn3283-3ubuntu4) precise; urgency=low
+
+  * Allow LXC devices (lxc/console, lxc/tty[1234]) that we'll start using
+    in LXC with Precise.
+
+ -- Stéphane Graber <stgraber at ubuntu.com>  Fri, 10 Feb 2012 15:34:05 -0500
+
+shadow (1:4.1.4.2+svn3283-3ubuntu3) precise; urgency=low
+
+  * Fix case of ttyAMA0-3 devices and move them near the ttyAM0-15 ones;
+    Debian #544184; fixes console on Vexpress boards (e.g. in QEMU).
+
+ -- Loïc Minier <loic.minier at ubuntu.com>  Wed, 30 Nov 2011 22:47:47 +0100
+
+shadow (1:4.1.4.2+svn3283-3ubuntu2) oneiric; urgency=low
+
+  * debian/login.defs:
+    - Update documentation of USERGROUPS_ENAB: with pam_umask, the UPG
+      handling does not only apply to "former (pre-PAM) uses".
+    - Update documentation of UMASK: Explain that USERGROUPS_ENAB will modify
+      this default for UPGs. (Closes: #583971)
+
+ -- Martin Pitt <martin.pitt at ubuntu.com>  Fri, 24 Jun 2011 11:07:34 +0200
+
+shadow (1:4.1.4.2+svn3283-3ubuntu1) natty; urgency=low
+
+  * The "string cheese" release.
+  * Merge from Debian unstable.  Remaining changes:
+    - Ubuntu specific:
+      + debian/login.defs: use SHA512 by default for password crypt routine.
+    - debian/{source_shadow.py,rules}: Add apport hook
+    - debian/rules: fix FTBFS from newer libtools
+    - debian/patches/495_stdout-encrypted-password: chpasswd can report
+      password hashes on stdout (Debian bug 505640).
+  * Dropped changes, merged in Debian:
+    - debian/patches/300_CVE-2011-0721: reject newlines in GECOS updates.
+    - CVE-2011-0721
+  * Mark passwd Multi-Arch: foreign, so packages that aren't of the same
+    arch can depend on it.
+
+ -- Steve Langasek <steve.langasek at ubuntu.com>  Sun, 20 Feb 2011 15:59:15 -0800
+
 shadow (1:4.1.4.2+svn3283-3) unstable; urgency=high
 
   * The "Trappe d'Echourgnac" release.
@@ -164,6 +353,34 @@ shadow (1:4.1.4.2+svn3283-3) unstable; u
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Mon, 13 Feb 2011 23:20:05 +0100
 
+shadow (1:4.1.4.2+svn3283-2ubuntu3) natty; urgency=low
+
+  * SECURITY UPDATE: could inject NIS groups memberships into /etc/passwd.
+    - debian/patches/300_CVE-2011-0721: reject newlines in GECOS updates.
+    - CVE-2011-0721
+
+ -- Kees Cook <kees at ubuntu.com>  Tue, 15 Feb 2011 13:57:01 -0800
+
+shadow (1:4.1.4.2+svn3283-2ubuntu2) natty; urgency=low
+
+  * debian/patches/495_stdout-encrypted-password: adjust patch for changes 
+    in src/chpasswd.c to fix FTBFS
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Tue, 04 Jan 2011 15:48:49 +0100
+
+shadow (1:4.1.4.2+svn3283-2ubuntu1) natty; urgency=low
+
+  * Merge from debian unstable.  Remaining changes:
+    - Ubuntu specific:
+      + debian/login.defs: use SHA512 by default for password crypt routine.
+    - debian/{source_shadow.py,rules}: Add apport hook
+    - debian/rules: fix FTBFS from newer libtools
+    - debian/patches/495_stdout-encrypted-password: chpasswd can report
+      password hashes on stdout (Debian bug 505640).
+    - Rework 495_stdout-encrypted-password to cope with chpasswd using PAM.
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Wed, 24 Nov 2010 13:42:42 +0100
+
 shadow (1:4.1.4.2+svn3283-2) unstable; urgency=low
 
   * The "Bleu du Vercors-Sassenage" release.
@@ -235,6 +452,32 @@ shadow (1:4.1.4.2+svn3283-1) unstable; u
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Sun, 29 Aug 2010 21:14:12 +0200
 
+shadow (1:4.1.4.2-1ubuntu3) maverick; urgency=low
+
+  * add ttyO0-3 to debian/securetty.linux, if OMAP kernels are built with
+    TI's DMA-offloaded driver instead of the default 8250 one the serial tty's
+    are called like that (LP: #512845).
+
+ -- Oliver Grawert <ogra at ubuntu.com>  Tue, 31 Aug 2010 14:45:17 +0200
+
+shadow (1:4.1.4.2-1ubuntu2) lucid; urgency=low
+
+  * debian/{source_shadow.py,rules}: Add apport hook
+  * debian/rules: fix FTBFS from newer libtools
+
+ -- Marc Deslauriers <marc.deslauriers at ubuntu.com>  Tue, 26 Jan 2010 08:54:59 -0500
+
+shadow (1:4.1.4.2-1ubuntu1) lucid; urgency=low
+
+  * Merged with debian unstable. Remaning changes (LP: #477299):
+    - Ubuntu specific:
+      + debian/login.defs: use SHA512 by default for password crypt routine.
+    - debian/patches/495_stdout-encrypted-password: chpasswd can report
+      password hashes on stdout (Debian bug 505640).
+    - Rework 495_stdout-encrypted-password to cope with chpasswd using PAM.
+
+ -- Nicolas Valcárcel Scerpella (Canonical) <nvalcarcel at canonical.com>  Sat, 07 Nov 2009 04:55:18 -0500
+
 shadow (1:4.1.4.2-1) unstable; urgency=low
 
   * The "Tome des Bauges" release.
@@ -262,6 +505,25 @@ shadow (1:4.1.4.2-1) unstable; urgency=l
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Fri, 24 Jul 2009 05:03:23 +0200
 
+shadow (1:4.1.4.1-1ubuntu2) karmic; urgency=low
+
+  * debian/securetty.linux: also list ttyS2 and ttyS3; beagleboard uses ttyS2
+    as serial port.
+
+ -- Loïc Minier <loic.minier at ubuntu.com>  Fri, 31 Jul 2009 15:34:56 +0200
+
+shadow (1:4.1.4.1-1ubuntu1) karmic; urgency=low
+
+  * Resynchronise with Debian. Remaining changes:
+    - Ubuntu specific:
+      + debian/login.defs: use SHA512 by default for password crypt routine.
+    - debian/patches/495_stdout-encrypted-password: chpasswd can report
+      password hashes on stdout (Debian bug 505640).
+  * Rework 495_stdout-encrypted-password to cope with chpasswd using PAM.
+    It's looking a bit ugly now ...
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Wed, 03 Jun 2009 11:16:51 +0100
+
 shadow (1:4.1.4.1-1) unstable; urgency=low
 
   * The "Chevrotin" release.
@@ -349,6 +611,21 @@ shadow (1:4.1.4-1) unstable; urgency=low
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Mon, 11 May 2009 00:25:11 +0200
 
+shadow (1:4.1.3.1-1ubuntu1) karmic; urgency=low
+
+  * Merge from debian unstable, remaining changes:
+    - Ubuntu specific:
+      + debian/login.defs: use SHA512 by default for password crypt routine.
+    - debian/patches/stdout-encrypted-password.patch: chpasswd can report
+      password hashes on stdout (debian bug 505640).
+    - debian/login.pam: Enable SELinux support (debian bug 527106).
+    - debian/securetty.linux: support Freescale MX-series (debian bug 527095).
+  * Add debian/patches/300_lastlog_failure: fixed upstream (debian bug 524873).
+  * Drop debian/patches/593_omit_lastchange_field_if_clock_is_misset: fixed
+    upstream.
+
+ -- Kees Cook <kees at ubuntu.com>  Tue, 05 May 2009 09:45:21 -0700
+
 shadow (1:4.1.3.1-1) unstable; urgency=low
 
   * The "Le Puant Macéré" release.
@@ -444,6 +721,108 @@ shadow (1:4.1.3-1) unstable; urgency=low
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Tue, 14 Apr 2009 23:33:22 +0200
 
+shadow (1:4.1.1-6ubuntu6) jaunty; urgency=low
+
+  * debian/login.preinst: fix typo in grep (LP: #354887).
+
+ -- Kees Cook <kees at ubuntu.com>  Fri, 03 Apr 2009 22:12:07 -0700
+
+shadow (1:4.1.1-6ubuntu5) jaunty; urgency=low
+
+  * debian/login.preinst: add special-case handling to restore the
+    original white-space in /etc/login.defs that is changed by
+    system-tools-backends (LP: #316756).
+
+ -- Kees Cook <kees at ubuntu.com>  Fri, 03 Apr 2009 14:33:43 -0700
+
+shadow (1:4.1.1-6ubuntu4) jaunty; urgency=low
+
+  * debian/patches/593_omit_lastchange_field_if_clock_is_misset (LP: #349504)
+    - If the system clock is set to Jan 01, 1970, and a new user is created
+      the last changed field gets set to 0, which tells login that the 
+      password is expired and must be changed. During installation, 
+      this can cause autologin to fail. Having the clock set to 01/01/1970
+      on a fresh install is common on the ARM architecture, so this is a high
+      priority bug since its likely to affect most ARM users on first install
+
+ -- Michael Casadevall <mcasadevall at ubuntu.com>  Thu, 02 Apr 2009 14:05:31 -0400
+
+shadow (1:4.1.1-6ubuntu3) jaunty; urgency=low
+
+  [ Bryan McLellan ]
+  * Don't do the vm-builder root password check on fresh installations
+    (LP: #340841).
+
+ -- Colin Watson <cjwatson at ubuntu.com>  Tue, 17 Mar 2009 13:32:55 +0000
+
+shadow (1:4.1.1-6ubuntu2) jaunty; urgency=low
+
+  * debian/securetty.linux (LP: #316841)
+    - Updated securetty support for Freescale MX-series boards
+
+ -- Michael Casadevall <sonicmctails at gmail.com>  Tue, 13 Jan 2009 12:56:38 -0500
+
+shadow (1:4.1.1-6ubuntu1) jaunty; urgency=low
+
+  * Merge from debian unstable, remaining changes:
+    - Ubuntu specific:
+      + debian/login.pam: Enable SELinux support in login.pam.
+      + debian/rules: regenerate autoconf to avoid libtool-caused FTBFS.
+      + debian/login.defs: use SHA512 by default for password crypt routine.
+      + debian/passwd.postinst: disable the root password for virtual
+        machines created with vm-builder on Ubuntu 8.10.
+    - debian/patches/stdout-encrypted-password.patch: allow chpasswd to
+      report encrypted passwords to stdout for tools needing encrypted
+      passwords (debian bug 505640).
+
+ -- Kees Cook <kees at ubuntu.com>  Mon, 08 Dec 2008 00:44:46 -0800
+
+shadow (1:4.1.1-6) unstable; urgency=medium
+
+  * The "Rollot" release.
+  * debian/patches/303_login_symlink_attack: Fix a race condition that could
+    lead to gaining ownership or changing mode of arbitrary files.
+    Closes: #505271 
+  * debian/patches/304_su.1_synopsis: Fix the su synopsis. username is
+    referenced in the manpage, not LOGIN. Closes: #501830
+  * debian/patches/305_login.1_japanese: Fix the path of the utmp and wtmp
+    files. Closes: #501353
+
+ -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Fri, 14 Nov 2008 21:52:42 +0100
+
+shadow (1:4.1.1-5ubuntu3) jaunty; urgency=low
+
+  * disable the root password for virtual machines created with vm-builder
+    on Ubuntu 8.10. (LP: #296841)
+
+ -- Jamie Strandboge <jamie at ubuntu.com>  Thu, 13 Nov 2008 20:32:42 -0600
+
+shadow (1:4.1.1-5ubuntu2) jaunty; urgency=low
+
+  * debian/login.defs: use SHA512 by default for password crypt routine
+    (LP: #51551, currently Ubuntu specific).
+  * debian/patches/stdout-encrypted-password.patch: allow chpasswd to report
+    encrypted passwords to stdout for tools needing encrypted passwords
+    (debian bug 505640).
+  * debian/rules: regenerate autoconf to avoid libtool-caused FTBFS.
+
+ -- Kees Cook <kees at ubuntu.com>  Thu, 13 Nov 2008 16:43:48 -0800
+
+shadow (1:4.1.1-5ubuntu1) jaunty; urgency=low
+
+  * Merge from debian unstable, remaining changes:
+    - debian/login.pam: Enable SELinux support in login.pam.
+
+ -- Scott James Remnant <scott at ubuntu.com>  Wed, 05 Nov 2008 07:26:43 +0000
+
+shadow (1:4.1.1-5) unstable; urgency=low
+
+  * The "Bergues" release.
+  * debian/login.pam: restore the Etch behavior of pam_securetty.so in case of
+    unknown user. Closes: #443322, #495831
+
+ -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Sun, 14 Sep 2008 19:13:34 +0200
+
 shadow (1:4.1.1-4) unstable; urgency=low
 
   * The "Rocamadour" release.
@@ -521,6 +900,13 @@ shadow (1:4.1.1-2) unstable; urgency=low
 
  -- Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>  Fri, 13 Jun 2008 01:27:16 +0200
 
+shadow (1:4.1.1-1ubuntu1) intrepid; urgency=low
+
+  * Merge from debian unstable, remaining changes:
+    - debian/login.pam: Enable SELinux support in login.pam.
+
+ -- Kees Cook <kees at ubuntu.com>  Mon, 09 Jun 2008 10:08:38 -0700
+
 shadow (1:4.1.1-1) unstable; urgency=low
 
   * New upstream release. This closes the following bugs:
@@ -646,6 +1032,20 @@ shadow (1:4.1.0-1) unstable; urgency=low
 
  -- Christian Perrier <bubulle at debian.org>  Sat, 12 Jan 2008 20:40:02 +0100
 
+shadow (1:4.0.18.2-1ubuntu2) hardy; urgency=low
+
+  * Add 498_make_useradd_faster_with_ldap: make useradd faster when
+    nsswitch uses LDAP or some other remote names database (LP: #120015),
+    thanks to Vince Busam.
+
+ -- Matt T. Proud <mtp at google.com>  Fri, 08 Feb 2008 18:30:51 -0800
+
+shadow (1:4.0.18.2-1ubuntu1) hardy; urgency=low
+
+  * debian/login.pam: Enable SELinux support in login.pam (LP: #191326).
+
+ -- Caleb Case <ccase at tresys.com>  Fri, 08 Feb 2008 02:20:06 -0500
+
 shadow (1:4.0.18.2-1) unstable; urgency=low
 
   * The "Vacherin" release.
@@ -1588,7 +1988,7 @@ shadow (1:4.0.12-5) unstable; urgency=lo
   * Really add /etc/pam.d/su. Closes: #330291
   
  -- Christian Perrier <bubulle at debian.org>  Wed, 28 Sep 2005 19:59:31 +0200
-   
+
 shadow (1:4.0.12-4) unstable; urgency=low
 
   * The "Epoisses" release
@@ -2920,7 +3320,7 @@ shadow (20000902-6.1) unstable; urgency=
   * Upgrade to latest config.sub and config.guess.  Closes: #88547
  
  -- Gerhard Tonn <gt at debian.org>  Fri,  1 Jun 2001 20:38:43 +0200
-                                                              
+
 shadow (20000902-6) unstable; urgency=medium
 
   * actually set root's password when appropriate
diff -pruN 1:4.1.5.1-1.1/debian/control 1:4.1.5.1-1.1ubuntu1/debian/control
--- 1:4.1.5.1-1.1/debian/control	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/control	2014-05-02 23:36:42.000000000 +0000
@@ -1,7 +1,8 @@
 Source: shadow
 Section: admin
 Priority: required
-Maintainer: Shadow package maintainers <pkg-shadow-devel at lists.alioth.debian.org>
+Maintainer: Ubuntu Developers <ubuntu-devel-discuss at lists.ubuntu.com>
+XSBC-Original-Maintainer: Shadow package maintainers <pkg-shadow-devel at lists.alioth.debian.org>
 Standards-Version: 3.9.3
 Uploaders: Christian Perrier <bubulle at debian.org>, Nicolas FRANCOIS (Nekral) <nicolas.francois at centraliens.net>
 Build-Depends: autoconf, automake1.11, libtool, 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)
@@ -34,3 +35,9 @@ Description: system login tools
  workgroup type situations). The su program allows changing your effective
  user ID (useful being able to execute commands as another user).
 
+Package: uidmap
+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.
diff -pruN 1:4.1.5.1-1.1/debian/login.defs 1:4.1.5.1-1.1ubuntu1/debian/login.defs
--- 1:4.1.5.1-1.1/debian/login.defs	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/login.defs	2014-05-02 23:36:42.000000000 +0000
@@ -139,6 +139,11 @@ TTYPERM		0600
 # 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
@@ -209,13 +214,14 @@ DEFAULT_HOME	yes
 #USERDEL_CMD	/usr/sbin/userdel_local
 
 #
+# Enable setting of the umask group bits to be the same as owner bits
+# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
+# the same as gid, and username is the same as the primary group name.
+#
 # 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
 
 #
diff -pruN 1:4.1.5.1-1.1/debian/login.pam 1:4.1.5.1-1.1ubuntu1/debian/login.pam
--- 1:4.1.5.1-1.1/debian/login.pam	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/login.pam	2014-05-02 23:36:42.000000000 +0000
@@ -84,7 +84,7 @@ session    optional   pam_lastlog.so
 # (Replaces the `MOTD_FILE' option in login.defs)
 # This includes a dynamically generated part from /run/motd.dynamic
 # and a static (admin-editable) part from /etc/motd.
-session    optional   pam_motd.so  motd=/run/motd.dynamic
+session    optional   pam_motd.so  motd=/run/motd.dynamic noupdate
 session    optional   pam_motd.so
 
 # Prints the status of the user's mailbox upon succesful login
diff -pruN 1:4.1.5.1-1.1/debian/login.postinst 1:4.1.5.1-1.1ubuntu1/debian/login.postinst
--- 1:4.1.5.1-1.1/debian/login.postinst	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/login.postinst	2014-05-02 23:36:42.000000000 +0000
@@ -14,14 +14,34 @@ then
 fi
 rm -f /etc/pam.d/login.pre-upgrade 2>/dev/null
 
-if [ "$1" = "configure" ] && [ "$2" = "" ]
-then
+if [ "$1" = "configure" ]; then
 	# Install faillog during initial installs only
-	if [ ! -f /var/log/faillog ] ; then
+	if [ "$2" = "" ] && [ ! -f /var/log/faillog ] ; then
 		touch /var/log/faillog
 		chown root:root /var/log/faillog
 		chmod 644 /var/log/faillog
 	fi
+
+	# FIXME: Transition code, can be dropped after Ubuntu 13.10 goes EOL
+	if [ -e /etc/subuid.pre-upgrade ]; then
+		mv /etc/subuid.pre-upgrade /etc/subuid
+	fi
+	if [ -e /etc/subgid.pre-upgrade ]; then
+		mv /etc/subgid.pre-upgrade /etc/subgid
+	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
 fi
 
 #DEBHELPER#
diff -pruN 1:4.1.5.1-1.1/debian/login.preinst 1:4.1.5.1-1.1ubuntu1/debian/login.preinst
--- 1:4.1.5.1-1.1/debian/login.preinst	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/login.preinst	2014-05-02 23:36:42.000000000 +0000
@@ -31,6 +31,16 @@ case "$1" in
 		fi
 	    fi
 	    
+
+        # FIXME: Transition code, can be dropped after Ubuntu 13.10 goes EOL
+        if dpkg --compare-versions $2 lt 1:4.1.5.1-1ubuntu7; then
+            if [ -e /etc/subuid ]; then
+                mv /etc/subuid /etc/subuid.pre-upgrade
+            fi
+            if [ -e /etc/subgid ]; then
+                mv /etc/subgid /etc/subgid.pre-upgrade
+            fi
+        fi
     ;;
 
     abort-upgrade)
diff -pruN 1:4.1.5.1-1.1/debian/passwd.conf 1:4.1.5.1-1.1ubuntu1/debian/passwd.conf
--- 1:4.1.5.1-1.1/debian/passwd.conf	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/passwd.conf	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,18 @@
+# passwd - clear locks on passwd and related files
+#
+# Copyright 2012 Canonical Ltd.
+# Author: Dmitrijs Ledkovs
+#
+# This helper clears locks on passwd to avoid million duplicate bug reports
+# like this one: https://launchpad.net/bugs/523896
+# Ideally we'd know what lock-up, and doesn't clear the lock, and fix that.
+# But it appears to be safe enough to clear them unconditionally on boot.
+#
+
+description	"Clear passwd locks"
+
+start on filesystem
+
+task
+
+exec rm -f /etc/gshadow.lock /etc/shadow.lock /etc/passwd.lock /etc/group.lock
diff -pruN 1:4.1.5.1-1.1/debian/passwd.dirs 1:4.1.5.1-1.1ubuntu1/debian/passwd.dirs
--- 1:4.1.5.1-1.1/debian/passwd.dirs	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/passwd.dirs	2014-05-02 23:36:42.000000000 +0000
@@ -1,2 +1,3 @@
 usr/share/lintian/overrides
 etc/default
+etc/init
diff -pruN 1:4.1.5.1-1.1/debian/passwd.install 1:4.1.5.1-1.1ubuntu1/debian/passwd.install
--- 1:4.1.5.1-1.1/debian/passwd.install	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/passwd.install	2014-05-02 23:36:42.000000000 +0000
@@ -55,6 +55,8 @@ 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/man8/chgpasswd.8
 usr/share/man/man8/chpasswd.8
 usr/share/man/man8/groupadd.8
diff -pruN 1:4.1.5.1-1.1/debian/patches/1000_configure_userns 1:4.1.5.1-1.1ubuntu1/debian/patches/1000_configure_userns
--- 1:4.1.5.1-1.1/debian/patches/1000_configure_userns	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/1000_configure_userns	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,105 @@
+=== modified file 'etc/login.defs'
+Index: shadow/etc/login.defs
+===================================================================
+--- shadow.orig/etc/login.defs	2014-02-16 19:31:38.934898148 -0500
++++ shadow/etc/login.defs	2014-02-16 19:31:38.926898149 -0500
+@@ -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
+@@ -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 retries if password is bad
+Index: shadow/src/newusers.c
+===================================================================
+--- shadow.orig/src/newusers.c	2014-02-16 19:31:38.934898148 -0500
++++ shadow/src/newusers.c	2014-02-16 19:31:38.926898149 -0500
+@@ -946,8 +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 ();
++	is_sub_uid = sub_uid_file_present () && !rflg;
++	is_sub_gid = sub_gid_file_present () && !rflg;
+ 
+ 	open_files ();
+ 
+Index: shadow/src/useradd.c
+===================================================================
+--- shadow.orig/src/useradd.c	2014-02-16 19:31:38.934898148 -0500
++++ shadow/src/useradd.c	2014-02-16 19:31:38.926898149 -0500
+@@ -1978,6 +1978,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.
+ 	 */
+@@ -2001,18 +2005,20 @@
+ 	 */
+ 	user_groups[0] = (char *) 0;
+ 
+-
+ 	is_shadow_pwd = spw_file_present ();
+ #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 ();
+ 
+ 	process_flags (argc, argv);
+ 
++	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));
++
++	get_defaults ();
++
+ #ifdef ACCT_TOOLS_SETUID
+ #ifdef USE_PAM
+ 	{
+Index: shadow/libmisc/find_new_sub_uids.c
+===================================================================
+--- shadow.orig/libmisc/find_new_sub_uids.c	2014-02-16 19:31:38.934898148 -0500
++++ shadow/libmisc/find_new_sub_uids.c	2014-02-16 19:31:38.926898149 -0500
+@@ -56,7 +56,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) >= max) {
+ 		(void) fprintf (stderr,
+Index: shadow/libmisc/find_new_sub_gids.c
+===================================================================
+--- shadow.orig/libmisc/find_new_sub_gids.c	2014-02-16 19:32:21.298896382 -0500
++++ shadow/libmisc/find_new_sub_gids.c	2014-02-16 19:32:34.462895834 -0500
+@@ -56,7 +56,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) >= max) {
+ 		(void) fprintf (stderr,
diff -pruN 1:4.1.5.1-1.1/debian/patches/495_stdout-encrypted-password 1:4.1.5.1-1.1ubuntu1/debian/patches/495_stdout-encrypted-password
--- 1:4.1.5.1-1.1/debian/patches/495_stdout-encrypted-password	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/495_stdout-encrypted-password	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,129 @@
+## Description: add some description
+## Origin/Author: add some origin or author
+## Bug: bug URL
+Index: b/man/chpasswd.8.xml
+===================================================================
+--- a/man/chpasswd.8.xml
++++ b/man/chpasswd.8.xml
+@@ -169,6 +169,12 @@
+     </variablelist>
+     <variablelist remap='IP'>
+       <varlistentry>
++        <term><option>-S</option>, <option>--stdout</option></term>
++        <listitem>
++          <para>Report encrypted passwords to stdout instead of updating password file.</para>
++        </listitem>
++       </varlistentry>
++       <varlistentry>
+ 	<term><option>-h</option>, <option>--help</option></term>
+ 	<listitem>
+ 	  <para>Display help message and exit.</para>
+Index: b/src/chpasswd.c
+===================================================================
+--- a/src/chpasswd.c
++++ b/src/chpasswd.c
+@@ -71,6 +71,8 @@
+ static bool pw_locked = false;
+ static bool spw_locked = false;
+ 
++static int use_stdout = 0;
++
+ /* local function prototypes */
+ static void fail_exit (int code);
+ static /*@noreturn@*/void usage (int status);
+@@ -134,6 +136,9 @@
+ 	                "                                crypt algorithms\n"),
+ 	              usageout);
+ #endif				/* USE_SHA_CRYPT */
++        (void) fputs (_("  -S, --stdout                  report encrypted passwords to stdout\n"
++                        "                                instead of changing the passwd file\n"),
++                      usageout);
+ 	(void) fputs ("\n", usageout);
+ 
+ 	exit (status);
+@@ -156,14 +161,15 @@
+ #ifdef USE_SHA_CRYPT
+ 		{"sha-rounds",   required_argument, NULL, 's'},
+ #endif				/* USE_SHA_CRYPT */
++		{"stdout",       no_argument,       NULL, 'S'},
+ 		{NULL, 0, NULL, '\0'}
+ 	};
+ 
+ 	while ((c = getopt_long (argc, argv,
+ #ifdef USE_SHA_CRYPT
+-	                         "c:ehmR:s:",
++	                         "c:ehmR:s:S",
+ #else				/* !USE_SHA_CRYPT */
+-	                         "c:ehmR:",
++	                         "c:ehmR:S",
+ #endif				/* !USE_SHA_CRYPT */
+ 	                         long_options, NULL)) != -1) {
+ 		switch (c) {
+@@ -192,6 +198,9 @@
+ 			}
+ 			break;
+ #endif				/* USE_SHA_CRYPT */
++                case 'S':
++                        use_stdout = 1;
++                        break;
+ 		default:
+ 			usage (E_USAGE);
+ 			/*@notreached@*/break;
+@@ -255,6 +264,7 @@
+  */
+ static void check_perms (void)
+ {
++	if (use_stdout) return;
+ #ifdef USE_PAM
+ #ifdef ACCT_TOOLS_SETUID
+ 	/* If chpasswd uses PAM and is SUID, check the permissions,
+@@ -405,17 +415,19 @@
+ 
+ 	OPENLOG ("chpasswd");
+ 
++	if (!use_stdout) {
+ 	check_perms ();
+ 
+ #ifdef USE_PAM
+-	if (!use_pam)
++	if (!use_pam) {
+ #endif				/* USE_PAM */
+-	{
+ 		is_shadow_pwd = spw_file_present ();
+ 
+ 		open_files ();
++#ifdef USE_PAM
++	}
++#endif				/* USE_PAM */
+ 	}
+-
+ 	/*
+ 	 * Read each line, separating the user name from the password. The
+ 	 * password entry for each user will be looked up in the appropriate
+@@ -493,6 +505,10 @@
+ 			cp = pw_encrypt (newpwd,
+ 			                 crypt_make_salt(crypt_method, arg));
+ 		}
++		if (use_stdout) {
++		        fprintf (stdout, "%s:%s\n", name, cp);
++		        continue;
++		}
+ 
+ 		/*
+ 		 * Get the password file entry for this user. The user must
+@@ -608,6 +624,7 @@
+ 		fail_exit (1);
+ 	}
+ 
++	if (!use_stdout) {
+ #ifdef USE_PAM
+ 	if (!use_pam)
+ #endif				/* USE_PAM */
+@@ -617,6 +634,7 @@
+ 	}
+ 
+ 	nscd_flush_cache ("passwd");
++	}
+ 
+ 	return (0);
+ }
diff -pruN 1:4.1.5.1-1.1/debian/patches/496_su_kill_process_group 1:4.1.5.1-1.1ubuntu1/debian/patches/496_su_kill_process_group
--- 1:4.1.5.1-1.1/debian/patches/496_su_kill_process_group	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/496_su_kill_process_group	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,29 @@
+Description: su: Kill the child process group, not just the immediate child
+ This is needed now that su no longer starts a controlling terminal when not
+ running an interactive shell.
+Author: Colin Watson <cjwatson at ubuntu.com>
+Forwarded: no
+Last-Update: 2013-07-26
+
+Index: b/src/su.c
+===================================================================
+--- a/src/su.c
++++ b/src/su.c
+@@ -194,7 +194,7 @@
+ static RETSIGTYPE kill_child (int unused(s))
+ {
+ 	if (0 != pid_child) {
+-		(void) kill (pid_child, SIGKILL);
++		(void) kill (-pid_child, SIGKILL);
+ 		(void) fputs (_(" ...killed.\n"), stderr);
+ 	} else {
+ 		(void) fputs (_(" ...waiting for child to terminate.\n"),
+@@ -383,7 +383,7 @@
+ 		(void) fputs ("\n", stderr);
+ 		(void) fputs (_("Session terminated, terminating shell..."),
+ 		              stderr);
+-		(void) kill (pid_child, caught);
++		(void) kill (-pid_child, caught);
+ 	}
+ 
+ 	ret = pam_close_session (pamh, 0);
diff -pruN 1:4.1.5.1-1.1/debian/patches/series 1:4.1.5.1-1.1ubuntu1/debian/patches/series
--- 1:4.1.5.1-1.1/debian/patches/series	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/series	2014-05-02 23:36:42.000000000 +0000
@@ -16,3 +16,22 @@
 523_su_arguments_are_no_more_concatenated_by_default
 508_nologin_in_usr_sbin
 505_useradd_recommend_adduser
+495_stdout-encrypted-password 
+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
+496_su_kill_process_group
+1000_configure_userns
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/01_userns_doc 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/01_userns_doc
--- 1:4.1.5.1-1.1/debian/patches/userns/01_userns_doc	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/01_userns_doc	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,334 @@
+From ebiederm at xmission.com  Tue Jan 22 09:14:18 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZu7-0004Pj-Ec; Tue, 22 Jan 2013 02:12:30 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:12:23 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <877gn5shs8.fsf at 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 at 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 at 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>
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/02_userns_doc_login.defs 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/02_userns_doc_login.defs
--- 1:4.1.5.1-1.1/debian/patches/userns/02_userns_doc_login.defs	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/02_userns_doc_login.defs	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,218 @@
+From ebiederm at xmission.com  Tue Jan 22 09:14:55 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZuf-0004T0-MS; Tue, 22 Jan 2013 02:13:07 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:12:58 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <871uddshr9.fsf at 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 at 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 at 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>
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/03_userns_implement_commonio_append 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/03_userns_implement_commonio_append
--- 1:4.1.5.1-1.1/debian/patches/userns/03_userns_implement_commonio_append	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/03_userns_implement_commonio_append	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,110 @@
+From ebiederm at xmission.com  Tue Jan 22 09:15:19 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at xmission.com>)
+	id 1TxZv8-0004VI-Fi; Tue, 22 Jan 2013 02:13:32 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:13:26 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87vcapr361.fsf at 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 at 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 at 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 *);
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/04_userns_add_backend_support 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/04_userns_add_backend_support
--- 1:4.1.5.1-1.1/debian/patches/userns/04_userns_add_backend_support	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/04_userns_add_backend_support	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,685 @@
+From ebiederm at xmission.com  Tue Jan 22 09:16:29 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZwE-0004bA-Mv; Tue, 22 Jan 2013 02:14:42 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:14:35 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87liblr344.fsf at 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 at 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 at 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
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/05_userns_implemend_find_new_sub_xids 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/05_userns_implemend_find_new_sub_xids
--- 1:4.1.5.1-1.1/debian/patches/userns/05_userns_implemend_find_new_sub_xids	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/05_userns_implemend_find_new_sub_xids	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,283 @@
+From ebiederm at xmission.com  Tue Jan 22 09:17:02 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZwj-0004g0-9e; Tue, 22 Jan 2013 02:15:14 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:15:05 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87fw1tr33a.fsf at 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 at 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 at 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;
++}
++
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/06_userns_userdel 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/06_userns_userdel
--- 1:4.1.5.1-1.1/debian/patches/userns/06_userns_userdel	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/06_userns_userdel	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,236 @@
+From ebiederm at xmission.com  Tue Jan 22 09:18:47 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZyQ-0004qs-T1; Tue, 22 Jan 2013 02:16:58 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:16:51 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <878v7lr30c.fsf at 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 at 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 at 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.
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/07_userns_useradd 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/07_userns_useradd
--- 1:4.1.5.1-1.1/debian/patches/userns/07_userns_useradd	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/07_userns_useradd	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,285 @@
+From ebiederm at xmission.com  Tue Jan 22 09:19:29 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZz4-0004tF-BP; Tue, 22 Jan 2013 02:17:36 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:17:30 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <8738xtr2z9.fsf at 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 at 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 at 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) {
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/08_userns_detect_busy_subids 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/08_userns_detect_busy_subids
--- 1:4.1.5.1-1.1/debian/patches/userns/08_userns_detect_busy_subids	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/08_userns_detect_busy_subids	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,133 @@
+From ebiederm at xmission.com  Tue Jan 22 09:19:49 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1TxZzN-0004ul-H6; Tue, 22 Jan 2013 02:18:01 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:17:50 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87y5flpoe9.fsf at 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 at 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 at 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__ */
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/09_userns_usermod 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/09_userns_usermod
--- 1:4.1.5.1-1.1/debian/patches/userns/09_userns_usermod	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/09_userns_usermod	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,536 @@
+From ebiederm at xmission.com  Tue Jan 22 09:20:27 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at xmission.com>)
+	id 1TxZzw-0004wm-8g; Tue, 22 Jan 2013 02:18:40 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:18:24 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87sj5tpodb.fsf at 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 at 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 at 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) {
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/10_userns_newusers 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/10_userns_newusers
--- 1:4.1.5.1-1.1/debian/patches/userns/10_userns_newusers	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/10_userns_newusers	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,256 @@
+From ebiederm at xmission.com  Tue Jan 22 09:21:21 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at 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 at 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 at 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 at 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 at xmission.com>)
+	id 1Txa0y-000519-2O; Tue, 22 Jan 2013 02:19:34 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:19:28 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87k3r5pobj.fsf at 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 at 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 at 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++;
++			}
++		}
+ 	}
+ 
+ 	/*
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/11_userns_newxidmap 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/11_userns_newxidmap
--- 1:4.1.5.1-1.1/debian/patches/userns/11_userns_newxidmap	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/11_userns_newxidmap	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,1004 @@
+From ebiederm at xmission.com  Tue Jan 22 09:22:07 2013
+Return-Path: <ebiederm at xmission.com>
+X-Original-To: serge at hallyn.com
+Delivered-To: serge at hallyn.com
+Received: by mail.hallyn.com (Postfix, from userid 5001)
+	id E5D16C80F4; Tue, 22 Jan 2013 09:22:07 +0000 (UTC)
+X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
+X-Spam-Level: 
+X-Spam-Status: No, score=-0.2 required=8.0 tests=BAD_ENC_HEADER,BAYES_00,
+	LONGWORDS,RCVD_IN_DNSWL_MED 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 2E206C80D1
+	for <serge at hallyn.com>; Tue, 22 Jan 2013 09:22:03 +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 at xmission.com>)
+	id 1Txa1k-0000xE-Ix; Tue, 22 Jan 2013 02:20:20 -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 at xmission.com>)
+	id 1Txa1b-00059T-Lu; Tue, 22 Jan 2013 02:20:20 -0700
+From: ebiederm at xmission.com (Eric W. Biederman)
+To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois at centraliens.net>
+Cc: <Pkg-shadow-devel at lists.alioth.debian.org>,  Linux Containers <containers at lists.linux-foundation.org>,  "Michael Kerrisk \(man-pages\)" <mtk.manpages at gmail.com>,  "Serge E. Hallyn" <serge at hallyn.com>
+References: <87d2wxshu0.fsf at xmission.com>
+Date: Tue, 22 Jan 2013 01:20:07 -0800
+In-Reply-To: <87d2wxshu0.fsf at xmission.com> (Eric W. Biederman's message of
+	"Tue, 22 Jan 2013 01:11:19 -0800")
+Message-ID: <87ehhdpoag.fsf at 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/nox3f5bDq7zL9eOiGra/HoCkv7o07HDs=
+X-SA-Exim-Connect-IP: 98.207.153.68
+X-SA-Exim-Mail-From: ebiederm at xmission.com
+Subject: [PATCH 11/11] newuidmap,newgidmap: New suid helpers for using 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: 2081                                                  
+Status: RO
+Content-Length: 31344
+Lines: 965
+
+
+Signed-off-by: "Eric W. Biederman" <ebiederm at xmission.com>
+---
+ libmisc/Makefile.am |    2 +
+ libmisc/idmapping.c |  126 +++++++++++++++++++++++++++++++++++
+ libmisc/idmapping.h |   44 ++++++++++++
+ man/Makefile.am     |    4 +
+ man/newgidmap.1.xml |  157 +++++++++++++++++++++++++++++++++++++++++++
+ man/newuidmap.1.xml |  154 +++++++++++++++++++++++++++++++++++++++++++
+ src/Makefile.am     |    5 +-
+ src/newgidmap.c     |  183 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ src/newuidmap.c     |  183 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 9 files changed, 856 insertions(+), 2 deletions(-)
+ create mode 100644 libmisc/idmapping.c
+ create mode 100644 libmisc/idmapping.h
+ create mode 100644 man/newgidmap.1.xml
+ create mode 100644 man/newuidmap.1.xml
+ create mode 100644 src/newgidmap.c
+ create mode 100644 src/newuidmap.c
+
+Index: shadow/libmisc/Makefile.am
+===================================================================
+--- shadow.orig/libmisc/Makefile.am	2013-02-01 15:27:53.836080342 -0600
++++ shadow/libmisc/Makefile.am	2013-02-01 15:27:53.828080343 -0600
+@@ -32,6 +32,8 @@
+ 	getgr_nam_gid.c \
+ 	getrange.c \
+ 	hushed.c \
++	idmapping.h \
++	idmapping.c \
+ 	isexpired.c \
+ 	limits.c \
+ 	list.c log.c \
+Index: shadow/libmisc/idmapping.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ shadow/libmisc/idmapping.c	2013-02-01 15:27:53.828080343 -0600
+@@ -0,0 +1,126 @@
++/*
++ * Copyright (c) 2013 Eric 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.
++ */
++
++#include <config.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <limits.h>
++#include <stdlib.h>
++#include "prototypes.h"
++#include "idmapping.h"
++
++struct map_range *get_map_ranges(int ranges, int argc, char **argv)
++{
++	struct map_range *mappings, *mapping;
++	int idx, argidx;
++
++	if ((ranges * 3) > argc) {
++		fprintf(stderr, "ranges: %u argc: %d\n",
++			ranges, argc);
++		fprintf(stderr,
++			_( "%s: Not enough arguments to form %u mappings\n"),
++			Prog, ranges);
++		return NULL;
++	}
++
++	mappings = calloc(ranges, sizeof(*mappings));
++	if (!mappings) {
++		fprintf(stderr, _( "%s: Memory allocation failure\n"),
++			Prog);
++		exit(EXIT_FAILURE);
++	}
++
++	/* Gather up the ranges from the command line */
++	mapping = mappings;
++	for (idx = 0; idx < ranges; idx++, argidx += 3, mapping++) {
++		if (!getulong(argv[argidx + 0], &mapping->upper))
++			return NULL;
++		if (!getulong(argv[argidx + 1], &mapping->lower))
++			return NULL;
++		if (!getulong(argv[argidx + 2], &mapping->count))
++			return NULL;
++	}
++	return mappings;
++}
++
++/* Number of ascii digits needed to print any unsigned long in decimal.
++ * There are approximately 10 bits for every 3 decimal digits.
++ * So from bits to digits the formula is roundup((Number of bits)/10) * 3.
++ * For common sizes of integers this works out to:
++ *  2bytes -->  6 ascii estimate  -> 65536  (5 real)
++ *  4bytes --> 12 ascii estimated -> 4294967296 (10 real)
++ *  8bytes --> 21 ascii estimated -> 18446744073709551616 (20 real)
++ * 16bytes --> 39 ascii estimated -> 340282366920938463463374607431768211456 (39 real)
++ */
++#define ULONG_DIGITS ((((sizeof(unsigned long) * CHAR_BIT) + 9)/10)*3)
++
++
++void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings,
++	const char *map_file)
++{
++	int idx;
++	struct map_range *mapping;
++	size_t bufsize;
++	char *buf, *pos;
++	int fd;
++
++	bufsize = ranges * ((ULONG_DIGITS  + 1) * 3);
++	pos = buf = xmalloc(bufsize);
++
++	/* Build the mapping command */
++	mapping = mappings;
++	for (idx = 0; idx < ranges; idx++, mapping++) {
++		/* Append this range to the string that will be written */
++		int written = snprintf(pos, bufsize - (pos - buf),
++			"%lu %lu %lu\n",
++			mapping->upper,
++			mapping->lower,
++			mapping->count);
++		if ((written <= 0) || (written >= (bufsize - (pos - buf)))) {
++			fprintf(stderr, _("%s: snprintf failed!\n"), Prog);
++			exit(EXIT_FAILURE);
++		}
++		pos += written;
++	}
++
++	/* Write the mapping to the maping file */
++	fd = openat(proc_dir_fd, map_file, O_WRONLY);
++	if (fd < 0) {
++		fprintf(stderr, _("%s: open of %s failed: %s\n"),
++			Prog, map_file, strerror(errno));
++		exit(EXIT_FAILURE);
++	}
++	if (write(fd, buf, pos - buf) != (pos - buf)) {
++		fprintf(stderr, _("%s: write to %s failed: %s\n"),
++			Prog, map_file, strerror(errno));
++		exit(EXIT_FAILURE);
++	}
++	close(fd);
++}
+Index: shadow/libmisc/idmapping.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ shadow/libmisc/idmapping.h	2013-02-01 15:27:53.828080343 -0600
+@@ -0,0 +1,44 @@
++/*
++ * Copyright (c) 2013 Eric 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.
++ */
++
++#ifndef _IDMAPPING_H_
++#define _IDMAPPING_H_
++
++struct map_range {
++	unsigned long upper;
++	unsigned long lower;
++	unsigned long count;
++};
++
++extern struct map_range *get_map_ranges(int ranges, int argc, char **argv);
++extern void write_mapping(int proc_dir_fd, int ranges,
++	struct map_range *mappings, const char *map_file);
++
++#endif /* _ID_MAPPING_H_ */
++
+Index: shadow/man/Makefile.am
+===================================================================
+--- shadow.orig/man/Makefile.am	2013-02-01 15:27:53.836080342 -0600
++++ shadow/man/Makefile.am	2013-02-01 15:27:53.828080343 -0600
+@@ -30,7 +30,9 @@
+ 	man1/login.1 \
+ 	man5/login.defs.5 \
+ 	man8/logoutd.8 \
++	man1/newgidmap.1 \
+ 	man1/newgrp.1 \
++	man1/newuidmap.1 \
+ 	man8/newusers.8 \
+ 	man8/nologin.8 \
+ 	man1/passwd.1 \
+@@ -83,7 +85,9 @@
+ 	login.access.5.xml \
+ 	login.defs.5.xml \
+ 	logoutd.8.xml \
++	newgidmap.1.xml \
+ 	newgrp.1.xml \
++	newuidmap.1.xml \
+ 	newusers.8.xml \
+ 	nologin.8.xml \
+ 	passwd.1.xml \
+Index: shadow/man/newgidmap.1.xml
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ shadow/man/newgidmap.1.xml	2013-02-01 15:27:53.828080343 -0600
+@@ -0,0 +1,157 @@
++<?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='newgidmap.1'>
++  <refmeta>
++    <refentrytitle>newgidmap</refentrytitle>
++    <manvolnum>1</manvolnum>
++    <refmiscinfo class="sectdesc">User Commands</refmiscinfo>
++    <refmiscinfo class="source">shadow-utils</refmiscinfo>
++    <refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
++  </refmeta>
++  <refnamediv id='name'>
++    <refname>newgidmap</refname>
++    <refpurpose>set the gid mapping of a user namespace</refpurpose>
++  </refnamediv>
++
++  <refsynopsisdiv id='synopsis'>
++    <cmdsynopsis>
++      <command>newgidmap</command>
++      <arg choice='plain'>
++	<replaceable>pid</replaceable>
++      </arg>
++      <arg choice='plain'>
++	<replaceable>gid</replaceable>
++      </arg>
++      <arg choice='plain'>
++	<replaceable>lowergid</replaceable>
++      </arg>
++      <arg choice='plain'>
++	<replaceable>count</replaceable>
++      </arg>
++      <arg choice='opt'>
++	<arg choice='plain'>
++	  <replaceable>pid</replaceable>
++	</arg>
++	<arg choice='plain'>
++	  <replaceable>gid</replaceable>
++	</arg>
++	<arg choice='plain'>
++	  <replaceable>lowergid</replaceable>
++	</arg>
++	<arg choice='plain'>
++	  <replaceable>count</replaceable>
++	</arg>
++	<arg choice='opt'>
++	  <replaceable>...</replaceable>
++	</arg>
++      </arg>
++    </cmdsynopsis>
++  </refsynopsisdiv>
++
++  <refsect1 id='description'>
++    <title>DESCRIPTION</title>
++    <para>
++      The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on it's
++      command line arguments and the gids allowed in <filename>/etc/subgid</filename>.
++    </para>
++
++  </refsect1>
++
++  <refsect1 id='options'>
++    <title>OPTIONS</title>
++    <para>
++      There currently are no options to the <command>newgidmap</command> command.
++    </para>
++    <variablelist remap='IP'>
++    </variablelist>
++  </refsect1>
++
++  <refsect1 id='note'>
++    <title>NOTE</title>
++    <para>
++      The only restriction placed on the login shell is that the command
++      name must be listed in <filename>/etc/shells</filename>, unless the
++      invoker is the superuser, and then any value may be added. An
++      account with a restricted login shell may not change her login shell.
++      For this reason, placing <filename>/bin/rsh</filename> in
++      <filename>/etc/shells</filename> is discouraged since accidentally
++      changing to a restricted shell would prevent the user from ever
++      changing her login shell back to its original value.
++    </para>
++  </refsect1>
++
++
++  <refsect1 id='files'>
++    <title>FILES</title>
++    <variablelist>
++      <varlistentry>
++	<term><filename>/etc/subgid</filename></term>
++	<listitem>
++	  <para>List of users subordinate user IDs.</para>
++	</listitem>
++      </varlistentry>
++      <varlistentry>
++	<term><filename>/proc/[pid]/gid_map</filename></term>
++	<listitem>
++	  <para>Mapping of gids from one between user namespaces.</para>
++	</listitem>
++      </varlistentry>
++    </variablelist>
++  </refsect1>
++
++  <refsect1 id='see_also'>
++    <title>SEE ALSO</title>
++    <para>
++      <citerefentry>
++	<refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>useradd</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>usermod</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>newusers</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>userdel</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>subgid</refentrytitle><manvolnum>5</manvolnum>
++      </citerefentry>.
++    </para>
++  </refsect1>
++</refentry>
+Index: shadow/man/newuidmap.1.xml
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ shadow/man/newuidmap.1.xml	2013-02-01 15:27:53.828080343 -0600
+@@ -0,0 +1,154 @@
++<?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='newuidmap.1'>
++  <refmeta>
++    <refentrytitle>newuidmap</refentrytitle>
++    <manvolnum>1</manvolnum>
++    <refmiscinfo class="sectdesc">User Commands</refmiscinfo>
++    <refmiscinfo class="source">shadow-utils</refmiscinfo>
++    <refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
++  </refmeta>
++  <refnamediv id='name'>
++    <refname>newuidmap</refname>
++    <refpurpose>set the uid mapping of a user namespace</refpurpose>
++  </refnamediv>
++
++  <refsynopsisdiv id='synopsis'>
++    <cmdsynopsis>
++      <command>newuidmap</command>
++      <arg choice='plain'>
++	<replaceable>pid</replaceable>
++      </arg>
++      <arg choice='plain'>
++	<replaceable>uid</replaceable>
++      </arg>
++      <arg choice='plain'>
++	<replaceable>loweruid</replaceable>
++      </arg>
++      <arg choice='plain'>
++	<replaceable>count</replaceable>
++      </arg>
++      <arg choice='opt'>
++	<arg choice='plain'>
++	  <replaceable>uid</replaceable>
++	</arg>
++	<arg choice='plain'>
++	  <replaceable>loweruid</replaceable>
++	</arg>
++	<arg choice='plain'>
++	  <replaceable>count</replaceable>
++	</arg>
++	<arg choice='opt'>
++	  <replaceable>...</replaceable>
++	</arg>
++      </arg>
++    </cmdsynopsis>
++  </refsynopsisdiv>
++
++  <refsect1 id='description'>
++    <title>DESCRIPTION</title>
++    <para>
++      The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on it's
++      command line arguments and the uids allowed in <filename>/etc/subuid</filename>.
++    </para>
++
++  </refsect1>
++
++  <refsect1 id='options'>
++    <title>OPTIONS</title>
++    <para>
++      There currently are no options to the <command>newuidmap</command> command.
++    </para>
++    <variablelist remap='IP'>
++    </variablelist>
++  </refsect1>
++
++  <refsect1 id='note'>
++    <title>NOTE</title>
++    <para>
++      The only restriction placed on the login shell is that the command
++      name must be listed in <filename>/etc/shells</filename>, unless the
++      invoker is the superuser, and then any value may be added. An
++      account with a restricted login shell may not change her login shell.
++      For this reason, placing <filename>/bin/rsh</filename> in
++      <filename>/etc/shells</filename> is discouraged since accidentally
++      changing to a restricted shell would prevent the user from ever
++      changing her login shell back to its original value.
++    </para>
++  </refsect1>
++
++
++  <refsect1 id='files'>
++    <title>FILES</title>
++    <variablelist>
++      <varlistentry>
++	<term><filename>/etc/subuid</filename></term>
++	<listitem>
++	  <para>List of users subordinate user IDs.</para>
++	</listitem>
++      </varlistentry>
++      <varlistentry>
++	<term><filename>/proc/[pid]/uid_map</filename></term>
++	<listitem>
++	  <para>Mapping of uids from one between user namespaces.</para>
++	</listitem>
++      </varlistentry>
++    </variablelist>
++  </refsect1>
++
++  <refsect1 id='see_also'>
++    <title>SEE ALSO</title>
++    <para>
++      <citerefentry>
++	<refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>useradd</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>usermod</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>newusers</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>userdel</refentrytitle><manvolnum>8</manvolnum>
++      </citerefentry>,
++      <citerefentry>
++	<refentrytitle>subuid</refentrytitle><manvolnum>5</manvolnum>
++      </citerefentry>.
++    </para>
++  </refsect1>
++</refentry>
+Index: shadow/src/Makefile.am
+===================================================================
+--- shadow.orig/src/Makefile.am	2013-02-01 15:27:53.836080342 -0600
++++ shadow/src/Makefile.am	2013-02-01 15:27:53.832080342 -0600
+@@ -23,7 +23,8 @@
+ # $prefix/bin and $prefix/sbin, no install-data hacks...)
+ 
+ bin_PROGRAMS   = groups login su
+-ubin_PROGRAMS  = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
++ubin_PROGRAMS  = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd \
++	newgidmap newuidmap
+ usbin_PROGRAMS = \
+ 	cppw \
+ 	chgpasswd \
+@@ -50,7 +51,7 @@
+ noinst_PROGRAMS = id sulogin
+ 
+ suidbins       = su
+-suidubins      = chage chfn chsh expiry gpasswd newgrp passwd
++suidubins      = chage chfn chsh expiry gpasswd newgrp passwd newuidmap newgidmap
+ if ACCT_TOOLS_SETUID
+ 	suidubins += chage chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
+ endif
+Index: shadow/src/newgidmap.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ shadow/src/newgidmap.c	2013-02-01 15:27:53.832080342 -0600
+@@ -0,0 +1,183 @@
++/*
++ * Copyright (c) 2013 Eric 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.
++ */
++
++#include <config.h>
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include "defines.h"
++#include "prototypes.h"
++#include "subordinateio.h"
++#include "idmapping.h"
++
++/*
++ * Global variables
++ */
++const char *Prog;
++
++static bool verify_range(struct passwd *pw, struct map_range *range)
++{
++	/* 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))
++		return true;
++
++	/* Allow a process to map it's own gid */
++	if ((range->count == 1) && (pw->pw_gid == range->lower))
++		return true;
++
++	return false;
++}
++
++static void verify_ranges(struct passwd *pw, int ranges,
++	struct map_range *mappings)
++{
++	struct map_range *mapping;
++	int idx;
++
++	mapping = mappings;
++	for (idx = 0; idx < ranges; idx++, mapping++) {
++		if (!verify_range(pw, mapping)) {
++			fprintf(stderr, _( "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"),
++				Prog,
++				mapping->upper,
++				mapping->upper + mapping->count,
++				mapping->lower,
++				mapping->lower + mapping->count);
++			exit(EXIT_FAILURE);
++		}
++	}
++}
++
++static void usage(void)
++{
++	fprintf(stderr, _("usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"), Prog);
++	exit(EXIT_FAILURE);
++}
++
++/*
++ * newgidmap - Set the gid_map for the specified process
++ */
++int main(int argc, char **argv)
++{
++	char proc_dir_name[PATH_MAX];
++	char *target_str;
++	pid_t target, parent;
++	int proc_dir_fd;
++	int ranges;
++	struct map_range *mappings;
++	struct stat st;
++	struct passwd *pw;
++	int written;
++
++	Prog = Basename (argv[0]);
++
++	/*
++	 * The valid syntax are
++	 * newgidmap target_pid
++	 */
++	if (argc < 2)
++		usage();
++
++	/* Find the process that needs it's user namespace
++	 * gid mapping set.
++	 */
++	target_str = argv[1];
++	if (!get_pid(target_str, &target))
++		usage();
++
++	written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
++		target);
++	if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
++		fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
++			Prog, strerror(errno));
++	}
++
++	proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
++	if (proc_dir_fd < 0) {
++		fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
++			Prog, target);
++		return EXIT_FAILURE;
++	}
++
++	/* Who am i? */
++	pw = get_my_pwent ();
++	if (NULL == pw) {
++		fprintf (stderr,
++			_("%s: Cannot determine your user name.\n"),
++			Prog);
++		SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
++				(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"),
++			Prog, target);
++		return EXIT_FAILURE;
++	}
++
++	/* Verify real user and real group matches the password entry
++	 * and the effective user and group of the program whose
++	 * mappings we have been asked to set.
++	 */
++	if ((getuid() != pw->pw_uid) ||
++	    (getgid() != pw->pw_gid) ||
++	    (pw->pw_uid != st.st_uid) ||
++	    (pw->pw_gid != st.st_gid)) {
++		fprintf(stderr, _( "%s: Target %u is owned by a different user\n" ),
++			Prog, target);
++		return EXIT_FAILURE;
++	}
++
++	if (!sub_gid_open(O_RDONLY)) {
++		return EXIT_FAILURE;
++	}
++
++	ranges = ((argc - 2) + 2) / 3;
++	mappings = get_map_ranges(ranges, argc - 2, argv + 2);
++	if (!mappings)
++		usage();
++
++	verify_ranges(pw, ranges, mappings);
++
++	write_mapping(proc_dir_fd, ranges, mappings, "gid_map");
++	sub_gid_close();
++
++	return EXIT_SUCCESS;
++}
+Index: shadow/src/newuidmap.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ shadow/src/newuidmap.c	2013-02-01 15:27:53.832080342 -0600
+@@ -0,0 +1,183 @@
++/*
++ * Copyright (c) 2013 Eric 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.
++ */
++
++#include <config.h>
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <stdbool.h>
++#include <stdlib.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include "defines.h"
++#include "prototypes.h"
++#include "subordinateio.h"
++#include "idmapping.h"
++
++/*
++ * Global variables
++ */
++const char *Prog;
++
++static bool verify_range(struct passwd *pw, struct map_range *range)
++{
++	/* An empty range is invalid */
++	if (range->count == 0)
++		return false;
++
++	/* Test /etc/subuid */
++	if (have_sub_uids(pw->pw_name, range->lower, range->count))
++		return true;
++
++	/* Allow a process to map it's own uid */
++	if ((range->count == 1) && (pw->pw_uid == range->lower))
++		return true;
++
++	return false;
++}
++
++static void verify_ranges(struct passwd *pw, int ranges,
++	struct map_range *mappings)
++{
++	struct map_range *mapping;
++	int idx;
++
++	mapping = mappings;
++	for (idx = 0; idx < ranges; idx++, mapping++) {
++		if (!verify_range(pw, mapping)) {
++			fprintf(stderr, _( "%s: uid range [%lu-%lu) -> [%lu-%lu) not allowed\n"),
++				Prog,
++				mapping->upper,
++				mapping->upper + mapping->count,
++				mapping->lower,
++				mapping->lower + mapping->count);
++			exit(EXIT_FAILURE);
++		}
++	}
++}
++
++void usage(void)
++{
++	fprintf(stderr, _("usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"), Prog);
++	exit(EXIT_FAILURE);
++}
++
++/*
++ * newuidmap - Set the uid_map for the specified process
++ */
++int main(int argc, char **argv)
++{
++	char proc_dir_name[PATH_MAX];
++	char *target_str;
++	pid_t target, parent;
++	int proc_dir_fd;
++	int ranges;
++	struct map_range *mappings;
++	struct stat st;
++	struct passwd *pw;
++	int written;
++
++	Prog = Basename (argv[0]);
++
++	/*
++	 * The valid syntax are
++	 * newuidmap target_pid
++	 */
++	if (argc < 2)
++		usage();
++
++	/* Find the process that needs it's user namespace
++	 * uid mapping set.
++	 */
++	target_str = argv[1];
++	if (!get_pid(target_str, &target))
++		usage();
++
++	written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
++		target);
++	if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
++		fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
++			Prog, strerror(errno));
++	}
++
++	proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
++	if (proc_dir_fd < 0) {
++		fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
++			Prog, target);
++		return EXIT_FAILURE;
++	}
++
++	/* Who am i? */
++	pw = get_my_pwent ();
++	if (NULL == pw) {
++		fprintf (stderr,
++			_("%s: Cannot determine your user name.\n"),
++			Prog);
++		SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
++				(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"),
++			Prog, target);
++		return EXIT_FAILURE;
++	}
++
++	/* Verify real user and real group matches the password entry
++	 * and the effective user and group of the program whose
++	 * mappings we have been asked to set.
++	 */
++	if ((getuid() != pw->pw_uid) ||
++	    (getgid() != pw->pw_gid) ||
++	    (pw->pw_uid != st.st_uid) ||
++	    (pw->pw_gid != st.st_gid)) {
++		fprintf(stderr, _( "%s: Target %u is owned by a different user\n" ),
++			Prog, target);
++		return EXIT_FAILURE;
++	}
++
++	if (!sub_uid_open(O_RDONLY)) {
++		return EXIT_FAILURE;
++	}
++
++	ranges = ((argc - 2) + 2) / 3;
++	mappings = get_map_ranges(ranges, argc - 2, argv + 2);
++	if (!mappings)
++		usage();
++
++	verify_ranges(pw, ranges, mappings);
++
++	write_mapping(proc_dir_fd, ranges, mappings, "uid_map");
++	sub_uid_close();
++
++	return EXIT_SUCCESS;
++}
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/12_userns_selinuxlibs 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/12_userns_selinuxlibs
--- 1:4.1.5.1-1.1/debian/patches/userns/12_userns_selinuxlibs	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/12_userns_selinuxlibs	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,13 @@
+Index: shadow-4.1.5.1/src/Makefile.am
+===================================================================
+--- shadow-4.1.5.1.orig/src/Makefile.am	2013-02-04 11:56:40.485335430 -0600
++++ shadow-4.1.5.1/src/Makefile.am	2013-02-04 11:57:49.525334261 -0600
+@@ -80,6 +80,8 @@
+ endif
+ 
+ chage_LDADD    = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
++newuidmap_LDADD    = $(LDADD) $(LIBSELINUX)
++newgidmap_LDADD    = $(LDADD) $(LIBSELINUX)
+ chfn_LDADD     = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
+ chgpasswd_LDADD = $(LDADD) $(LIBPAM_SUID) $(LIBSELINUX) $(LIBCRYPT)
+ chsh_LDADD     = $(LDADD) $(LIBPAM) $(LIBSELINUX) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/13_subordinate_parse_static_buf 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/13_subordinate_parse_static_buf
--- 1:4.1.5.1-1.1/debian/patches/userns/13_subordinate_parse_static_buf	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/13_subordinate_parse_static_buf	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,23 @@
+Description: subordinateio: Fix subordinate_parse to have an internal static buffer
+ subordinate_parse is supposed to return a static structure that
+ represents one line in /etc/subuid or /etc/subgid.  I goofed and
+ failed to make the variable rangebuf that holds the username of
+ in the returned structure static.
+ .
+ Add this missing static specification.
+Author: <Eric W. Biederman" <ebiederm at xmission.com>
+Origin: upstream
+Forwarded: no
+Index: shadow-4.1.5.1/lib/subordinateio.c
+===================================================================
+--- shadow-4.1.5.1.orig/lib/subordinateio.c	2013-02-04 11:56:40.265335433 -0600
++++ shadow-4.1.5.1/lib/subordinateio.c	2013-02-04 12:32:46.653298752 -0600
+@@ -48,7 +48,7 @@
+ static void *subordinate_parse (const char *line)
+ {
+ 	static struct subordinate_range range;
+-	char rangebuf[1024];
++	static char rangebuf[1024];
+ 	int i;
+ 	char *cp;
+ 	char *fields[NFIELDS];
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/14_fix_getopt 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/14_fix_getopt
--- 1:4.1.5.1-1.1/debian/patches/userns/14_fix_getopt	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/14_fix_getopt	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,24 @@
+Index: shadow-userns/src/usermod.c
+===================================================================
+--- shadow-userns.orig/src/usermod.c	2013-02-05 16:35:10.608485591 +0000
++++ shadow-userns/src/usermod.c	2013-02-05 17:16:20.540485591 +0000
+@@ -993,9 +993,9 @@
+ 		};
+ 		while ((c = getopt_long (argc, argv,
+ #ifdef WITH_SELINUX
+-			                 "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:",
++			                 "ac:d:e:f:g:G:hl:Lmop:R:s:u:UZ:v:w:V:W:",
+ #else				/* !WITH_SELINUX */
+-			                 "ac:d:e:f:g:G:hl:Lmop:R:s:u:U",
++			                 "ac:d:e:f:g:G:hl:Lmop:R:s:u:Uv:w:V:W:",
+ #endif				/* !WITH_SELINUX */
+ 			                 long_options, NULL)) != -1) {
+ 			switch (c) {
+@@ -1141,6 +1141,7 @@
+ 					exit(E_BAD_ARG);
+ 				}
+ 				wflg = true;
++                break;
+ 			case 'W':
+ 				if (prepend_range (optarg, &del_sub_gids) == 0) {
+ 					fprintf (stderr,
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/16_add-argument-sanity-checking.patch 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/16_add-argument-sanity-checking.patch
--- 1:4.1.5.1-1.1/debian/patches/userns/16_add-argument-sanity-checking.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/16_add-argument-sanity-checking.patch	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,80 @@
+From df3c8c1f7f47ceff607595067458f1d8e53eaab8 Mon Sep 17 00:00:00 2001
+From: Serge Hallyn <serge.hallyn at ubuntu.com>
+Date: Fri, 21 Jun 2013 11:47:36 -0500
+Subject: [PATCH 1/1] userns: add argument sanity checking
+
+In find_new_sub_{u,g}ids, check for min, count and max values.
+
+In idmapping.c:get_map_ranges(), make sure that the value passed
+in for ranges did not overflow.  Couldn't happen with the current
+code, but this is a sanity check for any future potential mis-uses.
+
+Signed-off-by: Serge Hallyn <serge.hallyn at ubuntu.com>
+---
+ libmisc/find_new_sub_gids.c |  8 ++++++++
+ libmisc/find_new_sub_uids.c |  8 ++++++++
+ libmisc/idmapping.c         | 10 ++++++++++
+ 3 files changed, 26 insertions(+)
+
+diff --git a/libmisc/find_new_sub_gids.c b/libmisc/find_new_sub_gids.c
+index 68046ac..fd44978 100644
+--- a/libmisc/find_new_sub_gids.c
++++ b/libmisc/find_new_sub_gids.c
+@@ -58,6 +58,14 @@ int find_new_sub_gids (const char *owner,
+ 	max = getdef_ulong ("SUB_GID_MAX", 600100000UL);
+ 	count = getdef_ulong ("SUB_GID_COUNT", 10000);
+ 
++	if (min >= max || count >= max || (min + count) >= max) {
++		(void) fprintf (stderr,
++				_("%s: Invalid configuration: SUB_GID_MIN (%lu),"
++				  " SUB_GID_MAX (%lu), SUB_GID_COUNT (%lu)\n"),
++			Prog, min, max, count);
++		return -1;
++	}
++
+ 	/* Is there a preferred range that works? */
+ 	if ((*range_count != 0) &&
+ 	    (*range_start >= min) &&
+diff --git a/libmisc/find_new_sub_uids.c b/libmisc/find_new_sub_uids.c
+index f1720f9..b608c59 100644
+--- a/libmisc/find_new_sub_uids.c
++++ b/libmisc/find_new_sub_uids.c
+@@ -58,6 +58,14 @@ int find_new_sub_uids (const char *owner,
+ 	max = getdef_ulong ("SUB_UID_MAX", 600100000UL);
+ 	count = getdef_ulong ("SUB_UID_COUNT", 10000);
+ 
++	if (min >= max || count >= max || (min + count) >= max) {
++		(void) fprintf (stderr,
++				_("%s: Invalid configuration: SUB_UID_MIN (%lu),"
++				  " SUB_UID_MAX (%lu), SUB_UID_COUNT (%lu)\n"),
++			Prog, min, max, count);
++		return -1;
++	}
++
+ 	/* Is there a preferred range that works? */
+ 	if ((*range_count != 0) &&
+ 	    (*range_start >= min) &&
+diff --git a/libmisc/idmapping.c b/libmisc/idmapping.c
+index cb9e898..4147796 100644
+--- a/libmisc/idmapping.c
++++ b/libmisc/idmapping.c
+@@ -41,6 +41,16 @@ struct map_range *get_map_ranges(int ranges, int argc, char **argv)
+ 	struct map_range *mappings, *mapping;
+ 	int idx, argidx;
+ 
++	if (ranges < 0 || argc < 0) {
++		fprintf(stderr, "%s: error calculating number of arguments\n", Prog);
++		return NULL;
++	}
++
++	if (ranges != ((argc - 2) + 2) / 3) {
++		fprintf(stderr, "%s: ranges: %u is wrong for argc: %d\n", Prog, ranges, argc);
++		return NULL;
++	}
++
+ 	if ((ranges * 3) > argc) {
+ 		fprintf(stderr, "ranges: %u argc: %d\n",
+ 			ranges, argc);
+-- 
+1.8.1.2
+
diff -pruN 1:4.1.5.1-1.1/debian/patches/userns/manpagetypo 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/manpagetypo
--- 1:4.1.5.1-1.1/debian/patches/userns/manpagetypo	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/patches/userns/manpagetypo	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,26 @@
+Index: shadow/man/subgid.5.xml
+===================================================================
+--- shadow.orig/man/subgid.5.xml	2013-03-06 15:19:23.848386200 -0600
++++ shadow/man/subgid.5.xml	2013-03-06 15:19:51.240386816 -0600
+@@ -104,7 +104,7 @@
+ 	<refentrytitle>subuid</refentrytitle><manvolnum>5</manvolnum>
+       </citerefentry>,
+       <citerefentry>
+-	<refentrytitle>logindefs</refentrytitle><manvolnum>5</manvolnum>
++	<refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
+       </citerefentry>,
+       <citerefentry>
+ 	<refentrytitle>newuidmap</refentrytitle><manvolnum>1</manvolnum>
+Index: shadow/man/subuid.5.xml
+===================================================================
+--- shadow.orig/man/subuid.5.xml	2013-03-06 15:19:09.660385881 -0600
++++ shadow/man/subuid.5.xml	2013-03-06 15:19:44.956386675 -0600
+@@ -104,7 +104,7 @@
+ 	<refentrytitle>subgid</refentrytitle><manvolnum>5</manvolnum>
+       </citerefentry>,
+       <citerefentry>
+-	<refentrytitle>logindefs</refentrytitle><manvolnum>5</manvolnum>
++	<refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
+       </citerefentry>,
+       <citerefentry>
+ 	<refentrytitle>newuidmap</refentrytitle><manvolnum>1</manvolnum>
diff -pruN 1:4.1.5.1-1.1/debian/rules 1:4.1.5.1-1.1ubuntu1/debian/rules
--- 1:4.1.5.1-1.1/debian/rules	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/rules	2014-05-02 23:36:42.000000000 +0000
@@ -40,6 +40,8 @@ endif
 	dh_installpam -p login --name=su
 	install -c -m 444 debian/login.defs debian/login/etc/login.defs
 	install -c -m 444 debian/securetty.$(DEB_HOST_ARCH_OS) debian/login/etc/securetty
+	install -d debian/login/usr/share/apport/package-hooks
+	install -c -m 644 debian/source_shadow.py debian/login/usr/share/apport/package-hooks/source_shadow.py
 	dh_lintian -p login
 
 binary-install/passwd::
@@ -55,12 +57,22 @@ binary-install/passwd::
 	dh_installpam -p passwd --name=chpasswd
 	dh_installpam -p passwd --name=newusers
 	install -c -m 644 debian/useradd.default debian/passwd/etc/default/useradd
+
+	## Ubuntu
+	# Upstart job for clearing locks
+	install -m 644 debian/passwd.conf debian/passwd/etc/init/passwd.conf
+	##
+
 	install -d debian/passwd/sbin
 	install -c -m 555 debian/shadowconfig.sh debian/passwd/sbin/shadowconfig
 	install -c -m 444 debian/cpgr.8 debian/passwd/usr/share/man/man8
 	install -c -m 444 debian/cppw.8 debian/passwd/usr/share/man/man8
 	dh_lintian -p passwd
 
+binary-predeb/uidmap::
+	chmod u+s debian/uidmap/usr/bin/newuidmap
+	chmod u+s debian/uidmap/usr/bin/newgidmap
+
 binary-predeb/login::
 	# No real need for login to be setuid root
 	# chmod u+s debian/login/bin/login
diff -pruN 1:4.1.5.1-1.1/debian/securetty.linux 1:4.1.5.1-1.1ubuntu1/debian/securetty.linux
--- 1:4.1.5.1-1.1/debian/securetty.linux	2014-05-02 23:36:42.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/securetty.linux	2014-05-02 23:36:42.000000000 +0000
@@ -385,6 +385,13 @@ ttymxc3
 ttymxc4
 ttymxc5
 
+# LXC (Linux Containers)
+lxc/console
+lxc/tty1
+lxc/tty2
+lxc/tty3
+lxc/tty4
+
 # Serial Console for MIPS Swarm
 duart0
 duart1
diff -pruN 1:4.1.5.1-1.1/debian/source_shadow.py 1:4.1.5.1-1.1ubuntu1/debian/source_shadow.py
--- 1:4.1.5.1-1.1/debian/source_shadow.py	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/source_shadow.py	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+
+'''Apport package hook for shadow
+
+(c) 2010 Canonical Ltd.
+Contributors:
+Marc Deslauriers <marc.deslauriers at canonical.com>
+
+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.  See http://www.gnu.org/copyleft/gpl.html for
+the full text of the license.
+'''
+
+from apport.hookutils import *
+
+def add_info(report):
+
+    attach_file_if_exists(report, '/etc/login.defs', 'LoginDefs')
+
+if __name__ == '__main__':
+    report = {}
+    add_info(report)
+    for key in report:
+        print('[%s]\n%s' % (key, report[key]))
diff -pruN 1:4.1.5.1-1.1/debian/uidmap.install 1:4.1.5.1-1.1ubuntu1/debian/uidmap.install
--- 1:4.1.5.1-1.1/debian/uidmap.install	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1.1ubuntu1/debian/uidmap.install	2014-05-02 23:36:42.000000000 +0000
@@ -0,0 +1,4 @@
+usr/bin/newuidmap
+usr/bin/newgidmap
+usr/share/man/man1/newuidmap.1
+usr/share/man/man1/newgidmap.1


More information about the Pkg-shadow-devel mailing list