/* Copyright © 2005-2007 Roger Leigh * * 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 * . * *********************************************************************/ #include #include "sbuild-auth.h" #include #include #include #include #include #include #include #include using std::cerr; using std::endl; using boost::format; using namespace sbuild; namespace { typedef std::pair emap; /** * This is a list of the supported error codes. It's used to * construct the real error codes map. */ emap init_errors[] = { emap(auth::HOSTNAME, N_("Failed to get hostname")), // TRANSLATORS: %1% = user name or user ID emap(auth::USER, N_("User '%1%' not found")), // TRANSLATORS: %1% = group name or group ID emap(auth::GROUP, N_("Group '%1%' not found")), emap(auth::AUTHENTICATION, N_("Authentication failed")), emap(auth::AUTHORISATION, N_("Access not authorised")), emap(auth::PAM_DOUBLE_INIT, N_("PAM is already initialised")), emap(auth::PAM, N_("PAM error")) }; } template<> error::map_type error::error_strings (init_errors, init_errors + (sizeof(init_errors) / sizeof(init_errors[0]))); auth::auth (std::string const& service_name): service(service_name), uid(0), gid(0), user(), command(), home(), wd(), shell(), user_environment(), ruid(), rgid(), ruser(), rgroup(), message_verbosity(VERBOSITY_NORMAL) { this->ruid = getuid(); this->rgid = getgid(); struct passwd *pwent = getpwuid(this->ruid); if (pwent == 0) { if (errno) throw error(this->ruid, USER, strerror(errno)); else throw error(this->ruid, USER); } this->ruser = pwent->pw_name; struct group *grent = getgrgid(this->rgid); if (grent == 0) { if (errno) throw error(this->ruid, GROUP, strerror(errno)); else throw error(this->ruid, GROUP); } this->rgroup = grent->gr_name; /* By default, the auth user is the same as the remote user. */ set_user(this->ruser); } auth::~auth () { // Shutdown PAM. try { stop(); } catch (error const& e) { sbuild::log_exception_error(e); } } std::string const& auth::get_service () const { return this->service; } uid_t auth::get_uid () const { return this->uid; } gid_t auth::get_gid () const { return this->gid; } std::string const& auth::get_user () const { return this->user; } void auth::set_user (std::string const& user) { this->uid = getuid(); this->gid = getgid(); this->home = "/"; this->shell = "/bin/false"; this->user = user; struct passwd *pwent = getpwnam(this->user.c_str()); if (pwent == 0) { if (errno) throw error(user, USER, strerror(errno)); else throw error(user, USER); } this->uid = pwent->pw_uid; this->gid = pwent->pw_gid; this->home = pwent->pw_dir; this->shell = pwent->pw_shell; log_debug(DEBUG_INFO) << format("auth uid = %1%, gid = %2%") % this->uid % this->gid << endl; } string_list const& auth::get_command () const { return this->command; } void auth::set_command (string_list const& command) { this->command = command; } std::string const& auth::get_home () const { return this->home; } std::string const& auth::get_wd () const { return this->wd; } void auth::set_wd (std::string const& wd) { this->wd = wd; } std::string const& auth::get_shell () const { return this->shell; } environment const& auth::get_environment () const { return this->user_environment; } void auth::set_environment (char **environment) { set_environment(sbuild::environment(environment)); } void auth::set_environment (environment const& environment) { this->user_environment = environment; } 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. if (this->uid == 0) minimal.add(std::make_pair("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11")); else if (this->user_environment.empty()) minimal.add(std::make_pair("PATH", "/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games")); if (this->user_environment.empty()) { if (!this->home.empty() ) minimal.add(std::make_pair("HOME", this->home)); else minimal.add(std::make_pair("HOME", "/")); if (!this->user.empty()) { minimal.add(std::make_pair("LOGNAME", this->user)); minimal.add(std::make_pair("USER", this->user)); } { const char *term = getenv("TERM"); if (term) minimal.add(std::make_pair("TERM", term)); } if (!this->shell.empty()) minimal.add(std::make_pair("SHELL", this->shell)); } return minimal; } uid_t auth::get_ruid () const { return this->ruid; } gid_t auth::get_rgid () const { return this->rgid; } std::string const& auth::get_ruser () const { return this->ruser; } std::string const& auth::get_rgroup () const { return this->rgroup; } auth::verbosity auth::get_verbosity () const { return this->message_verbosity; } void auth::set_verbosity (auth::verbosity verbosity) { this->message_verbosity = verbosity; } void auth::start () { } void auth::stop () { } void auth::authenticate (status auth_status) { } void auth::setupenv () { } void auth::account () { } void auth::cred_establish () { } void auth::cred_delete () { } void auth::open_session () { } void auth::close_session () { }