* [PATCH 01/11] Documentation for /etc/subuid and /etc/subgid
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
@ 2013-01-22 9:12 ` Eric W. Biederman
2013-01-22 9:12 ` [PATCH 02/11] login.defs.5: Document the new variables in login.defs Eric W. Biederman
` (16 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:12 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
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
diff --git a/man/Makefile.am b/man/Makefile.am
index b39043e..be7f5e2 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -43,6 +43,8 @@ man_MANS = \
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 @@ man_XMANS = \
sg.1.xml \
su.1.xml \
suauth.5.xml \
+ subgid.5.xml \
+ subuid.5.xml \
useradd.8.xml \
userdel.8.xml \
usermod.8.xml \
diff --git a/man/subgid.5.xml b/man/subgid.5.xml
new file mode 100644
index 0000000..3855319
--- /dev/null
+++ b/man/subgid.5.xml
@@ -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>
diff --git a/man/subuid.5.xml b/man/subuid.5.xml
new file mode 100644
index 0000000..60f139f
--- /dev/null
+++ b/man/subuid.5.xml
@@ -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>
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 02/11] login.defs.5: Document the new variables in login.defs
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-01-22 9:12 ` [PATCH 01/11] Documentation for /etc/subuid and /etc/subgid Eric W. Biederman
@ 2013-01-22 9:12 ` Eric W. Biederman
2013-01-22 9:13 ` [PATCH 03/11] Implement commonio_append Eric W. Biederman
` (15 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:12 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
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
diff --git a/man/Makefile.am b/man/Makefile.am
index be7f5e2..fc617e9 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -163,6 +163,8 @@ login_defs_v = \
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
diff --git a/man/login.defs.5.xml b/man/login.defs.5.xml
index 459b866..d5279ca 100644
--- a/man/login.defs.5.xml
+++ b/man/login.defs.5.xml
@@ -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>
diff --git a/man/login.defs.d/SUB_GID_COUNT.xml b/man/login.defs.d/SUB_GID_COUNT.xml
new file mode 100644
index 0000000..db1a25b
--- /dev/null
+++ b/man/login.defs.d/SUB_GID_COUNT.xml
@@ -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>
diff --git a/man/login.defs.d/SUB_UID_COUNT.xml b/man/login.defs.d/SUB_UID_COUNT.xml
new file mode 100644
index 0000000..bea3b6a
--- /dev/null
+++ b/man/login.defs.d/SUB_UID_COUNT.xml
@@ -0,0 +1,46 @@
+<!--
+ Copyright (c) 2013, Eric W. Biederman
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the copyright holders or contributors may not be used to
+ endorse or promote products derived from this software without
+ specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+<varlistentry>
+ <term><option>SUB_UID_MIN</option> (number)</term>
+ <term><option>SUB_UID_MAX</option> (number)</term>
+ <term><option>SUB_UID_COUNT</option> (number)</term>
+ <listitem>
+ <para>
+ The commands <command>useradd</command> and <command>newusers</command>
+ allocate <option>SUB_UID_COUNT</option> unused user IDs from the range
+ <option>SUB_UID_MIN</option> to <option>SUB_UID_MAX</option> for each
+ new user.
+ </para>
+ <para>
+ The default values for <option>SUB_GID_MAN</option>,
+ <option>SUB_GID_MIN</option>, <option>SUB_GID_COUNT</option>
+ are respectively 100000, 600100000 and 10000.
+ </para>
+ </listitem>
+</varlistentry>
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 03/11] Implement commonio_append.
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-01-22 9:12 ` [PATCH 01/11] Documentation for /etc/subuid and /etc/subgid Eric W. Biederman
2013-01-22 9:12 ` [PATCH 02/11] login.defs.5: Document the new variables in login.defs Eric W. Biederman
@ 2013-01-22 9:13 ` Eric W. Biederman
2013-01-22 9:13 ` Eric W. Biederman
` (14 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:13 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
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-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
lib/commonio.c | 30 ++++++++++++++++++++++++++++++
lib/commonio.h | 1 +
2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/lib/commonio.c b/lib/commonio.c
index 6b6ce7b..7a76975 100644
--- a/lib/commonio.c
+++ b/lib/commonio.c
@@ -1113,6 +1113,36 @@ int commonio_update (struct commonio_db *db, const void *eptr)
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)
{
diff --git a/lib/commonio.h b/lib/commonio.h
index a1117a8..1866b89 100644
--- a/lib/commonio.h
+++ b/lib/commonio.h
@@ -146,6 +146,7 @@ extern int commonio_lock_nowait (struct commonio_db *, bool log);
extern int commonio_open (struct commonio_db *, int);
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
extern int commonio_update (struct commonio_db *, const void *);
+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 *);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 03/11] Implement commonio_append.
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (2 preceding siblings ...)
2013-01-22 9:13 ` [PATCH 03/11] Implement commonio_append Eric W. Biederman
@ 2013-01-22 9:13 ` Eric W. Biederman
2013-01-22 9:14 ` [PATCH 04/11] Add backend support for suboridnate uids and gids Eric W. Biederman
` (13 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:13 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
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-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
lib/commonio.c | 30 ++++++++++++++++++++++++++++++
lib/commonio.h | 1 +
2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/lib/commonio.c b/lib/commonio.c
index 6b6ce7b..7a76975 100644
--- a/lib/commonio.c
+++ b/lib/commonio.c
@@ -1113,6 +1113,36 @@ int commonio_update (struct commonio_db *db, const void *eptr)
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)
{
diff --git a/lib/commonio.h b/lib/commonio.h
index a1117a8..1866b89 100644
--- a/lib/commonio.h
+++ b/lib/commonio.h
@@ -146,6 +146,7 @@ extern int commonio_lock_nowait (struct commonio_db *, bool log);
extern int commonio_open (struct commonio_db *, int);
extern /*@observer@*/ /*@null@*/const void *commonio_locate (struct commonio_db *, const char *);
extern int commonio_update (struct commonio_db *, const void *);
+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 *);
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 04/11] Add backend support for suboridnate uids and gids
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (3 preceding siblings ...)
2013-01-22 9:13 ` Eric W. Biederman
@ 2013-01-22 9:14 ` Eric W. Biederman
[not found] ` <87liblr344.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-01-22 9:15 ` [PATCH 05/11] Implement find_new_sub_uids find_new_sub_gids Eric W. Biederman
` (12 subsequent siblings)
17 siblings, 1 reply; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:14 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
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-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
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
diff --git a/etc/login.defs b/etc/login.defs
index 5b6fab3..01a0089 100644
--- a/etc/login.defs
+++ b/etc/login.defs
@@ -226,6 +226,10 @@ UID_MAX 60000
# System accounts
SYS_UID_MIN 101
SYS_UID_MAX 999
+# Extra per user uids
+SUB_UID_MIN 100000
+SUB_UID_MAX 600100000
+SUB_UID_COUNT 10000
#
# Min/max values for automatic gid selection in groupadd
@@ -235,6 +239,10 @@ GID_MAX 60000
# System accounts
SYS_GID_MIN 101
SYS_GID_MAX 999
+# Extra per user group ids
+SUB_GID_MIN 100000
+SUB_GID_MAX 600100000
+SUB_GID_COUNT 10000
#
# Max number of login retries if password is bad
diff --git a/lib/Makefile.am b/lib/Makefile.am
index c448dd3..6db86cd 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -39,6 +39,8 @@ libshadow_la_SOURCES = \
pwio.c \
pwio.h \
pwmem.c \
+ subordinateio.h \
+ subordinateio.c \
selinux.c \
semanage.c \
sgetgrent.c \
diff --git a/lib/getdef.c b/lib/getdef.c
index ac08163..f872bb3 100644
--- a/lib/getdef.c
+++ b/lib/getdef.c
@@ -81,6 +81,12 @@ static struct itemdef def_table[] = {
{"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},
diff --git a/lib/subordinateio.c b/lib/subordinateio.c
new file mode 100644
index 0000000..851cfa0
--- /dev/null
+++ b/lib/subordinateio.c
@@ -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;
+}
diff --git a/lib/subordinateio.h b/lib/subordinateio.h
new file mode 100644
index 0000000..f27b3c0
--- /dev/null
+++ b/lib/subordinateio.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012- Eric W. Biederman
+ */
+
+#ifndef _SUBORDINATEIO_H
+#define _SUBORDINATEIO_H
+
+#include <sys/types.h>
+
+extern int sub_uid_close(void);
+extern bool is_sub_uid_range_free(uid_t start, unsigned long count);
+extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count);
+extern bool sub_uid_file_present (void);
+extern bool sub_uid_assigned(const char *owner);
+extern int sub_uid_lock (void);
+extern int sub_uid_setdbname (const char *filename);
+extern /*@observer@*/const char *sub_uid_dbname (void);
+extern int sub_uid_open (int mode);
+extern int sub_uid_unlock (void);
+extern int sub_uid_add (const char *owner, uid_t start, unsigned long count);
+extern int sub_uid_remove (const char *owner, uid_t start, unsigned long count);
+extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count);
+
+extern int sub_gid_close(void);
+extern bool is_sub_gid_range_free(gid_t start, unsigned long count);
+extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count);
+extern bool sub_gid_file_present (void);
+extern bool sub_gid_assigned(const char *owner);
+extern int sub_gid_lock (void);
+extern int sub_gid_setdbname (const char *filename);
+extern /*@observer@*/const char *sub_gid_dbname (void);
+extern int sub_gid_open (int mode);
+extern int sub_gid_unlock (void);
+extern int sub_gid_add (const char *owner, gid_t start, unsigned long count);
+extern int sub_gid_remove (const char *owner, gid_t start, unsigned long count);
+extern uid_t sub_gid_find_free_range(gid_t min, gid_t max, unsigned long count);
+
+#endif
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 05/11] Implement find_new_sub_uids find_new_sub_gids
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (4 preceding siblings ...)
2013-01-22 9:14 ` [PATCH 04/11] Add backend support for suboridnate uids and gids Eric W. Biederman
@ 2013-01-22 9:15 ` Eric W. Biederman
2013-01-22 9:16 ` [PATCH 06/11] userdel: Add support for removing subordinate user and group ids Eric W. Biederman
` (11 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:15 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Functions for finding new subordinate uid and gids ranges for use
with useradd.
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
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
diff --git a/lib/prototypes.h b/lib/prototypes.h
index 00d9e0b..487fb07 100644
--- a/lib/prototypes.h
+++ b/lib/prototypes.h
@@ -149,6 +149,15 @@ extern int find_new_uid (bool sys_user,
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);
diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am
index 9da2ec3..5de9193 100644
--- a/libmisc/Makefile.am
+++ b/libmisc/Makefile.am
@@ -25,6 +25,8 @@ libmisc_a_SOURCES = \
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 \
diff --git a/libmisc/find_new_sub_gids.c b/libmisc/find_new_sub_gids.c
new file mode 100644
index 0000000..68046ac
--- /dev/null
+++ b/libmisc/find_new_sub_gids.c
@@ -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;
+}
+
diff --git a/libmisc/find_new_sub_uids.c b/libmisc/find_new_sub_uids.c
new file mode 100644
index 0000000..f1720f9
--- /dev/null
+++ b/libmisc/find_new_sub_uids.c
@@ -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;
+}
+
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 06/11] userdel: Add support for removing subordinate user and group ids.
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (5 preceding siblings ...)
2013-01-22 9:15 ` [PATCH 05/11] Implement find_new_sub_uids find_new_sub_gids Eric W. Biederman
@ 2013-01-22 9:16 ` Eric W. Biederman
2013-01-22 9:17 ` [PATCH 07/11] useradd: Add support for subordinate user identifiers Eric W. Biederman
` (10 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:16 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
src/userdel.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 115 insertions(+), 0 deletions(-)
diff --git a/src/userdel.c b/src/userdel.c
index 4439f62..0c9b83d 100644
--- a/src/userdel.c
+++ b/src/userdel.c
@@ -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_pwd;
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 @@ static void close_files (void)
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 @@ static void fail_exit (int code)
}
}
#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 @@ static void open_files (void)
}
}
#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 @@ static void update_user (void)
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 @@ int main (int argc, char **argv)
#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.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 07/11] useradd: Add support for subordinate user identifiers
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (6 preceding siblings ...)
2013-01-22 9:16 ` [PATCH 06/11] userdel: Add support for removing subordinate user and group ids Eric W. Biederman
@ 2013-01-22 9:17 ` Eric W. Biederman
2013-01-22 9:17 ` [PATCH 08/11] Add support for detecting busy subordinate user ids Eric W. Biederman
` (9 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:17 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
src/useradd.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 140 insertions(+), 1 deletions(-)
diff --git a/src/useradd.c b/src/useradd.c
index bfddfc6..87ba98d 100644
--- a/src/useradd.c
+++ b/src/useradd.c
@@ -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_pwd;
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 @@ static bool home_added = false;
#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 @@ static void fail_exit (int code)
}
}
#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,
@@ -1378,6 +1415,18 @@ static void close_files (void)
}
#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 ());
@@ -1432,6 +1481,34 @@ static void close_files (void)
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;
+ }
}
/*
@@ -1486,6 +1563,36 @@ static void open_files (void)
}
}
#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)
@@ -1732,13 +1839,27 @@ static void usr_update (void)
#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.
*/
@@ -1884,6 +2005,8 @@ int main (int argc, char **argv)
#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 ();
@@ -2034,6 +2157,22 @@ int main (int argc, char **argv)
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) {
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 08/11] Add support for detecting busy subordinate user ids
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (7 preceding siblings ...)
2013-01-22 9:17 ` [PATCH 07/11] useradd: Add support for subordinate user identifiers Eric W. Biederman
@ 2013-01-22 9:17 ` Eric W. Biederman
2013-01-22 9:18 ` [PATCH 09/11] usermod: Add support for subordinate uids and gids Eric W. Biederman
` (8 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:17 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
libmisc/user_busy.c | 18 +++++++++++++-----
1 files changed, 13 insertions(+), 5 deletions(-)
diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c
index 168f9d5..04cfc31 100644
--- a/libmisc/user_busy.c
+++ b/libmisc/user_busy.c
@@ -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 @@ static int user_busy_utmp (const char *name)
#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 @@ static int check_status (const char *sname, uid_t uid)
&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 @@ static int user_busy_processes (const char *name, uid_t uid)
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 @@ static int user_busy_processes (const char *name, uid_t uid)
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 @@ static int user_busy_processes (const char *name, uid_t uid)
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 @@ static int user_busy_processes (const char *name, uid_t uid)
}
(void) closedir (proc);
+ sub_uid_close();
return 0;
}
#endif /* __linux__ */
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 09/11] usermod: Add support for subordinate uids and gids.
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (8 preceding siblings ...)
2013-01-22 9:17 ` [PATCH 08/11] Add support for detecting busy subordinate user ids Eric W. Biederman
@ 2013-01-22 9:18 ` Eric W. Biederman
2013-01-22 9:19 ` [PATCH 10/11] newusers: Add support for assiging " Eric W. Biederman
` (7 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:18 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
man/usermod.8.xml | 80 +++++++++++++++++
src/usermod.c | 255 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 332 insertions(+), 3 deletions(-)
diff --git a/man/usermod.8.xml b/man/usermod.8.xml
index 322d181..0a23416 100644
--- a/man/usermod.8.xml
+++ b/man/usermod.8.xml
@@ -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>
diff --git a/src/usermod.c b/src/usermod.c
index e411a32..448eed0 100644
--- a/src/usermod.c
+++ b/src/usermod.c
@@ -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 @@ static bool
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_pwd;
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 @@ static int get_groups (char *list)
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 @@ static /*@noreturn@*/void usage (int status)
(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 @@ static /*@noreturn@*/void fail_exit (int code)
/* 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 @@ static void process_flags (int argc, char **argv)
{"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 @@ static void process_flags (int argc, char **argv)
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 @@ static void process_flags (int argc, char **argv)
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 @@ static void process_flags (int argc, char **argv)
Prog, (unsigned long) user_newid);
exit (E_UID_IN_USE);
}
+
}
/*
@@ -1248,6 +1382,10 @@ static void close_files (void)
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 @@ static void close_files (void)
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 @@ static void open_files (void)
}
#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 @@ static void usr_update (void)
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 @@ int main (int argc, char **argv)
#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 @@ int main (int argc, char **argv)
* 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 @@ int main (int argc, char **argv)
*/
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) {
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 10/11] newusers: Add support for assiging subordinate uids and gids.
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (9 preceding siblings ...)
2013-01-22 9:18 ` [PATCH 09/11] usermod: Add support for subordinate uids and gids Eric W. Biederman
@ 2013-01-22 9:19 ` Eric W. Biederman
2013-01-22 9:20 ` [PATCH 11/11] newuidmap, newgidmap: New suid helpers for using " Eric W. Biederman
` (6 subsequent siblings)
17 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:19 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
src/newusers.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 124 insertions(+), 0 deletions(-)
diff --git a/src/newusers.c b/src/newusers.c
index c25f40e..e5e832c 100644
--- a/src/newusers.c
+++ b/src/newusers.c
@@ -65,6 +65,7 @@
#include "pwio.h"
#include "sgroupio.h"
#include "shadowio.h"
+#include "subordinateio.h"
#include "chkname.h"
/*
@@ -82,6 +83,8 @@ static long sha_rounds = 5000;
#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 sgr_locked = 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;
/* local function prototypes */
static void usage (int status);
@@ -178,6 +183,20 @@ static void fail_exit (int code)
}
}
#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 @@ static void open_files (void)
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 @@ static void open_files (void)
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 @@ static void close_files (void)
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 @@ static void close_files (void)
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 @@ int main (int argc, char **argv)
#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 @@ int main (int argc, char **argv)
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++;
+ }
+ }
}
/*
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* [PATCH 11/11] newuidmap, newgidmap: New suid helpers for using subordinate uids and gids
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (10 preceding siblings ...)
2013-01-22 9:19 ` [PATCH 10/11] newusers: Add support for assiging " Eric W. Biederman
@ 2013-01-22 9:20 ` Eric W. Biederman
[not found] ` <87ehhdpoag.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
2013-01-29 18:15 ` [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces Rob Landley
` (5 subsequent siblings)
17 siblings, 1 reply; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-22 9:20 UTC (permalink / raw)
To: Nicolas François
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages)
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
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
diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am
index 5de9193..76f3c05 100644
--- a/libmisc/Makefile.am
+++ b/libmisc/Makefile.am
@@ -32,6 +32,8 @@ libmisc_a_SOURCES = \
getgr_nam_gid.c \
getrange.c \
hushed.c \
+ idmapping.h \
+ idmapping.c \
isexpired.c \
limits.c \
list.c log.c \
diff --git a/libmisc/idmapping.c b/libmisc/idmapping.c
new file mode 100644
index 0000000..cb9e898
--- /dev/null
+++ b/libmisc/idmapping.c
@@ -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);
+}
diff --git a/libmisc/idmapping.h b/libmisc/idmapping.h
new file mode 100644
index 0000000..88cf761
--- /dev/null
+++ b/libmisc/idmapping.h
@@ -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_ */
+
diff --git a/man/Makefile.am b/man/Makefile.am
index fc617e9..b50ca41 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -30,7 +30,9 @@ man_MANS = \
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 @@ man_XMANS = \
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 \
diff --git a/man/newgidmap.1.xml b/man/newgidmap.1.xml
new file mode 100644
index 0000000..424a480
--- /dev/null
+++ b/man/newgidmap.1.xml
@@ -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>
diff --git a/man/newuidmap.1.xml b/man/newuidmap.1.xml
new file mode 100644
index 0000000..c6687ea
--- /dev/null
+++ b/man/newuidmap.1.xml
@@ -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>
diff --git a/src/Makefile.am b/src/Makefile.am
index 88cae99..1390cae 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,7 +24,8 @@ INCLUDES = \
bin_PROGRAMS = groups login su
sbin_PROGRAMS = nologin
-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 = \
chgpasswd \
chpasswd \
@@ -49,7 +50,7 @@ usbin_PROGRAMS = \
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
diff --git a/src/newgidmap.c b/src/newgidmap.c
new file mode 100644
index 0000000..1527a61
--- /dev/null
+++ b/src/newgidmap.c
@@ -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;
+}
diff --git a/src/newuidmap.c b/src/newuidmap.c
new file mode 100644
index 0000000..69c5094
--- /dev/null
+++ b/src/newuidmap.c
@@ -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;
+}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (11 preceding siblings ...)
2013-01-22 9:20 ` [PATCH 11/11] newuidmap, newgidmap: New suid helpers for using " Eric W. Biederman
@ 2013-01-29 18:15 ` Rob Landley
2013-01-29 22:28 ` Eric W. Biederman
2013-01-30 5:35 ` Vasily Kulikov
` (4 subsequent siblings)
17 siblings, 1 reply; 59+ messages in thread
From: Rob Landley @ 2013-01-29 18:15 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
I am waaaay behind on email.
On 01/22/2013 03:11:19 AM, Eric W. Biederman wrote:
>
> The kernel support for user namespaces allows ordinary users to use
> multiple uids and gids if they can get a trusted program to tell the
> kernel the set of subordinate uids and gids they are allowed to use.
Could you give an example of this? (If this takes off I'll probably
want to add support to toybox, but from the man pages I don't
understand what it's for.)
> This is my work to make that trusted program.
> Two new files are added /etc/subuid /etc/subgid that specify
> ranges of uids and gids that users may uses.
They must use a contiguous range with count, not
"landley:4000-4999,6103,7002-7005"?
> useradd, and newusers are modifed to add users to those files.
> userdel is modeifed to remove users from those files.
> usermod is modified to give manual control of what goes in those
> files.
> newuidmap and newgidmap read the new files and update
> /proc/[pid]/uid_map and /proc/[pid]/gid_map respectively
> as requested by their command line parameters and as allowed
> by the /etc/subuid and /etc/subgid.
I'm not finding uid_map and gid_map in
Documentation/filesystems/proc.txt, is this a pending patch?
Rob
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
2013-01-29 18:15 ` [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces Rob Landley
@ 2013-01-29 22:28 ` Eric W. Biederman
0 siblings, 0 replies; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-29 22:28 UTC (permalink / raw)
To: Rob Landley
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
Rob Landley <rob-VoJi6FS/r0vR7s880joybQ@public.gmane.org> writes:
> I am waaaay behind on email.
>
> On 01/22/2013 03:11:19 AM, Eric W. Biederman wrote:
>>
>> The kernel support for user namespaces allows ordinary users to use
>> multiple uids and gids if they can get a trusted program to tell the
>> kernel the set of subordinate uids and gids they are allowed to use.
>
> Could you give an example of this? (If this takes off I'll probably
> want to add support to toybox, but from the man pages I don't
> understand what it's for.)
The interesting programs for me are useradd, userdel, which I don't
think toybox plays with and newuidmap and newgidmap.
The primary application is running unprivileged containers with user
namespaces. A user namespace allows setuid and setgid in between
uids and gids that are mapped for that user namespace.
/proc/<pid>/uid_map gives the mapping from uids in the user namespace
to uids on the host system. The format is multiple lines of the form:
<userns_uid> <system_uid> <count>
/proc/<pid>/gid_map has the same format excpet for gids.
/etc/subuid and /etc/subgid list the extra system uids that we will
allow a user to use in the context of user namespaces.
The idea is that unshare or clone will be used to create a new process
and then wait while another process of the same user outside of the
user namespace will call newuidmap and newgidmap to write to set the
mappings.
I have appened a trivial command line example of using newuidmap and
newgidmap and unshare.
Without privileged helper programs people are limited to using their
own uid as the underlying uid in a user-namespace which seriously
limits what kind of systems you can run in a container.
>> This is my work to make that trusted program.
>> Two new files are added /etc/subuid /etc/subgid that specify
>> ranges of uids and gids that users may uses.
>
> They must use a contiguous range with count, not
> "landley:4000-4999,6103,7002-7005"?
No. Although I can see the argument for that format.
Using multiple ranges per line is harder to parse, harder to ensure
that you properly handle arbitarily long lines, and harder to tell
if the last number in the range is included or not. And I have been
burnt badly by implementations having arbitrarly short line limits in
/etc/group.
So to encode your example it would be:
landley:4000:1000
landley:6103:1
landley:7002:4
As I allow multiple lines for the same user.
In practice I only expect there will need to be a single line per user
in most instances as a single range should be enough for most uses.
Also a contiguous range is important for sanity so a sysadmin can look
at a set of uids and easily recognize they all belong to fred, and even
more important when working with /proc/<pid>/uid_map as the kernel
currently only supports 5 uid mapping ranges.
>> useradd, and newusers are modifed to add users to those files.
>> userdel is modeifed to remove users from those files.
>> usermod is modified to give manual control of what goes in those
>> files.
>
>> newuidmap and newgidmap read the new files and update
>> /proc/[pid]/uid_map and /proc/[pid]/gid_map respectively
>> as requested by their command line parameters and as allowed
>> by the /etc/subuid and /etc/subgid.
>
> I'm not finding uid_map and gid_map in
> Documentation/filesystems/proc.txt, is this a pending patch?
Interesting. I hadn't even registered on the existence of
Documentation/filesystems/proc.txt.
I have sent out man page patches to document or at least start
documenting uid_map and gid_map. But having just done a git update
it looks like Michael hasn't pushed those changes out in the man-pages
git tree yet. :( He may be waiting until 3.8 goes final.
Eric
----
#!/bin/bash
set -x
set -e
export IFIFO=/tmp/shadow-test-$$-in
export OFIFO=/tmp/shadow-test-$$-out
rm -f $IFIFO $OFIFO
mkfifo $IFIFO
mkfifo $OFIFO
unshare --user /bin/bash <<'EOF' &
echo waiting-for-uid-and-gid-maps > $OFIFO
read LINE < $IFIFO
$SHELL -l -i < /dev/tty > /dev/tty 2> /dev/tty
EOF
child=$!
read LINE < $OFIFO
uid=$(id --user)
gid=$(id --group)
newuidmap $child 0 $uid 1 1 100000 9999 65534 109999 1
newgidmap $child 0 $gid 1 1 100000 9999 65534 109999 1
echo uid-and-gid-maps > $IFIFO
wait $child
rm -f $IFIFO $OFIFO
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (12 preceding siblings ...)
2013-01-29 18:15 ` [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces Rob Landley
@ 2013-01-30 5:35 ` Vasily Kulikov
2013-01-30 6:40 ` Eric W. Biederman
2013-02-22 12:16 ` Glauber Costa
` (3 subsequent siblings)
17 siblings, 1 reply; 59+ messages in thread
From: Vasily Kulikov @ 2013-01-30 5:35 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
Hi Eric,
On Tue, Jan 22, 2013 at 01:11 -0800, Eric W. Biederman wrote:
> The kernel support for user namespaces allows ordinary users to use
> multiple uids and gids if they can get a trusted program to tell the
> kernel the set of subordinate uids and gids they are allowed to use.
>
> This is my work to make that trusted program.
> Two new files are added /etc/subuid /etc/subgid that specify
> ranges of uids and gids that users may uses.
>
> useradd, and newusers are modifed to add users to those files.
>
> userdel is modeifed to remove users from those files.
>
> usermod is modified to give manual control of what goes in those files.
>
> newuidmap and newgidmap read the new files and update
> /proc/[pid]/uid_map and /proc/[pid]/gid_map respectively
> as requested by their command line parameters and as allowed
> by the /etc/subuid and /etc/subgid.
>
> The following patches are against the current developent trunk
> of pkg-shadow svn rev 3745. With minor tweaking of man/Makefile.am
> these patches also apply to shadow 4.1.5.
Why patch shadow tools? Why not implement the feature as a PAM module?
All other capabilities granting things are implemented as PAM modules:
pam_group, pam_namespace, pam_cap. I don't see why it cannot be fully
modularized, a common admin doesn't need multiple uid/gid user_ns for
non-root users at all, why patch basic tools?
Thanks,
--
Vasily Kulikov
http://www.openwall.com - bringing security into open computing environments
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
2013-01-30 5:35 ` Vasily Kulikov
@ 2013-01-30 6:40 ` Eric W. Biederman
[not found] ` <87vcafyy0k.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
0 siblings, 1 reply; 59+ messages in thread
From: Eric W. Biederman @ 2013-01-30 6:40 UTC (permalink / raw)
To: Vasily Kulikov
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
Vasily Kulikov <segoon-cxoSlKxDwOJWk0Htik3J/w@public.gmane.org> writes:
> Hi Eric,
>
> On Tue, Jan 22, 2013 at 01:11 -0800, Eric W. Biederman wrote:
>> The kernel support for user namespaces allows ordinary users to use
>> multiple uids and gids if they can get a trusted program to tell the
>> kernel the set of subordinate uids and gids they are allowed to use.
>>
>> This is my work to make that trusted program.
>> Two new files are added /etc/subuid /etc/subgid that specify
>> ranges of uids and gids that users may uses.
>>
>> useradd, and newusers are modifed to add users to those files.
>>
>> userdel is modeifed to remove users from those files.
>>
>> usermod is modified to give manual control of what goes in those files.
>>
>> newuidmap and newgidmap read the new files and update
>> /proc/[pid]/uid_map and /proc/[pid]/gid_map respectively
>> as requested by their command line parameters and as allowed
>> by the /etc/subuid and /etc/subgid.
>>
>> The following patches are against the current developent trunk
>> of pkg-shadow svn rev 3745. With minor tweaking of man/Makefile.am
>> these patches also apply to shadow 4.1.5.
>
> Why patch shadow tools? Why not implement the feature as a PAM
> module?
I need hooks into useradd and userdel to managed the subordinate
user ids and group ids when users are added and removed from the
system. PAM doesn't appear to have any hooks like that at all.
Furthermore shadow-utils is where other uids and gids are allocated
and it makes sense to keep the allocation functions together so if it
makes sense they can talk to each other
> All other capabilities granting things are implemented as PAM modules:
> pam_group, pam_namespace, pam_cap.
Except when you want to program the mapping is not at login time.
Programming the mapping needs to happen when a user namespace is set up.
The admin of the user namespace knows which uids and gids will be used
in that user namespace. The system is configured to know which uids
and gids that user can map to.
> I don't see why it cannot be fully
> modularized, a common admin doesn't need multiple uid/gid user_ns for
> non-root users at all, why patch basic tools?
The common admin doesn't _yet_ need multiple uid/gid user_ns for
non-root users.
As of linux 3.8 you don't need any special privilege to create a user
namespace. Once you have a user namespace you can create other
namespaces. This is good for building containers for light weigh
virtualization and testing and this is good for sandboxing subprocess.
The chrome-browser sandbox uses a setuid application to set a up
namespaces for this purpose.
A couple of extra uids should make the sandboxing uses much more
complete. Not to mention the advantages of being able to run another
distro in a lighter more portable form than hardware virtualization.
Given the habit of the distributions of enabling everything possible I
believe it will become common for distributions to allocate multiple
uids and gids to users by default.
Eric
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (13 preceding siblings ...)
2013-01-30 5:35 ` Vasily Kulikov
@ 2013-02-22 12:16 ` Glauber Costa
[not found] ` <51276189.5040803-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
2013-03-03 15:37 ` Serge E. Hallyn
` (2 subsequent siblings)
17 siblings, 1 reply; 59+ messages in thread
From: Glauber Costa @ 2013-02-22 12:16 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
On 01/22/2013 01:11 PM, Eric W. Biederman wrote:
>
> The kernel support for user namespaces allows ordinary users to use
> multiple uids and gids if they can get a trusted program to tell the
> kernel the set of subordinate uids and gids they are allowed to use.
>
> This is my work to make that trusted program.
> Two new files are added /etc/subuid /etc/subgid that specify
> ranges of uids and gids that users may uses.
>
> useradd, and newusers are modifed to add users to those files.
>
> userdel is modeifed to remove users from those files.
>
> usermod is modified to give manual control of what goes in those files.
>
> newuidmap and newgidmap read the new files and update
> /proc/[pid]/uid_map and /proc/[pid]/gid_map respectively
> as requested by their command line parameters and as allowed
> by the /etc/subuid and /etc/subgid.
>
> The following patches are against the current developent trunk
> of pkg-shadow svn rev 3745. With minor tweaking of man/Makefile.am
> these patches also apply to shadow 4.1.5.
>
> Eric W. Biederman (11):
> Documentation for /etc/subuid and /etc/subgid
> login.defs.5: Document the new variables in login.defs
> Implement commonio_append.
> Add backend support for suboridnate uids and gids
> Implement find_new_sub_uids find_new_sub_gids
> userdel: Add support for removing subordinate user and group ids.
> useradd: Add support for subordinate user identifiers
> Add support for detecting busy subordinate user ids
> usermod: Add support for subordinate uids and gids.
> newusers: Add support for assiging subordinate uids and gids.
> newuidmap,newgidmap: New suid helpers for using subordinate uids and gids
Hi,
Is there any intention to merge this (or any later version thereof) ?
I intend to start excluding uid ranges for containers usage in OpenVZ,
and support for that in tooling would come in handy.
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (14 preceding siblings ...)
2013-02-22 12:16 ` Glauber Costa
@ 2013-03-03 15:37 ` Serge E. Hallyn
2013-03-07 15:23 ` Dwight Engen
2013-07-28 17:14 ` [Pkg-shadow-devel] " Christian PERRIER
17 siblings, 0 replies; 59+ messages in thread
From: Serge E. Hallyn @ 2013-03-03 15:37 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
Hi Nekral,
This isn't a great urgency, but the final userns kernel support needed
for this patchset to be useful should land in 3.9, so it isn't that
far off. Do you have any objections to/feedback on this set? Would
this be possible to get into Debian?
thanks,
-serge
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (15 preceding siblings ...)
2013-03-03 15:37 ` Serge E. Hallyn
@ 2013-03-07 15:23 ` Dwight Engen
2013-07-28 17:14 ` [Pkg-shadow-devel] " Christian PERRIER
17 siblings, 0 replies; 59+ messages in thread
From: Dwight Engen @ 2013-03-07 15:23 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
Hi Eric, here are some minor fixups to your patch set. I think the
NOTE section is left over from chsh, and doesn't apply here.
diff -ur shadow-4.1.5.1.orig/man/newgidmap.1.xml shadow-4.1.5.1/man/newgidmap.1.xml
--- shadow-4.1.5.1.orig/man/newgidmap.1.xml 2013-03-06 16:20:53.873175769 -0500
+++ shadow-4.1.5.1/man/newgidmap.1.xml 2013-03-06 16:52:46.327142067 -0500
@@ -98,21 +98,6 @@
</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>
diff -ur shadow-4.1.5.1.orig/man/newuidmap.1.xml shadow-4.1.5.1/man/newuidmap.1.xml
--- shadow-4.1.5.1.orig/man/newuidmap.1.xml 2013-03-06 16:20:53.873175769 -0500
+++ shadow-4.1.5.1/man/newuidmap.1.xml 2013-03-06 16:52:46.327142067 -0500
@@ -95,21 +95,6 @@
</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>
diff -ur shadow-4.1.5.1.orig/man/subgid.5.xml shadow-4.1.5.1/man/subgid.5.xml
--- shadow-4.1.5.1.orig/man/subgid.5.xml 2013-03-06 16:20:53.861175769 -0500
+++ shadow-4.1.5.1/man/subgid.5.xml 2013-03-06 16:52:46.327142067 -0500
@@ -48,7 +48,7 @@
<title>DESCRIPTION</title>
<para>
Each line in <filename>/etc/subgid</filename> contains
- a user id and a range of suboridinate user ids that user
+ a user name and a range of suboridinate group ids that user
is allowed to use.
This is specified with three fields delimited by colons
@@ -60,21 +60,21 @@
<para>login name</para>
</listitem>
<listitem>
- <para>numerical subordinate user ID</para>
+ <para>numerical subordinate group ID</para>
</listitem>
<listitem>
- <para>numerical subordinate user ID count</para>
+ <para>numerical subordinate group 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
+ This file specifies the group IDs that ordinary users may use
+ with the <command>newgidmap</command> command to
configure gid mapping in a user namespace.
</para>
<para>
- Multiple ranges may be specified per user ID.
+ Multiple ranges may be specified per user.
</para>
</refsect1>
diff -ur shadow-4.1.5.1.orig/man/subuid.5.xml shadow-4.1.5.1/man/subuid.5.xml
--- shadow-4.1.5.1.orig/man/subuid.5.xml 2013-03-06 16:20:53.862175769 -0500
+++ shadow-4.1.5.1/man/subuid.5.xml 2013-03-06 16:52:46.328142067 -0500
@@ -48,7 +48,7 @@
<title>DESCRIPTION</title>
<para>
Each line in <filename>/etc/subuid</filename> contains
- a user id and a range of suboridinate user ids that user
+ a user name and a range of suboridinate user ids that user
is allowed to use.
This is specified with three fields delimited by colons
@@ -68,13 +68,13 @@
</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
+ This file specifies the user IDs that ordinary users may use
+ with the <command>newuidmap</command> command to
configure uid mapping in a user namespace.
</para>
<para>
- Multiple ranges may be specified per user ID.
+ Multiple ranges may be specified per user.
</para>
</refsect1>
diff -ur shadow-4.1.5.1.orig/src/usermod.c shadow-4.1.5.1/src/usermod.c
--- shadow-4.1.5.1.orig/src/usermod.c 2013-03-06 16:20:53.872175769 -0500
+++ shadow-4.1.5.1/src/usermod.c 2013-03-06 16:53:17.560141517 -0500
@@ -410,9 +410,9 @@
(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 (_(" -V, --del-subuids FIRST-LAST remove 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);
+ (void) fputs (_(" -W, --del-subgids FIRST-LAST remove 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 */
@@ -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:Uv:V:w:W:Z:",
#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:V:w:W:",
#endif /* !WITH_SELINUX */
long_options, NULL)) != -1) {
switch (c) {
^ permalink raw reply [flat|nested] 59+ messages in thread
* Re: [Pkg-shadow-devel] [PATCH 00/11] pkg-shadow support subordinate ids with user namespaces
[not found] ` <87d2wxshu0.fsf-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
` (16 preceding siblings ...)
2013-03-07 15:23 ` Dwight Engen
@ 2013-07-28 17:14 ` Christian PERRIER
[not found] ` <20130728171451.GX5670-FvNwPcshoeM/MCprI7ZU+I/wHUNs+SP4HZ5vskTnxNA@public.gmane.org>
17 siblings, 1 reply; 59+ messages in thread
From: Christian PERRIER @ 2013-07-28 17:14 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux Containers,
Pkg-shadow-devel-XbBxUvOt3X2LieD7tvxI8l/i77bcL1HB,
Michael Kerrisk (man-pages),
Nicolas François
[-- Attachment #1.1: Type: text/plain, Size: 2516 bytes --]
Quoting Eric W. Biederman (ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org):
>
> The kernel support for user namespaces allows ordinary users to use
> multiple uids and gids if they can get a trusted program to tell the
> kernel the set of subordinate uids and gids they are allowed to use.
>
> This is my work to make that trusted program.
> Two new files are added /etc/subuid /etc/subgid that specify
> ranges of uids and gids that users may uses.
>
> useradd, and newusers are modifed to add users to those files.
>
> userdel is modeifed to remove users from those files.
>
> usermod is modified to give manual control of what goes in those files.
>
> newuidmap and newgidmap read the new files and update
> /proc/[pid]/uid_map and /proc/[pid]/gid_map respectively
> as requested by their command line parameters and as allowed
> by the /etc/subuid and /etc/subgid.
>
> The following patches are against the current developent trunk
> of pkg-shadow svn rev 3745. With minor tweaking of man/Makefile.am
> these patches also apply to shadow 4.1.5.
>
> Eric W. Biederman (11):
> Documentation for /etc/subuid and /etc/subgid
> login.defs.5: Document the new variables in login.defs
> Implement commonio_append.
> Add backend support for suboridnate uids and gids
> Implement find_new_sub_uids find_new_sub_gids
> userdel: Add support for removing subordinate user and group ids.
> useradd: Add support for subordinate user identifiers
> Add support for detecting busy subordinate user ids
> usermod: Add support for subordinate uids and gids.
> newusers: Add support for assiging subordinate uids and gids.
> newuidmap,newgidmap: New suid helpers for using subordinate uids and gids
> ---
OK, now we're ready for this.
Eric, I have no skills to decide whether your patches can be included
or not. My proposal is to go ahead and include them in the upcomign
4.2 release, that will be compiled and uploaded in Debian as soon as
released, so that it gets extensive testing.
We now have an "upstream" git repository at
http://github.com/shadow-maint/shadow.git
Would you mind pushing your set of patches there?
That requires an account on github and include you in the project
members (Serge Hallyn can do that).
I would prefer this over committing/pushing myself.
I really apologize for the too long delay working on this. We now need
to revive shadow's development.
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
[-- Attachment #2: Type: text/plain, Size: 205 bytes --]
_______________________________________________
Containers mailing list
Containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
https://lists.linuxfoundation.org/mailman/listinfo/containers
^ permalink raw reply [flat|nested] 59+ messages in thread