1
From ebiederm@xmission.com Tue Jan 22 09:22:07 2013
2
Return-Path: <ebiederm@xmission.com>
3
X-Original-To: serge@hallyn.com
4
Delivered-To: serge@hallyn.com
5
Received: by mail.hallyn.com (Postfix, from userid 5001)
6
id E5D16C80F4; Tue, 22 Jan 2013 09:22:07 +0000 (UTC)
7
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail
9
X-Spam-Status: No, score=-0.2 required=8.0 tests=BAD_ENC_HEADER,BAYES_00,
10
LONGWORDS,RCVD_IN_DNSWL_MED autolearn=no version=3.3.1
11
Received: from out02.mta.xmission.com (out02.mta.xmission.com [166.70.13.232])
12
(using TLSv1 with cipher AES256-SHA (256/256 bits))
13
(No client certificate requested)
14
by mail.hallyn.com (Postfix) with ESMTPS id 2E206C80D1
15
for <serge@hallyn.com>; Tue, 22 Jan 2013 09:22:03 +0000 (UTC)
16
Received: from in02.mta.xmission.com ([166.70.13.52])
17
by out02.mta.xmission.com with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32)
19
(envelope-from <ebiederm@xmission.com>)
20
id 1Txa1k-0000xE-Ix; Tue, 22 Jan 2013 02:20:20 -0700
21
Received: from c-98-207-153-68.hsd1.ca.comcast.net ([98.207.153.68] helo=eric-ThinkPad-X220.xmission.com)
22
by in02.mta.xmission.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16)
24
(envelope-from <ebiederm@xmission.com>)
25
id 1Txa1b-00059T-Lu; Tue, 22 Jan 2013 02:20:20 -0700
26
From: ebiederm@xmission.com (Eric W. Biederman)
27
To: Nicolas =?utf-8?Q?Fran=C3=A7ois?= <nicolas.francois@centraliens.net>
28
Cc: <Pkg-shadow-devel@lists.alioth.debian.org>, Linux Containers <containers@lists.linux-foundation.org>, "Michael Kerrisk \(man-pages\)" <mtk.manpages@gmail.com>, "Serge E. Hallyn" <serge@hallyn.com>
29
References: <87d2wxshu0.fsf@xmission.com>
30
Date: Tue, 22 Jan 2013 01:20:07 -0800
31
In-Reply-To: <87d2wxshu0.fsf@xmission.com> (Eric W. Biederman's message of
32
"Tue, 22 Jan 2013 01:11:19 -0800")
33
Message-ID: <87ehhdpoag.fsf@xmission.com>
34
User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)
36
Content-Type: text/plain
37
X-XM-AID: U2FsdGVkX1/nox3f5bDq7zL9eOiGra/HoCkv7o07HDs=
38
X-SA-Exim-Connect-IP: 98.207.153.68
39
X-SA-Exim-Mail-From: ebiederm@xmission.com
40
Subject: [PATCH 11/11] newuidmap,newgidmap: New suid helpers for using subordinate uids and gids
41
X-SA-Exim-Version: 4.2.1 (built Wed, 14 Nov 2012 14:26:46 -0700)
42
X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com)
49
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
51
libmisc/Makefile.am | 2 +
52
libmisc/idmapping.c | 126 +++++++++++++++++++++++++++++++++++
53
libmisc/idmapping.h | 44 ++++++++++++
55
man/newgidmap.1.xml | 157 +++++++++++++++++++++++++++++++++++++++++++
56
man/newuidmap.1.xml | 154 +++++++++++++++++++++++++++++++++++++++++++
57
src/Makefile.am | 5 +-
58
src/newgidmap.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++
59
src/newuidmap.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++
60
9 files changed, 856 insertions(+), 2 deletions(-)
61
create mode 100644 libmisc/idmapping.c
62
create mode 100644 libmisc/idmapping.h
63
create mode 100644 man/newgidmap.1.xml
64
create mode 100644 man/newuidmap.1.xml
65
create mode 100644 src/newgidmap.c
66
create mode 100644 src/newuidmap.c
68
Index: shadow/libmisc/Makefile.am
69
===================================================================
70
--- shadow.orig/libmisc/Makefile.am 2013-02-01 15:27:53.836080342 -0600
71
+++ shadow/libmisc/Makefile.am 2013-02-01 15:27:53.828080343 -0600
81
Index: shadow/libmisc/idmapping.c
82
===================================================================
83
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
84
+++ shadow/libmisc/idmapping.c 2013-02-01 15:27:53.828080343 -0600
87
+ * Copyright (c) 2013 Eric Biederman
88
+ * All rights reserved.
90
+ * Redistribution and use in source and binary forms, with or without
91
+ * modification, are permitted provided that the following conditions
93
+ * 1. Redistributions of source code must retain the above copyright
94
+ * notice, this list of conditions and the following disclaimer.
95
+ * 2. Redistributions in binary form must reproduce the above copyright
96
+ * notice, this list of conditions and the following disclaimer in the
97
+ * documentation and/or other materials provided with the distribution.
98
+ * 3. The name of the copyright holders or contributors may not be used to
99
+ * endorse or promote products derived from this software without
100
+ * specific prior written permission.
102
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
103
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
104
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
105
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
106
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
107
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
108
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
109
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
110
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
111
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
112
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
116
+#include <sys/types.h>
117
+#include <sys/stat.h>
121
+#include "prototypes.h"
122
+#include "idmapping.h"
124
+struct map_range *get_map_ranges(int ranges, int argc, char **argv)
126
+ struct map_range *mappings, *mapping;
129
+ if ((ranges * 3) > argc) {
130
+ fprintf(stderr, "ranges: %u argc: %d\n",
133
+ _( "%s: Not enough arguments to form %u mappings\n"),
138
+ mappings = calloc(ranges, sizeof(*mappings));
140
+ fprintf(stderr, _( "%s: Memory allocation failure\n"),
142
+ exit(EXIT_FAILURE);
145
+ /* Gather up the ranges from the command line */
146
+ mapping = mappings;
147
+ for (idx = 0; idx < ranges; idx++, argidx += 3, mapping++) {
148
+ if (!getulong(argv[argidx + 0], &mapping->upper))
150
+ if (!getulong(argv[argidx + 1], &mapping->lower))
152
+ if (!getulong(argv[argidx + 2], &mapping->count))
158
+/* Number of ascii digits needed to print any unsigned long in decimal.
159
+ * There are approximately 10 bits for every 3 decimal digits.
160
+ * So from bits to digits the formula is roundup((Number of bits)/10) * 3.
161
+ * For common sizes of integers this works out to:
162
+ * 2bytes --> 6 ascii estimate -> 65536 (5 real)
163
+ * 4bytes --> 12 ascii estimated -> 4294967296 (10 real)
164
+ * 8bytes --> 21 ascii estimated -> 18446744073709551616 (20 real)
165
+ * 16bytes --> 39 ascii estimated -> 340282366920938463463374607431768211456 (39 real)
167
+#define ULONG_DIGITS ((((sizeof(unsigned long) * CHAR_BIT) + 9)/10)*3)
170
+void write_mapping(int proc_dir_fd, int ranges, struct map_range *mappings,
171
+ const char *map_file)
174
+ struct map_range *mapping;
179
+ bufsize = ranges * ((ULONG_DIGITS + 1) * 3);
180
+ pos = buf = xmalloc(bufsize);
182
+ /* Build the mapping command */
183
+ mapping = mappings;
184
+ for (idx = 0; idx < ranges; idx++, mapping++) {
185
+ /* Append this range to the string that will be written */
186
+ int written = snprintf(pos, bufsize - (pos - buf),
191
+ if ((written <= 0) || (written >= (bufsize - (pos - buf)))) {
192
+ fprintf(stderr, _("%s: snprintf failed!\n"), Prog);
193
+ exit(EXIT_FAILURE);
198
+ /* Write the mapping to the maping file */
199
+ fd = openat(proc_dir_fd, map_file, O_WRONLY);
201
+ fprintf(stderr, _("%s: open of %s failed: %s\n"),
202
+ Prog, map_file, strerror(errno));
203
+ exit(EXIT_FAILURE);
205
+ if (write(fd, buf, pos - buf) != (pos - buf)) {
206
+ fprintf(stderr, _("%s: write to %s failed: %s\n"),
207
+ Prog, map_file, strerror(errno));
208
+ exit(EXIT_FAILURE);
212
Index: shadow/libmisc/idmapping.h
213
===================================================================
214
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
215
+++ shadow/libmisc/idmapping.h 2013-02-01 15:27:53.828080343 -0600
218
+ * Copyright (c) 2013 Eric Biederman
219
+ * All rights reserved.
221
+ * Redistribution and use in source and binary forms, with or without
222
+ * modification, are permitted provided that the following conditions
224
+ * 1. Redistributions of source code must retain the above copyright
225
+ * notice, this list of conditions and the following disclaimer.
226
+ * 2. Redistributions in binary form must reproduce the above copyright
227
+ * notice, this list of conditions and the following disclaimer in the
228
+ * documentation and/or other materials provided with the distribution.
229
+ * 3. The name of the copyright holders or contributors may not be used to
230
+ * endorse or promote products derived from this software without
231
+ * specific prior written permission.
233
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
234
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
235
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
236
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
237
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
238
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
239
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
240
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
241
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
243
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
246
+#ifndef _IDMAPPING_H_
247
+#define _IDMAPPING_H_
250
+ unsigned long upper;
251
+ unsigned long lower;
252
+ unsigned long count;
255
+extern struct map_range *get_map_ranges(int ranges, int argc, char **argv);
256
+extern void write_mapping(int proc_dir_fd, int ranges,
257
+ struct map_range *mappings, const char *map_file);
259
+#endif /* _ID_MAPPING_H_ */
261
Index: shadow/man/Makefile.am
262
===================================================================
263
--- shadow.orig/man/Makefile.am 2013-02-01 15:27:53.836080342 -0600
264
+++ shadow/man/Makefile.am 2013-02-01 15:27:53.828080343 -0600
285
Index: shadow/man/newgidmap.1.xml
286
===================================================================
287
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
288
+++ shadow/man/newgidmap.1.xml 2013-02-01 15:27:53.828080343 -0600
290
+<?xml version="1.0" encoding="UTF-8"?>
292
+ Copyright (c) 2013 Eric W. Biederman
293
+ All rights reserved.
295
+ Redistribution and use in source and binary forms, with or without
296
+ modification, are permitted provided that the following conditions
298
+ 1. Redistributions of source code must retain the above copyright
299
+ notice, this list of conditions and the following disclaimer.
300
+ 2. Redistributions in binary form must reproduce the above copyright
301
+ notice, this list of conditions and the following disclaimer in the
302
+ documentation and/or other materials provided with the distribution.
303
+ 3. The name of the copyright holders or contributors may not be used to
304
+ endorse or promote products derived from this software without
305
+ specific prior written permission.
307
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
308
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
309
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
310
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
311
+ HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
312
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
313
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
314
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
315
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
316
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
317
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
319
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
320
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
321
+<!-- SHADOW-CONFIG-HERE -->
324
+<refentry id='newgidmap.1'>
326
+ <refentrytitle>newgidmap</refentrytitle>
327
+ <manvolnum>1</manvolnum>
328
+ <refmiscinfo class="sectdesc">User Commands</refmiscinfo>
329
+ <refmiscinfo class="source">shadow-utils</refmiscinfo>
330
+ <refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
332
+ <refnamediv id='name'>
333
+ <refname>newgidmap</refname>
334
+ <refpurpose>set the gid mapping of a user namespace</refpurpose>
337
+ <refsynopsisdiv id='synopsis'>
339
+ <command>newgidmap</command>
340
+ <arg choice='plain'>
341
+ <replaceable>pid</replaceable>
343
+ <arg choice='plain'>
344
+ <replaceable>gid</replaceable>
346
+ <arg choice='plain'>
347
+ <replaceable>lowergid</replaceable>
349
+ <arg choice='plain'>
350
+ <replaceable>count</replaceable>
353
+ <arg choice='plain'>
354
+ <replaceable>pid</replaceable>
356
+ <arg choice='plain'>
357
+ <replaceable>gid</replaceable>
359
+ <arg choice='plain'>
360
+ <replaceable>lowergid</replaceable>
362
+ <arg choice='plain'>
363
+ <replaceable>count</replaceable>
366
+ <replaceable>...</replaceable>
372
+ <refsect1 id='description'>
373
+ <title>DESCRIPTION</title>
375
+ The <command>newgidmap</command> sets <filename>/proc/[pid]/gid_map</filename> based on it's
376
+ command line arguments and the gids allowed in <filename>/etc/subgid</filename>.
381
+ <refsect1 id='options'>
382
+ <title>OPTIONS</title>
384
+ There currently are no options to the <command>newgidmap</command> command.
386
+ <variablelist remap='IP'>
390
+ <refsect1 id='note'>
391
+ <title>NOTE</title>
393
+ The only restriction placed on the login shell is that the command
394
+ name must be listed in <filename>/etc/shells</filename>, unless the
395
+ invoker is the superuser, and then any value may be added. An
396
+ account with a restricted login shell may not change her login shell.
397
+ For this reason, placing <filename>/bin/rsh</filename> in
398
+ <filename>/etc/shells</filename> is discouraged since accidentally
399
+ changing to a restricted shell would prevent the user from ever
400
+ changing her login shell back to its original value.
405
+ <refsect1 id='files'>
406
+ <title>FILES</title>
409
+ <term><filename>/etc/subgid</filename></term>
411
+ <para>List of users subordinate user IDs.</para>
415
+ <term><filename>/proc/[pid]/gid_map</filename></term>
417
+ <para>Mapping of gids from one between user namespaces.</para>
423
+ <refsect1 id='see_also'>
424
+ <title>SEE ALSO</title>
427
+ <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
430
+ <refentrytitle>useradd</refentrytitle><manvolnum>8</manvolnum>
433
+ <refentrytitle>usermod</refentrytitle><manvolnum>8</manvolnum>
436
+ <refentrytitle>newusers</refentrytitle><manvolnum>8</manvolnum>
439
+ <refentrytitle>userdel</refentrytitle><manvolnum>8</manvolnum>
442
+ <refentrytitle>subgid</refentrytitle><manvolnum>5</manvolnum>
447
Index: shadow/man/newuidmap.1.xml
448
===================================================================
449
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
450
+++ shadow/man/newuidmap.1.xml 2013-02-01 15:27:53.828080343 -0600
452
+<?xml version="1.0" encoding="UTF-8"?>
454
+ Copyright (c) 2013 Eric W. Biederman
455
+ All rights reserved.
457
+ Redistribution and use in source and binary forms, with or without
458
+ modification, are permitted provided that the following conditions
460
+ 1. Redistributions of source code must retain the above copyright
461
+ notice, this list of conditions and the following disclaimer.
462
+ 2. Redistributions in binary form must reproduce the above copyright
463
+ notice, this list of conditions and the following disclaimer in the
464
+ documentation and/or other materials provided with the distribution.
465
+ 3. The name of the copyright holders or contributors may not be used to
466
+ endorse or promote products derived from this software without
467
+ specific prior written permission.
469
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
470
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
471
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
472
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
473
+ HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
474
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
475
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
476
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
477
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
478
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
479
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
481
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.5//EN"
482
+ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
483
+<!-- SHADOW-CONFIG-HERE -->
486
+<refentry id='newuidmap.1'>
488
+ <refentrytitle>newuidmap</refentrytitle>
489
+ <manvolnum>1</manvolnum>
490
+ <refmiscinfo class="sectdesc">User Commands</refmiscinfo>
491
+ <refmiscinfo class="source">shadow-utils</refmiscinfo>
492
+ <refmiscinfo class="version">&SHADOW_UTILS_VERSION;</refmiscinfo>
494
+ <refnamediv id='name'>
495
+ <refname>newuidmap</refname>
496
+ <refpurpose>set the uid mapping of a user namespace</refpurpose>
499
+ <refsynopsisdiv id='synopsis'>
501
+ <command>newuidmap</command>
502
+ <arg choice='plain'>
503
+ <replaceable>pid</replaceable>
505
+ <arg choice='plain'>
506
+ <replaceable>uid</replaceable>
508
+ <arg choice='plain'>
509
+ <replaceable>loweruid</replaceable>
511
+ <arg choice='plain'>
512
+ <replaceable>count</replaceable>
515
+ <arg choice='plain'>
516
+ <replaceable>uid</replaceable>
518
+ <arg choice='plain'>
519
+ <replaceable>loweruid</replaceable>
521
+ <arg choice='plain'>
522
+ <replaceable>count</replaceable>
525
+ <replaceable>...</replaceable>
531
+ <refsect1 id='description'>
532
+ <title>DESCRIPTION</title>
534
+ The <command>newuidmap</command> sets <filename>/proc/[pid]/uid_map</filename> based on it's
535
+ command line arguments and the uids allowed in <filename>/etc/subuid</filename>.
540
+ <refsect1 id='options'>
541
+ <title>OPTIONS</title>
543
+ There currently are no options to the <command>newuidmap</command> command.
545
+ <variablelist remap='IP'>
549
+ <refsect1 id='note'>
550
+ <title>NOTE</title>
552
+ The only restriction placed on the login shell is that the command
553
+ name must be listed in <filename>/etc/shells</filename>, unless the
554
+ invoker is the superuser, and then any value may be added. An
555
+ account with a restricted login shell may not change her login shell.
556
+ For this reason, placing <filename>/bin/rsh</filename> in
557
+ <filename>/etc/shells</filename> is discouraged since accidentally
558
+ changing to a restricted shell would prevent the user from ever
559
+ changing her login shell back to its original value.
564
+ <refsect1 id='files'>
565
+ <title>FILES</title>
568
+ <term><filename>/etc/subuid</filename></term>
570
+ <para>List of users subordinate user IDs.</para>
574
+ <term><filename>/proc/[pid]/uid_map</filename></term>
576
+ <para>Mapping of uids from one between user namespaces.</para>
582
+ <refsect1 id='see_also'>
583
+ <title>SEE ALSO</title>
586
+ <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
589
+ <refentrytitle>useradd</refentrytitle><manvolnum>8</manvolnum>
592
+ <refentrytitle>usermod</refentrytitle><manvolnum>8</manvolnum>
595
+ <refentrytitle>newusers</refentrytitle><manvolnum>8</manvolnum>
598
+ <refentrytitle>userdel</refentrytitle><manvolnum>8</manvolnum>
601
+ <refentrytitle>subuid</refentrytitle><manvolnum>5</manvolnum>
606
Index: shadow/src/Makefile.am
607
===================================================================
608
--- shadow.orig/src/Makefile.am 2013-02-01 15:27:53.836080342 -0600
609
+++ shadow/src/Makefile.am 2013-02-01 15:27:53.832080342 -0600
611
# $prefix/bin and $prefix/sbin, no install-data hacks...)
613
bin_PROGRAMS = groups login su
614
-ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd
615
+ubin_PROGRAMS = faillog lastlog chage chfn chsh expiry gpasswd newgrp passwd \
616
+ newgidmap newuidmap
621
noinst_PROGRAMS = id sulogin
624
-suidubins = chage chfn chsh expiry gpasswd newgrp passwd
625
+suidubins = chage chfn chsh expiry gpasswd newgrp passwd newuidmap newgidmap
627
suidubins += chage chgpasswd chpasswd groupadd groupdel groupmod newusers useradd userdel usermod
629
Index: shadow/src/newgidmap.c
630
===================================================================
631
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
632
+++ shadow/src/newgidmap.c 2013-02-01 15:27:53.832080342 -0600
635
+ * Copyright (c) 2013 Eric Biederman
636
+ * All rights reserved.
638
+ * Redistribution and use in source and binary forms, with or without
639
+ * modification, are permitted provided that the following conditions
641
+ * 1. Redistributions of source code must retain the above copyright
642
+ * notice, this list of conditions and the following disclaimer.
643
+ * 2. Redistributions in binary form must reproduce the above copyright
644
+ * notice, this list of conditions and the following disclaimer in the
645
+ * documentation and/or other materials provided with the distribution.
646
+ * 3. The name of the copyright holders or contributors may not be used to
647
+ * endorse or promote products derived from this software without
648
+ * specific prior written permission.
650
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
651
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
652
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
653
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
654
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
655
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
656
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
657
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
658
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
659
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
660
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
667
+#include <stdbool.h>
669
+#include <sys/types.h>
670
+#include <sys/stat.h>
672
+#include "defines.h"
673
+#include "prototypes.h"
674
+#include "subordinateio.h"
675
+#include "idmapping.h"
682
+static bool verify_range(struct passwd *pw, struct map_range *range)
684
+ /* An empty range is invalid */
685
+ if (range->count == 0)
688
+ /* Test /etc/subgid */
689
+ if (have_sub_gids(pw->pw_name, range->lower, range->count))
692
+ /* Allow a process to map it's own gid */
693
+ if ((range->count == 1) && (pw->pw_gid == range->lower))
699
+static void verify_ranges(struct passwd *pw, int ranges,
700
+ struct map_range *mappings)
702
+ struct map_range *mapping;
705
+ mapping = mappings;
706
+ for (idx = 0; idx < ranges; idx++, mapping++) {
707
+ if (!verify_range(pw, mapping)) {
708
+ fprintf(stderr, _( "%s: gid range [%lu-%lu) -> [%lu-%lu) not allowed\n"),
711
+ mapping->upper + mapping->count,
713
+ mapping->lower + mapping->count);
714
+ exit(EXIT_FAILURE);
719
+static void usage(void)
721
+ fprintf(stderr, _("usage: %s <pid> <gid> <lowergid> <count> [ <gid> <lowergid> <count> ] ... \n"), Prog);
722
+ exit(EXIT_FAILURE);
726
+ * newgidmap - Set the gid_map for the specified process
728
+int main(int argc, char **argv)
730
+ char proc_dir_name[PATH_MAX];
732
+ pid_t target, parent;
735
+ struct map_range *mappings;
740
+ Prog = Basename (argv[0]);
743
+ * The valid syntax are
744
+ * newgidmap target_pid
749
+ /* Find the process that needs it's user namespace
752
+ target_str = argv[1];
753
+ if (!get_pid(target_str, &target))
756
+ written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
758
+ if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
759
+ fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
760
+ Prog, strerror(errno));
763
+ proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
764
+ if (proc_dir_fd < 0) {
765
+ fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
767
+ return EXIT_FAILURE;
771
+ pw = get_my_pwent ();
774
+ _("%s: Cannot determine your user name.\n"),
776
+ SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
777
+ (unsigned long) getuid ()));
778
+ return EXIT_FAILURE;
781
+ /* Get the effective uid and effective gid of the target process */
782
+ if (fstat(proc_dir_fd, &st) < 0) {
783
+ fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
785
+ return EXIT_FAILURE;
788
+ /* Verify real user and real group matches the password entry
789
+ * and the effective user and group of the program whose
790
+ * mappings we have been asked to set.
792
+ if ((getuid() != pw->pw_uid) ||
793
+ (getgid() != pw->pw_gid) ||
794
+ (pw->pw_uid != st.st_uid) ||
795
+ (pw->pw_gid != st.st_gid)) {
796
+ fprintf(stderr, _( "%s: Target %u is owned by a different user\n" ),
798
+ return EXIT_FAILURE;
801
+ if (!sub_gid_open(O_RDONLY)) {
802
+ return EXIT_FAILURE;
805
+ ranges = ((argc - 2) + 2) / 3;
806
+ mappings = get_map_ranges(ranges, argc - 2, argv + 2);
810
+ verify_ranges(pw, ranges, mappings);
812
+ write_mapping(proc_dir_fd, ranges, mappings, "gid_map");
815
+ return EXIT_SUCCESS;
817
Index: shadow/src/newuidmap.c
818
===================================================================
819
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
820
+++ shadow/src/newuidmap.c 2013-02-01 15:27:53.832080342 -0600
823
+ * Copyright (c) 2013 Eric Biederman
824
+ * All rights reserved.
826
+ * Redistribution and use in source and binary forms, with or without
827
+ * modification, are permitted provided that the following conditions
829
+ * 1. Redistributions of source code must retain the above copyright
830
+ * notice, this list of conditions and the following disclaimer.
831
+ * 2. Redistributions in binary form must reproduce the above copyright
832
+ * notice, this list of conditions and the following disclaimer in the
833
+ * documentation and/or other materials provided with the distribution.
834
+ * 3. The name of the copyright holders or contributors may not be used to
835
+ * endorse or promote products derived from this software without
836
+ * specific prior written permission.
838
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
839
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
840
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
841
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
842
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
843
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
844
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
845
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
846
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
847
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
848
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
855
+#include <stdbool.h>
857
+#include <sys/types.h>
858
+#include <sys/stat.h>
860
+#include "defines.h"
861
+#include "prototypes.h"
862
+#include "subordinateio.h"
863
+#include "idmapping.h"
870
+static bool verify_range(struct passwd *pw, struct map_range *range)
872
+ /* An empty range is invalid */
873
+ if (range->count == 0)
876
+ /* Test /etc/subuid */
877
+ if (have_sub_uids(pw->pw_name, range->lower, range->count))
880
+ /* Allow a process to map it's own uid */
881
+ if ((range->count == 1) && (pw->pw_uid == range->lower))
887
+static void verify_ranges(struct passwd *pw, int ranges,
888
+ struct map_range *mappings)
890
+ struct map_range *mapping;
893
+ mapping = mappings;
894
+ for (idx = 0; idx < ranges; idx++, mapping++) {
895
+ if (!verify_range(pw, mapping)) {
896
+ fprintf(stderr, _( "%s: uid range [%lu-%lu) -> [%lu-%lu) not allowed\n"),
899
+ mapping->upper + mapping->count,
901
+ mapping->lower + mapping->count);
902
+ exit(EXIT_FAILURE);
909
+ fprintf(stderr, _("usage: %s <pid> <uid> <loweruid> <count> [ <uid> <loweruid> <count> ] ... \n"), Prog);
910
+ exit(EXIT_FAILURE);
914
+ * newuidmap - Set the uid_map for the specified process
916
+int main(int argc, char **argv)
918
+ char proc_dir_name[PATH_MAX];
920
+ pid_t target, parent;
923
+ struct map_range *mappings;
928
+ Prog = Basename (argv[0]);
931
+ * The valid syntax are
932
+ * newuidmap target_pid
937
+ /* Find the process that needs it's user namespace
940
+ target_str = argv[1];
941
+ if (!get_pid(target_str, &target))
944
+ written = snprintf(proc_dir_name, sizeof(proc_dir_name), "/proc/%u/",
946
+ if ((written <= 0) || (written >= sizeof(proc_dir_name))) {
947
+ fprintf(stderr, "%s: snprintf of proc path failed: %s\n",
948
+ Prog, strerror(errno));
951
+ proc_dir_fd = open(proc_dir_name, O_DIRECTORY);
952
+ if (proc_dir_fd < 0) {
953
+ fprintf(stderr, _("%s: Could not open proc directory for target %u\n"),
955
+ return EXIT_FAILURE;
959
+ pw = get_my_pwent ();
962
+ _("%s: Cannot determine your user name.\n"),
964
+ SYSLOG ((LOG_WARN, "Cannot determine the user name of the caller (UID %lu)",
965
+ (unsigned long) getuid ()));
966
+ return EXIT_FAILURE;
969
+ /* Get the effective uid and effective gid of the target process */
970
+ if (fstat(proc_dir_fd, &st) < 0) {
971
+ fprintf(stderr, _("%s: Could not stat directory for target %u\n"),
973
+ return EXIT_FAILURE;
976
+ /* Verify real user and real group matches the password entry
977
+ * and the effective user and group of the program whose
978
+ * mappings we have been asked to set.
980
+ if ((getuid() != pw->pw_uid) ||
981
+ (getgid() != pw->pw_gid) ||
982
+ (pw->pw_uid != st.st_uid) ||
983
+ (pw->pw_gid != st.st_gid)) {
984
+ fprintf(stderr, _( "%s: Target %u is owned by a different user\n" ),
986
+ return EXIT_FAILURE;
989
+ if (!sub_uid_open(O_RDONLY)) {
990
+ return EXIT_FAILURE;
993
+ ranges = ((argc - 2) + 2) / 3;
994
+ mappings = get_map_ranges(ranges, argc - 2, argv + 2);
998
+ verify_ranges(pw, ranges, mappings);
1000
+ write_mapping(proc_dir_fd, ranges, mappings, "uid_map");
1003
+ return EXIT_SUCCESS;