| // Copyright 2012 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // This class is most definitely NOT re-entrant. | |
| #include "login_manager/generator_job.h" | |
| #include <errno.h> | |
| #include <signal.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <map> | |
| #include <memory> | |
| #include <optional> | |
| #include <string> | |
| #include <vector> | |
| #include <base/files/file_path.h> | |
| #include <base/logging.h> | |
| #include <base/strings/string_util.h> | |
| #include "login_manager/system_utils.h" | |
| namespace login_manager { | |
| namespace { | |
| const char kKeygenExecutable[] = "/sbin/keygen"; | |
| } // namespace | |
| GeneratorJobFactoryInterface::~GeneratorJobFactoryInterface() {} | |
| GeneratorJob::Factory::Factory() {} | |
| GeneratorJob::Factory::~Factory() {} | |
| std::unique_ptr<GeneratorJobInterface> GeneratorJob::Factory::Create( | |
| const std::string& filename, | |
| const base::FilePath& user_path, | |
| const std::optional<base::FilePath> ns_path, | |
| uid_t desired_uid, | |
| SystemUtils* utils) { | |
| return std::unique_ptr<GeneratorJobInterface>( | |
| new GeneratorJob(filename, user_path, ns_path, desired_uid, utils)); | |
| } | |
| GeneratorJob::GeneratorJob(const std::string& filename, | |
| const base::FilePath& user_path, | |
| const std::optional<base::FilePath> ns_path, | |
| uid_t desired_uid, | |
| SystemUtils* utils) | |
| : filename_(filename), | |
| user_path_(user_path), | |
| ns_path_(ns_path), | |
| system_(utils), | |
| subprocess_(desired_uid, system_) {} | |
| GeneratorJob::~GeneratorJob() {} | |
| bool GeneratorJob::RunInBackground() { | |
| std::vector<std::string> argv; | |
| argv.push_back(kKeygenExecutable); | |
| argv.push_back(filename_); | |
| argv.push_back(user_path_.value()); | |
| if (ns_path_) { | |
| subprocess_.EnterExistingMountNamespace(ns_path_.value()); | |
| } | |
| return subprocess_.ForkAndExec(argv, std::vector<std::string>()); | |
| } | |
| void GeneratorJob::KillEverything(int signal, const std::string& message) { | |
| if (subprocess_.GetPid() < 0) | |
| return; | |
| subprocess_.KillEverything(signal); | |
| } | |
| void GeneratorJob::Kill(int signal, const std::string& message) { | |
| if (subprocess_.GetPid() < 0) | |
| return; | |
| subprocess_.Kill(signal); | |
| } | |
| void GeneratorJob::WaitAndAbort(base::TimeDelta timeout) { | |
| if (subprocess_.GetPid() < 0) | |
| return; | |
| if (!system_->ProcessGroupIsGone(subprocess_.GetPid(), timeout)) | |
| KillEverything(SIGABRT, std::string()); | |
| else | |
| DLOG(INFO) << "Cleaned up child " << subprocess_.GetPid(); | |
| } | |
| const std::string GeneratorJob::GetName() const { | |
| base::FilePath exec_file(kKeygenExecutable); | |
| return exec_file.BaseName().value(); | |
| } | |
| pid_t GeneratorJob::CurrentPid() const { | |
| return subprocess_.GetPid(); | |
| } | |
| } // namespace login_manager |