[Pkg-shadow-devel] Ubuntu shadow 1:4.1.5.1-1ubuntu5

Ubuntu Merge-o-Matic mom at ubuntu.com
Fri Jun 28 15:38:58 UTC 2013


This e-mail has been sent due to an upload to Ubuntu that contains Ubuntu
changes.  It contains the difference between the new version and the
previous version of the same source package in Ubuntu.
-------------- next part --------------
Format: 1.8
Date: Fri, 28 Jun 2013 11:31:51 +0100
Source: shadow
Binary: passwd login uidmap
Architecture: source
Version: 1:4.1.5.1-1ubuntu5
Distribution: saucy
Urgency: low
Maintainer: Ubuntu Developers <ubuntu-devel-discuss at lists.ubuntu.com>
Changed-By: Dmitrijs Ledkovs <dmitrij.ledkov at ubuntu.com>
Description: 
 login      - system login tools
 passwd     - change and administer password and group data
 uidmap     - programs to help use subuids
Launchpad-Bugs-Fixed: 1192864
Changes: 
 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.
Checksums-Sha1: 
 e7f6421964b27e39f289930e0ca49dd04b5cc196 2369 shadow_4.1.5.1-1ubuntu5.dsc
 02c66b6c33a5baeabdc5ea8190bced578e0f94ef 111787 shadow_4.1.5.1-1ubuntu5.diff.gz
Checksums-Sha256: 
 851a0ecb86ea1d64a01bf597713e6856b934880a9a640bedcf9f31faf6aa46d4 2369 shadow_4.1.5.1-1ubuntu5.dsc
 5076ea2618b81d84c6f234d366e450286fc683a35b6435d895083880cbb5bc59 111787 shadow_4.1.5.1-1ubuntu5.diff.gz
Files: 
 75d8ab92b2813ccaa164de0108416d06 2369 admin required shadow_4.1.5.1-1ubuntu5.dsc
 9b6d4124a0afd0bb9cd0727851c5eeb1 111787 admin required shadow_4.1.5.1-1ubuntu5.diff.gz
Original-Maintainer: Shadow package maintainers <pkg-shadow-devel at lists.alioth.debian.org>
-------------- next part --------------
diff -pruN 1:4.1.5.1-1ubuntu4/debian/changelog 1:4.1.5.1-1ubuntu5/debian/changelog
--- 1:4.1.5.1-1ubuntu4/debian/changelog	2013-06-28 15:36:40.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/changelog	2013-06-28 15:36:39.000000000 +0000
@@ -1,3 +1,19 @@
+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
diff -pruN 1:4.1.5.1-1ubuntu4/debian/control 1:4.1.5.1-1ubuntu5/debian/control
--- 1:4.1.5.1-1ubuntu4/debian/control	2013-06-28 15:36:40.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/control	2013-06-28 15:36:39.000000000 +0000
@@ -34,3 +34,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-1ubuntu4/debian/passwd.install 1:4.1.5.1-1ubuntu5/debian/passwd.install
--- 1:4.1.5.1-1ubuntu4/debian/passwd.install	2013-06-28 15:36:40.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/passwd.install	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/series 1:4.1.5.1-1ubuntu5/debian/patches/series
--- 1:4.1.5.1-1ubuntu4/debian/patches/series	2013-06-28 15:36:40.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/series	2013-06-28 15:36:39.000000000 +0000
@@ -17,4 +17,19 @@
 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
diff -pruN 1:4.1.5.1-1ubuntu4/debian/patches/userns/01_userns_doc 1:4.1.5.1-1ubuntu5/debian/patches/userns/01_userns_doc
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/01_userns_doc	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/01_userns_doc	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/02_userns_doc_login.defs 1:4.1.5.1-1ubuntu5/debian/patches/userns/02_userns_doc_login.defs
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/02_userns_doc_login.defs	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/02_userns_doc_login.defs	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/03_userns_implement_commonio_append 1:4.1.5.1-1ubuntu5/debian/patches/userns/03_userns_implement_commonio_append
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/03_userns_implement_commonio_append	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/03_userns_implement_commonio_append	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/04_userns_add_backend_support 1:4.1.5.1-1ubuntu5/debian/patches/userns/04_userns_add_backend_support
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/04_userns_add_backend_support	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/04_userns_add_backend_support	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/05_userns_implemend_find_new_sub_xids 1:4.1.5.1-1ubuntu5/debian/patches/userns/05_userns_implemend_find_new_sub_xids
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/05_userns_implemend_find_new_sub_xids	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/05_userns_implemend_find_new_sub_xids	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/06_userns_userdel 1:4.1.5.1-1ubuntu5/debian/patches/userns/06_userns_userdel
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/06_userns_userdel	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/06_userns_userdel	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/07_userns_useradd 1:4.1.5.1-1ubuntu5/debian/patches/userns/07_userns_useradd
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/07_userns_useradd	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/07_userns_useradd	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/08_userns_detect_busy_subids 1:4.1.5.1-1ubuntu5/debian/patches/userns/08_userns_detect_busy_subids
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/08_userns_detect_busy_subids	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/08_userns_detect_busy_subids	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/09_userns_usermod 1:4.1.5.1-1ubuntu5/debian/patches/userns/09_userns_usermod
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/09_userns_usermod	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/09_userns_usermod	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/10_userns_newusers 1:4.1.5.1-1ubuntu5/debian/patches/userns/10_userns_newusers
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/10_userns_newusers	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/10_userns_newusers	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/11_userns_newxidmap 1:4.1.5.1-1ubuntu5/debian/patches/userns/11_userns_newxidmap
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/11_userns_newxidmap	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/11_userns_newxidmap	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/12_userns_selinuxlibs 1:4.1.5.1-1ubuntu5/debian/patches/userns/12_userns_selinuxlibs
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/12_userns_selinuxlibs	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/12_userns_selinuxlibs	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/13_subordinate_parse_static_buf 1:4.1.5.1-1ubuntu5/debian/patches/userns/13_subordinate_parse_static_buf
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/13_subordinate_parse_static_buf	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/13_subordinate_parse_static_buf	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/14_fix_getopt 1:4.1.5.1-1ubuntu5/debian/patches/userns/14_fix_getopt
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/14_fix_getopt	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/14_fix_getopt	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/16_add-argument-sanity-checking.patch 1:4.1.5.1-1ubuntu5/debian/patches/userns/16_add-argument-sanity-checking.patch
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/16_add-argument-sanity-checking.patch	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/16_add-argument-sanity-checking.patch	2013-06-28 15:36:39.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-1ubuntu4/debian/patches/userns/manpagetypo 1:4.1.5.1-1ubuntu5/debian/patches/userns/manpagetypo
--- 1:4.1.5.1-1ubuntu4/debian/patches/userns/manpagetypo	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/patches/userns/manpagetypo	2013-06-28 15:36:39.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-1ubuntu4/debian/rules 1:4.1.5.1-1ubuntu5/debian/rules
--- 1:4.1.5.1-1ubuntu4/debian/rules	2013-06-28 15:36:40.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/rules	2013-06-28 15:36:39.000000000 +0000
@@ -42,6 +42,8 @@ binary-install/login::
 	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/subuid debian/login/etc/subuid
+	install -c -m 644 debian/subuid debian/login/etc/subgid
 	install -c -m 644 debian/source_shadow.py debian/login/usr/share/apport/package-hooks/source_shadow.py
 	dh_lintian -p login
 
@@ -75,6 +77,10 @@ endif
 	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-1ubuntu4/debian/subuid 1:4.1.5.1-1ubuntu5/debian/subuid
--- 1:4.1.5.1-1ubuntu4/debian/subuid	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/subuid	2013-06-28 15:36:39.000000000 +0000
@@ -0,0 +1 @@
+# empty default subuid/subgid file
diff -pruN 1:4.1.5.1-1ubuntu4/debian/uidmap.install 1:4.1.5.1-1ubuntu5/debian/uidmap.install
--- 1:4.1.5.1-1ubuntu4/debian/uidmap.install	1970-01-01 00:00:00.000000000 +0000
+++ 1:4.1.5.1-1ubuntu5/debian/uidmap.install	2013-06-28 15:36:39.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