|
|
43fe83 |
From 838cf2f32c9f7050da3ae5a31b3108ce77684839 Mon Sep 17 00:00:00 2001
|
|
|
43fe83 |
Message-Id: <838cf2f32c9f7050da3ae5a31b3108ce77684839.1377873638.git.jdenemar@redhat.com>
|
|
|
43fe83 |
From: Dan Walsh <dwalsh@redhat.com>
|
|
|
43fe83 |
Date: Tue, 13 Aug 2013 15:20:40 +0100
|
|
|
43fe83 |
Subject: [PATCH] Introduce a virt-login-shell binary
|
|
|
43fe83 |
|
|
|
43fe83 |
For https://bugzilla.redhat.com/show_bug.cgi?id=988491
|
|
|
43fe83 |
|
|
|
43fe83 |
Add a virt-login-shell binary that can be set as a user's
|
|
|
43fe83 |
shell, such that when they login, it causes them to enter
|
|
|
43fe83 |
the LXC container with a name matching their user name.
|
|
|
43fe83 |
|
|
|
43fe83 |
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
|
|
|
43fe83 |
(cherry picked from commit 54d69f540c9928da98f10202b3f21b7abb00bac1)
|
|
|
43fe83 |
---
|
|
|
43fe83 |
.gitignore | 1 +
|
|
|
43fe83 |
libvirt.spec.in | 3 +
|
|
|
43fe83 |
po/POTFILES.in | 1 +
|
|
|
43fe83 |
tools/Makefile.am | 30 +++-
|
|
|
43fe83 |
tools/virt-login-shell.c | 350 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
43fe83 |
tools/virt-login-shell.conf | 26 ++++
|
|
|
43fe83 |
tools/virt-login-shell.pod | 62 ++++++++
|
|
|
43fe83 |
7 files changed, 472 insertions(+), 1 deletion(-)
|
|
|
43fe83 |
create mode 100644 tools/virt-login-shell.c
|
|
|
43fe83 |
create mode 100644 tools/virt-login-shell.conf
|
|
|
43fe83 |
create mode 100644 tools/virt-login-shell.pod
|
|
|
43fe83 |
|
|
|
43fe83 |
diff --git a/po/POTFILES.in b/po/POTFILES.in
|
|
|
43fe83 |
index 1fd84af..884b70a 100644
|
|
|
43fe83 |
--- a/po/POTFILES.in
|
|
|
43fe83 |
+++ b/po/POTFILES.in
|
|
|
43fe83 |
@@ -231,3 +231,4 @@ tools/virt-host-validate-common.c
|
|
|
43fe83 |
tools/virt-host-validate-lxc.c
|
|
|
43fe83 |
tools/virt-host-validate-qemu.c
|
|
|
43fe83 |
tools/virt-host-validate.c
|
|
|
43fe83 |
+tools/virt-login-shell.c
|
|
|
43fe83 |
diff --git a/tools/Makefile.am b/tools/Makefile.am
|
|
|
43fe83 |
index 644a86d..00c582a 100644
|
|
|
43fe83 |
--- a/tools/Makefile.am
|
|
|
43fe83 |
+++ b/tools/Makefile.am
|
|
|
43fe83 |
@@ -37,6 +37,7 @@ EXTRA_DIST = \
|
|
|
43fe83 |
virt-pki-validate.in \
|
|
|
43fe83 |
virt-sanlock-cleanup.in \
|
|
|
43fe83 |
virt-sanlock-cleanup.8 \
|
|
|
43fe83 |
+ virt-login-shell.pod \
|
|
|
43fe83 |
virsh.pod \
|
|
|
43fe83 |
libvirt-guests.sysconf \
|
|
|
43fe83 |
virsh-edit.c \
|
|
|
43fe83 |
@@ -52,8 +53,11 @@ EXTRA_DIST = \
|
|
|
43fe83 |
|
|
|
43fe83 |
DISTCLEANFILES =
|
|
|
43fe83 |
|
|
|
43fe83 |
+confdir = $(sysconfdir)/libvirt
|
|
|
43fe83 |
+conf_DATA = virt-login-shell.conf
|
|
|
43fe83 |
+
|
|
|
43fe83 |
bin_SCRIPTS = virt-xml-validate virt-pki-validate
|
|
|
43fe83 |
-bin_PROGRAMS = virsh virt-host-validate
|
|
|
43fe83 |
+bin_PROGRAMS = virsh virt-host-validate virt-login-shell
|
|
|
43fe83 |
libexec_SCRIPTS = libvirt-guests.sh
|
|
|
43fe83 |
|
|
|
43fe83 |
if WITH_SANLOCK
|
|
|
43fe83 |
@@ -65,6 +69,7 @@ dist_man1_MANS = \
|
|
|
43fe83 |
virt-host-validate.1 \
|
|
|
43fe83 |
virt-pki-validate.1 \
|
|
|
43fe83 |
virt-xml-validate.1 \
|
|
|
43fe83 |
+ virt-login-shell.1 \
|
|
|
43fe83 |
virsh.1
|
|
|
43fe83 |
if WITH_SANLOCK
|
|
|
43fe83 |
dist_man8_MANS = virt-sanlock-cleanup.8
|
|
|
43fe83 |
@@ -128,6 +133,24 @@ virt_host_validate_CFLAGS = \
|
|
|
43fe83 |
$(COVERAGE_CFLAGS) \
|
|
|
43fe83 |
$(NULL)
|
|
|
43fe83 |
|
|
|
43fe83 |
+virt_login_shell_SOURCES = \
|
|
|
43fe83 |
+ virt-login-shell.conf \
|
|
|
43fe83 |
+ virt-login-shell.c
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+virt_login_shell_LDFLAGS = $(COVERAGE_LDFLAGS)
|
|
|
43fe83 |
+virt_login_shell_LDADD = \
|
|
|
43fe83 |
+ $(STATIC_BINARIES) \
|
|
|
43fe83 |
+ $(PIE_LDFLAGS) \
|
|
|
43fe83 |
+ $(RELRO_LDFLAGS) \
|
|
|
43fe83 |
+ ../src/libvirt.la \
|
|
|
43fe83 |
+ ../src/libvirt-lxc.la \
|
|
|
43fe83 |
+ ../gnulib/lib/libgnu.la
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+virt_login_shell_CFLAGS = \
|
|
|
43fe83 |
+ $(WARN_CFLAGS) \
|
|
|
43fe83 |
+ $(PIE_CFLAGS) \
|
|
|
43fe83 |
+ $(COVERAGE_CFLAGS)
|
|
|
43fe83 |
+
|
|
|
43fe83 |
virsh_SOURCES = \
|
|
|
43fe83 |
console.c console.h \
|
|
|
43fe83 |
virsh.c virsh.h \
|
|
|
43fe83 |
@@ -189,6 +212,11 @@ virsh_win_icon.$(OBJEXT): virsh_win_icon.rc
|
|
|
43fe83 |
--output-format coff --output $@
|
|
|
43fe83 |
endif
|
|
|
43fe83 |
|
|
|
43fe83 |
+virt-login-shell.1: virt-login-shell.pod $(top_srcdir)/configure.ac
|
|
|
43fe83 |
+ $(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@ \
|
|
|
43fe83 |
+ && if grep 'POD ERROR' $(srcdir)/$@ ; then \
|
|
|
43fe83 |
+ rm $(srcdir)/$@; exit 1; fi
|
|
|
43fe83 |
+
|
|
|
43fe83 |
virsh.1: virsh.pod $(top_srcdir)/configure.ac
|
|
|
43fe83 |
$(AM_V_GEN)$(POD2MAN) $< $(srcdir)/$@ \
|
|
|
43fe83 |
&& if grep 'POD ERROR' $(srcdir)/$@ ; then \
|
|
|
43fe83 |
diff --git a/tools/virt-login-shell.c b/tools/virt-login-shell.c
|
|
|
43fe83 |
new file mode 100644
|
|
|
43fe83 |
index 0000000..ffbc713
|
|
|
43fe83 |
--- /dev/null
|
|
|
43fe83 |
+++ b/tools/virt-login-shell.c
|
|
|
43fe83 |
@@ -0,0 +1,350 @@
|
|
|
43fe83 |
+/*
|
|
|
43fe83 |
+ * virt-login-shell.c: a shell to connect to a container
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * Copyright (C) 2013 Red Hat, Inc.
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * This library is free software; you can redistribute it and/or
|
|
|
43fe83 |
+ * modify it under the terms of the GNU Lesser General Public
|
|
|
43fe83 |
+ * License as published by the Free Software Foundation; either
|
|
|
43fe83 |
+ * version 2.1 of the License, or (at your option) any later version.
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * This library is distributed in the hope that it will be useful,
|
|
|
43fe83 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
43fe83 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
43fe83 |
+ * Lesser General Public License for more details.
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * You should have received a copy of the GNU Lesser General Public
|
|
|
43fe83 |
+ * License along with this library. If not, see
|
|
|
43fe83 |
+ * <http://www.gnu.org/licenses/>.
|
|
|
43fe83 |
+ *
|
|
|
43fe83 |
+ * Daniel Walsh <dwalsh@redhat.com>
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+#include <config.h>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#include <stdarg.h>
|
|
|
43fe83 |
+#include <getopt.h>
|
|
|
43fe83 |
+#include <stdio.h>
|
|
|
43fe83 |
+#include <errno.h>
|
|
|
43fe83 |
+#include <stdlib.h>
|
|
|
43fe83 |
+#include <fnmatch.h>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+#include "internal.h"
|
|
|
43fe83 |
+#include "virerror.h"
|
|
|
43fe83 |
+#include "virconf.h"
|
|
|
43fe83 |
+#include "virutil.h"
|
|
|
43fe83 |
+#include "virfile.h"
|
|
|
43fe83 |
+#include "virprocess.h"
|
|
|
43fe83 |
+#include "configmake.h"
|
|
|
43fe83 |
+#include "virstring.h"
|
|
|
43fe83 |
+#include "viralloc.h"
|
|
|
43fe83 |
+#include "vircommand.h"
|
|
|
43fe83 |
+#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static ssize_t nfdlist = 0;
|
|
|
43fe83 |
+static int *fdlist = NULL;
|
|
|
43fe83 |
+static const char *conf_file = SYSCONFDIR "/libvirt/virt-login-shell.conf";
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static void virLoginShellFini(virConnectPtr conn, virDomainPtr dom)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ size_t i;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ for (i = 0; i < nfdlist; i++)
|
|
|
43fe83 |
+ VIR_FORCE_CLOSE(fdlist[i]);
|
|
|
43fe83 |
+ VIR_FREE(fdlist);
|
|
|
43fe83 |
+ nfdlist = 0;
|
|
|
43fe83 |
+ if (dom)
|
|
|
43fe83 |
+ virDomainFree(dom);
|
|
|
43fe83 |
+ if (conn)
|
|
|
43fe83 |
+ virConnectClose(conn);
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static int virLoginShellAllowedUser(virConfPtr conf,
|
|
|
43fe83 |
+ const char *name,
|
|
|
43fe83 |
+ gid_t *groups)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virConfValuePtr p;
|
|
|
43fe83 |
+ int ret = -1;
|
|
|
43fe83 |
+ char *ptr = NULL;
|
|
|
43fe83 |
+ size_t i;
|
|
|
43fe83 |
+ char *gname = NULL;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ p = virConfGetValue(conf, "allowed_users");
|
|
|
43fe83 |
+ if (p && p->type == VIR_CONF_LIST) {
|
|
|
43fe83 |
+ virConfValuePtr pp;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ /* Calc length and check items */
|
|
|
43fe83 |
+ for (pp = p->list; pp; pp = pp->next) {
|
|
|
43fe83 |
+ if (pp->type != VIR_CONF_STRING) {
|
|
|
43fe83 |
+ virReportSystemError(EINVAL, "%s", _("shell must be a list of strings"));
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ } else {
|
|
|
43fe83 |
+ /*
|
|
|
43fe83 |
+ If string begins with a % this indicates a linux group.
|
|
|
43fe83 |
+ Check to see if the user is in the Linux Group.
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ if (pp->str[0] == '%') {
|
|
|
43fe83 |
+ ptr = &pp->str[1];
|
|
|
43fe83 |
+ if (!ptr)
|
|
|
43fe83 |
+ continue;
|
|
|
43fe83 |
+ for (i = 0; groups[i]; i++) {
|
|
|
43fe83 |
+ if (!(gname = virGetGroupName(groups[i])))
|
|
|
43fe83 |
+ continue;
|
|
|
43fe83 |
+ if (fnmatch(ptr, gname, 0) == 0) {
|
|
|
43fe83 |
+ ret = 0;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ VIR_FREE(gname);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ VIR_FREE(groups);
|
|
|
43fe83 |
+ continue;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ if (fnmatch(pp->str, name, 0) == 0) {
|
|
|
43fe83 |
+ ret = 0;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ virReportSystemError(EPERM, _("%s not listed as an allowed_users in %s"), name, conf_file);
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
+ VIR_FREE(gname);
|
|
|
43fe83 |
+ VIR_FREE(groups);
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static char **virLoginShellGetShellArgv(virConfPtr conf)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ size_t i;
|
|
|
43fe83 |
+ char **shargv=NULL;
|
|
|
43fe83 |
+ virConfValuePtr p;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ p = virConfGetValue(conf, "shell");
|
|
|
43fe83 |
+ if (!p)
|
|
|
43fe83 |
+ return virStringSplit("/bin/sh -l", " ", 3);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (p && p->type == VIR_CONF_LIST) {
|
|
|
43fe83 |
+ size_t len;
|
|
|
43fe83 |
+ virConfValuePtr pp;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ /* Calc length and check items */
|
|
|
43fe83 |
+ for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
|
|
|
43fe83 |
+ if (pp->type != VIR_CONF_STRING) {
|
|
|
43fe83 |
+ virReportSystemError(EINVAL, "%s", _("shell must be a list of strings"));
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (VIR_ALLOC_N(shargv, len + 1) < 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
+ for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
|
|
|
43fe83 |
+ if (VIR_STRDUP(shargv[i], pp->str) < 0)
|
|
|
43fe83 |
+ goto error;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ shargv[len] = NULL;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ return shargv;
|
|
|
43fe83 |
+error:
|
|
|
43fe83 |
+ virStringFreeList(shargv);
|
|
|
43fe83 |
+ return NULL;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+static char *progname;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+/*
|
|
|
43fe83 |
+ * Print usage
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+static void
|
|
|
43fe83 |
+usage(void)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ fprintf(stdout, _("\n"
|
|
|
43fe83 |
+ "%s is a privileged program that allows non root users \n"
|
|
|
43fe83 |
+ "specified in %s to join a Linux container \n"
|
|
|
43fe83 |
+ "with a matching user name and launch a shell. \n"
|
|
|
43fe83 |
+ "\n%s [options]\n\n"
|
|
|
43fe83 |
+ " options:\n"
|
|
|
43fe83 |
+ " -h | --help this help:\n\n"), progname, conf_file, progname);
|
|
|
43fe83 |
+ return;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+int
|
|
|
43fe83 |
+main(int argc, char **argv)
|
|
|
43fe83 |
+{
|
|
|
43fe83 |
+ virConfPtr conf = NULL;
|
|
|
43fe83 |
+ const char *login_shell_path = conf_file;
|
|
|
43fe83 |
+ pid_t cpid;
|
|
|
43fe83 |
+ int ret = EXIT_FAILURE;
|
|
|
43fe83 |
+ int status;
|
|
|
43fe83 |
+ int status2;
|
|
|
43fe83 |
+ uid_t uid = getuid();
|
|
|
43fe83 |
+ gid_t gid = getgid();
|
|
|
43fe83 |
+ char *name = NULL;
|
|
|
43fe83 |
+ char **shargv = NULL;
|
|
|
43fe83 |
+ virSecurityModelPtr secmodel = NULL;
|
|
|
43fe83 |
+ virSecurityLabelPtr seclabel = NULL;
|
|
|
43fe83 |
+ virDomainPtr dom = NULL;
|
|
|
43fe83 |
+ virConnectPtr conn = NULL;
|
|
|
43fe83 |
+ char *homedir = NULL;
|
|
|
43fe83 |
+ int arg;
|
|
|
43fe83 |
+ int longindex = -1;
|
|
|
43fe83 |
+ int ngroups;
|
|
|
43fe83 |
+ gid_t *groups = NULL;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ struct option opt[] = {
|
|
|
43fe83 |
+ {"help", no_argument, NULL, 'h'},
|
|
|
43fe83 |
+ {NULL, 0, NULL, 0}
|
|
|
43fe83 |
+ };
|
|
|
43fe83 |
+ if (virInitialize() < 0) {
|
|
|
43fe83 |
+ fprintf(stderr, _("Failed to initialize libvirt Error Handling"));
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ virSetErrorFunc(NULL, NULL);
|
|
|
43fe83 |
+ virSetErrorLogPriorityFunc(NULL);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ progname = argv[0];
|
|
|
43fe83 |
+ if (!setlocale(LC_ALL, "")) {
|
|
|
43fe83 |
+ perror("setlocale");
|
|
|
43fe83 |
+ /* failure to setup locale is not fatal */
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ if (!bindtextdomain(PACKAGE, LOCALEDIR)) {
|
|
|
43fe83 |
+ perror("bindtextdomain");
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ if (!textdomain(PACKAGE)) {
|
|
|
43fe83 |
+ perror("textdomain");
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ /* The only option we support is help
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ while ((arg = getopt_long(argc, argv, "h", opt, &longindex)) != -1) {
|
|
|
43fe83 |
+ switch (arg) {
|
|
|
43fe83 |
+ case 'h':
|
|
|
43fe83 |
+ usage();
|
|
|
43fe83 |
+ exit(EXIT_SUCCESS);
|
|
|
43fe83 |
+ break;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (argc > optind) {
|
|
|
43fe83 |
+ virReportSystemError(EINVAL, _("%s takes no options"), progname);
|
|
|
43fe83 |
+ errno = EINVAL;
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (uid == 0) {
|
|
|
43fe83 |
+ virReportSystemError(EPERM, _("%s must be run by non root users"), progname);
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ name = virGetUserName(uid);
|
|
|
43fe83 |
+ if (!name)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ homedir = virGetUserDirectoryByUID(uid);
|
|
|
43fe83 |
+ if (!homedir)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!(conf = virConfReadFile(login_shell_path, 0)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if ((ngroups = virGetGroupList(uid, gid, &groups)) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virLoginShellAllowedUser(conf, name, groups) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!(shargv = virLoginShellGetShellArgv(conf)))
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ conn = virConnectOpen("lxc:///");
|
|
|
43fe83 |
+ if (!conn)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ dom = virDomainLookupByName(conn, name);
|
|
|
43fe83 |
+ if (!dom)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (!virDomainIsActive(dom) && virDomainCreate(dom)) {
|
|
|
43fe83 |
+ virErrorPtr last_error;
|
|
|
43fe83 |
+ last_error = virGetLastError();
|
|
|
43fe83 |
+ if (last_error->code != VIR_ERR_OPERATION_INVALID) {
|
|
|
43fe83 |
+ virReportSystemError(last_error->code,_("Can't create %s container: %s"), name, virGetLastErrorMessage());
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if ((nfdlist = virDomainLxcOpenNamespace(dom, &fdlist, 0)) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ if (VIR_ALLOC(secmodel) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ if (VIR_ALLOC(seclabel) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ if (virNodeGetSecurityModel(conn, secmodel) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+ if (virDomainGetSecurityLabel(dom, seclabel) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virFork(&cpid) < 0)
|
|
|
43fe83 |
+ goto cleanup;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (cpid == 0) {
|
|
|
43fe83 |
+ pid_t ccpid;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ /* Fork once because we don't want to affect
|
|
|
43fe83 |
+ * virt-login-shell's namespace itself
|
|
|
43fe83 |
+ */
|
|
|
43fe83 |
+ if (virSetUIDGID(0, 0, NULL, 0) < 0)
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virDomainLxcEnterSecurityLabel(secmodel,
|
|
|
43fe83 |
+ seclabel,
|
|
|
43fe83 |
+ NULL,
|
|
|
43fe83 |
+ 0) < 0)
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (nfdlist > 0) {
|
|
|
43fe83 |
+ if (virDomainLxcEnterNamespace(dom,
|
|
|
43fe83 |
+ nfdlist,
|
|
|
43fe83 |
+ fdlist,
|
|
|
43fe83 |
+ NULL,
|
|
|
43fe83 |
+ NULL,
|
|
|
43fe83 |
+ 0) < 0)
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ ret = virSetUIDGID(uid, gid, groups, ngroups);
|
|
|
43fe83 |
+ VIR_FREE(groups);
|
|
|
43fe83 |
+ if (ret < 0)
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (virFork(&ccpid) < 0)
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ if (ccpid == 0) {
|
|
|
43fe83 |
+ if (chdir(homedir) < 0) {
|
|
|
43fe83 |
+ virReportSystemError(errno, _("Unable chdir(%s)"), homedir);
|
|
|
43fe83 |
+ return EXIT_FAILURE;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ if (execv(shargv[0], (char *const*) shargv) < 0) {
|
|
|
43fe83 |
+ virReportSystemError(errno, _("Unable exec shell %s"), shargv[0]);
|
|
|
43fe83 |
+ return -errno;
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ return virProcessWait(ccpid, &status2);
|
|
|
43fe83 |
+ }
|
|
|
43fe83 |
+ ret = virProcessWait(cpid, &status);
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+cleanup:
|
|
|
43fe83 |
+ virConfFree(conf);
|
|
|
43fe83 |
+ virLoginShellFini(conn, dom);
|
|
|
43fe83 |
+ virStringFreeList(shargv);
|
|
|
43fe83 |
+ VIR_FREE(name);
|
|
|
43fe83 |
+ VIR_FREE(homedir);
|
|
|
43fe83 |
+ VIR_FREE(seclabel);
|
|
|
43fe83 |
+ VIR_FREE(secmodel);
|
|
|
43fe83 |
+ VIR_FREE(groups);
|
|
|
43fe83 |
+ if (ret)
|
|
|
43fe83 |
+ virDispatchError(NULL);
|
|
|
43fe83 |
+ return ret;
|
|
|
43fe83 |
+}
|
|
|
43fe83 |
diff --git a/tools/virt-login-shell.conf b/tools/virt-login-shell.conf
|
|
|
43fe83 |
new file mode 100644
|
|
|
43fe83 |
index 0000000..835fd3f
|
|
|
43fe83 |
--- /dev/null
|
|
|
43fe83 |
+++ b/tools/virt-login-shell.conf
|
|
|
43fe83 |
@@ -0,0 +1,26 @@
|
|
|
43fe83 |
+# Master configuration file for the virt-login-shell program.
|
|
|
43fe83 |
+# All settings described here are optional - if omitted, sensible
|
|
|
43fe83 |
+# defaults are used.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+# By default, virt-login-shell will connect you to a container running
|
|
|
43fe83 |
+# with the /bin/sh program. Modify the shell variable if you want your
|
|
|
43fe83 |
+# users to run a different shell or a setup container when joining a
|
|
|
43fe83 |
+# container. Shell commands must be a list of commands/options separated by
|
|
|
43fe83 |
+# comma and delimited by square brackets. Defaults to: /bin/sh -l.
|
|
|
43fe83 |
+# Modify and uncomment the following to modify the login shell.
|
|
|
43fe83 |
+# shell = [ "/bin/sh", "-l" ]
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+# allowed_users specifies the user names of all users that are allowed to
|
|
|
43fe83 |
+# execute virt-login-shell. You can specify the users as a comma
|
|
|
43fe83 |
+# separated list of usernames or user groups.
|
|
|
43fe83 |
+# The list of names support glob syntax.
|
|
|
43fe83 |
+# To disallow all users (default)
|
|
|
43fe83 |
+# allowed_users = []
|
|
|
43fe83 |
+# If you do not specify any names (default) then no one is allowed
|
|
|
43fe83 |
+# to use this executable.
|
|
|
43fe83 |
+# To allow fred and joe only
|
|
|
43fe83 |
+# allowed_users = ["fred", "joe"]
|
|
|
43fe83 |
+# To allow all users within a specific group prefix the group name with %.
|
|
|
43fe83 |
+# allowed_users = ["%engineers"]
|
|
|
43fe83 |
+# To allow all users specify the following
|
|
|
43fe83 |
+# allowed_users = [ "*" ]
|
|
|
43fe83 |
diff --git a/tools/virt-login-shell.pod b/tools/virt-login-shell.pod
|
|
|
43fe83 |
new file mode 100644
|
|
|
43fe83 |
index 0000000..0cd35cf
|
|
|
43fe83 |
--- /dev/null
|
|
|
43fe83 |
+++ b/tools/virt-login-shell.pod
|
|
|
43fe83 |
@@ -0,0 +1,62 @@
|
|
|
43fe83 |
+=head1 NAME
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+virt-login-shell - tool to execute a shell within a container matching the users name
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 SYNOPSIS
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+B<virt-login-shell>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 DESCRIPTION
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+The B<virt-login-shell> program is setuid shell that is used to join
|
|
|
43fe83 |
+an LXC container that matches the users name. If the container is not
|
|
|
43fe83 |
+running virt-login-shell will attempt to start the container.
|
|
|
43fe83 |
+virt-sandbox-shell is not allowed to be run by root. Normal users will get
|
|
|
43fe83 |
+added to a container that matches their username, if it exists. And they are
|
|
|
43fe83 |
+configured in /etc/libvirt/virt-login-shell.conf.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+The basic structure of most virt-login-shell usage is:
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ virt-login-shell
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 CONFIG
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+By default, virt-login-shell will execute the /bin/sh program for the user.
|
|
|
43fe83 |
+You can modify this behaviour by defining the shell variable in /etc/libvirt/virt-login-shell.conf.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+eg. shell = [ "/bin/ksh", "--login"]
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+By default no users are allowed to user virt-login-shell, if you want to allow
|
|
|
43fe83 |
+certain users to use virt-login-shell, you need to modify the allowed_users variable in /etc/libvirt/virt-login-shell.conf.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+eg. allowed_users = [ "tom", "dick", "harry" ]
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 BUGS
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+Report any bugs discovered to the libvirt community via the mailing
|
|
|
43fe83 |
+list C<http://libvirt.org/contact.html> or bug tracker C<http://libvirt.org/bugs.html>.
|
|
|
43fe83 |
+Alternatively report bugs to your software distributor / vendor.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 AUTHORS
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ Please refer to the AUTHORS file distributed with libvirt.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+ Daniel Walsh <dwalsh at redhat dot com>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 COPYRIGHT
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+Copyright (C) 2013 Red Hat, Inc., and the authors listed in the
|
|
|
43fe83 |
+libvirt AUTHORS file.
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 LICENSE
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+virt-login-shell is distributed under the terms of the GNU LGPL v2+.
|
|
|
43fe83 |
+This is free software; see the source for copying conditions. There
|
|
|
43fe83 |
+is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
|
43fe83 |
+PURPOSE
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=head1 SEE ALSO
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+L<virsh(1)>, L<http://www.libvirt.org/>
|
|
|
43fe83 |
+
|
|
|
43fe83 |
+=cut
|
|
|
43fe83 |
--
|
|
|
43fe83 |
1.8.3.2
|
|
|
43fe83 |
|