Package: schroot Version: 1.6.10-1 Severity: important Debian Release: 8.0 Tags: patch
schroot allows to set a Linux personality for chroots, e.g. to run a 32bit chroot on a 64bit system. And there is a schroot setup script to start services when entering the schroot. But these service setup script ignores the personality; that's my problem. So what is actually happening. Pasted From the RfC mails - thread is here: http://lists.alioth.debian.org/pipermail/buildd-tools-devel/2015-February/009398.html > I don't have any own setup script. > > I have a build / development system (Debian Wheezy), which is running > icecc. It's 64bit. The build schroot is an Ubuntu Precise schroot, 32bit. > > The config for the schroot contains the line "setup.services=iceccd", so > an iceccd instance is started per schroot session. The schroots iceccd > runs without remote connect, so just distributes jobs. > > So the user hacks on LibreOffice in the schroot and compiles using all > free icecc resources on several machines. > > But without the patch / personality-helper, the schroot sessions iceccd > is started in the host system context, so it thinks, it's running on a > 64bit system and generates 64bit object files, which obviuosly fails to > link, when the build system expects 32bit object files. So I've basically derivated a small schroot helper "schroot-impersonate" from "schroot-mount", which understands the schroot personality types and starts a command with the chroots personality. This program is now used in the service setup script and fixes my build problem. Actually I think all command run in inside the chroot from a setup scripts should set the personality, so this should become a schroot chroot personality wrapper, as the personality should always and just be applied in the chroot. The two attached patches: For schroot 1.6: was tested with the schroot-wheezy-backport git branch. At applies to schroot-1.6 FWIW. The original patch was done 1/2 year ago, but I did some cleanup and just a quick test and it still "seems to work". For schroot 1.7: was just compile tested - I currently don't have a Jessie environment. Regards, Jan-Marek
From 83603af12eb28314baf8330de244acc3c5f45374 Mon Sep 17 00:00:00 2001 From: Jan-Marek Glogowski <glo...@fbihome.de> Date: Mon, 11 Aug 2014 17:28:32 +0200 Subject: [PATCH] Add personality impersonator A little binary to run a program with the same personality then the chroot. This is currently used to run the chroot services with the correct personality. --- bin/CMakeLists.txt | 1 + bin/schroot-impersonate/CMakeLists.txt | 30 +++++ .../schroot-impersonate-main.cc | 148 +++++++++++++++++++++ bin/schroot-impersonate/schroot-impersonate-main.h | 89 +++++++++++++ .../schroot-impersonate-options.cc | 106 +++++++++++++++ .../schroot-impersonate-options.h | 75 +++++++++++ bin/schroot-impersonate/schroot-impersonate.cc | 47 +++++++ etc/setup.d/70services | 6 +- sbuild/sbuild-chroot-facet-personality.cc | 2 + 9 files changed, 502 insertions(+), 2 deletions(-) create mode 100644 bin/schroot-impersonate/CMakeLists.txt create mode 100644 bin/schroot-impersonate/schroot-impersonate-main.cc create mode 100644 bin/schroot-impersonate/schroot-impersonate-main.h create mode 100644 bin/schroot-impersonate/schroot-impersonate-options.cc create mode 100644 bin/schroot-impersonate/schroot-impersonate-options.h create mode 100644 bin/schroot-impersonate/schroot-impersonate.cc diff --git a/bin/CMakeLists.txt b/bin/CMakeLists.txt index 87cf774..1e69d34 100644 --- a/bin/CMakeLists.txt +++ b/bin/CMakeLists.txt @@ -22,5 +22,6 @@ add_subdirectory(dchroot) add_subdirectory(dchroot-dsa) add_subdirectory(schroot) add_subdirectory(schroot-base) +add_subdirectory(schroot-impersonate) add_subdirectory(schroot-listmounts) add_subdirectory(schroot-mount) diff --git a/bin/schroot-impersonate/CMakeLists.txt b/bin/schroot-impersonate/CMakeLists.txt new file mode 100644 index 0000000..56f8753 --- /dev/null +++ b/bin/schroot-impersonate/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> +# +# schroot is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# schroot is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. +# +##################################################################### + +set(impersonate_sources + schroot-impersonate-main.h + schroot-impersonate-main.cc + schroot-impersonate-options.h + schroot-impersonate-options.cc + schroot-impersonate.cc) + +add_executable(schroot-impersonate ${impersonate_sources}) +target_link_libraries(schroot-impersonate sbuild schroot-base) + +install(TARGETS schroot-impersonate RUNTIME + DESTINATION ${SCHROOT_LIBEXEC_DIR}) diff --git a/bin/schroot-impersonate/schroot-impersonate-main.cc b/bin/schroot-impersonate/schroot-impersonate-main.cc new file mode 100644 index 0000000..e662762 --- /dev/null +++ b/bin/schroot-impersonate/schroot-impersonate-main.cc @@ -0,0 +1,148 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include "schroot-impersonate-main.h" + +#include <cerrno> +#include <climits> +#include <cstdio> +#include <cstdlib> +#include <ctime> +#include <iostream> +#include <locale> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <boost/format.hpp> + +#include <sbuild/sbuild-personality.h> + + +using std::endl; +using boost::format; +using sbuild::_; +using sbuild::N_; +using namespace schroot_impersonate; + +namespace +{ + + typedef std::pair<main::error_code,const char *> emap; + + /** + * This is a list of the supported error codes. It's used to + * construct the real error codes map. + */ + emap init_errors[] = + { + // TRANSLATORS: %1% = command name + emap(main::EXEC, N_("Failed to execute â%1%â")), + }; + +} + +template<> +sbuild::error<main::error_code>::map_type +sbuild::error<main::error_code>::error_strings +(init_errors, + init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); + +main::main (options::ptr& options): + schroot_base::main("schroot-impersonate", + // TRANSLATORS: '...' is an ellipsis e.g. U+2026, + // and '-' is an em-dash. + _("[OPTIONâ¦] [COMMAND] â run command with persona"), + options, + false), + opts(options) +{ +} + +main::~main () +{ +} + +void +main::action_impersonate () +{ +#ifdef SBUILD_FEATURE_PERSONALITY + + /* Set the process execution domain. */ + if (!opts->persona.empty()) + { + sbuild::personality execPersonality( opts->persona ); + execPersonality.set(); + log_debug(sbuild::DEBUG_NOTICE) << "Set personality=" + << opts->persona << std::endl; + } + +#endif // SCHROOT_FEATURE_PERSONALITY + + sbuild::string_list command; + sbuild::environment env(environ); + + std::copy(opts->command.begin(), opts->command.end(), + std::back_inserter(command)); + + sbuild::log_debug(sbuild::DEBUG_NOTICE) + << "command=" + << sbuild::string_list_to_string(command, ", ") + << std::endl; + + try + { + sbuild::log_debug(sbuild::DEBUG_INFO) + << "impersonate_main: executing " + << sbuild::string_list_to_string(command, ", ") + << std::endl; + exec(command[0], command, env); + error e(command[0], EXEC, strerror(errno)); + sbuild::log_exception_error(e); + } + catch (std::exception const& e) + { + sbuild::log_exception_error(e); + } + catch (...) + { + sbuild::log_error() + << _("An unknown exception occurred") << std::endl; + } + + // This should never be reached. + exit(EXIT_FAILURE); +} + +int +main::run_impl () +{ + if (this->opts->action == options::ACTION_HELP) + action_help(std::cerr); + else if (this->opts->action == options::ACTION_VERSION) + action_version(std::cerr); + else if (this->opts->action == options::ACTION_IMPERSONATE) + action_impersonate(); + else + assert(0); // Invalid action. + + return EXIT_SUCCESS; +} diff --git a/bin/schroot-impersonate/schroot-impersonate-main.h b/bin/schroot-impersonate/schroot-impersonate-main.h new file mode 100644 index 0000000..ec2e095 --- /dev/null +++ b/bin/schroot-impersonate/schroot-impersonate-main.h @@ -0,0 +1,89 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef SCHROOT_IMPERSONATE_MAIN_H +#define SCHROOT_IMPERSONATE_MAIN_H + +#include <schroot-base/schroot-base-main.h> + +#include <schroot-impersonate/schroot-impersonate-options.h> + +#include <sbuild/sbuild-custom-error.h> + +/** + * schroot-impersonate program components + */ +namespace schroot_impersonate +{ + + /** + * Frontend for schroot. This class is used to "run" schroot. + */ + class main : public schroot_base::main + { + public: + /// Error codes. + enum error_code + { + EXEC ///< Failed to execute command. + }; + + /// Exception type. + typedef sbuild::custom_error<error_code> error; + + /** + * The constructor. + * + * @param options the command-line options to use. + */ + main (options::ptr& options); + + /// The destructor. + virtual ~main (); + + private: + /** + * List mounts. + */ + virtual void + action_impersonate (); + + protected: + /** + * Run the program. + * + * @returns 0 on success, 1 on failure or the exit status of the + * chroot command. + */ + virtual int + run_impl (); + + private: + /// The program options. + options::ptr opts; + }; + +} + +#endif /* SCHROOT_IMPERSONATE_MAIN_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/bin/schroot-impersonate/schroot-impersonate-options.cc b/bin/schroot-impersonate/schroot-impersonate-options.cc new file mode 100644 index 0000000..5caf8b0 --- /dev/null +++ b/bin/schroot-impersonate/schroot-impersonate-options.cc @@ -0,0 +1,106 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include <sbuild/sbuild-i18n.h> + +#include "schroot-impersonate-options.h" + +#include <cstdlib> +#include <iostream> + +#include <boost/format.hpp> +#include <boost/program_options.hpp> + +using std::endl; +using boost::format; +using sbuild::_; +namespace opt = boost::program_options; +using namespace schroot_impersonate; + +const options::action_type options::ACTION_IMPERSONATE ("impersonate"); + +options::options (): + schroot_base::options(), + persona(), + command(), + persona_opts(_("Persona")) +{ +} + +options::~options () +{ +} + +void +options::add_options () +{ + // Chain up to add basic options. + schroot_base::options::add_options(); + + action.add(ACTION_IMPERSONATE); + action.set_default(ACTION_IMPERSONATE); + + persona_opts.add_options() + ("persona,p", opt::value<std::string>(&this->persona), + _("Persona to use")); + + hidden.add_options() + ("command", opt::value<sbuild::string_list>(&this->command), + _("Command to run")); + + positional.add("command", -1); +} + +void +options::add_option_groups () +{ + // Chain up to add basic option groups. + schroot_base::options::add_option_groups(); + +#ifndef BOOST_PROGRAM_OPTIONS_DESCRIPTION_OLD + if (!persona_opts.options().empty()) +#else + if (!persona_opts.primary_keys().empty()) +#endif + { + visible.add(persona_opts); + global.add(persona_opts); + } +} + +void +options::check_options () +{ + // Chain up to check basic options. + schroot_base::options::check_options(); + + if (this->action == ACTION_IMPERSONATE) + { + if (this->command.begin() == this->command.end()) + throw error(_("No command specified")); + + if (!vm.count("persona")) + { + const char *env_persona = getenv("CHROOT_PERSONALITY"); + if (env_persona) + this->persona = env_persona; + } + } +} diff --git a/bin/schroot-impersonate/schroot-impersonate-options.h b/bin/schroot-impersonate/schroot-impersonate-options.h new file mode 100644 index 0000000..e0a36c9 --- /dev/null +++ b/bin/schroot-impersonate/schroot-impersonate-options.h @@ -0,0 +1,75 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef SCHROOT_IMPERSONATE_OPTIONS_H +#define SCHROOT_IMPERSONATE_OPTIONS_H + +#include <schroot-base/schroot-base-options.h> + +#include <string> + +namespace schroot_impersonate +{ + + /** + * schroot-impersonate command-line options. + */ + class options : public schroot_base::options + { + public: + /// A shared_ptr to an options object. + typedef std::shared_ptr<options> ptr; + + /// Begin, run and end a session. + static const action_type ACTION_IMPERSONATE; + + /// The constructor. + options (); + + /// The destructor. + virtual ~options (); + + /// The persona to use. + std::string persona; + + /// Command to run. + sbuild::string_list command; + + protected: + virtual void + add_options (); + + virtual void + add_option_groups (); + + virtual void + check_options (); + + /// Mount options group. + boost::program_options::options_description persona_opts; + }; + +} + +#endif /* SCHROOT_IMPERSONATE_OPTIONS_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/bin/schroot-impersonate/schroot-impersonate.cc b/bin/schroot-impersonate/schroot-impersonate.cc new file mode 100644 index 0000000..53b5510 --- /dev/null +++ b/bin/schroot-impersonate/schroot-impersonate.cc @@ -0,0 +1,47 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include "schroot-impersonate-options.h" +#include "schroot-impersonate-main.h" + +#include <schroot-base/schroot-base-run.h> + +using std::endl; +using boost::format; +namespace opt = boost::program_options; + +using namespace schroot_impersonate; + +/** + * Main routine. + * + * @param argc the number of arguments + * @param argv argument vector + * + * @returns 0 on success, 1 on failure or the exit status of the + * chroot command. + */ +int +main (int argc, + char *argv[]) +{ + return schroot_base::run + <schroot_impersonate::options, schroot_impersonate::main>(argc, argv); +} diff --git a/etc/setup.d/70services b/etc/setup.d/70services index c0cc1b2..6775e1a 100755 --- a/etc/setup.d/70services +++ b/etc/setup.d/70services @@ -38,7 +38,8 @@ if [ $STAGE = "setup-start" ] || [ $STAGE = "setup-recover" ]; then SETUP_SERVICES=$(echo "$SETUP_SERVICES" | tr ',' '\n') for service in $SETUP_SERVICES; do - chroot "$CHROOT_PATH" /usr/sbin/invoke-rc.d --force "$service" start + "$LIBEXEC_DIR"/schroot-impersonate -- $(which chroot) \ + "$CHROOT_PATH" /usr/sbin/invoke-rc.d --force "$service" start done elif [ $STAGE = "setup-stop" ]; then @@ -48,7 +49,8 @@ elif [ $STAGE = "setup-stop" ]; then SETUP_SERVICES=$(echo "$SETUP_SERVICES" | tr ',' '\n' | tac) for service in $SETUP_SERVICES; do - chroot "$CHROOT_PATH" /usr/sbin/invoke-rc.d --force "$service" stop || true + "$LIBEXEC_DIR"/schroot-impersonate -- $(which chroot) "$CHROOT_PATH" \ + /usr/sbin/invoke-rc.d --force "$service" stop || true done fi diff --git a/sbuild/sbuild-chroot-facet-personality.cc b/sbuild/sbuild-chroot-facet-personality.cc index ef9ad10..20af301 100644 --- a/sbuild/sbuild-chroot-facet-personality.cc +++ b/sbuild/sbuild-chroot-facet-personality.cc @@ -72,6 +72,8 @@ void chroot_facet_personality::setup_env (chroot const& chroot, environment& env) const { + if (get_persona().get_name() != "undefined") + env.add("CHROOT_PERSONALITY", get_persona().get_name()); } sbuild::chroot::session_flags -- 1.9.1
From 9ba8b8573f13157dffb371391f1440bc78e5037c Mon Sep 17 00:00:00 2001 From: Jan-Marek Glogowski <jan-marek.glogow...@muenchen.de> Date: Thu, 5 Feb 2015 12:00:40 +0100 Subject: [PATCH 1/2] Add personality impersonator A little binary to run a program with the same personality then the chroot. This is currently used to run the chroot services with the correct personality. --- CMakeLists.txt | 1 + etc/setup.d/70services | 6 +- lib/schroot/chroot/facet/personality.cc | 6 ++ lib/schroot/chroot/facet/personality.h | 3 + libexec/impersonate/CMakeLists.txt | 30 +++++++ libexec/impersonate/impersonate.cc | 45 ++++++++++ libexec/impersonate/main.cc | 140 ++++++++++++++++++++++++++++++++ libexec/impersonate/main.h | 93 +++++++++++++++++++++ libexec/impersonate/options.cc | 113 ++++++++++++++++++++++++++ libexec/impersonate/options.h | 78 ++++++++++++++++++ libexec/mount/options.cc | 10 +-- 11 files changed, 518 insertions(+), 7 deletions(-) create mode 100644 libexec/impersonate/CMakeLists.txt create mode 100644 libexec/impersonate/impersonate.cc create mode 100644 libexec/impersonate/main.cc create mode 100644 libexec/impersonate/main.h create mode 100644 libexec/impersonate/options.cc create mode 100644 libexec/impersonate/options.h diff --git a/CMakeLists.txt b/CMakeLists.txt index dd9c5da..babf44c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -317,6 +317,7 @@ add_subdirectory(lib/test) add_subdirectory(bin/schroot) add_subdirectory(bin/dchroot) add_subdirectory(bin/dchroot-dsa) +add_subdirectory(libexec/impersonate) add_subdirectory(libexec/listmounts) add_subdirectory(libexec/mount) add_subdirectory(test) diff --git a/etc/setup.d/70services b/etc/setup.d/70services index aff3c10..eddb98a 100755 --- a/etc/setup.d/70services +++ b/etc/setup.d/70services @@ -38,7 +38,8 @@ if [ $STAGE = "setup-start" ] || [ $STAGE = "setup-recover" ]; then SETUP_SERVICES=$(echo "$SETUP_SERVICES" | tr ',' '\n') for service in $SETUP_SERVICES; do - chroot "$CHROOT_PATH" /usr/sbin/invoke-rc.d --force "$service" start + "$LIBEXEC_DIR"/impersonate -- $(which chroot) \ + "$CHROOT_PATH" /usr/sbin/invoke-rc.d --force "$service" start done elif [ $STAGE = "setup-stop" ]; then @@ -48,7 +49,8 @@ elif [ $STAGE = "setup-stop" ]; then SETUP_SERVICES=$(echo "$SETUP_SERVICES" | tr ',' '\n' | tac) for service in $SETUP_SERVICES; do - chroot "$CHROOT_PATH" /usr/sbin/invoke-rc.d --force "$service" stop || true + "$LIBEXEC_DIR"/impersonate -- $(which chroot) "$CHROOT_PATH" \ + /usr/sbin/invoke-rc.d --force "$service" stop || true done fi diff --git a/lib/schroot/chroot/facet/personality.cc b/lib/schroot/chroot/facet/personality.cc index 044df6d..d6f0da7 100644 --- a/lib/schroot/chroot/facet/personality.cc +++ b/lib/schroot/chroot/facet/personality.cc @@ -119,6 +119,12 @@ namespace schroot keyfile::PRIORITY_OPTIONAL); } + void + personality::setup_env (environment& env) const + { + if (get_persona().get_name() != "undefined") + env.add("CHROOT_PERSONALITY", get_persona().get_name()); + } } } } diff --git a/lib/schroot/chroot/facet/personality.h b/lib/schroot/chroot/facet/personality.h index 82bcf52..23de596 100644 --- a/lib/schroot/chroot/facet/personality.h +++ b/lib/schroot/chroot/facet/personality.h @@ -91,6 +91,9 @@ namespace schroot virtual void set_keyfile (const keyfile& keyfile); + virtual void + setup_env (environment& env) const; + private: /// Process execution domain (Linux only). schroot::personality persona; diff --git a/libexec/impersonate/CMakeLists.txt b/libexec/impersonate/CMakeLists.txt new file mode 100644 index 0000000..ef7ba6e --- /dev/null +++ b/libexec/impersonate/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> +# +# schroot is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# schroot is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see +# <http://www.gnu.org/licenses/>. +# +##################################################################### + +set(impersonate_sources + main.h + main.cc + options.h + options.cc + impersonate.cc) + +add_executable(impersonate ${impersonate_sources}) +target_link_libraries(impersonate libschroot bin-common) + +install(TARGETS impersonate RUNTIME + DESTINATION ${SCHROOT_LIBEXEC_DIR}) diff --git a/libexec/impersonate/impersonate.cc b/libexec/impersonate/impersonate.cc new file mode 100644 index 0000000..fd1b206 --- /dev/null +++ b/libexec/impersonate/impersonate.cc @@ -0,0 +1,45 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include <libexec/impersonate/options.h> +#include <libexec/impersonate/main.h> + +#include <bin-common/run.h> + +using std::endl; +using boost::format; +namespace opt = boost::program_options; + +/** + * Main routine. + * + * @param argc the number of arguments + * @param argv argument vector + * + * @returns 0 on success, 1 on failure or the exit status of the + * chroot command. + */ +int +main (int argc, + char *argv[]) +{ + return bin::common::run + <bin::schroot_impersonate::options, bin::schroot_impersonate::main>(argc, argv); +} diff --git a/libexec/impersonate/main.cc b/libexec/impersonate/main.cc new file mode 100644 index 0000000..7418e19 --- /dev/null +++ b/libexec/impersonate/main.cc @@ -0,0 +1,140 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include "main.h" + +#include <cerrno> +#include <climits> +#include <cstdio> +#include <cstdlib> +#include <ctime> +#include <iostream> +#include <locale> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <boost/format.hpp> + +#include <schroot/personality.h> +#include <schroot/util.h> + +using std::endl; +using boost::format; +using schroot::_; +using schroot::N_; + +namespace schroot +{ + + template<> + error<bin::schroot_impersonate::main::error_code>::map_type + error<bin::schroot_impersonate::main::error_code>::error_strings = + { + // TRANSLATORS: %1% = command name + {bin::schroot_impersonate::main::EXEC, N_("Failed to execute â%1%â")} + }; + +} + +namespace bin +{ + namespace schroot_impersonate + { + + main::main (options::ptr& options): + bin::common::main("schroot-impersonate", + // TRANSLATORS: '...' is an ellipsis e.g. U+2026, + // and '-' is an em-dash. + _("[OPTIONâ¦] [COMMAND] â run command with persona"), + options, + false), + opts(options) + { + } + + main::~main () + { + } + + void + main::action_impersonate () + { +#ifdef SCHROOT_FEATURE_PERSONALITY + + /* Set the process execution domain. */ + if (!opts->persona.empty()) + { + schroot::personality execPersonality( opts->persona ); + execPersonality.set(); + schroot::log_debug(schroot::DEBUG_NOTICE) + << "Set personality=" << opts->persona << std::endl; + } + +#endif // SCHROOT_FEATURE_PERSONALITY + + schroot::string_list command; + schroot::environment env(environ); + + std::copy(opts->command.begin(), opts->command.end(), + std::back_inserter(command)); + + try + { + schroot::log_debug(schroot::DEBUG_INFO) + << "impersonate_main: executing " + << schroot::string_list_to_string(command, ", ") + << std::endl; + exec(command[0], command, env); + error e(command[0], EXEC, strerror(errno)); + schroot::log_exception_error(e); + } + catch (const std::exception& e) + { + schroot::log_exception_error(e); + } + catch (...) + { + schroot::log_error() + << _("An unknown exception occurred") << std::endl; + } + + // This should never be reached. + exit(EXIT_FAILURE); + } + + int + main::run_impl () + { + if (this->opts->action == options::ACTION_HELP) + action_help(std::cerr); + else if (this->opts->action == options::ACTION_VERSION) + action_version(std::cerr); + else if (this->opts->action == options::ACTION_IMPERSONATE) + action_impersonate(); + else + assert(0); // Invalid action. + + return EXIT_SUCCESS; + } + + } +} diff --git a/libexec/impersonate/main.h b/libexec/impersonate/main.h new file mode 100644 index 0000000..4bea482 --- /dev/null +++ b/libexec/impersonate/main.h @@ -0,0 +1,93 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef LIBEXEC_IMPERSONATE_MAIN_H +#define LIBEXEC_IMPERSONATE_MAIN_H + +#include <bin-common/main.h> + +#include <libexec/impersonate/options.h> + +#include <schroot/custom-error.h> +#include <schroot/environment.h> + +namespace bin +{ + /** + * schroot-mount program components + */ + namespace schroot_impersonate + { + + /** + * Frontend for schroot-impersonate. This class is used to "run" schroot-impersonate. + */ + class main : public bin::common::main + { + public: + /// Error codes. + enum error_code + { + EXEC ///< Failed to execute command. + }; + + /// Exception type. + typedef schroot::custom_error<error_code> error; + + /** + * The constructor. + * + * @param options the command-line options to use. + */ + main (options::ptr& options); + + /// The destructor. + virtual ~main (); + + private: + /** + * Run command with personality. + */ + virtual void + action_impersonate (); + + protected: + /** + * Run the program. + * + * @returns 0 on success, 1 on failure or the exit status of the + * chroot command. + */ + virtual int + run_impl (); + + private: + /// The program options. + options::ptr opts; + }; + + } +} + +#endif /* LIBEXEC_IMPERSONATE_MAIN_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/libexec/impersonate/options.cc b/libexec/impersonate/options.cc new file mode 100644 index 0000000..0839222 --- /dev/null +++ b/libexec/impersonate/options.cc @@ -0,0 +1,113 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#include <config.h> + +#include <schroot/i18n.h> + +#include <libexec/impersonate/options.h> + +#include <cstdlib> +#include <iostream> + +#include <boost/format.hpp> +#include <boost/program_options.hpp> + +using std::endl; +using boost::format; +using schroot::_; +namespace opt = boost::program_options; + +namespace bin +{ + namespace schroot_impersonate + { + + const options::action_type options::ACTION_IMPERSONATE ("impersonate"); + + options::options (): + bin::common::options(), + persona(), + command(), + persona_opts(_("Persona")) + { + } + + options::~options () + { + } + + void + options::add_options () + { + // Chain up to add basic options. + bin::common::options::add_options(); + + action.add(ACTION_IMPERSONATE); + action.set_default(ACTION_IMPERSONATE); + + persona_opts.add_options() + ("persona,p", opt::value<std::string>(&this->persona), + _("Persona to use")); + + hidden.add_options() + ("command", opt::value<schroot::string_list>(&this->command), + _("Command to run")); + + positional.add("command", -1); + } + + void + options::add_option_groups () + { + // Chain up to add basic option groups. + bin::common::options::add_option_groups(); + +#ifndef BOOST_PROGRAM_OPTIONS_DESCRIPTION_OLD + if (!persona_opts.options().empty()) +#else + if (!persona_opts.primary_keys().empty()) +#endif + { + visible.add(persona_opts); + global.add(persona_opts); + } + } + + void + options::check_options () + { + // Chain up to check basic options. + bin::common::options::check_options(); + + if (this->action == ACTION_IMPERSONATE) + { + if (this->command.begin() == this->command.end()) + throw error(_("No command specified")); + + if (!vm.count("persona")) + { + const char *env_persona = getenv("CHROOT_PERSONALITY"); + if (env_persona) + this->persona = env_persona; + } + } + } + + } +} diff --git a/libexec/impersonate/options.h b/libexec/impersonate/options.h new file mode 100644 index 0000000..e4c3db9 --- /dev/null +++ b/libexec/impersonate/options.h @@ -0,0 +1,78 @@ +/* Copyright © 2015 Jan-Marek Glogowski <glo...@fbihome.de> + * + * schroot is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * schroot is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see + * <http://www.gnu.org/licenses/>. + * + *********************************************************************/ + +#ifndef LIBEXEC_IMPERSONATE_OPTIONS_H +#define LIBEXEC_IMPERSONATE_OPTIONS_H + +#include <bin-common/options.h> + +#include <string> + +namespace bin +{ + namespace schroot_impersonate + { + + /** + * schroot-impersonate command-line options. + */ + class options : public bin::common::options + { + public: + /// A shared_ptr to an options object. + typedef std::shared_ptr<options> ptr; + + /// Begin, run and end a session. + static const action_type ACTION_IMPERSONATE; + + /// The constructor. + options (); + + /// The destructor. + virtual ~options (); + + /// The persona to use. + std::string persona; + + /// Command to run. + schroot::string_list command; + + protected: + virtual void + add_options (); + + virtual void + add_option_groups (); + + virtual void + check_options (); + + /// Mount options group. + boost::program_options::options_description persona_opts; + }; + + } +} + +#endif /* LIBEXEC_IMPERSONATE_OPTIONS_H */ + +/* + * Local Variables: + * mode:C++ + * End: + */ diff --git a/libexec/mount/options.cc b/libexec/mount/options.cc index 9045c6f..a33a977 100644 --- a/libexec/mount/options.cc +++ b/libexec/mount/options.cc @@ -82,12 +82,12 @@ namespace bin #ifndef BOOST_PROGRAM_OPTIONS_DESCRIPTION_OLD if (!mount.options().empty()) #else - if (!mount.primary_keys().empty()) + if (!mount.primary_keys().empty()) #endif - { - visible.add(mount); - global.add(mount); - } + { + visible.add(mount); + global.add(mount); + } } void -- 1.9.1