diff options
author | Roger Leigh <rleigh@debian.org> | 2010-06-27 19:50:13 +0100 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2010-06-27 19:53:59 +0100 |
commit | 713064aae506233c7179d5190a556e4b9f459de6 (patch) | |
tree | 35d11afdd75e28526cd431c85d41927f0de78702 | |
parent | f0d29b5d50735e5ddde2891faa660b85795ad1ae (diff) | |
download | schroot-713064aae506233c7179d5190a556e4b9f459de6.tar.gz |
sbuild::chroot: Add preserve-environment key
Move handling complete environment out of sbuild::auth;
the minimal environment and auth_environment are now only
PAM-provided environment variables. These are merged with
the user environment only when required.
Functions using the environment for HOME and PATH now need
explicitly providing with an environment.
-rw-r--r-- | bin/dchroot-dsa/dchroot-dsa-session.cc | 9 | ||||
-rw-r--r-- | bin/dchroot-dsa/dchroot-dsa-session.h | 9 | ||||
-rw-r--r-- | bin/dchroot/dchroot-session-base.cc | 4 | ||||
-rw-r--r-- | bin/dchroot/dchroot-session-base.h | 2 | ||||
-rw-r--r-- | bin/dchroot/dchroot-session.cc | 9 | ||||
-rw-r--r-- | bin/dchroot/dchroot-session.h | 9 | ||||
-rw-r--r-- | bin/schroot/schroot-main-base.cc | 3 | ||||
-rw-r--r-- | man/schroot.1.in | 2 | ||||
-rw-r--r-- | man/schroot.conf.5.in | 9 | ||||
-rw-r--r-- | sbuild/sbuild-auth.cc | 11 | ||||
-rw-r--r-- | sbuild/sbuild-auth.h | 13 | ||||
-rw-r--r-- | sbuild/sbuild-chroot.cc | 25 | ||||
-rw-r--r-- | sbuild/sbuild-chroot.h | 20 | ||||
-rw-r--r-- | sbuild/sbuild-session.cc | 55 | ||||
-rw-r--r-- | sbuild/sbuild-session.h | 40 | ||||
-rw-r--r-- | test/config.ex2/sarge | 1 | ||||
-rw-r--r-- | test/config.ex2/sid | 1 | ||||
-rw-r--r-- | test/sbuild-chroot.cc | 12 | ||||
-rw-r--r-- | test/test-sbuild-chroot.h | 2 |
19 files changed, 180 insertions, 56 deletions
diff --git a/bin/dchroot-dsa/dchroot-dsa-session.cc b/bin/dchroot-dsa/dchroot-dsa-session.cc index 8d2cc742..a872c1b9 100644 --- a/bin/dchroot-dsa/dchroot-dsa-session.cc +++ b/bin/dchroot-dsa/dchroot-dsa-session.cc @@ -90,7 +90,7 @@ session::get_chroot_auth_status (sbuild::auth::status status, } sbuild::string_list -session::get_login_directories () const +session::get_login_directories (sbuild::environment const& env) const { sbuild::string_list ret; @@ -113,9 +113,10 @@ session::get_login_directories () const } void -session::get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - sbuild::string_list& command) const +session::get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + sbuild::string_list& command, + sbuild::environment const& env) const { std::string programstring = command[0]; file = programstring; diff --git a/bin/dchroot-dsa/dchroot-dsa-session.h b/bin/dchroot-dsa/dchroot-dsa-session.h index 20ad328b..abb5aeeb 100644 --- a/bin/dchroot-dsa/dchroot-dsa-session.h +++ b/bin/dchroot-dsa/dchroot-dsa-session.h @@ -61,12 +61,13 @@ namespace dchroot_dsa sbuild::chroot::ptr const& chroot) const; virtual sbuild::string_list - get_login_directories () const; + get_login_directories (sbuild::environment const& env) const; virtual void - get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - sbuild::string_list& command) const; + get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + sbuild::string_list& command, + sbuild::environment const& env) const; }; } diff --git a/bin/dchroot/dchroot-session-base.cc b/bin/dchroot/dchroot-session-base.cc index 4fe75a07..3d8ef4ed 100644 --- a/bin/dchroot/dchroot-session-base.cc +++ b/bin/dchroot/dchroot-session-base.cc @@ -76,9 +76,9 @@ session_base::run_impl () } sbuild::string_list -session_base::get_command_directories () const +session_base::get_command_directories (sbuild::environment const& env) const { // dchroot does not treat logins differently from commands with // respect to the cwd inside the chroot. - return get_login_directories(); + return get_login_directories(env); } diff --git a/bin/dchroot/dchroot-session-base.h b/bin/dchroot/dchroot-session-base.h index 1d8938f3..d6da5f4e 100644 --- a/bin/dchroot/dchroot-session-base.h +++ b/bin/dchroot/dchroot-session-base.h @@ -75,7 +75,7 @@ namespace dchroot run_impl (); virtual sbuild::string_list - get_command_directories () const; + get_command_directories (sbuild::environment const& env) const; private: /// dchroot compatibility enabled? diff --git a/bin/dchroot/dchroot-session.cc b/bin/dchroot/dchroot-session.cc index acd4710a..b25ef083 100644 --- a/bin/dchroot/dchroot-session.cc +++ b/bin/dchroot/dchroot-session.cc @@ -68,7 +68,7 @@ session::get_chroot_auth_status (sbuild::auth::status status, } sbuild::string_list -session::get_login_directories () const +session::get_login_directories (sbuild::environment const& env) const { sbuild::string_list ret; @@ -96,9 +96,10 @@ session::get_login_directories () const } void -session::get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - sbuild::string_list& command) const +session::get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + sbuild::string_list& command, + sbuild::environment const& env) const { std::string programstring = sbuild::string_list_to_string(command, " "); diff --git a/bin/dchroot/dchroot-session.h b/bin/dchroot/dchroot-session.h index 8c215c00..700eac06 100644 --- a/bin/dchroot/dchroot-session.h +++ b/bin/dchroot/dchroot-session.h @@ -60,12 +60,13 @@ namespace dchroot sbuild::chroot::ptr const& chroot) const; virtual sbuild::string_list - get_login_directories () const; + get_login_directories (sbuild::environment const& env) const; virtual void - get_user_command (sbuild::chroot::ptr& session_chroot, - std::string& file, - sbuild::string_list& command) const; + get_user_command (sbuild::chroot::ptr& session_chroot, + std::string& file, + sbuild::string_list& command, + sbuild::environment const& env) const; }; } diff --git a/bin/schroot/schroot-main-base.cc b/bin/schroot/schroot-main-base.cc index 81927f88..f1a8dac2 100644 --- a/bin/schroot/schroot-main-base.cc +++ b/bin/schroot/schroot-main-base.cc @@ -301,8 +301,7 @@ main_base::run_impl () this->session->get_auth()->set_command(this->options->command); if (!this->options->directory.empty()) this->session->get_auth()->set_wd(this->options->directory); - if (this->options->preserve) - this->session->get_auth()->set_environment(environ); + this->session->set_preserve_environment(this->options->preserve); this->session->set_session_id(this->options->session_name); this->session->set_force(this->options->session_force); if (this->options->quiet) diff --git a/man/schroot.1.in b/man/schroot.1.in index f463990c..6831fc5b 100644 --- a/man/schroot.1.in +++ b/man/schroot.1.in @@ -157,7 +157,7 @@ status. .IP The default behaviour is as follows (all directory paths are inside the chroot). A login shell is run in the current working directory. If this is -not available, it will try $HOME (when \fI\\-\-preserve\-environment\fP is +not available, it will try $HOME (when \fI\-\-preserve\-environment\fP is used), then the user's home directory, and \fI/\fP inside the chroot in turn. A command is always run in the current working directory inside the chroot. If none of the directories are available, schroot will exit with an error status. diff --git a/man/schroot.conf.5.in b/man/schroot.conf.5.in index a68760be..46f12b83 100644 --- a/man/schroot.conf.5.in +++ b/man/schroot.conf.5.in @@ -130,7 +130,14 @@ Linux are \[oq]bsd\[cq], \[oq]hpux\[cq], \[oq]irix32\[cq], \[oq]irix64\[cq], systems is \[oq]undefined\[cq]. The default value for non-Linux systems is \[oq]undefined\[cq]. .TP -\f[CBI]environment\-filter=\fP\f[CI]refex\fP +\f[CBI]preserve\-environment=\fP\f[CI]true\fP|\f[CI]false\fP +By default, the environment will not be preserved inside the chroot, instead a +minimal environment will be used. Set to \f[CI]true\fP to always preserve the +environment. This is useful for example when running X applications inside the +chroot, which need the environment to function correctly. The environment may +also be preserved using the \fI\-\-preserve\-environment\fP option. +.TP +\f[CBI]environment\-filter=\fP\f[CI]regex\fP The environment to be set in the chroot will be filtered in order to remove environment variables which may pose a security risk. Any environment variable matching the specified POSIX extended regular expression will be removed prior diff --git a/sbuild/sbuild-auth.cc b/sbuild/sbuild-auth.cc index ed156a8d..86b2ab18 100644 --- a/sbuild/sbuild-auth.cc +++ b/sbuild/sbuild-auth.cc @@ -29,6 +29,7 @@ #include <sstream> #include <syslog.h> +#include <unistd.h> #include <boost/format.hpp> @@ -77,7 +78,7 @@ auth::auth (std::string const& service_name): home(), wd(), shell(), - user_environment(), + user_environment(environ), ruid(), rgid(), ruser(), @@ -231,8 +232,6 @@ environment auth::get_minimal_environment () const { environment minimal; - if (!this->user_environment.empty()) - minimal = this->user_environment; // For security, PATH is always set to a sane state for root, but // only set in other cases if not preserving the environment. @@ -264,6 +263,12 @@ auth::get_minimal_environment () const return minimal; } +environment +auth::get_complete_environment () const +{ + return get_auth_environment() + get_environment(); +} + uid_t auth::get_ruid () const { diff --git a/sbuild/sbuild-auth.h b/sbuild/sbuild-auth.h index 83cb270e..0986d57e 100644 --- a/sbuild/sbuild-auth.h +++ b/sbuild/sbuild-auth.h @@ -245,14 +245,23 @@ namespace sbuild set_environment (environment const& environment); /** - * Get the minimal environment. This is the user environment plus + * Get the minimal environment. This is essential environment + * variables which are set if not already present. + * + * @returns an environment list. + */ + environment + get_minimal_environment () const; + + /** + * Get the complete environment. This is the user environment plus * essential environment variables which are set if not already * present. * * @returns an environment list. */ environment - get_minimal_environment () const; + get_complete_environment () const; /** * Get the PAM environment. This is the environment as set by PAM diff --git a/sbuild/sbuild-chroot.cc b/sbuild/sbuild-chroot.cc index 37ef6fa0..c048639e 100644 --- a/sbuild/sbuild-chroot.cc +++ b/sbuild/sbuild-chroot.cc @@ -108,6 +108,7 @@ sbuild::chroot::chroot (): root_users(), root_groups(), aliases(), + preserve_environment(false), environment_filter(SBUILD_DEFAULT_ENVIRONMENT_FILTER), mount_location(), original(true), @@ -131,6 +132,7 @@ sbuild::chroot::chroot (const chroot& rhs): root_users(rhs.root_users), root_groups(rhs.root_groups), aliases(rhs.aliases), + preserve_environment(rhs.preserve_environment), environment_filter(rhs.environment_filter), mount_location(rhs.mount_location), original(rhs.original), @@ -324,6 +326,18 @@ sbuild::chroot::set_aliases (string_list const& aliases) this->aliases = aliases; } +bool +sbuild::chroot::get_preserve_environment () const +{ + return this->preserve_environment; +} + +void +sbuild::chroot::set_preserve_environment (bool preserve_environment) +{ + this->preserve_environment = preserve_environment; +} + regex const& sbuild::chroot::get_environment_filter () const { @@ -596,6 +610,7 @@ sbuild::chroot::get_details (chroot const& chroot, .add(_("Root Users"), chroot.get_root_users()) .add(_("Root Groups"), chroot.get_root_groups()) .add(_("Aliases"), chroot.get_aliases()) + .add(_("Preserve Environment"), chroot.get_preserve_environment()) .add(_("Environment Filter"), chroot.get_environment_filter()) .add(_("Run Setup Scripts"), chroot.get_run_setup_scripts()) .add(_("Script Configuration"), chroot.get_script_config()) @@ -703,6 +718,10 @@ sbuild::chroot::get_keyfile (chroot const& chroot, keyfile::set_object_value(chroot, &chroot::get_verbosity_string, keyfile, chroot.get_keyfile_name(), "message-verbosity"); + + keyfile::set_object_value(chroot, &chroot::get_preserve_environment, + keyfile, chroot.get_keyfile_name(), + "preserve-environment"); } void @@ -849,4 +868,10 @@ sbuild::chroot::set_keyfile (chroot& chroot, "message-verbosity", keyfile::PRIORITY_OPTIONAL); used_keys.push_back("message-verbosity"); + + keyfile::get_object_value(chroot, &chroot::set_preserve_environment, + keyfile, chroot.get_keyfile_name(), + "preserve-environment", + keyfile::PRIORITY_OPTIONAL); + used_keys.push_back("preserve-environment"); } diff --git a/sbuild/sbuild-chroot.h b/sbuild/sbuild-chroot.h index 2788bbde..03fac5d0 100644 --- a/sbuild/sbuild-chroot.h +++ b/sbuild/sbuild-chroot.h @@ -352,6 +352,22 @@ namespace sbuild set_aliases (string_list const& aliases); /** + * Check if the environment should be preserved in the chroot. + * + * @returns true to preserve or false to clean. + */ + bool + get_preserve_environment () const; + + /** + * Set if the environment should be preserved in the chroot. + * + * @param preserve_environment true to preserve or false to clean. + */ + void + set_preserve_environment (bool preserve_environment); + + /** * Get the environment filter of the chroot. This is a POSIX * extended regular expression used to remove insecure environment * variables from the chroot environment. @@ -362,7 +378,7 @@ namespace sbuild get_environment_filter () const; /** - * Get the environment filter of the chroot. This is a POSIX + * Set the environment filter of the chroot. This is a POSIX * extended regular expression used to remove insecure environment * variables from the chroot environment. * @@ -760,6 +776,8 @@ namespace sbuild string_list root_groups; /// Alternative names for the chroot. string_list aliases; + /// Preserve environment? + bool preserve_environment; /// Environment filter regex. regex environment_filter; /// Location to mount chroot in the filesystem (if any). diff --git a/sbuild/sbuild-session.cc b/sbuild/sbuild-session.cc index cac37cc3..24a4183b 100644 --- a/sbuild/sbuild-session.cc +++ b/sbuild/sbuild-session.cc @@ -272,6 +272,7 @@ session::session (std::string const& service, saved_termios(), termios_ok(false), verbosity(), + preserve_environment(false), cwd(sbuild::getcwd()) { } @@ -353,6 +354,18 @@ session::set_verbosity (std::string const& verbosity) } bool +session::get_preserve_environment () const +{ + return this->preserve_environment; +} + +void +session::set_preserve_environment (bool preserve_environment) +{ + this->preserve_environment = preserve_environment; +} + +bool session::get_force () const { return this->force; @@ -632,10 +645,6 @@ session::run_impl () chroot::ptr chroot(ch->clone()); assert(chroot); - // Override chroot verbosity if needed. - if (!this->verbosity.empty()) - ch->set_verbosity(this->verbosity); - /* Create a session using randomly-generated session ID. */ if (ch->get_session_flags() & chroot::SESSION_CREATE) { @@ -676,6 +685,10 @@ session::run_impl () } assert(chroot); + // Override chroot verbosity if needed. + if (!this->verbosity.empty()) + chroot->set_verbosity(this->verbosity); + // Following authentication success, default child status to // success so that operations such as beginning, ending and // recovering sessions will return success unless an @@ -756,7 +769,7 @@ session::run_impl () } string_list -session::get_login_directories () const +session::get_login_directories (environment const& env) const { string_list ret; @@ -772,7 +785,6 @@ session::get_login_directories () const ret.push_back(this->cwd); // Set $HOME. - environment env = this->authstat->get_auth_environment(); std::string home; if (env.get("HOME", home) && std::find(ret.begin(), ret.end(), home) == ret.end()) @@ -791,7 +803,7 @@ session::get_login_directories () const } string_list -session::get_command_directories () const +session::get_command_directories (environment const& env) const { string_list ret; @@ -835,14 +847,15 @@ session::get_shell () const void session::get_command (sbuild::chroot::ptr& session_chroot, std::string& file, - string_list& command) const + string_list& command, + environment const& env) const { /* Run login shell */ if (command.empty() || command[0].empty()) // No command get_login_command(session_chroot, file, command); else - get_user_command(session_chroot, file, command); + get_user_command(session_chroot, file, command, env); } void @@ -930,10 +943,10 @@ session::get_login_command (sbuild::chroot::ptr& session_chroot, void session::get_user_command (sbuild::chroot::ptr& session_chroot, std::string& file, - string_list& command) const + string_list& command, + environment const& env) const { /* Search for program in path. */ - environment env = this->authstat->get_auth_environment(); std::string path; if (!env.get("PATH", path)) path.clear(); @@ -1148,6 +1161,15 @@ session::run_child (sbuild::chroot::ptr& session_chroot) assert(!get_shell().empty()); assert(this->authstat->is_initialised()); // PAM must be initialised + /* Set up environment */ + environment env; + env.set_filter(session_chroot->get_environment_filter()); + + if (get_preserve_environment() || session_chroot->get_preserve_environment()) + env += this->authstat->get_complete_environment(); + else + env += this->authstat->get_auth_environment(); + // Store before chroot call. this->cwd = sbuild::getcwd(); log_debug(DEBUG_INFO) << "CWD=" << this->cwd << std::endl; @@ -1201,9 +1223,9 @@ session::run_child (sbuild::chroot::ptr& session_chroot) string_list dlist; if (command.empty() || command[0].empty()) // No command - dlist = get_login_directories(); + dlist = get_login_directories(env); else - dlist = get_command_directories(); + dlist = get_command_directories(env); log_debug(DEBUG_INFO) << format("Directory fallbacks: %1%") % string_list_to_string(dlist, ", ") << endl; @@ -1235,16 +1257,11 @@ session::run_child (sbuild::chroot::ptr& session_chroot) } /* Fix up the command for exec. */ - get_command(session_chroot, file, command); + get_command(session_chroot, file, command, env); log_debug(DEBUG_NOTICE) << "command=" << string_list_to_string(command, ", ") << std::endl; - /* Set up environment */ - environment env; - env.set_filter(session_chroot->get_environment_filter()); - env += this->authstat->get_auth_environment(); - // Add equivalents to sudo's SUDO_USER, SUDO_UID, SUDO_GID, and // SUDO_COMMAND. env.add(std::make_pair("SCHROOT_COMMAND", diff --git a/sbuild/sbuild-session.h b/sbuild/sbuild-session.h index e7c79bed..fe74e162 100644 --- a/sbuild/sbuild-session.h +++ b/sbuild/sbuild-session.h @@ -215,6 +215,22 @@ namespace sbuild set_verbosity (std::string const& verbosity); /** + * Check if the environment should be preserved in the chroot. + * + * @returns true to preserve or false to clean. + */ + bool + get_preserve_environment () const; + + /** + * Set if the environment should be preserved in the chroot. + * + * @param preserve_environment true to preserve or false to clean. + */ + void + set_preserve_environment (bool preserve_environment); + + /** * Get the force status of this session. * * @returns true if operation will be forced, otherwise false. @@ -304,19 +320,21 @@ namespace sbuild * Get a list of directories to change to when running a login * shell. Multiple directories are used as fallbacks. * + * @param env the environment to use for HOME * @returns a list of directories */ virtual string_list - get_login_directories () const; + get_login_directories (environment const& env) const; /** * Get a list of directories to change to when running a command * Multiple directories are used as fallbacks. * + * @param env the environment to use for HOME * @returns a list of directories */ virtual string_list - get_command_directories () const; + get_command_directories (environment const& env) const; /** * Get the shell to run. This finds a suitable shell to run in @@ -335,11 +353,13 @@ namespace sbuild * present in the chroot list and the chroot configuration object. * @param file the filename to pass to execve(2). * @param command the argv to pass to execve(2). + * @param env the environment to use for PATH */ virtual void - get_command (chroot::ptr& session_chroot, - std::string& file, - string_list& command) const; + get_command (chroot::ptr& session_chroot, + std::string& file, + string_list& command, + environment const& env) const; /** * Get the command to run a login shell. @@ -361,11 +381,13 @@ namespace sbuild * present in the chroot list and the chroot configuration object. * @param file the filename to pass to execve(2). * @param command the argv to pass to execve(2). + * @param env the environment to use for PATH */ virtual void - get_user_command (chroot::ptr& session_chroot, - std::string& file, - string_list& command) const; + get_user_command (chroot::ptr& session_chroot, + std::string& file, + string_list& command, + environment const& env) const; private: /** @@ -515,6 +537,8 @@ namespace sbuild bool termios_ok; /// Message verbosity. std::string verbosity; + /// Preserve environment? + bool preserve_environment; protected: /// Current working directory. diff --git a/test/config.ex2/sarge b/test/config.ex2/sarge index 359ce713..8306da10 100644 --- a/test/config.ex2/sarge +++ b/test/config.ex2/sarge @@ -6,3 +6,4 @@ groups=sbuild root-groups=root,sbuild #root-groups=root aliases=stable +preserve-environment=true
\ No newline at end of file diff --git a/test/config.ex2/sid b/test/config.ex2/sid index 03d271ca..fdd25a30 100644 --- a/test/config.ex2/sid +++ b/test/config.ex2/sid @@ -16,3 +16,4 @@ groups=sbuild,root root-groups=root,sbuild directory=/srv/chroot/sid message-verbosity=verbose +preserve-environment=false
\ No newline at end of file diff --git a/test/sbuild-chroot.cc b/test/sbuild-chroot.cc index 850a7aa0..fda58514 100644 --- a/test/sbuild-chroot.cc +++ b/test/sbuild-chroot.cc @@ -115,6 +115,7 @@ class test_chroot : public test_chroot_base<basic_chroot> CPPUNIT_TEST(test_active); CPPUNIT_TEST(test_run_setup_scripts); CPPUNIT_TEST(test_verbose); + CPPUNIT_TEST(test_preserve_environment); CPPUNIT_TEST_EXCEPTION(test_verbose_error, sbuild::chroot::error); CPPUNIT_TEST(test_chroot_type); CPPUNIT_TEST(test_setup_env); @@ -231,6 +232,17 @@ public: CPPUNIT_ASSERT(std::string(chroot->get_verbosity_string()) == "normal"); } + void test_preserve_environment() + { + std::tr1::shared_ptr<basic_chroot> c = std::tr1::dynamic_pointer_cast<basic_chroot>(chroot); + + CPPUNIT_ASSERT(chroot->get_preserve_environment() == false); + c->set_preserve_environment(true); + CPPUNIT_ASSERT(chroot->get_preserve_environment() == true); + c->set_preserve_environment(false); + CPPUNIT_ASSERT(chroot->get_preserve_environment() == false); + } + void test_verbose_error() { std::tr1::shared_ptr<basic_chroot> c = std::tr1::dynamic_pointer_cast<basic_chroot>(chroot); diff --git a/test/test-sbuild-chroot.h b/test/test-sbuild-chroot.h index 99f95892..47b67138 100644 --- a/test/test-sbuild-chroot.h +++ b/test/test-sbuild-chroot.h @@ -150,6 +150,7 @@ public: chroot->set_groups(sbuild::split_string("group1,group2", ",")); chroot->set_root_groups(sbuild::split_string("group3,group4", ",")); chroot->set_verbosity("quiet"); + chroot->set_preserve_environment(false); sbuild::chroot_facet_personality::ptr pfac (chroot->get_facet<sbuild::chroot_facet_personality>()); @@ -195,6 +196,7 @@ public: keyfile.set_value(group, "command-prefix", ""); keyfile.set_value(group, "script-config", "default/config"); keyfile.set_value(group, "message-verbosity", "quiet"); + keyfile.set_value(group, "preserve-environment", "false"); } void setup_keyfile_session (sbuild::keyfile& keyfile, |