]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/lxc_unshare.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
33 #include <sys/types.h>
39 #include "namespace.h"
43 lxc_log_define(lxc_unshare_ui
, lxc
);
47 fprintf(stderr
, "%s <options> command [command_arguments]\n", basename(cmd
));
48 fprintf(stderr
, "Options are:\n");
49 fprintf(stderr
, "\t -s flags: ORed list of flags to unshare:\n" \
50 "\t MOUNT, PID, UTSNAME, IPC, USER, NETWORK\n");
51 fprintf(stderr
, "\t -u <id> : new id to be set if -s USER is specified\n");
55 static uid_t
lookup_user(const char *optarg
)
57 char name
[sysconf(_SC_LOGIN_NAME_MAX
)];
59 struct passwd
*pwent
= NULL
;
61 if (!optarg
|| (optarg
[0] == '\0'))
64 if (sscanf(optarg
, "%u", &uid
) < 1) {
65 /* not a uid -- perhaps a username */
66 if (sscanf(optarg
, "%s", name
) < 1)
69 pwent
= getpwnam(name
);
71 ERROR("invalid username %s", name
);
76 pwent
= getpwuid(uid
);
78 ERROR("invalid uid %d", uid
);
93 static int do_start(void *arg
)
95 struct start_arg
*start_arg
= arg
;
96 char **args
= *start_arg
->args
;
97 int flags
= *start_arg
->flags
;
98 uid_t uid
= *start_arg
->uid
;
100 if (flags
& CLONE_NEWUSER
&& setuid(uid
)) {
101 ERROR("failed to set uid %d: %s", uid
, strerror(errno
));
105 execvp(args
[0], args
);
107 ERROR("failed to exec: '%s': %s", args
[0], strerror(errno
));
111 int main(int argc
, char *argv
[])
115 char *namespaces
= NULL
;
118 uid_t uid
= -1; /* valid only if (flags & CLONE_NEWUSER) */
121 struct start_arg start_arg
= {
127 while ((opt
= getopt(argc
, argv
, "s:u:h")) != -1) {
135 uid
= lookup_user(optarg
);
141 if (argv
[optind
] == NULL
) {
142 ERROR("a command to execute in the new namespace is required");
146 args
= &argv
[optind
];
148 ret
= lxc_caps_init();
152 ret
= lxc_fill_namespace_flags(namespaces
, &flags
);
156 if (!(flags
& CLONE_NEWUSER
) && uid
!= -1) {
157 ERROR("-u <uid> needs -s USER option");
161 pid
= lxc_clone(do_start
, &start_arg
, flags
);
163 ERROR("failed to clone");
167 if (waitpid(pid
, &status
, 0) < 0) {
168 ERROR("failed to wait for '%d'", pid
);
172 return lxc_error_set_and_log(pid
, status
);