// Copyright 2017 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 "authpolicy/tgt_manager.h"

#include <algorithm>
#include <vector>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/location.h>
#include <base/notreached.h>
#include <base/strings/stringprintf.h>
#include <base/threading/platform_thread.h>
#include <base/threading/thread_task_runner_handle.h>

#include "authpolicy/anonymizer.h"
#include "authpolicy/authpolicy_flags.h"
#include "authpolicy/authpolicy_metrics.h"
#include "authpolicy/constants.h"
#include "authpolicy/jail_helper.h"
#include "authpolicy/log_colors.h"
#include "authpolicy/platform_helper.h"
#include "authpolicy/process_executor.h"
#include "authpolicy/samba_helper.h"
#include "bindings/authpolicy_containers.pb.h"

namespace authpolicy {

namespace {

// Requested TGT lifetimes in the kinit command. Format is 1d2h3m. If a server
// has a lower maximum lifetimes, the lifetimes of the TGT are capped.
const char kRequestedTgtValidityLifetime[] = "1d";
const char kRequestedTgtRenewalLifetime[] = "7d";

// Don't try to renew TGTs more often than this interval.
const int kMinTgtRenewDelaySeconds = 300;
static_assert(kMinTgtRenewDelaySeconds > 0, "");

// Fraction of the TGT validity lifetime to schedule automatic TGT renewal. For
// instance, if the TGT is valid for another 1000 seconds and the factor is 0.8,
// the TGT would be renewed after 800 seconds. Must be strictly between 0 and 1.
constexpr float kTgtRenewValidityLifetimeFraction = 0.8f;
static_assert(kTgtRenewValidityLifetimeFraction > 0.0f, "");
static_assert(kTgtRenewValidityLifetimeFraction < 1.0f, "");

// Size limit for GetKerberosFiles (1 MB).
const size_t kKrb5FileSizeLimit = 1024 * 1024;

// Invalid/unset file descriptor.
constexpr int kInvalidFd = -1;

// Encryption types for Kerberos configuration
constexpr char kEncTypesAES[] =
    "aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96";
constexpr char kEncTypesRC4[] = "rc4-hmac";

// Kerberos configuration file data.
const char kKrb5ConfData[] =
    "[libdefaults]\n"
    "\tdefault_tgs_enctypes = %s\n"
    "\tdefault_tkt_enctypes = %s\n"
    "\tpermitted_enctypes = %s\n"
    // Prune weak ciphers from the above list. With current settings it’s a
    // no-op, but still.
    "\tallow_weak_crypto = false\n"
    // This flag allows for authentication forwarding without requiring the user
    // to enter a password again. (see
    // https://tools.ietf.org/html/rfc4120#section-2.6)
    "\tforwardable = true\n"
    // Default is 300 seconds, but we might add a policy for that in the future.
    "\tclockskew = 300\n"
    // Required for password change.
    "\tdefault_realm = %s\n";
const char kKrb5RealmData[] =
    "[realms]\n"
    "\t%s = {\n"
    "\t\tkdc = [%s]\n"
    "\t\tkpasswd_server = [%s]\n"
    "\t}\n";

// Env variable to trace debug info of kinit and kpasswd.
const char kKrb5TraceEnvKey[] = "KRB5_TRACE";

// Maximum kinit tries.
const int kKinitMaxTries = 60;
// Wait interval between two kinit tries.
const int kKinitRetryWaitSeconds = 1;

// Keys for interpreting kinit, klist and kpasswd output.
const char kKeyBadPrincipal[] =
    "not found in Kerberos database while getting initial credentials";
const char kKeyBadPrincipal2[] =
    "Client not found in Kerberos database getting initial ticket";
const char kKeyBadPassword[] =
    "Preauthentication failed while getting initial credentials";
const char kKeyBadPassword2[] =
    "Password incorrect while getting initial credentials";
const char kKeyBadPassword3[] =
    "Preauthentication failed getting initial ticket";
const char kKeyPasswordExpiredStdout[] =
    "Password expired.  You must change it now.";
const char kKeyPasswordRejectedStdout[] = "Password change rejected";
const char kCannotReadPasswordStderr[] =
    "Cannot read password while getting initial credentials";
const char kKeyCannotResolve[] =
    "Cannot resolve network address for KDC in realm";
const char kKeyCannotContactKDC[] = "Cannot contact any KDC";
const char kKeyCannotFindKDC[] = "Cannot find KDC";
const char kKeyNoCrentialsCache[] = "No credentials cache found";
const char kKeyTicketExpired[] = "Ticket expired while renewing credentials";
const char kKeyEncTypeNotSupported[] = "KDC has no support for encryption type";

// Nice marker for TGT renewal related logs, for easy grepping.
const char kTgtRenewalHeader[] = "TGT RENEWAL - ";

// Returns true if the given principal is a machine principal.
bool IsMachine(const std::string& principal) {
  return Contains(principal, "$@");
}

// Reads the file at |path| into |data|. Returns |ERROR_LOCAL_IO| if the file
// could not be read.
WARN_UNUSED_RESULT ErrorType ReadFile(const base::FilePath& path,
                                      std::string* data) {
  data->clear();
  if (!base::ReadFileToStringWithMaxSize(path, data, kKrb5FileSizeLimit)) {
    PLOG(ERROR) << "Failed to read '" << path.value() << "'";
    data->clear();
    return ERROR_LOCAL_IO;
  }
  return ERROR_NONE;
}

// Formats a time delta in 1h 2m 3s format.
std::string FormatTimeDelta(int delta_seconds) {
  int h = delta_seconds / 3600;
  int m = (delta_seconds / 60) % 60;
  int s = delta_seconds % 60;

  std::string str;
  if (h > 0)
    str += base::StringPrintf("%ih", h);
  if (h > 0 || m > 0)
    str += base::StringPrintf("%s%im", str.size() > 0 ? " " : "", m);
  str += base::StringPrintf("%s%is", str.size() > 0 ? " " : "", s);
  return str;
}

std::ostream& operator<<(std::ostream& os,
                         const protos::TgtLifetime& lifetime) {
  os << "(valid for " << FormatTimeDelta(lifetime.validity_seconds())
     << ", renewable for " << FormatTimeDelta(lifetime.renewal_seconds())
     << ")";
  return os;
}

// In case kinit failed, checks the output and returns appropriate error codes.
WARN_UNUSED_RESULT ErrorType GetKinitError(const ProcessExecutor& kinit_cmd,
                                           bool is_machine_principal) {
  DCHECK_NE(0, kinit_cmd.GetExitCode());
  const std::string& kinit_out = kinit_cmd.GetStdout();
  const std::string& kinit_err = kinit_cmd.GetStderr();

  if (Contains(kinit_err, kKeyCannotContactKDC)) {
    LOG(ERROR) << "kinit failed - failed to contact KDC";
    return ERROR_CONTACTING_KDC_FAILED;
  }
  if (Contains(kinit_err, kKeyBadPrincipal)) {
    LOG(ERROR) << "kinit failed - bad "
               << (is_machine_principal ? "machine" : "user") << " name";
    return is_machine_principal ? ERROR_BAD_MACHINE_NAME : ERROR_BAD_USER_NAME;
  }
  if (Contains(kinit_err, kKeyBadPassword) ||
      Contains(kinit_err, kKeyBadPassword2)) {
    LOG(ERROR) << "kinit failed - bad password";
    return ERROR_BAD_PASSWORD;
  }
  // Check both stderr and stdout here since any kinit error in the change-
  // password-workflow would otherwise be interpreted as 'password expired'.
  if (Contains(kinit_out, kKeyPasswordExpiredStdout) &&
      Contains(kinit_err, kCannotReadPasswordStderr)) {
    if (Contains(kinit_out, kKeyPasswordRejectedStdout)) {
      LOG(ERROR) << "kinit failed - password rejected";
      return ERROR_PASSWORD_REJECTED;
    } else {
      LOG(ERROR) << "kinit failed - password expired";
      return ERROR_PASSWORD_EXPIRED;
    }
  }
  if (Contains(kinit_err, kKeyCannotResolve)) {
    LOG(ERROR) << "kinit failed - cannot resolve KDC realm";
    return ERROR_NETWORK_PROBLEM;
  }
  if (Contains(kinit_err, kKeyNoCrentialsCache)) {
    LOG(ERROR) << "kinit failed - no credentials cache found";
    return ERROR_NO_CREDENTIALS_CACHE_FOUND;
  }
  if (Contains(kinit_err, kKeyTicketExpired)) {
    LOG(ERROR) << "kinit failed - ticket expired";
    return ERROR_KERBEROS_TICKET_EXPIRED;
  }
  if (Contains(kinit_err, kKeyEncTypeNotSupported)) {
    LOG(ERROR) << "kinit failed - KDC does not support encryption type";
    return ERROR_KDC_DOES_NOT_SUPPORT_ENCRYPTION_TYPE;
  }
  LOG(ERROR) << "kinit failed with exit code " << kinit_cmd.GetExitCode();
  return ERROR_KINIT_FAILED;
}

// In case klist failed, checks the output and returns appropriate error codes.
WARN_UNUSED_RESULT ErrorType GetKListError(const ProcessExecutor& klist_cmd) {
  DCHECK_NE(0, klist_cmd.GetExitCode());
  const std::string& klist_out = klist_cmd.GetStdout();
  const std::string& klist_err = klist_cmd.GetStderr();

  if (Contains(klist_err, kKeyNoCrentialsCache)) {
    LOG(ERROR) << "klist failed - no credentials cache found";
    return ERROR_NO_CREDENTIALS_CACHE_FOUND;
  }

  // Test the return value of klist -s. The command returns 1 if the TGT is
  // invalid and 0 otherwise. Does not print anything.
  const std::vector<std::string>& args = klist_cmd.GetArgs();
  if (klist_out.empty() && klist_err.empty() &&
      std::find(args.begin(), args.end(), "-s") != args.end()) {
    LOG(ERROR) << "klist failed - ticket expired";
    return ERROR_KERBEROS_TICKET_EXPIRED;
  }

  LOG(ERROR) << "klist failed with exit code " << klist_cmd.GetExitCode();
  return ERROR_KLIST_FAILED;
}

// In case kpasswd failed, checks the output and returns appropriate error
// codes.
WARN_UNUSED_RESULT ErrorType GetKPasswdError(const ProcessExecutor& kpasswd_cmd,
                                             bool is_machine_principal) {
  DCHECK_NE(0, kpasswd_cmd.GetExitCode());
  const std::string& kpasswd_err = kpasswd_cmd.GetStderr();

  if (Contains(kpasswd_err, kKeyCannotContactKDC) ||
      Contains(kpasswd_err, kKeyCannotFindKDC)) {
    LOG(ERROR) << "kpasswd failed - failed to contact KDC";
    return ERROR_CONTACTING_KDC_FAILED;
  }
  if (Contains(kpasswd_err, kKeyBadPrincipal2)) {
    LOG(ERROR) << "kpasswd failed - bad "
               << (is_machine_principal ? "machine" : "user") << " name";
    return is_machine_principal ? ERROR_BAD_MACHINE_NAME : ERROR_BAD_USER_NAME;
  }
  if (Contains(kpasswd_err, kKeyBadPassword3)) {
    LOG(ERROR) << "kpasswd failed - bad password";
    return ERROR_BAD_PASSWORD;
  }
  if (Contains(kpasswd_err, kKeyPasswordRejectedStdout)) {
    LOG(ERROR) << "kpasswd failed - password rejected";
    return ERROR_PASSWORD_REJECTED;
  }

  LOG(ERROR) << "kpasswd failed with exit code " << kpasswd_cmd.GetExitCode();
  return ERROR_KPASSWD_FAILED;
}

std::string GetEncryptionTypesString(KerberosEncryptionTypes encryption_types) {
  switch (encryption_types) {
    case ENC_TYPES_ALL:
      return base::StringPrintf("%s %s", kEncTypesAES, kEncTypesRC4);
    case ENC_TYPES_STRONG:
      return kEncTypesAES;
    case ENC_TYPES_LEGACY:
      return kEncTypesRC4;
    case ENC_TYPES_COUNT:
      NOTREACHED() << "Not a valid encryption type and will default to strong.";
      return kEncTypesAES;
  }
}

}  // namespace

TgtManager::TgtManager(const PathService* path_service,
                       AuthPolicyMetrics* metrics,
                       const protos::DebugFlags* flags,
                       const JailHelper* jail_helper,
                       Anonymizer* anonymizer,
                       Delegate* delegate,
                       Path config_path,
                       Path credential_cache_path)
    : paths_(path_service),
      metrics_(metrics),
      flags_(flags),
      jail_helper_(jail_helper),
      anonymizer_(anonymizer),
      delegate_(delegate),
      config_path_(config_path),
      credential_cache_path_(credential_cache_path) {}

TgtManager::~TgtManager() {
  // Do a best-effort cleanup.
  base::DeleteFile(base::FilePath(paths_->Get(config_path_)));
  base::DeleteFile(base::FilePath(paths_->Get(credential_cache_path_)));

  // Note that the destuctor of |tgt_renewal_callback_| does not cancel.
  tgt_renewal_callback_.Cancel();
}

void TgtManager::SetPrincipal(const std::string& principal) {
  principal_ = principal;
  is_machine_principal_ = IsMachine(principal);
}

void TgtManager::Reset() {
  principal_.clear();
  is_machine_principal_ = false;
  realm_.clear();
  kdc_ip_.clear();
  kinit_retry_ = false;
  encryption_types_ = ENC_TYPES_STRONG;
  EnableTgtAutoRenewal(false);
}

ErrorType TgtManager::AcquireTgtWithPassword(int password_fd) {
  return AcquireTgt(password_fd, Path::INVALID);
}

ErrorType TgtManager::AcquireTgtWithKeytab(Path keytab_path) {
  return AcquireTgt(kInvalidFd, keytab_path);
}

ErrorType TgtManager::AcquireTgt(int password_fd, Path keytab_path) {
  // Either password or keytab.
  DCHECK((password_fd != kInvalidFd) ^ (keytab_path != Path::INVALID));

  // Make sure we have the info we need.
  DCHECK(!principal_.empty());
  DCHECK(!realm_.empty());

  // Call kinit to get the Kerberos ticket-granting-ticket.
  ProcessExecutor kinit_cmd(
      {paths_->Get(Path::KINIT), principal_, kValidityLifetimeParam,
       kRequestedTgtValidityLifetime, kRenewalLifetimeParam,
       kRequestedTgtRenewalLifetime});
  if (keytab_path != Path::INVALID) {
    kinit_cmd.PushArg(kUseKeytabParam);
    kinit_cmd.SetEnv(kKrb5KTEnvKey, kFilePrefix + paths_->Get(keytab_path));
  }
  ErrorType error = RunKinit(&kinit_cmd, password_fd);
  if (error == ERROR_CONTACTING_KDC_FAILED) {
    LOG(WARNING) << "Retrying kinit without KDC IP config in the krb5.conf";
    kdc_ip_.clear();
    error = RunKinit(&kinit_cmd, password_fd);
  }

  // Don't retry again.
  kinit_retry_ = false;

  // If it worked, re-trigger the TGT renewal task.
  if (error == ERROR_NONE && tgt_autorenewal_enabled_)
    UpdateTgtAutoRenewal();

  // Trigger signal if files changed.
  MaybeTriggerKerberosFilesChanged();

  return error;
}

ErrorType TgtManager::GetKerberosFiles(KerberosFiles* files) {
  files->clear_krb5cc();
  files->clear_krb5conf();

  ErrorType error;
  std::string krb5cc;
  {
    // Note: The krb5cc is readable only by authpolicyd-exec.
    ScopedSwitchToSavedUid switch_scope;
    base::FilePath krb5cc_path(paths_->Get(credential_cache_path_));
    if (!base::PathExists(krb5cc_path))
      return ERROR_NONE;
    error = ReadFile(krb5cc_path, &krb5cc);
    if (error != ERROR_NONE)
      return error;
  }

  std::string krb5conf;
  base::FilePath krb5conf_path(paths_->Get(config_path_));
  error = ReadFile(krb5conf_path, &krb5conf);
  if (error != ERROR_NONE)
    return error;

  files->mutable_krb5cc()->assign(krb5cc.begin(), krb5cc.end());
  files->mutable_krb5conf()->assign(krb5conf.begin(), krb5conf.end());
  return ERROR_NONE;
}

void TgtManager::SetKerberosFilesChangedCallback(
    const base::Closure& callback) {
  kerberos_files_changed_ = callback;
}

void TgtManager::EnableTgtAutoRenewal(bool enabled) {
  if (tgt_autorenewal_enabled_ != enabled) {
    tgt_autorenewal_enabled_ = enabled;
    UpdateTgtAutoRenewal();
  }
}

ErrorType TgtManager::RenewTgt() {
  // kinit -R renews the TGT.
  ProcessExecutor kinit_cmd({paths_->Get(Path::KINIT), kRenewParam});
  ErrorType error = RunKinit(&kinit_cmd, kInvalidFd);

  // No matter if it worked or not, reschedule auto-renewal. We might be offline
  // and want to try again later.
  UpdateTgtAutoRenewal();

  // Trigger signal if files changed.
  MaybeTriggerKerberosFilesChanged();

  // Let the delegate do its thing.
  delegate_->OnTgtRenewed();

  return error;
}

ErrorType TgtManager::GetTgtLifetime(protos::TgtLifetime* lifetime) {
  // Check local file first before calling klist -s, since that would respond
  // ERROR_KERBEROS_TICKET_EXPIRED instead of ERROR_NO_CREDENTIALS_CACHE_FOUND.
  if (!base::PathExists(base::FilePath(paths_->Get(credential_cache_path_)))) {
    LOG(ERROR) << "GetTgtLifetime failed - no credentials cache found";
    return ERROR_NO_CREDENTIALS_CACHE_FOUND;
  }

  // Call klist -s to find out whether the TGT is still valid.
  {
    ProcessExecutor klist_cmd({paths_->Get(Path::KLIST), kSetExitStatusParam,
                               kCredentialCacheParam,
                               paths_->Get(credential_cache_path_)});
    if (!jail_helper_->SetupJailAndRun(&klist_cmd, Path::KLIST_SECCOMP,
                                       TIMER_KLIST)) {
      return GetKListError(klist_cmd);
    }
  }

  // Now that we know the TGT is valid, call klist again (without -s) and parse
  // the output to get the TGT lifetime.
  {
    ProcessExecutor klist_cmd({paths_->Get(Path::KLIST), kCredentialCacheParam,
                               paths_->Get(credential_cache_path_)});
    if (!jail_helper_->SetupJailAndRun(&klist_cmd, Path::KLIST_SECCOMP,
                                       TIMER_KLIST)) {
      return GetKListError(klist_cmd);
    }

    // Parse the output to find the lifetime. Enclose in a sandbox for security
    // considerations.
    ProcessExecutor parse_cmd({paths_->Get(Path::PARSER), kCmdParseTgtLifetime,
                               SerializeFlags(*flags_)});
    parse_cmd.SetInputString(klist_cmd.GetStdout());
    if (!jail_helper_->SetupJailAndRun(&parse_cmd, Path::PARSER_SECCOMP,
                                       TIMER_NONE)) {
      LOG(ERROR) << "authpolicy_parser parse_tgt_lifetime failed with "
                 << "exit code " << parse_cmd.GetExitCode();
      return ERROR_PARSE_FAILED;
    }
    if (!lifetime->ParseFromString(parse_cmd.GetStdout())) {
      LOG(ERROR) << "Failed to parse TGT lifetime protobuf from string";
      return ERROR_PARSE_FAILED;
    }
    return ERROR_NONE;
  }
}

ErrorType TgtManager::ChangePassword(const std::string& old_password,
                                     const std::string& new_password) {
  // Write configuration.
  ErrorType error = WriteKrb5Conf();
  if (error != ERROR_NONE)
    return error;

  // Write passwords to pipe.
  base::ScopedFD password_fd = WriteStringToPipe(
      old_password + "\n" + new_password + "\n" + new_password);
  if (!password_fd.is_valid())
    return ERROR_LOCAL_IO;

  // Setup and run kpasswd command.
  DCHECK(!principal_.empty());
  ProcessExecutor kpasswd_cmd({paths_->Get(Path::KPASSWD), principal_});
  kpasswd_cmd.SetInputFile(password_fd.get());
  kpasswd_cmd.SetEnv(kKrb5ConfEnvKey, kFilePrefix + paths_->Get(config_path_));
  SetupKrb5Trace(&kpasswd_cmd);
  if (!jail_helper_->SetupJailAndRun(&kpasswd_cmd, Path::KPASSWD_SECCOMP,
                                     TIMER_KPASSWD)) {
    OutputKrb5Trace();
    return GetKPasswdError(kpasswd_cmd, is_machine_principal_);
  }
  return ERROR_NONE;
}

bool TgtManager::Backup(protos::TgtState* state) {
  // Read the TGT first since it can fail.
  // Note: The krb5cc is readable only by authpolicyd-exec.
  std::string krb5cc;
  {
    ScopedSwitchToSavedUid switch_scope;
    base::FilePath krb5cc_path(paths_->Get(credential_cache_path_));
    if (!base::ReadFileToStringWithMaxSize(krb5cc_path, &krb5cc,
                                           kKrb5FileSizeLimit)) {
      PLOG(ERROR)
          << "TGT backup failed to read Kerberos credential cache from '"
          << krb5cc_path.value() << "'";
      return false;
    }
  }

  // Store data in the state blob.
  DCHECK(state);
  state->set_realm(realm_);
  state->set_kdc_ip(kdc_ip_);
  state->set_principal(principal_);
  state->set_krb5cc(krb5cc);
  return true;
}

bool TgtManager::Restore(const protos::TgtState& state) {
  // Verify state.
  if (!state.has_realm() || !state.has_kdc_ip() || !state.has_principal() ||
      !state.has_krb5cc()) {
    LOG(ERROR) << "TGT restore failed, invalid state";
    return false;
  }

  // Write TGT first since it can fail.
  // Note: The krb5cc is writeable only by authpolicyd-exec.
  {
    ScopedSwitchToSavedUid switch_scope;
    const base::FilePath krb5cc_path(paths_->Get(credential_cache_path_));
    const int size = static_cast<int>(state.krb5cc().size());
    if (base::WriteFile(krb5cc_path, state.krb5cc().data(), size) != size) {
      PLOG(ERROR) << "TGT restore failed to write Kerberos credential cache to "
                  << krb5cc_path.value();
      return false;
    }
  }

  realm_ = state.realm();
  kdc_ip_ = state.kdc_ip();
  SetPrincipal(state.principal());

  // Do a best effort restoring the config. It is needed e.g. for
  // GetKerberosFiles(). Don't exit here since we'd be in an undefined state.
  // Even if this fails here, it'll eventually recover since many instances
  // write the config.
  ignore_result(WriteKrb5Conf());

  // Trigger files changed signal.
  kerberos_files_dirty_ = true;
  MaybeTriggerKerberosFilesChanged();

  return true;
}

ErrorType TgtManager::RunKinit(ProcessExecutor* kinit_cmd,
                               int password_fd) const {
  // Write configuration.
  ErrorType error = WriteKrb5Conf();
  if (error != ERROR_NONE)
    return error;

  // Set Kerberos credential cache and configuration file paths.
  kinit_cmd->SetEnv(kKrb5CCEnvKey, paths_->Get(credential_cache_path_));
  kinit_cmd->SetEnv(kKrb5ConfEnvKey, kFilePrefix + paths_->Get(config_path_));

  error = ERROR_NONE;
  const int max_tries = (kinit_retry_ ? kKinitMaxTries : 1);
  int tries, failed_tries = 0;
  for (tries = 1; tries <= max_tries; ++tries) {
    // Sleep between subsequent tries (probably a propagation issue).
    if (tries > 1 && !kinit_retry_sleep_disabled_for_testing_) {
      base::PlatformThread::Sleep(
          base::TimeDelta::FromSeconds(kKinitRetryWaitSeconds));
    }
    SetupKrb5Trace(kinit_cmd);

    // Set password as input. Duplicate it in any case since we don't know
    // whether we'll have to rerun.
    base::ScopedFD password_dup;
    if (password_fd != kInvalidFd) {
      password_dup = DuplicatePipe(password_fd);
      if (!password_dup.is_valid()) {
        error = ERROR_LOCAL_IO;
        break;
      }
      kinit_cmd->SetInputFile(password_dup.get());
    }

    if (jail_helper_->SetupJailAndRun(kinit_cmd, Path::KINIT_SECCOMP,
                                      TIMER_KINIT)) {
      error = ERROR_NONE;
      break;
    }

    failed_tries++;
    OutputKrb5Trace();
    error = GetKinitError(*kinit_cmd, is_machine_principal_);

    // If kinit fails because credentials are not propagated yet, these are
    // the error types you get.
    if (error != ERROR_BAD_USER_NAME && error != ERROR_BAD_MACHINE_NAME &&
        error != ERROR_BAD_PASSWORD) {
      break;
    }
  }
  metrics_->Report(METRIC_KINIT_FAILED_TRY_COUNT, failed_tries);

  // If there was no error, assume that the Kerberos credential cache changed.
  if (error == ERROR_NONE)
    kerberos_files_dirty_ = true;

  return error;
}

ErrorType TgtManager::WriteKrb5Conf() const {
  const std::string enc_types = GetEncryptionTypesString(encryption_types_);
  std::string data =
      base::StringPrintf(kKrb5ConfData, enc_types.c_str(), enc_types.c_str(),
                         enc_types.c_str(), realm_.c_str());
  if (!kdc_ip_.empty()) {
    data += base::StringPrintf(kKrb5RealmData, realm_.c_str(), kdc_ip_.c_str(),
                               kdc_ip_.c_str());
  }
  const base::FilePath krbconf_path(paths_->Get(config_path_));

  // Only set kerberos_files_dirty_ if the config data has actually changed.
  // Otherwise, the KerberosFilesChanged signal gets triggered way too often,
  // causing the krb5cc in Chrome to reset all the time.
  std::string prev_data;
  if (!base::ReadFileToStringWithMaxSize(krbconf_path, &prev_data,
                                         kKrb5FileSizeLimit) ||
      data != prev_data) {
    const int data_size = static_cast<int>(data.size());
    if (base::WriteFile(krbconf_path, data.data(), data_size) != data_size) {
      LOG(ERROR) << "Failed to write krb5 conf file '" << krbconf_path.value()
                 << "'";
      return ERROR_LOCAL_IO;
    }
    kerberos_files_dirty_ = true;
  }

  return ERROR_NONE;
}

void TgtManager::SetupKrb5Trace(ProcessExecutor* krb5_cmd) const {
  if (!flags_->trace_krb5())
    return;
  const std::string& trace_path = paths_->Get(Path::KRB5_TRACE);
  {
    // Delete krb5 trace file (must be done as authpolicyd-exec).
    ScopedSwitchToSavedUid switch_scope;
    if (!base::DeleteFile(base::FilePath(trace_path))) {
      LOG(WARNING) << "Failed to delete krb5 trace file";
    }
  }
  krb5_cmd->SetEnv(kKrb5TraceEnvKey, trace_path);
}

void TgtManager::OutputKrb5Trace() const {
  if (!flags_->trace_krb5())
    return;
  const std::string& trace_path = paths_->Get(Path::KRB5_TRACE);
  std::string trace;
  {
    // Read krb5 trace file (must be done as authpolicyd-exec).
    ScopedSwitchToSavedUid switch_scope;
    if (!base::ReadFileToString(base::FilePath(trace_path), &trace))
      trace = "<failed to read>";
  }
  LogLongString(kColorKrb5Trace, "Krb5 trace: ", trace, anonymizer_);
}

void TgtManager::UpdateTgtAutoRenewal() {
  // Cancel an existing callback if there is any.
  if (!tgt_renewal_callback_.IsCancelled())
    tgt_renewal_callback_.Cancel();

  if (tgt_autorenewal_enabled_) {
    // Find out how long the TGT is valid.
    protos::TgtLifetime lifetime;
    ErrorType error = GetTgtLifetime(&lifetime);
    if (error == ERROR_NONE && lifetime.validity_seconds() > 0) {
      if (lifetime.validity_seconds() >= lifetime.renewal_seconds()) {
        // If we TGT got renewed a lot and/or is not renewable, the validity
        // lifetime is bounded by the renewal lifetime.
        LOG(WARNING) << kTgtRenewalHeader << "TGT cannot be renewed anymore "
                     << lifetime;
      } else {
        // Trigger the renewal somewhere in the validity lifetime of the TGT.
        int delay_seconds = static_cast<int>(lifetime.validity_seconds() *
                                             kTgtRenewValidityLifetimeFraction);

        // Make sure we don't trigger excessively often in case the renewal
        // fails and we're getting close to the end of the validity lifetime.
        delay_seconds = std::max(delay_seconds, kMinTgtRenewDelaySeconds);

        LOG(INFO) << kTgtRenewalHeader << "Scheduling renewal in "
                  << FormatTimeDelta(delay_seconds) << " " << lifetime;

        tgt_renewal_callback_.Reset(
            base::Bind(&TgtManager::AutoRenewTgt, base::Unretained(this)));
        base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
            FROM_HERE, tgt_renewal_callback_.callback(),
            base::TimeDelta::FromSeconds(delay_seconds));
      }
    } else if (error == ERROR_KERBEROS_TICKET_EXPIRED) {
      // Expiry is the most likely error, print a nice message.
      LOG(WARNING) << kTgtRenewalHeader << "TGT expired, reinitializing "
                   << "requires credentials";
    }
  }
}

void TgtManager::AutoRenewTgt() {
  LOG(INFO) << kTgtRenewalHeader << "Running scheduled TGT renewal";
  ErrorType error = RenewTgt();
  if (error == ERROR_NONE)
    LOG(INFO) << kTgtRenewalHeader << "Succeeded";
  else
    LOG(ERROR) << kTgtRenewalHeader << "Failed with error " << error;
  metrics_->ReportError(ERROR_OF_AUTO_TGT_RENEWAL, error);
}

void TgtManager::MaybeTriggerKerberosFilesChanged() {
  if (kerberos_files_dirty_ && !kerberos_files_changed_.is_null())
    kerberos_files_changed_.Run();
  kerberos_files_dirty_ = false;
}

}  // namespace authpolicy
