// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "login_manager/child_job.h"

#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <base/logging.h>
#include <base/time/time.h>
#include <base/memory/scoped_ptr.h>

#include "login_manager/session_manager_service.h"
#include "login_manager/system_utils.h"

namespace login_manager {
const int ChildJobInterface::kCantSetUid = 127;
const int ChildJobInterface::kCantSetGid = 128;
const int ChildJobInterface::kCantSetGroups = 129;
const int ChildJobInterface::kCantSetEnv = 130;
const int ChildJobInterface::kCantExec = 255;

ChildJobInterface::Subprocess::Subprocess(uid_t desired_uid,
                                          SystemUtils* system)
    : pid_(-1),
      desired_uid_(desired_uid),
      system_(system) {
}

ChildJobInterface::Subprocess::~Subprocess() {}

bool ChildJobInterface::Subprocess::ForkAndExec(
    const std::vector<std::string>& args,
    const std::map<std::string, std::string>& environment_variables) {
  pid_ = system_->fork();
  if (pid_ == 0) {
    SessionManagerService::RevertHandlers();
    // We try to set our UID/GID to the desired UID, and then exec
    // the command passed in.
    int exit_code = SetIDs();
    if (exit_code)
      exit(exit_code);

    logging::CloseLogFile();  // So browser does not inherit logging FD.

    if (clearenv() != 0) {
      PLOG(ERROR) << "Error clearing environment";
      exit(kCantSetEnv);
    }
    for (std::map<std::string, std::string>::const_iterator it =
             environment_variables.begin();
         it != environment_variables.end(); ++it) {
      if (setenv(it->first.c_str(), it->second.c_str(), 1) != 0) {
        PLOG(ERROR) << "Error exporting " << it->first << "=" << it->second;
        exit(kCantSetEnv);
      }
    }

    scoped_ptr<char const*[]> argv(new char const*[args.size() + 1]);
    for (size_t i = 0; i < args.size(); ++i)
      argv[i] = args[i].c_str();
    argv[args.size()] = 0;

    execv(argv[0], const_cast<char* const*>(argv.get()));

    // Should never get here, unless we couldn't exec the command.
    PLOG(ERROR) << "Error executing " << argv[0];
    exit(kCantExec);
  } else if (pid_ < 0) {
    return false;
  }
  return true;
}

void ChildJobInterface::Subprocess::KillEverything(int signal) {
  DCHECK_GT(pid_, 0);
  system_->kill(-pid_, desired_uid_, signal);
}

void ChildJobInterface::Subprocess::Kill(int signal) {
  DCHECK_GT(pid_, 0);
  system_->kill(pid_, desired_uid_, signal);
}

int ChildJobInterface::Subprocess::SetIDs() {
  int to_return = 0;
  struct passwd* entry = getpwuid(desired_uid_);
  endpwent();
  if (initgroups(entry->pw_name, entry->pw_gid) == -1)
    to_return = kCantSetGroups;
  if (setgid(entry->pw_gid) == -1)
    to_return = kCantSetGid;
  if (setuid(desired_uid_) == -1)
    to_return = kCantSetUid;
  if (setsid() == -1)
    LOG(ERROR) << "can't setsid: " << strerror(errno);
  return to_return;
}

};  // namespace login_manager
