// 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/files/file_util.h>
#include <base/location.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;
  }
}

}  // 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_)),
                   false /* recursive */);
  base::DeleteFile(base::FilePath(paths_->Get(credential_cache_path_)),
                   false /* recursive */);

  // 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), false /* recursive */)) {
      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
